Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Nov 2011 16:42:23 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r227567 - stable/8/sbin/fdisk
Message-ID:  <201111161642.pAGGgN4W057626@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Nov 16 16:42:23 2011
New Revision: 227567
URL: http://svn.freebsd.org/changeset/base/227567

Log:
  MFC r227272:
    Add reference to gpart(8).
  
  MFC r227292:
    Improve error reporting when MBR can not be written.
    Remove obsolete code which uses DIOCSMBR ioctl.
    When writing MBR first check that GEOM_MBR is available, if it is not
    available, then try write MBR directly to provider. If both are failed,
    then recommend to use gpart(8).
  
  MFC r227295:
    Fix multi-line comment formatting.
  
    Pointed by:   jh

Modified:
  stable/8/sbin/fdisk/fdisk.8
  stable/8/sbin/fdisk/fdisk.c
Directory Properties:
  stable/8/sbin/fdisk/   (props changed)

Modified: stable/8/sbin/fdisk/fdisk.8
==============================================================================
--- stable/8/sbin/fdisk/fdisk.8	Wed Nov 16 16:29:05 2011	(r227566)
+++ stable/8/sbin/fdisk/fdisk.8	Wed Nov 16 16:42:23 2011	(r227567)
@@ -476,6 +476,7 @@ The default boot code.
 .Sh SEE ALSO
 .Xr boot0cfg 8 ,
 .Xr bsdlabel 8 ,
+.Xr gpart 8 ,
 .Xr newfs 8
 .Sh BUGS
 The default boot code will not necessarily handle all slice types

Modified: stable/8/sbin/fdisk/fdisk.c
==============================================================================
--- stable/8/sbin/fdisk/fdisk.c	Wed Nov 16 16:29:05 2011	(r227566)
+++ stable/8/sbin/fdisk/fdisk.c	Wed Nov 16 16:42:23 2011	(r227567)
@@ -229,6 +229,7 @@ get_type(int t)
 }
 
 
+static int geom_class_available(const char *);
 static void print_s0(void);
 static void print_part(const struct dos_partition *);
 static void init_sector0(unsigned long start);
@@ -764,49 +765,76 @@ read_disk(off_t sector, void *buf)
 }
 
 static int
-write_disk(off_t sector, void *buf)
+geom_class_available(const char *name)
 {
+	struct gclass *class;
+	struct gmesh mesh;
 	int error;
+
+	error = geom_gettree(&mesh);
+	if (error != 0)
+		errc(1, error, "Cannot get GEOM tree");
+
+	LIST_FOREACH(class, &mesh.lg_class, lg_class) {
+		if (strcmp(class->lg_name, name) == 0) {
+			geom_deletetree(&mesh);
+			return (1);
+		}
+	}
+
+	geom_deletetree(&mesh);
+
+	return (0);
+}
+
+static int
+write_disk(off_t sector, void *buf)
+{
 	struct gctl_req *grq;
 	const char *errmsg;
-	char fbuf[BUFSIZ], *pname;
-	int i, fdw;
+	char *pname;
+	int error;
 
-	grq = gctl_get_handle();
-	gctl_ro_param(grq, "verb", -1, "write MBR");
-	gctl_ro_param(grq, "class", -1, "MBR");
-	pname = g_providername(fd);
-	if (pname == NULL) {
-		warn("Error getting providername for %s", disk);
-		return (-1);
-	}
-	gctl_ro_param(grq, "geom", -1, pname);
-	gctl_ro_param(grq, "data", secsize, buf);
-	errmsg = gctl_issue(grq);
-	free(pname);
-	if (errmsg == NULL) {
+	/* Check that GEOM_MBR is available */
+	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");
+		pname = g_providername(fd);
+		if (pname == NULL) {
+			warn("Error getting providername for %s", disk);
+			return (-1);
+		}
+		gctl_ro_param(grq, "geom", -1, pname);
+		gctl_ro_param(grq, "data", secsize, buf);
+		errmsg = gctl_issue(grq);
+		free(pname);
+		if (errmsg == NULL) {
+			gctl_free(grq);
+			return(0);
+		}
+		if (!q_flag)
+			warnx("GEOM_MBR: %s", errmsg);
 		gctl_free(grq);
-		return(0);
-	}
-	if (!q_flag)	/* GEOM errors are benign, not all devices supported */
-		warnx("%s", errmsg);
-	gctl_free(grq);
-
-	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)
+	} else {
+		/*
+		 * Try to write MBR directly. This may help when disk
+		 * is not in use.
+		 * XXX: hardcoded sectorsize
+		 */
+		error = pwrite(fd, buf, secsize, (sector * 512));
+		if (error == secsize)
 			return (0);
 	}
-	warnx("Failed to write sector zero");
+
+	/*
+	 * GEOM_MBR is not available or failed to write MBR.
+	 * Now check that we have GEOM_PART and recommend to use gpart (8).
+	 */
+	if (geom_class_available("PART") != 0)
+		warnx("Failed to write MBR. Try to use gpart(8).");
+	else
+		warnx("Failed to write sector zero");
 	return(EINVAL);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111161642.pAGGgN4W057626>