Esempio n. 1
0
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);
}
Esempio n. 2
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);
}