Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Nov 2011 15:36:53 +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-9@freebsd.org
Subject:   svn commit: r227560 - stable/9/sbin/fdisk
Message-ID:  <201111161536.pAGFarLF055087@svn.freebsd.org>

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

Log:
  MFC r227272:
    Add reference to gpart(8).
  
  MFC r227280:
    Initialize "acc" value inside the loop to reset failed attempts.
  
    PR:           misc/162262
  
  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
  
  Approved by:	re (kib)

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

Modified: stable/9/sbin/fdisk/fdisk.8
==============================================================================
--- stable/9/sbin/fdisk/fdisk.8	Wed Nov 16 15:35:22 2011	(r227559)
+++ stable/9/sbin/fdisk/fdisk.8	Wed Nov 16 15:36:53 2011	(r227560)
@@ -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/9/sbin/fdisk/fdisk.c
==============================================================================
--- stable/9/sbin/fdisk/fdisk.c	Wed Nov 16 15:35:22 2011	(r227559)
+++ stable/9/sbin/fdisk/fdisk.c	Wed Nov 16 15:36:53 2011	(r227560)
@@ -232,6 +232,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);
@@ -767,49 +768,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);
 }
 
@@ -920,11 +948,12 @@ ok(const char *str)
 static int
 decimal(const char *str, int *num, int deflt, uint32_t maxval)
 {
-	long long acc = 0;
+	long long acc;
 	int c;
 	char *cp;
 
 	while (1) {
+		acc = 0;
 		printf("Supply a decimal value for \"%s\" [%d] ", str, deflt);
 		fflush(stdout);
 		if (fgets(lbuf, LBUF, stdin) == NULL)
@@ -960,7 +989,6 @@ decimal(const char *str, int *num, int d
 			printf("%s is an invalid decimal number.  Try again.\n",
 				lbuf);
 	}
-
 }
 
 



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