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
This commit is contained in:
Poul-Henning Kamp 2003-04-23 08:25:20 +00:00
parent bf9ab27afb
commit 97b902efd2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=113896
2 changed files with 61 additions and 24 deletions

View File

@ -5,6 +5,9 @@ SRCS=sunlabel.c geom_sunlabel_enc.c
NOMAN= NOMAN=
WARNS=5 WARNS=5
DDADD= ${LIBGEOM}
LDADD= -lgeom
.PATH: ${.CURDIR}/../../sys/geom .PATH: ${.CURDIR}/../../sys/geom
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <err.h> #include <err.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <libgeom.h>
#include <paths.h> #include <paths.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -91,7 +92,6 @@ static int bflag;
static int Bflag; static int Bflag;
static int eflag; static int eflag;
static int nflag; static int nflag;
static int rflag = 1;
static int Rflag; static int Rflag;
static int wflag; static int wflag;
@ -140,7 +140,7 @@ main(int ac, char **av)
nflag = 1; nflag = 1;
break; break;
case 'r': case 'r':
rflag = 1; fprintf(stderr, "Obsolete -r flag ignored\n");
break; break;
case 'R': case 'R':
Rflag = 1; Rflag = 1;
@ -318,52 +318,86 @@ static void
write_label(struct sun_disklabel *sl, const char *disk, const char *bootpath) write_label(struct sun_disklabel *sl, const char *disk, const char *bootpath)
{ {
char path[MAXPATHLEN]; char path[MAXPATHLEN];
char boot[16 * 512]; char boot[SUN_BOOTSIZE];
char buf[SUN_SIZE]; char buf[SUN_SIZE];
const char *errstr;
off_t off; off_t off;
int bfd; int bfd;
int fd; int fd;
int i; int i;
struct gctl_req *grq;
sl->sl_magic = SUN_DKMAGIC; sl->sl_magic = SUN_DKMAGIC;
if (check_label(sl) != 0) if (check_label(sl) != 0)
errx(1, "invalid label"); errx(1, "invalid label");
bzero(buf, sizeof(buf));
sunlabel_enc(buf, sl);
if (nflag) { if (nflag) {
print_label(sl, disk, stdout); print_label(sl, disk, stdout);
} else if (rflag) { return;
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, disk); }
if ((fd = open(path, O_RDWR)) < 0) if (Bflag) {
err(1, "open %s", path); 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 (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++) { for (i = 0; i < SUN_NPART; i++) {
if (sl->sl_part[i].sdkp_nsectors == 0) if (sl->sl_part[i].sdkp_nsectors == 0)
continue; continue;
off = sl->sl_part[i].sdkp_cyloffset * off = sl->sl_part[i].sdkp_cyloffset *
sl->sl_ntracks * sl->sl_nsectors * 512; 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"); err(1, "lseek");
if (write(fd, boot, sizeof(boot)) != if (write(fd, boot + SUN_SIZE,
sizeof(boot)) sizeof(boot) - SUN_SIZE) !=
sizeof(boot) - SUN_SIZE)
err(1, "write"); 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); close(fd);
} else }
err(1, "implement!"); exit(0);
} }
static int static int