Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Mar 2007 08:01:43 GMT
From:      "Jukka A. Ukkonen"<jau@iki.fi>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/110182: Inability to read and write the same format makes fdisk far less than production quality
Message-ID:  <200703110801.l2B81hGD041609@www.freebsd.org>
Resent-Message-ID: <200703110810.l2B8A3Rv010431@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         110182
>Category:       bin
>Synopsis:       Inability to read and write the same format makes fdisk far less than production quality
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 11 08:10:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Jukka A. Ukkonen
>Release:        6.2-STABLE
>Organization:
private person
>Environment:
FreeBSD mjolnir 6.2-STABLE FreeBSD 6.2-STABLE #1: Wed Mar  7 03:19:18 EET 2007     root@mjolnir:/usr/obj/usr/src/sys/Mjolnir  i386
>Description:
Fdisk being unable to read what it writes does not support true production
environments' need to rebuild new equivalent slice tables to new disks.
At the moment one is forced to manual setting of the correct values or forced
to use locally built ad hoc scripts to convert the output from "fdisk -s".
Manual setting of the correct values is slow and error prone.
Scripted approach is error prone assuming fdisk might actually change one day.

Proper production quality approach is to make fdisk able to read and write
the same format.
This allows for storing existing values on an off-line media for emergensies.
This allows also dumping the slice table from an exsiting disk to a new one
which could be intended e.g. as a new mirror side.

A production level environment always requires ability to rebuild and replace
new disks in a semi-automatic manner such that one can rely on getting exactly
the same parameters as in an older model setup.
Speedy recovery and speedy addition of new (homogenized) storage are core
requirements for production environments.

To support this I added a new command line option -p which does otherwise
exactly the same as -s but in the same simple format fdisk is willing to read.
See the attached patch.

>How-To-Repeat:
Just try to rebuild a new side for a mgirror from scratch using two slices
on each disk.
Use the first slice for mirrored file system area and the second slices
for (interleaved) swap.

Notice! Mirroring the swap area makes really no sense at all, because it
only slows things down.
So, to speed things up even while swap gets used one really needs to make
use of the interleaved nature of swap parallelized on multiple disks.

One could do this using an fdisk configuration file like...
g c8942 h255 s63
p 1 0xa5 63 140504427
a 1
p 2 0xa5 140504490 3148740

But once you have this setup on one disk fdisk does not allow replicating
this to another disk, because with all probability your original slice layout
on the first disk was not generated using an fdisk configuration file but
using sysinstall.
To replicate this setup you really want to dump it out as is to be used as
input for initialization of a secondary disk using fdisk.

>Fix:
Apply the attached patch.
It adds a new option -p to fdisk.
This PR cover the same issue as bin/92723,
but overrides it completely by providing the patch
while also boosting the priority and severity.


Patch attached with submission follows:

--- fdisk.c.orig	Sat Mar 10 09:50:32 2007
+++ fdisk.c	Sat Mar 10 10:45:45 2007
@@ -120,6 +120,7 @@
 static int t_flag  = 0;		/* test only */
 static char *f_flag = NULL;	/* Read config info from file */
 static int v_flag  = 0;		/* Be verbose */
+static int print_config_flag = 0;
 
 static struct part_type
 {
@@ -247,7 +248,7 @@
 	int	partition = -1;
 	struct	dos_partition *partp;
 
-	while ((c = getopt(argc, argv, "BIab:f:istuv1234")) != -1)
+	while ((c = getopt(argc, argv, "BIab:f:ipstuv1234")) != -1)
 		switch (c) {
 		case 'B':
 			B_flag = 1;
@@ -267,6 +268,9 @@
 		case 'i':
 			i_flag = 1;
 			break;
+		case 'p':
+			print_config_flag = 1;
+			break;
 		case 's':
 			s_flag = 1;
 			break;
@@ -322,11 +326,44 @@
 	free(mboot.bootinst);
 	mboot.bootinst = NULL;
 
+	if (print_config_flag) {
+		if (read_s0())
+			err(1, "read_s0");
+
+		printf("g c%d h%d s%d\n", dos_cyls, dos_heads, dos_sectors);
+
+		for (i = 0; i < NDOSPART; i++) {
+			partp = ((struct dos_partition *) &mboot.parts) + i;
+
+			if (partp->dp_start == 0 && partp->dp_size == 0)
+				continue;
+
+			printf ("p %d 0x%02x %lu %lu\n",
+				i + 1,
+				partp->dp_typ,
+				(u_long) partp->dp_start,
+				(u_long) partp->dp_size);
+
+			/*
+			 *  Full flags for the partition.
+			 *
+			 *  printf ("f 0x%02x\n",
+			 *	    partp->dp_flag);
+			 */
+
+			if (partp->dp_flag & 0x80) {
+				printf ("a %d\n", i + 1);
+			}
+		}
+
+		exit(0);
+	}
+
 	if (s_flag) {
 		if (read_s0())
 			err(1, "read_s0");
-		printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads,
-		    dos_sectors);
+		printf("%s: %d cyl %d hd %d sec\n",
+		       disk, dos_cyls, dos_heads, dos_sectors);
 		printf("Part  %11s %11s Type Flags\n", "Start", "Size");
 		for (i = 0; i < NDOSPART; i++) {
 			partp = ((struct dos_partition *) &mboot.parts) + i;
--- src/sbin/fdisk/fdisk.c.orig	Mon Jun 26 04:18:17 2006
+++ src/sbin/fdisk/fdisk.c	Sun Mar 11 08:18:26 2007
@@ -120,6 +120,7 @@
 static int t_flag  = 0;		/* test only */
 static char *f_flag = NULL;	/* Read config info from file */
 static int v_flag  = 0;		/* Be verbose */
+static int print_config_flag = 0;
 
 static struct part_type
 {
@@ -247,7 +248,7 @@
 	int	partition = -1;
 	struct	dos_partition *partp;
 
-	while ((c = getopt(argc, argv, "BIab:f:istuv1234")) != -1)
+	while ((c = getopt(argc, argv, "BIab:f:ipstuv1234")) != -1)
 		switch (c) {
 		case 'B':
 			B_flag = 1;
@@ -267,6 +268,9 @@
 		case 'i':
 			i_flag = 1;
 			break;
+		case 'p':
+			print_config_flag = 1;
+			break;
 		case 's':
 			s_flag = 1;
 			break;
@@ -322,11 +326,44 @@
 	free(mboot.bootinst);
 	mboot.bootinst = NULL;
 
+	if (print_config_flag) {
+		if (read_s0())
+			err(1, "read_s0");
+
+		printf("g c%d h%d s%d\n", dos_cyls, dos_heads, dos_sectors);
+
+		for (i = 0; i < NDOSPART; i++) {
+			partp = ((struct dos_partition *) &mboot.parts) + i;
+
+			if (partp->dp_start == 0 && partp->dp_size == 0)
+				continue;
+
+			printf ("p %d 0x%02x %lu %lu\n",
+				i + 1,
+				partp->dp_typ,
+				(u_long) partp->dp_start,
+				(u_long) partp->dp_size);
+
+			/*
+			 *  Full flags for the partition.
+			 *
+			 *  printf ("f 0x%02x\n",
+			 *	    partp->dp_flag);
+			 */
+
+			if (partp->dp_flag & 0x80) {
+				printf ("a %d\n", i + 1);
+			}
+		}
+
+		exit(0);
+	}
+
 	if (s_flag) {
 		if (read_s0())
 			err(1, "read_s0");
-		printf("%s: %d cyl %d hd %d sec\n", disk, dos_cyls, dos_heads,
-		    dos_sectors);
+		printf("%s: %d cyl %d hd %d sec\n",
+		       disk, dos_cyls, dos_heads, dos_sectors);
 		printf("Part  %11s %11s Type Flags\n", "Start", "Size");
 		for (i = 0; i < NDOSPART; i++) {
 			partp = ((struct dos_partition *) &mboot.parts) + i;

>Release-Note:
>Audit-Trail:
>Unformatted:



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