diff options
author | phk <phk@FreeBSD.org> | 2003-04-23 08:25:20 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-04-23 08:25:20 +0000 |
commit | 47ef37e7e2594b33cff2386732823506b4745261 (patch) | |
tree | e3009d21a482505c2c1188a4879108f3ac8a9961 /sbin/sunlabel | |
parent | 15a332bfd66ed15bc8442e1d7a034e2d61d13085 (diff) | |
download | FreeBSD-src-47ef37e7e2594b33cff2386732823506b4745261.zip FreeBSD-src-47ef37e7e2594b33cff2386732823506b4745261.tar.gz |
If we cannot open the parent device for writing, use GEOM::CONFIG_GEOM
requests to write label and bootcode.
The -r argument is ignored (with a warning).
With a lot of help from: jake
Diffstat (limited to 'sbin/sunlabel')
-rw-r--r-- | sbin/sunlabel/Makefile | 3 | ||||
-rw-r--r-- | sbin/sunlabel/sunlabel.c | 82 |
2 files changed, 61 insertions, 24 deletions
diff --git a/sbin/sunlabel/Makefile b/sbin/sunlabel/Makefile index 68f9575..b06ca03 100644 --- a/sbin/sunlabel/Makefile +++ b/sbin/sunlabel/Makefile @@ -5,6 +5,9 @@ SRCS=sunlabel.c geom_sunlabel_enc.c NOMAN= WARNS=5 +DDADD= ${LIBGEOM} +LDADD= -lgeom + .PATH: ${.CURDIR}/../../sys/geom .include <bsd.prog.mk> diff --git a/sbin/sunlabel/sunlabel.c b/sbin/sunlabel/sunlabel.c index ee0355d..08e6745 100644 --- a/sbin/sunlabel/sunlabel.c +++ b/sbin/sunlabel/sunlabel.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <fcntl.h> #include <inttypes.h> +#include <libgeom.h> #include <paths.h> #include <stdio.h> #include <stdlib.h> @@ -91,7 +92,6 @@ static int bflag; static int Bflag; static int eflag; static int nflag; -static int rflag = 1; static int Rflag; static int wflag; @@ -140,7 +140,7 @@ main(int ac, char **av) nflag = 1; break; case 'r': - rflag = 1; + fprintf(stderr, "Obsolete -r flag ignored\n"); break; case 'R': Rflag = 1; @@ -318,52 +318,86 @@ static void write_label(struct sun_disklabel *sl, const char *disk, const char *bootpath) { char path[MAXPATHLEN]; - char boot[16 * 512]; + char boot[SUN_BOOTSIZE]; char buf[SUN_SIZE]; + const char *errstr; off_t off; int bfd; int fd; int i; + struct gctl_req *grq; sl->sl_magic = SUN_DKMAGIC; if (check_label(sl) != 0) errx(1, "invalid label"); + bzero(buf, sizeof(buf)); + sunlabel_enc(buf, sl); + if (nflag) { print_label(sl, disk, stdout); - } else if (rflag) { - snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk); - if ((fd = open(path, O_RDWR)) < 0) - err(1, "open %s", path); + return; + } + if (Bflag) { + if ((bfd = open(bootpath, O_RDONLY)) < 0) + err(1, "open %s", bootpath); + i = read(bfd, boot, sizeof(boot)); + if (i < 0) + err(1, "read"); + else if (i != sizeof (boot)) + errx(1, "read wrong size boot code (%d)", i); + close(bfd); + } + snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk); + fd = open(path, O_RDWR); + if (fd < 0) { + grq = gctl_get_handle(GCTL_CONFIG_GEOM); + gctl_ro_param(grq, "class", -1, "SUN"); + gctl_ro_param(grq, "geom", -1, disk); + gctl_ro_param(grq, "verb", -1, "write label"); + gctl_ro_param(grq, "label", sizeof buf, buf); + errstr = gctl_issue(grq); + if (errstr != NULL) + errx(1, "%s", errstr); + gctl_free(grq); + if (Bflag) { + grq = gctl_get_handle(GCTL_CONFIG_GEOM); + gctl_ro_param(grq, "class", -1, "SUN"); + gctl_ro_param(grq, "geom", -1, disk); + gctl_ro_param(grq, "verb", -1, "write bootcode"); + gctl_ro_param(grq, "bootcode", sizeof boot, boot); + errstr = gctl_issue(grq); + if (errstr != NULL) + errx(1, "%s", errstr); + gctl_free(grq); + } + } else { + if (lseek(fd, 0, SEEK_SET) < 0) + err(1, "lseek"); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err (1, "write"); if (Bflag) { - if ((bfd = open(bootpath, O_RDONLY)) < 0) - err(1, "open %s", bootpath); - if (read(bfd, boot, sizeof(boot)) != sizeof(boot)) - err(1, "read"); - close(bfd); for (i = 0; i < SUN_NPART; i++) { if (sl->sl_part[i].sdkp_nsectors == 0) continue; off = sl->sl_part[i].sdkp_cyloffset * sl->sl_ntracks * sl->sl_nsectors * 512; - if (lseek(fd, off, SEEK_SET) < 0) + /* + * Ignore first SUN_SIZE bytes of boot code to + * avoid overwriting the label. + */ + if (lseek(fd, off + SUN_SIZE, SEEK_SET) < 0) err(1, "lseek"); - if (write(fd, boot, sizeof(boot)) != - sizeof(boot)) + if (write(fd, boot + SUN_SIZE, + sizeof(boot) - SUN_SIZE) != + sizeof(boot) - SUN_SIZE) err(1, "write"); } } - if (lseek(fd, 0, SEEK_SET) < 0) - err(1, "lseek"); - bzero(buf, sizeof(buf)); - sunlabel_enc(buf, sl); - - if (write(fd, buf, sizeof(buf)) != sizeof(buf)) - err(1, "write"); close(fd); - } else - err(1, "implement!"); + } + exit(0); } static int |