[TEST/REVIEW] boot0cfg/fdisk issue fix

From: Poul-Henning Kamp <phk_at_phk.freebsd.dk>
Date: Tue, 05 Jul 2005 22:44:50 +0200
This is an attempt to fix an boot0cfg/fdisk issue which I have
overlooked.

The patch adds a g_ctl method to geom_mbr and makes boot0cfg and
fdisk use it to modify the MBR if possible.

Please test and report ASAP in order to get this solution into
RELENG_6

Index: sys/geom/geom_mbr.c
===================================================================
RCS file: /home/ncvs/src/sys/geom/geom_mbr.c,v
retrieving revision 1.65
diff -u -r1.65 geom_mbr.c
--- sys/geom/geom_mbr.c	14 Mar 2005 15:22:18 -0000	1.65
+++ sys/geom/geom_mbr.c	5 Jul 2005 20:40:34 -0000
_at__at_ -315,11 +315,54 _at__at_
 	return (gp);
 }
 
+static void
+g_mbr_config(struct gctl_req *req, struct g_class *mp, const char *verb)
+{
+	struct g_geom *gp;
+	struct g_consumer *cp;
+	struct g_mbr_softc *ms;
+	struct g_slicer *gsp;
+	int opened = 0, error = 0;
+	void *data;
+
+	g_topology_assert();
+	gp = gctl_get_geom(req, mp, "geom");
+	if (gp == NULL)
+		return;
+	if (strcmp(verb, "write sector zero")) {
+		gctl_error(req, "Unknown verb");
+		return;
+	}
+	gsp = gp->softc;
+	ms = gsp->softc;
+	data = gctl_get_paraml(req, "data", 512);
+	if (data == NULL)
+		return;
+	cp = LIST_FIRST(&gp->consumer);
+	if (cp->acw == 0) {
+		error = g_access(cp, 0, 1, 0);
+		if (error == 0)
+			opened = 1;
+	}
+	if (!error)
+		error = g_mbr_modify(gp, ms, data);
+	if (error)
+		gctl_error(req, "conflict with open slices");
+	if (!error)
+		error = g_write_data(cp, 0, data, 512);
+	if (error)
+		gctl_error(req, "sector zero write failed");
+	if (opened)
+		g_access(cp, 0, -1 , 0);
+	return;
+}
+
 static struct g_class g_mbr_class	= {
 	.name = MBR_CLASS_NAME,
 	.version = G_VERSION,
 	.taste = g_mbr_taste,
 	.dumpconf = g_mbr_dumpconf,
+	.ctlreq = g_mbr_config,
 	.ioctl = g_mbr_ioctl,
 };
 
Index: sbin/fdisk/Makefile
===================================================================
RCS file: /home/ncvs/src/sbin/fdisk/Makefile,v
retrieving revision 1.11
diff -u -r1.11 Makefile
--- sbin/fdisk/Makefile	23 Feb 2004 20:13:51 -0000	1.11
+++ sbin/fdisk/Makefile	5 Jul 2005 20:28:05 -0000
_at__at_ -7,6 +7,9 _at__at_
 
 .PATH:	${.CURDIR}/../../sys/geom
 
+DPADD	+=	${LIBGEOM}
+LDADD	+=	-lgeom
+
 .include <bsd.prog.mk>
 
 test:	${PROG}
Index: sbin/fdisk/fdisk.c
===================================================================
RCS file: /home/ncvs/src/sbin/fdisk/fdisk.c,v
retrieving revision 1.79
diff -u -r1.79 fdisk.c
--- sbin/fdisk/fdisk.c	1 May 2005 09:50:02 -0000	1.79
+++ sbin/fdisk/fdisk.c	5 Jul 2005 20:36:58 -0000
_at__at_ -38,6 +38,7 _at__at_
 #include <fcntl.h>
 #include <err.h>
 #include <errno.h>
+#include <libgeom.h>
 #include <paths.h>
 #include <regex.h>
 #include <stdint.h>
_at__at_ -80,7 +81,7 _at__at_
 };
 
 static struct mboot mboot;
-static int fd, fdw;
+static int fd;
 
 #define ACTIVE 0x80
 
_at__at_ -226,7 +227,7 _at__at_
 static void dos(struct dos_partition *partp);
 static int open_disk(int flag);
 static ssize_t read_disk(off_t sector, void *buf);
-static ssize_t write_disk(off_t sector, void *buf);
+static int write_disk(off_t sector, void *buf);
 static int get_params(void);
 static int read_s0(void);
 static int write_s0(void);
_at__at_ -692,10 +693,8 _at__at_
 open_disk(int flag)
 {
 	struct stat 	st;
-	int rwmode, p;
-	char *s;
+	int rwmode;
 
-	fdw = -1;
 	if (stat(disk, &st) == -1) {
 		if (errno == ENOENT)
 			return -2;
_at__at_ -706,23 +705,10 _at__at_
 		warnx("device %s is not character special", disk);
 	rwmode = a_flag || I_flag || B_flag || flag ? O_RDWR : O_RDONLY;
 	fd = open(disk, rwmode);
+	if (fd == -1 && errno == EPERM && rwmode == O_RDWR)
+		fd = open(disk, O_RDONLY);
 	if (fd == -1 && errno == ENXIO)
 		return -2;
-	if (fd == -1 && errno == EPERM && rwmode == O_RDWR) {
-		fd = open(disk, O_RDONLY);
-		if (fd == -1)
-			return -3;
-		for (p = 0; p < NDOSPART; p++) {
-			asprintf(&s, "%ss%d", disk, p + 1);
-			fdw = open(s, rwmode);
-			free(s);
-			if (fdw == -1)
-				continue;
-			break;
-		}
-		if (fdw == -1)
-			return -4;
-	}
 	if (fd == -1) {
 		warnx("can't open device %s", disk);
 		return -1;
_at__at_ -755,17 +741,46 _at__at_
 	return -1;
 }
 
-static ssize_t
+static int
 write_disk(off_t sector, void *buf)
 {
-
-	if (fdw != -1) {
-		return ioctl(fdw, DIOCSMBR, buf);
-	} else {
-		lseek(fd, (sector * 512), 0);
-		/* write out in the size that the read_disk found worked */
-		return write(fd, buf, secsize);
+	int error;
+	struct gctl_req *grq;
+	const char *q;
+	char fbuf[BUFSIZ];
+	int i, fdw;
+
+	grq = gctl_get_handle();
+	gctl_ro_param(grq, "verb", -1, "write sector zero");
+	gctl_ro_param(grq, "class", -1, "MBR");
+	q = strrchr(disk, '/');
+	if (q == NULL)
+		q = disk;
+	else
+		q++;
+	gctl_ro_param(grq, "geom", -1, q);
+	gctl_ro_param(grq, "data", secsize, buf);
+	q = gctl_issue(grq);
+	if (q == NULL)
+		return(0);
+	warnx("%s", q);
+	
+	error = pwrite(fd, buf, secsize, (sector * 512));
+	if (error == secsize)
+		return (0);
+
+	for (i = 1; i < 5; i++) {
+		sprintf(fbuf, "%ss%d", disk, i);
+		fdw = open(fbuf, O_RDWR, 0);
+		if (fdw < 0)
+			continue;
+		error = ioctl(fdw, DIOCSMBR, buf);
+		close(fdw);
+		if (error == 0)
+			return (0);
 	}
+	warnx("Failed to write sector zero");
+	return(EINVAL);
 }
 
 static int
Index: usr.sbin/boot0cfg/Makefile
===================================================================
RCS file: /home/ncvs/src/usr.sbin/boot0cfg/Makefile,v
retrieving revision 1.8
diff -u -r1.8 Makefile
--- usr.sbin/boot0cfg/Makefile	4 Apr 2003 17:49:12 -0000	1.8
+++ usr.sbin/boot0cfg/Makefile	5 Jul 2005 20:06:42 -0000
_at__at_ -5,4 +5,7 _at__at_
 
 WARNS?=	2
 
+DPADD=	${LIBGEOM}
+LDADD=	-lgeom
+
 .include <bsd.prog.mk>
Index: usr.sbin/boot0cfg/boot0cfg.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/boot0cfg/boot0cfg.c,v
retrieving revision 1.19
diff -u -r1.19 boot0cfg.c
--- usr.sbin/boot0cfg/boot0cfg.c	18 Dec 2004 11:04:10 -0000	1.19
+++ usr.sbin/boot0cfg/boot0cfg.c	5 Jul 2005 20:19:31 -0000
_at__at_ -35,6 +35,7 _at__at_
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <libgeom.h>
 #include <paths.h>
 #include <stdio.h>
 #include <stdlib.h>
_at__at_ -256,6 +257,8 _at__at_
     int fd, p;
     ssize_t n;
     char *s;
+    const char *q;
+    struct gctl_req *grq;
    
     fd = open(fname, O_WRONLY | flags, 0666);
     if (fd != -1) {
_at__at_ -265,12 +268,30 _at__at_
 	   errx(1, "%s: short write", fname);
 	return;
     }
+
     if (flags != 0)
 	err(1, "%s", fname);
+    grq = gctl_get_handle();
+    gctl_ro_param(grq, "verb", -1, "write sector zero");
+    gctl_ro_param(grq, "class", -1, "MBR");
+    q = strrchr(fname, '/');
+    if (q == NULL)
+	q = fname;
+    else
+	q++;
+    gctl_ro_param(grq, "geom", -1, q);
+    gctl_ro_param(grq, "data", mbr_size, mbr);
+    q = gctl_issue(grq);
+    if (q == NULL)
+	return;
+
+    warnx("%s: %s", fname, q);
+    gctl_free(grq);
+
 #ifdef DIOCSMBR
     for (p = 1; p < 5; p++) {
 	asprintf(&s, "%ss%d", fname, p);
-	fd = open(s, O_RDWR);
+	fd = open(s, O_RDONLY);
 	if (fd < 0) {
 	    free(s);
 	    continue;
-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk_at_FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
Received on Tue Jul 05 2005 - 18:44:54 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:38 UTC