Use new geom.ctl based OAM instead of ioctls.

Various cleanup.
This commit is contained in:
Poul-Henning Kamp 2003-05-03 08:04:24 +00:00
parent a767c3daa3
commit 5daa806da0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114569
2 changed files with 100 additions and 95 deletions

View File

@ -6,6 +6,9 @@ SRCS= bsdlabel.c geom_bsd_enc.c
#MAN+= bsdlabel.5 #MAN+= bsdlabel.5
MAN+= bsdlabel.8 MAN+= bsdlabel.8
DDADD= ${LIBGEOM}
LDADD= -lgeom -lbsdxml -lsbuf
.if ${MACHINE} == "pc98" .if ${MACHINE} == "pc98"
CFLAGS+= -DPC98 CFLAGS+= -DPC98
.endif .endif
@ -16,3 +19,6 @@ CFLAGS+= -DPC98
test: ${PROG} test: ${PROG}
sh ${.CURDIR}/runtest.sh sh ${.CURDIR}/runtest.sh
testx: ${PROG}
sh -x ${.CURDIR}/runtest.sh

View File

@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <libgeom.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
@ -101,12 +102,12 @@ __FBSDID("$FreeBSD$");
#define BIG_NEWFS_CPG 64U #define BIG_NEWFS_CPG 64U
void makelabel(const char *, const char *, struct disklabel *); void makelabel(const char *, const char *, struct disklabel *);
int writelabel(int, void *, struct disklabel *); int writelabel(void *, struct disklabel *);
void l_perror(const char *); void l_perror(const char *);
struct disklabel *readlabel(int); struct disklabel *readlabel(void);
struct disklabel *makebootarea(void *, struct disklabel *, int); struct disklabel *makebootarea(void *, struct disklabel *);
void display(FILE *, const struct disklabel *); void display(FILE *, const struct disklabel *);
int edit(struct disklabel *, int); int edit(struct disklabel *);
int editit(void); int editit(void);
char *skip(char *); char *skip(char *);
char *word(char *); char *word(char *);
@ -122,9 +123,9 @@ struct disklabel *getvirginlabel(void);
char *dkname; char *dkname;
char *specname; char *specname;
char *rawname;
char tmpfil[] = PATH_TMPFILE; char tmpfil[] = PATH_TMPFILE;
char namebuf[BBSIZE], *np = namebuf;
struct disklabel lab; struct disklabel lab;
int64_t bootarea[BBSIZE / 8]; int64_t bootarea[BBSIZE / 8];
char blank[] = ""; char blank[] = "";
@ -154,7 +155,6 @@ enum {
} op = UNSPEC; } op = UNSPEC;
int rflag;
int disable_write; /* set to disable writing to disk label */ int disable_write; /* set to disable writing to disk label */
int int
@ -162,7 +162,7 @@ main(int argc, char *argv[])
{ {
struct disklabel *lp; struct disklabel *lp;
FILE *t; FILE *t;
int ch, f = 0, error = 0; int ch, error = 0;
char *name = 0; char *name = 0;
while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1) while ((ch = getopt(argc, argv, "Bb:em:nRrs:w")) != -1)
@ -198,7 +198,6 @@ main(int argc, char *argv[])
op = EDIT; op = EDIT;
break; break;
case 'r': case 'r':
++rflag;
break; break;
case 'w': case 'w':
if (op != UNSPEC) if (op != UNSPEC)
@ -212,7 +211,6 @@ main(int argc, char *argv[])
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (installboot) { if (installboot) {
rflag++;
if (op == UNSPEC) if (op == UNSPEC)
op = WRITEBOOT; op = WRITEBOOT;
} else { } else {
@ -223,25 +221,16 @@ main(int argc, char *argv[])
if (argc < 1) if (argc < 1)
usage(); usage();
dkname = argv[0]; /* Figure out the names of the thing we're working on */
if (dkname[0] != '/') { if (argv[0][0] != '/') {
(void)sprintf(np, "%s%s%c", _PATH_DEV, dkname, 'a' + RAW_PART); dkname = argv[0];
specname = np; asprintf(&specname, "%s%s", _PATH_DEV, argv[0]);
np += strlen(specname) + 1; } else {
} else dkname = strrchr(argv[0], '/');
specname = dkname; dkname++;
f = open(specname, op == READ ? O_RDONLY : O_RDWR); specname = argv[0];
if (f < 0 && errno == ENOENT && dkname[0] != '/') {
(void)sprintf(specname, "%s%s", _PATH_DEV, dkname);
np = namebuf + strlen(specname) + 1;
f = open(specname, op == READ ? O_RDONLY : O_RDWR);
} }
if (f < 0 && errno == EBUSY) { asprintf(&rawname, "%s%c", specname, 'a' + RAW_PART);
/* lets try to get by with ioctls */
f = open(specname, O_RDONLY);
}
if (f < 0)
err(4, "%s", specname);
switch(op) { switch(op) {
@ -251,14 +240,14 @@ main(int argc, char *argv[])
case EDIT: case EDIT:
if (argc != 1) if (argc != 1)
usage(); usage();
lp = readlabel(f); lp = readlabel();
error = edit(lp, f); error = edit(lp);
break; break;
case READ: case READ:
if (argc != 1) if (argc != 1)
usage(); usage();
lp = readlabel(f); lp = readlabel();
display(stdout, lp); display(stdout, lp);
error = checklabel(lp); error = checklabel(lp);
break; break;
@ -267,12 +256,12 @@ main(int argc, char *argv[])
if (argc != 2) if (argc != 2)
usage(); usage();
if (!(t = fopen(argv[1], "r"))) if (!(t = fopen(argv[1], "r")))
err(4, "%s", argv[1]); err(4, "fopen %s", argv[1]);
if (!getasciilabel(t, &lab)) if (!getasciilabel(t, &lab))
exit(1); exit(1);
lp = makebootarea(bootarea, &lab, f); lp = makebootarea(bootarea, &lab);
*lp = lab; *lp = lab;
error = writelabel(f, bootarea, lp); error = writelabel(bootarea, lp);
break; break;
case WRITE: case WRITE:
@ -283,24 +272,24 @@ main(int argc, char *argv[])
if (argc != 2) if (argc != 2)
usage(); usage();
makelabel(argv[1], name, &lab); makelabel(argv[1], name, &lab);
lp = makebootarea(bootarea, &lab, f); lp = makebootarea(bootarea, &lab);
*lp = lab; *lp = lab;
if (checklabel(lp) == 0) if (checklabel(lp) == 0)
error = writelabel(f, bootarea, lp); error = writelabel(bootarea, lp);
break; break;
case WRITEBOOT: case WRITEBOOT:
{ {
struct disklabel tlab; struct disklabel tlab;
lp = readlabel(f); lp = readlabel();
tlab = *lp; tlab = *lp;
if (argc == 2) if (argc == 2)
makelabel(argv[1], 0, &lab); makelabel(argv[1], 0, &lab);
lp = makebootarea(bootarea, &lab, f); lp = makebootarea(bootarea, &lab);
*lp = tlab; *lp = tlab;
if (checklabel(lp) == 0) if (checklabel(lp) == 0)
error = writelabel(f, bootarea, lp); error = writelabel(bootarea, lp);
break; break;
} }
} }
@ -328,10 +317,12 @@ makelabel(const char *type, const char *name, struct disklabel *lp)
} }
int int
writelabel(int f, void *boot, struct disklabel *lp) writelabel(void *boot, struct disklabel *lp)
{ {
uint64_t *p, sum; uint64_t *p, sum;
int i; int i, fd;
struct gctl_req *grq;
char const *errstr;
if (disable_write) { if (disable_write) {
Warning("write to disk label supressed - label was as follows:"); Warning("write to disk label supressed - label was as follows:");
@ -343,31 +334,43 @@ writelabel(int f, void *boot, struct disklabel *lp)
lp->d_magic2 = DISKMAGIC; lp->d_magic2 = DISKMAGIC;
lp->d_checksum = 0; lp->d_checksum = 0;
lp->d_checksum = dkcksum(lp); lp->d_checksum = dkcksum(lp);
if (!rflag) {
if (ioctl(f, DIOCWDINFO, lp) < 0) {
l_perror("ioctl DIOCWDINFO");
return (1);
}
return (0);
}
bsd_disklabel_le_enc((u_char *)boot + labeloffset, lp); bsd_disklabel_le_enc((u_char *)boot + labeloffset, lp);
(void)lseek(f, (off_t)0, SEEK_SET);
if (alphacksum) { if (alphacksum) {
/* /* Generate the bootblock checksum for the SRM console. */
* Generate the bootblock checksum for the SRM console.
*/
for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++) for (p = (uint64_t *)boot, i = 0, sum = 0; i < 63; i++)
sum += p[i]; sum += p[i];
p[63] = sum; p[63] = sum;
} }
if (ioctl(f, DIOCBSDBB, &boot) == 0)
return (0); fd = open(specname, O_RDWR);
if (write(f, boot, bbsize) != bbsize) { if (fd < 0) {
warn("write"); grq = gctl_get_handle(GCTL_CONFIG_GEOM);
return (1); gctl_ro_param(grq, "class", -1, "BSD");
gctl_ro_param(grq, "geom", -1, dkname);
gctl_ro_param(grq, "verb", -1, "write label");
gctl_ro_param(grq, "label", 148+16*8, (u_char *)boot + labeloffset);
errstr = gctl_issue(grq);
if (errstr != NULL)
errx(1, "%s", errstr);
gctl_free(grq);
if (installboot) {
grq = gctl_get_handle(GCTL_CONFIG_GEOM);
gctl_ro_param(grq, "class", -1, "BSD");
gctl_ro_param(grq, "geom", -1, dkname);
gctl_ro_param(grq, "verb", -1, "write bootcode");
gctl_ro_param(grq, "bootcode", BBSIZE, boot);
errstr = gctl_issue(grq);
if (errstr != NULL)
errx(1, "%s", errstr);
gctl_free(grq);
}
} else {
if (write(fd, boot, bbsize) != bbsize) {
warn("write %s", specname);
close (fd);
return (1);
}
close (fd);
} }
return (0); return (0);
} }
@ -407,14 +410,21 @@ l_perror(const char *s)
* Use ioctl to get label unless -r flag is given. * Use ioctl to get label unless -r flag is given.
*/ */
struct disklabel * struct disklabel *
readlabel(int f) readlabel(void)
{ {
int f;
int error;
f = open(specname, O_RDONLY);
if (f < 0)
err(1, specname);
(void)lseek(f, (off_t)0, SEEK_SET); (void)lseek(f, (off_t)0, SEEK_SET);
if (read(f, bootarea, BBSIZE) < BBSIZE) if (read(f, bootarea, BBSIZE) < BBSIZE)
err(4, "%s", specname); err(4, "%s read", specname);
bsd_disklabel_le_dec((u_char *)bootarea + labeloffset, &lab, error = bsd_disklabel_le_dec((u_char *)bootarea + labeloffset, &lab, MAXPARTITIONS);
MAXPARTITIONS); if (error)
errx(1, "%s: invalid bsd label", specname);
close (f);
return (&lab); return (&lab);
} }
@ -423,12 +433,10 @@ readlabel(int f)
* Returns a pointer to the disklabel portion of the bootarea. * Returns a pointer to the disklabel portion of the bootarea.
*/ */
struct disklabel * struct disklabel *
makebootarea(void *boot, struct disklabel *dp, int f) makebootarea(void *boot, struct disklabel *dp)
{ {
struct disklabel *lp; struct disklabel *lp;
char *p;
int b; int b;
char *dkbasename;
struct stat sb; struct stat sb;
uint64_t *bootinfo; uint64_t *bootinfo;
int n; int n;
@ -440,6 +448,7 @@ makebootarea(void *boot, struct disklabel *dp, int f)
} }
lp = (struct disklabel *)((char *)boot + labeloffset); lp = (struct disklabel *)((char *)boot + labeloffset);
bzero((char *)lp, sizeof *lp); bzero((char *)lp, sizeof *lp);
#if 0
/* /*
* If we are not installing a boot program but we are installing a * If we are not installing a boot program but we are installing a
* label on disk then we must read the current bootarea so we don't * label on disk then we must read the current bootarea so we don't
@ -451,25 +460,13 @@ makebootarea(void *boot, struct disklabel *dp, int f)
bzero((char *)lp, sizeof *lp); bzero((char *)lp, sizeof *lp);
return (lp); return (lp);
} }
#endif
/* /*
* We are installing a boot program. Determine the name(s) and * We are installing a boot program. Determine the name(s) and
* read them into the appropriate places in the boot area. * read them into the appropriate places in the boot area.
*/ */
if (!xxboot) { if (xxboot == NULL)
dkbasename = np; asprintf(&xxboot, "%s/boot", _PATH_BOOTDIR);
if ((p = rindex(dkname, '/')) == NULL)
p = dkname;
else
p++;
while (*p && !isdigit(*p))
*np++ = *p++;
*np++ = '\0';
if (!xxboot) {
(void)sprintf(boot0, "%s/boot", _PATH_BOOTDIR);
xxboot = boot0;
}
}
b = open(xxboot, O_RDONLY); b = open(xxboot, O_RDONLY);
if (b < 0) if (b < 0)
@ -477,9 +474,15 @@ makebootarea(void *boot, struct disklabel *dp, int f)
if (fstat(b, &sb) != 0) if (fstat(b, &sb) != 0)
err(4, "%s", xxboot); err(4, "%s", xxboot);
if (alphacksum) { if (sb.st_size == BBSIZE) {
if (sb.st_size > BBSIZE - dp->d_secsize) n = read(b, (char *)boot, bbsize);
errx(4, "%s too large", xxboot); if (n != bbsize)
err(4, "%s", xxboot);
} else if (alphacksum) {
if (sb.st_size != BBSIZE - dp->d_secsize)
errx(4, "%s wrong size (%jd bytes, expected %jd bytes)",
xxboot, (intmax_t)sb.st_size,
(intmax_t)BBSIZE - dp->d_secsize);
/* /*
* On the alpha, the primary bootstrap starts at the * On the alpha, the primary bootstrap starts at the
* second sector of the boot area. The first sector * second sector of the boot area. The first sector
@ -495,12 +498,8 @@ makebootarea(void *boot, struct disklabel *dp, int f)
bootinfo[1] = 1; /* start at sector 1 */ bootinfo[1] = 1; /* start at sector 1 */
bootinfo[2] = 0; /* flags (must be zero) */ bootinfo[2] = 0; /* flags (must be zero) */
} else { } else {
if (sb.st_size != bbsize) errx(4, "%s is wrong size, is %jd bytes, expected %d bytes",
errx(4, "%s is wrong size, is %jd bytes, expected %d bytes",
xxboot, (intmax_t)sb.st_size, bbsize); xxboot, (intmax_t)sb.st_size, bbsize);
n = read(b, (char *)boot, bbsize);
if (n != bbsize)
err(4, "%s", xxboot);
} }
(void)close(b); (void)close(b);
@ -609,7 +608,7 @@ display(FILE *f, const struct disklabel *lp)
} }
int int
edit(struct disklabel *lp, int f) edit(struct disklabel *lp)
{ {
int c, fd; int c, fd;
struct disklabel label; struct disklabel label;
@ -633,7 +632,7 @@ edit(struct disklabel *lp, int f)
bzero((char *)&label, sizeof(label)); bzero((char *)&label, sizeof(label));
if (getasciilabel(fp, &label)) { if (getasciilabel(fp, &label)) {
*lp = label; *lp = label;
if (writelabel(f, bootarea, lp) == 0) { if (writelabel(bootarea, lp) == 0) {
fclose(fp); fclose(fp);
(void) unlink(tmpfil); (void) unlink(tmpfil);
return (0); return (0);
@ -1441,13 +1440,13 @@ usage(void)
fprintf(stderr, fprintf(stderr,
"%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: bsdlabel [-r] disk", "usage: bsdlabel disk",
"\t\t(to read label)", "\t\t(to read label)",
" bsdlabel -w [-nr] [-m machine] disk type [packid]", " bsdlabel -w [-n] [-m machine] disk type [packid]",
"\t\t(to write label with existing boot program)", "\t\t(to write label with existing boot program)",
" bsdlabel -e [-nr] [-m machine] disk", " bsdlabel -e [-n] [-m machine] disk",
"\t\t(to edit label)", "\t\t(to edit label)",
" bsdlabel -R [-nr] [-m machine] disk protofile", " bsdlabel -R [-n] [-m machine] disk protofile",
"\t\t(to restore label with existing boot program)", "\t\t(to restore label with existing boot program)",
" bsdlabel -B [-b boot] [-m machine] disk", " bsdlabel -B [-b boot] [-m machine] disk",
"\t\t(to install boot program with existing on-disk label)", "\t\t(to install boot program with existing on-disk label)",