static int writelabel(void) { int i, fd, serrno; struct gctl_req *grq; char const *errstr; struct disklabel *lp = &lab; if (disable_write) { warnx("write to disk label suppressed - label was as follows:"); display(stdout, NULL); return (0); } lp->d_magic = DISKMAGIC; lp->d_magic2 = DISKMAGIC; lp->d_checksum = 0; lp->d_checksum = dkcksum(lp); if (installboot) readboot(); for (i = 0; i < lab.d_npartitions; i++) if (lab.d_partitions[i].p_size) lab.d_partitions[i].p_offset += lba_offset; bsd_disklabel_le_enc(bootarea + labeloffset + labelsoffset * lab.d_secsize, lp); fd = open(specname, O_RDWR); if (fd < 0) { if (is_file) { warn("cannot open file %s for writing label", specname); return(1); } else serrno = errno; if (geom_class_available("PART") != 0) { /* * Since we weren't able open provider for * writing, then recommend user to use gpart(8). */ warnc(serrno, "cannot open provider %s for writing label", specname); warnx("Try to use gpart(8)."); return (1); } /* Give up if GEOM_BSD is not available. */ if (geom_class_available("BSD") == 0) { warnc(serrno, "%s", specname); return (1); } grq = gctl_get_handle(); gctl_ro_param(grq, "verb", -1, "write label"); gctl_ro_param(grq, "class", -1, "BSD"); gctl_ro_param(grq, "geom", -1, pname); gctl_ro_param(grq, "label", 148+16*8, bootarea + labeloffset + labelsoffset * lab.d_secsize); errstr = gctl_issue(grq); if (errstr != NULL) { warnx("%s", errstr); gctl_free(grq); return(1); } gctl_free(grq); if (installboot) { grq = gctl_get_handle(); gctl_ro_param(grq, "verb", -1, "write bootcode"); gctl_ro_param(grq, "class", -1, "BSD"); gctl_ro_param(grq, "geom", -1, pname); gctl_ro_param(grq, "bootcode", BBSIZE, bootarea); errstr = gctl_issue(grq); if (errstr != NULL) { warnx("%s", errstr); gctl_free(grq); return (1); } gctl_free(grq); } } else { if (write(fd, bootarea, bbsize) != bbsize) { warn("write %s", specname); close (fd); return (1); } close (fd); } return (0); }
/* * Write out the mbr to the specified file. */ static void write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) { struct gctl_req *grq; const char *errmsg; char *pname; ssize_t n; int fd; fd = open(fname, O_WRONLY | flags, 0666); if (fd != -1) { n = write(fd, mbr, mbr_size); close(fd); if (n != mbr_size) errx(1, "%s: short write", fname); return; } /* * If we're called to write to a backup file, don't try to * write through GEOM. */ if (flags != 0) err(1, "can't open file %s to write backup", fname); /* Try open it read only. */ fd = open(fname, O_RDONLY); if (fd == -1) { warn("error opening %s", fname); return; } pname = g_providername(fd); if (pname == NULL) { warn("error getting providername for %s", fname); return; } /* First check that GEOM_PART is available */ if (geom_class_available("PART") != 0) { grq = gctl_get_handle(); gctl_ro_param(grq, "class", -1, "PART"); gctl_ro_param(grq, "arg0", -1, pname); gctl_ro_param(grq, "verb", -1, "bootcode"); gctl_ro_param(grq, "bootcode", mbr_size, mbr); gctl_ro_param(grq, "flags", -1, "C"); errmsg = gctl_issue(grq); if (errmsg != NULL && errmsg[0] != '\0') errx(1, "GEOM_PART: write bootcode to %s failed: %s", fname, errmsg); gctl_free(grq); } else if (geom_class_available("MBR") != 0) { grq = gctl_get_handle(); gctl_ro_param(grq, "verb", -1, "write MBR"); gctl_ro_param(grq, "class", -1, "MBR"); gctl_ro_param(grq, "geom", -1, pname); gctl_ro_param(grq, "data", mbr_size, mbr); errmsg = gctl_issue(grq); if (errmsg != NULL) err(1, "GEOM_MBR: write MBR to %s failed", fname); gctl_free(grq); } else errx(1, "can't write MBR to %s", fname); free(pname); }