- Make use of the new and g_device_path utility function in libgeom to avoid

duplication of code in fdisk and boot0cfg. Also make use of g_providername to
  fix an issue with fdisk and boot0cfg not using the correct provider when
  writing the MBR.

Reviewed by:	phk
Approved by:	pjd (mentor)
This commit is contained in:
Ulf Lilleengen 2008-09-07 13:58:35 +00:00
parent f805f204b6
commit b31e5ae243
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182844
2 changed files with 53 additions and 82 deletions

View file

@ -245,7 +245,6 @@ static void usage(void);
int
main(int argc, char *argv[])
{
struct stat sb;
int c, i;
int partition = -1;
struct dos_partition *partp;
@ -307,18 +306,9 @@ main(int argc, char *argv[])
if (argc == 0) {
disk = get_rootdisk();
} else {
if (stat(argv[0], &sb) == 0) {
/* OK, full pathname given */
disk = argv[0];
} else if (errno == ENOENT && argv[0][0] != '/') {
/* Try prepending "/dev" */
asprintf(&disk, "%s%s", _PATH_DEV, argv[0]);
if (disk == NULL)
errx(1, "out of memory");
} else {
/* other stat error, let it fail below */
disk = argv[0];
}
disk = g_device_path(argv[0]);
if (disk == NULL)
err(1, "unable to get correct path for %s\n", argv[0]);
}
if (open_disk(u_flag) < 0)
err(1, "cannot open disk %s", disk);
@ -724,21 +714,14 @@ dos(struct dos_partition *partp)
static int
open_disk(int flag)
{
struct stat st;
int rwmode;
if (stat(disk, &st) == -1) {
if (errno == ENOENT)
return -2;
warnx("can't get file status of %s", disk);
return -1;
}
if ( !(st.st_mode & S_IFCHR) )
warnx("device %s is not character special", disk);
rwmode = a_flag || I_flag || B_flag || flag ? O_RDWR : O_RDONLY;
fd = open(disk, rwmode);
if (fd == -1 && errno == EPERM && rwmode == O_RDWR)
fd = open(disk, O_RDONLY);
/* Write mode if one of these flags are set. */
rwmode = (a_flag || I_flag || B_flag || flag);
fd = g_open(disk, rwmode);
/* If the mode fails, try read-only if we didn't. */
if (fd == -1 && errno == EPERM && rwmode)
fd = g_open(disk, 0);
if (fd == -1 && errno == ENXIO)
return -2;
if (fd == -1) {
@ -778,29 +761,30 @@ write_disk(off_t sector, void *buf)
{
int error;
struct gctl_req *grq;
const char *q;
char fbuf[BUFSIZ];
const char *errmsg;
char fbuf[BUFSIZ], *pname;
int i, fdw;
grq = gctl_get_handle();
gctl_ro_param(grq, "verb", -1, "write MBR");
gctl_ro_param(grq, "class", -1, "MBR");
q = strrchr(disk, '/');
if (q == NULL)
q = disk;
else
q++;
gctl_ro_param(grq, "geom", -1, q);
pname = g_providername(fd);
if (pname == NULL) {
warnx("Error getting providername for %s\n", disk);
return (-1);
}
gctl_ro_param(grq, "geom", -1, pname);
gctl_ro_param(grq, "data", secsize, buf);
q = gctl_issue(grq);
if (q == NULL) {
errmsg = gctl_issue(grq);
free(pname);
if (errmsg == NULL) {
gctl_free(grq);
return(0);
}
if (!q_flag) /* GEOM errors are benign, not all devices supported */
warnx("%s", q);
warnx("%s", errmsg);
gctl_free(grq);
error = pwrite(fd, buf, secsize, (sector * 512));
if (error == secsize)
return (0);
@ -841,21 +825,18 @@ get_params()
dos_cylsecs = cylsecs = heads * sectors;
disksecs = cyls * heads * sectors;
error = ioctl(fd, DIOCGSECTORSIZE, &u);
if (error != 0 || u == 0)
u = 512;
else
secsize = u;
u = g_sectorsize(fd);
if (u <= 0)
return (-1);
error = ioctl(fd, DIOCGMEDIASIZE, &o);
if (error == 0) {
disksecs = o / u;
cyls = dos_cyls = o / (u * dos_heads * dos_sectors);
}
o = g_mediasize(fd);
if (o < 0)
return (-1);
disksecs = o / u;
cyls = dos_cyls = o / (u * dos_heads * dos_sectors);
return (disksecs);
}
static int
read_s0()

View file

@ -80,7 +80,6 @@ static void display_mbr(u_int8_t *);
static int boot0version(const u_int8_t *);
static int boot0bs(const u_int8_t *);
static void stropt(const char *, int *, int *);
static char *mkrdev(const char *);
static int argtoi(const char *, int, int, int);
static void usage(void);
@ -142,7 +141,9 @@ main(int argc, char *argv[])
argv += optind;
if (argc != 1)
usage();
disk = mkrdev(*argv);
disk = g_device_path(*argv);
if (disk == NULL)
errx(1, "Unable to get providername for %s\n", *argv);
up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1
|| t_arg != -1;
@ -257,7 +258,8 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
int fd, p;
ssize_t n;
char *s;
const char *q;
const char *errmsg;
char *pname;
struct gctl_req *grq;
fd = open(fname, O_WRONLY | flags, 0666);
@ -269,23 +271,31 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
return;
}
/* Try open it read only. */
fd = open(fname, O_RDONLY);
if (fd == -1) {
warnx("Error opening %s\n", fname);
return;
}
pname = g_providername(fd);
if (pname == NULL) {
warnx("Error getting providername for %s\n", fname);
return;
}
if (flags != 0)
err(1, "%s", fname);
grq = gctl_get_handle();
gctl_ro_param(grq, "verb", -1, "write MBR");
gctl_ro_param(grq, "class", -1, "MBR");
q = strrchr(fname, '/');
if (q == NULL)
q = fname;
else
q++;
gctl_ro_param(grq, "geom", -1, q);
gctl_ro_param(grq, "geom", -1, pname);
gctl_ro_param(grq, "data", mbr_size, mbr);
q = gctl_issue(grq);
if (q == NULL)
errmsg = gctl_issue(grq);
if (errmsg == NULL) {
free(pname);
return;
warnx("%s: %s", fname, q);
}
warnx("%s: %s", fname, pname);
free(pname);
gctl_free(grq);
#ifdef DIOCSMBR
@ -421,26 +431,6 @@ stropt(const char *arg, int *xa, int *xo)
free(s);
}
/*
* Produce a device path for a "canonical" name, where appropriate.
*/
static char *
mkrdev(const char *fname)
{
char buf[MAXPATHLEN];
char *s;
if (!strchr(fname, '/')) {
snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
s = strdup(buf);
} else
s = strdup(fname);
if (s == NULL)
errx(1, "No more memory");
return s;
}
/*
* Convert and check an option argument.
*/