From owner-freebsd-bugs@FreeBSD.ORG Sun Mar 11 08:10:03 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id E4B7816A4DE for ; Sun, 11 Mar 2007 08:10:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id BBAFE13C442 for ; Sun, 11 Mar 2007 08:10:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l2B8A3J6010432 for ; Sun, 11 Mar 2007 08:10:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l2B8A3Rv010431; Sun, 11 Mar 2007 08:10:03 GMT (envelope-from gnats) Resent-Date: Sun, 11 Mar 2007 08:10:03 GMT Resent-Message-Id: <200703110810.l2B8A3Rv010431@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Jukka A. Ukkonen" Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C30B316A400 for ; Sun, 11 Mar 2007 08:01:44 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [69.147.83.33]) by mx1.freebsd.org (Postfix) with ESMTP id AF41913C481 for ; Sun, 11 Mar 2007 08:01:44 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l2B81iJ9041611 for ; Sun, 11 Mar 2007 08:01:44 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id l2B81hGD041609; Sun, 11 Mar 2007 08:01:43 GMT (envelope-from nobody) Message-Id: <200703110801.l2B81hGD041609@www.freebsd.org> Date: Sun, 11 Mar 2007 08:01:43 GMT From: "Jukka A. Ukkonen" To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.0 Cc: Subject: bin/110182: Inability to read and write the same format makes fdisk far less than production quality X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Mar 2007 08:10:04 -0000 >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: