From owner-freebsd-arch Thu Nov 2 14:32:44 2000 Delivered-To: freebsd-arch@freebsd.org Received: from mail.wgate.com (mail.wgate.com [38.219.83.4]) by hub.freebsd.org (Postfix) with ESMTP id 88D1337B4C5 for ; Thu, 2 Nov 2000 14:32:23 -0800 (PST) Received: from jesup.eng.tvol.net ([10.32.2.26]) by mail.wgate.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21) id VT2YB77J; Thu, 2 Nov 2000 17:32:29 -0500 Reply-To: Randell Jesup To: Matt Dillon Cc: Randell Jesup , Marius Bendiksen , arch@FreeBSD.ORG, Warner Losh Subject: Re: Like to commit my diskprep References: <200011021632.eA2GWZ138286@earth.backplane.com> <200011021725.eA2HPeM38718@earth.backplane.com> From: Randell Jesup Date: 02 Nov 2000 17:36:15 -0500 In-Reply-To: Matt Dillon's message of "Thu, 2 Nov 2000 09:25:40 -0800 (PST)" Message-ID: User-Agent: Gnus/5.0807 (Gnus v5.8.7) Emacs/20.7 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Following are changes to disklabel.c to change it to be much more user- friendly (and kick out more warnings for things like overlapped partitions). It supports the syntax I mentioned before: [snipped to keep things smaller] # size offset fstype [fsize bsize bps/cpg] a: 819200 0 4.2BSD 4096 16384 75 # (Cyl. 0 - 812*) b: 800M 819200 swap c: * 0 unused 0 0 e: 10% * 4.2BSD f: 5g * 4.2BSD g: * * 4.2BSD Note that I support both % and * for hog partitions. % is calculated as a %age of space remaining after all fixed-size partitions are dealt with, and * for size (hog) gets anything left after that. * for offset means "calculate it your damn self, disklabel, I don't care". :-) If fsize/etc aren't specified, it uses defaults. This might want to be improved (better defaults, as per other conversation). I also added a -n option to supress writing labels to the slice. Handy for testing!!! If -n is used, it'll dump what it would have written to stdout. WARNING: Playing with disklabel CAN frag your disk!!!!! Todo: add warnings about incompatibilities between old and new labels. update manpage change newfs defaults not require "0 0" after an unused partition. -- Randell Jesup, Worldgate Communications, ex-Scala, ex-Amiga OS team ('88-94) rjesup@wgate.com *** /usr/src/sbin/disklabel/disklabel.c Sat Jul 1 02:47:46 2000 --- disklabel.c Thu Nov 2 15:29:04 2000 *************** *** 80,85 **** --- 80,91 ---- #define BBSIZE 8192 /* size of boot area, with label */ #endif + /* FIX! These are too low, but are traditional */ + #define DEFAULT_NEWFS_BLOCK 8192U + #define DEFAULT_NEWFS_FRAG 1024U + #define DEFAULT_NEWFS_CPG 16U + + #ifdef tahoe #define NUMBOOT 0 #else *************** *** 119,124 **** --- 125,138 ---- struct disklabel lab; char bootarea[BBSIZE]; + /* partition 'c' is the full disk and is special */ + #define FULL_DISK_PART 2 + #define MAX_PART ('z') + #define MAX_NUM_PARTS (1 + MAX_PART-'a') + char part_size_type[MAX_NUM_PARTS]; + char part_offset_type[MAX_NUM_PARTS]; + int part_set[MAX_NUM_PARTS]; + #if NUMBOOT > 0 int installboot; /* non-zero if we should install a boot program */ char *bootbuf; /* pointer to buffer with remainder of boot prog */ *************** *** 134,145 **** } op = UNSPEC; int rflag; #ifdef DEBUG int debug; ! #define OPTIONS "BNRWb:ders:w" #else ! #define OPTIONS "BNRWb:ers:w" #endif int --- 148,160 ---- } op = UNSPEC; int rflag; + int disable_write; /* set to disable writing to disk label */ #ifdef DEBUG int debug; ! #define OPTIONS "BNRWb:denrs:w" #else ! #define OPTIONS "BNRWb:enrs:w" #endif int *************** *** 152,157 **** --- 167,174 ---- int ch, f = 0, flag, error = 0; char *name = 0; + disable_write = 0; /* paranoia */ + while ((ch = getopt(argc, argv, OPTIONS)) != -1) switch (ch) { #if NUMBOOT > 0 *************** *** 172,177 **** --- 189,197 ---- usage(); op = NOWRITE; break; + case 'n': + disable_write = 1; + break; case 'R': if (op != UNSPEC) usage(); *************** *** 398,473 **** register int i; #endif ! setbootflag(lp); ! lp->d_magic = DISKMAGIC; ! lp->d_magic2 = DISKMAGIC; ! lp->d_checksum = 0; ! lp->d_checksum = dkcksum(lp); ! if (rflag) { ! /* ! * First set the kernel disk label, ! * then write a label to the raw disk. ! * If the SDINFO ioctl fails because it is unimplemented, ! * keep going; otherwise, the kernel consistency checks ! * may prevent us from changing the current (in-core) ! * label. ! */ ! if (ioctl(f, DIOCSDINFO, lp) < 0 && ! errno != ENODEV && errno != ENOTTY) { ! l_perror("ioctl DIOCSDINFO"); ! return (1); ! } ! (void)lseek(f, (off_t)0, SEEK_SET); ! #ifdef __alpha__ ! /* ! * Generate the bootblock checksum for the SRM console. ! */ ! for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++) ! sum += p[i]; ! p[63] = sum; #endif ! ! /* ! * write enable label sector before write (if necessary), ! * disable after writing. ! */ ! flag = 1; ! if (ioctl(f, DIOCWLABEL, &flag) < 0) ! warn("ioctl DIOCWLABEL"); ! if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { ! warn("write"); ! return (1); ! } #if NUMBOOT > 0 ! /* ! * Output the remainder of the disklabel ! */ ! if (bootbuf && write(f, bootbuf, bootsize) != bootsize) { ! warn("write"); ! return(1); ! } #endif ! flag = 0; ! (void) ioctl(f, DIOCWLABEL, &flag); ! } else if (ioctl(f, DIOCWDINFO, lp) < 0) { ! l_perror("ioctl DIOCWDINFO"); ! return (1); ! } #ifdef vax ! if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { ! daddr_t alt; ! ! alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; ! for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { ! (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), ! SEEK_SET); ! if (write(f, boot, lp->d_secsize) < lp->d_secsize) ! warn("alternate label %d write", i/2); } - } #endif ! return (0); } void --- 418,502 ---- register int i; #endif ! if (disable_write) ! { ! Warning("write to disk label supressed - label was as follows:"); ! display(stdout,lp); ! return 0; ! } ! else ! { ! setbootflag(lp); ! lp->d_magic = DISKMAGIC; ! lp->d_magic2 = DISKMAGIC; ! lp->d_checksum = 0; ! lp->d_checksum = dkcksum(lp); ! if (rflag) { ! /* ! * First set the kernel disk label, ! * then write a label to the raw disk. ! * If the SDINFO ioctl fails because it is unimplemented, ! * keep going; otherwise, the kernel consistency checks ! * may prevent us from changing the current (in-core) ! * label. ! */ ! if (ioctl(f, DIOCSDINFO, lp) < 0 && ! errno != ENODEV && errno != ENOTTY) { ! l_perror("ioctl DIOCSDINFO"); ! return (1); ! } ! (void)lseek(f, (off_t)0, SEEK_SET); ! #ifdef __alpha__ ! /* ! * Generate the bootblock checksum for the SRM console. ! */ ! for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++) ! sum += p[i]; ! p[63] = sum; #endif ! ! /* ! * write enable label sector before write (if necessary), ! * disable after writing. ! */ ! flag = 1; ! if (ioctl(f, DIOCWLABEL, &flag) < 0) ! warn("ioctl DIOCWLABEL"); ! if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { ! warn("write"); ! return (1); ! } #if NUMBOOT > 0 ! /* ! * Output the remainder of the disklabel ! */ ! if (bootbuf && write(f, bootbuf, bootsize) != bootsize) { ! warn("write"); ! return(1); ! } #endif ! flag = 0; ! (void) ioctl(f, DIOCWLABEL, &flag); ! } else if (ioctl(f, DIOCWDINFO, lp) < 0) { ! l_perror("ioctl DIOCWDINFO"); ! return (1); ! } #ifdef vax ! if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { ! daddr_t alt; ! ! alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; ! for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { ! (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), ! SEEK_SET); ! if (write(f, boot, lp->d_secsize) < lp->d_secsize) ! warn("alternate label %d write", i/2); ! } } #endif ! return (0); ! } } void *************** *** 934,942 **** --- 963,980 ---- { register char **cpp, *cp; register struct partition *pp; + register int i; char *tp, *s, line[BUFSIZ]; int v, lineno = 0, errors = 0; + for (i = 0; i < MAX_NUM_PARTS; i++) + { + /* paranoia */ + part_set[i] = 0; + part_size_type[i] = '\0'; + part_offset_type[i] = '\0'; + } + lp->d_bbsize = BBSIZE; /* XXX */ lp->d_sbsize = SBSIZE; /* XXX */ while (fgets(line, sizeof(line) - 1, f)) { *************** *** 1138,1153 **** lp->d_trkseek = v; continue; } ! if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { unsigned part = *cp - 'a'; if (part > lp->d_npartitions) { fprintf(stderr, ! "line %d: bad partition name\n", lineno); errors++; continue; } pp = &lp->d_partitions[part]; #define NXTNUM(n) { \ if (tp == NULL) { \ fprintf(stderr, "line %d: too few numeric fields\n", lineno); \ --- 1176,1194 ---- lp->d_trkseek = v; continue; } ! /* the ':' was removed above */ ! if ('a' <= *cp && *cp <= MAX_PART && cp[1] == '\0') { unsigned part = *cp - 'a'; if (part > lp->d_npartitions) { fprintf(stderr, ! "line %d: partition name out of range a-%c: %s\n", ! lineno,'a' + lp->d_npartitions - 1,cp); errors++; continue; } pp = &lp->d_partitions[part]; + part_set[part] = 1; #define NXTNUM(n) { \ if (tp == NULL) { \ fprintf(stderr, "line %d: too few numeric fields\n", lineno); \ *************** *** 1160,1231 **** (n) = atoi(cp); \ } \ } ! NXTNUM(v); ! if (v < 0) { fprintf(stderr, "line %d: %s: bad partition size\n", lineno, cp); errors++; - } else - pp->p_size = v; - NXTNUM(v); - if (v < 0) { - fprintf(stderr, - "line %d: %s: bad partition offset\n", - lineno, cp); - errors++; - } else - pp->p_offset = v; - cp = tp, tp = word(cp); - cpp = fstypenames; - for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) - if ((s = *cpp) && streq(s, cp)) { - pp->p_fstype = cpp - fstypenames; - goto gottype; - } - if (isdigit(*cp)) - v = atoi(cp); - else - v = FSMAXTYPES; - if ((unsigned)v >= FSMAXTYPES) { - fprintf(stderr, "line %d: %s %s\n", lineno, - "Warning, unknown filesystem type", cp); - v = FS_UNUSED; - } - pp->p_fstype = v; - gottype: - - switch (pp->p_fstype) { - - case FS_UNUSED: /* XXX */ - NXTNUM(pp->p_fsize); - if (pp->p_fsize == 0) - break; - NXTNUM(v); - pp->p_frag = v / pp->p_fsize; break; ! case FS_BSDFFS: ! NXTNUM(pp->p_fsize); ! if (pp->p_fsize == 0) break; ! NXTNUM(v); ! pp->p_frag = v / pp->p_fsize; ! NXTNUM(pp->p_cpg); ! break; ! case FS_BSDLFS: ! NXTNUM(pp->p_fsize); ! if (pp->p_fsize == 0) ! break; ! NXTNUM(v); ! pp->p_frag = v / pp->p_fsize; ! NXTNUM(pp->p_cpg); ! break; ! default: ! break; } continue; } --- 1201,1315 ---- (n) = atoi(cp); \ } \ } + /* retain 1 character following number */ + #define NXTWORD(w,n) { \ + if (tp == NULL) { \ + fprintf(stderr, "line %d: too few numeric fields\n", lineno); \ + errors++; \ + break; \ + } else { \ + char *tmp; \ + cp = tp, tp = word(cp); \ + if (tp == NULL) \ + tp = cp; \ + (n) = strtol(cp,&tmp,10); \ + if (tmp) (w) = *tmp; \ + } \ + } ! v = 0; ! NXTWORD(part_size_type[part],v); ! if (v < 0 || ! (v == 0 && ! part_size_type[part] != '*')) ! { fprintf(stderr, "line %d: %s: bad partition size\n", lineno, cp); errors++; break; + } + else + { + pp->p_size = v; ! v = 0; ! NXTWORD(part_offset_type[part],v); ! if (v < 0 || ! (v == 0 && ! part_offset_type[part] != '*' && ! part_offset_type[part] != '\0')) ! { ! fprintf(stderr, ! "line %d: %s: bad partition offset\n", ! lineno, cp); ! errors++; break; ! } ! else ! { ! pp->p_offset = v; ! ! cp = tp, tp = word(cp); ! cpp = fstypenames; ! for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) ! if ((s = *cpp) && streq(s, cp)) { ! pp->p_fstype = cpp - fstypenames; ! goto gottype; ! } ! if (isdigit(*cp)) ! v = atoi(cp); ! else ! v = FSMAXTYPES; ! if ((unsigned)v >= FSMAXTYPES) { ! fprintf(stderr, "line %d: %s %s\n", lineno, ! "Warning, unknown filesystem type", cp); ! v = FS_UNUSED; ! } ! pp->p_fstype = v; ! gottype: ! /* Note: NXTNUM will break us out of the switch only */ ! switch (pp->p_fstype) { ! case FS_UNUSED: /* XXX */ ! /* are these really used for anything? */ ! NXTNUM(pp->p_fsize); ! if (pp->p_fsize == 0) ! break; ! NXTNUM(v); ! pp->p_frag = v / pp->p_fsize; ! break; ! ! /* These happen to be the same */ ! case FS_BSDFFS: ! case FS_BSDLFS: ! /* allow us to accept defaults for fsize/frag/cpg */ ! if (tp) ! { ! NXTNUM(pp->p_fsize); ! if (pp->p_fsize == 0) ! break; ! NXTNUM(v); ! pp->p_frag = v / pp->p_fsize; ! NXTNUM(pp->p_cpg); ! } ! else ! { ! /* FIX! These are too low, but are traditional */ ! pp->p_fsize = DEFAULT_NEWFS_BLOCK; ! pp->p_frag = (unsigned char) DEFAULT_NEWFS_FRAG; ! pp->p_cpg = DEFAULT_NEWFS_CPG; ! /* FIX! we should make these adaptive */ ! } ! break; ! ! default: ! break; ! } ! /* note: we may not have gotten all the entries for the fs */ ! /* though if we didn't, errors will be set. */ ! } } continue; } *************** *** 1250,1255 **** --- 1334,1342 ---- register struct partition *pp; int i, errors = 0; char part; + unsigned long total_size,total_percent,current_offset; + int seen_default_offset; + int hog_part; if (lp->d_secsize == 0) { fprintf(stderr, "sector size 0\n"); *************** *** 1286,1291 **** --- 1373,1547 ---- if (lp->d_npartitions > MAXPARTITIONS) Warning("number of partitions (%lu) > MAXPARTITIONS (%d)", (u_long)lp->d_npartitions, MAXPARTITIONS); + + /* first allocate space to the partitions, then offsets */ + total_size = 0; /* in sectors */ + total_percent = 0; /* in percent */ + hog_part = -1; + /* find all fixed partitions */ + for (i = 0; i < lp->d_npartitions; i++) { + pp = &lp->d_partitions[i]; + if (part_set[i]) + { + if (part_size_type[i] == '*') + { + /* partition 2 ('c') is special */ + if (i == FULL_DISK_PART) + pp->p_size = lp->d_secperunit; + else { + if (hog_part != -1) + Warning("Too many '*'-sized partitions (%c and %c)", + hog_part+'a',i+'a'); + else + hog_part = i; + } + } + else + { + char *type; + unsigned long size; + + size = pp->p_size; + switch (part_size_type[i]) + { + case '%': + total_percent += size; + break; + + case 'k': + case 'K': + size *= 1024UL; + break; + + case 'm': + case 'M': + size *= ((unsigned long) 1024*1024); + break; + + case 'g': + case 'G': + size *= ((unsigned long) 1024*1024*1024); + break; + + case '\0': + break; + + default: + Warning("unknown size specifier '%c' (K/M/G are valid)",part_size_type[i]); + break; + } + /* don't count %'s yet */ + if (part_size_type[i] != '%') + { + /* for all not in sectors, convert to sectors */ + if (part_size_type[i] != '\0') + { + if (size % lp->d_secsize != 0) + Warning("partition %c not an integer number of sectors", + i + 'a'); + size /= lp->d_secsize; + pp->p_size = size; + } + /* else already in sectors */ + /* partition 2 ('c') is special */ + if (i != FULL_DISK_PART) + total_size += size; + } + } + } + } + /* handle % partitions - note %'s don't need to add up to 100! */ + if (total_percent != 0) + { + long free_space = lp->d_secperunit - total_size; + + if (total_percent > 100) + { + fprintf(stderr,"total percentage %d is greater than 100\n", + total_percent); + errors++; + } + + if (free_space > 0) + { + for (i = 0; i < lp->d_npartitions; i++) { + pp = &lp->d_partitions[i]; + if (part_set[i] && part_size_type[i] == '%') + { + unsigned long old_size = pp->p_size; + + /* careful of overflows! and integer roundoff */ + pp->p_size = ((double)pp->p_size/100) * free_space; + total_size += pp->p_size; + + /* FIX we can lose a sector or so due to roundoff per + partition. A more complex algorithm could avoid that */ + } + } + } + else + { + fprintf(stderr, + "%ld sectors available to give to '*' and '%' partitions\n", + free_space); + errors++; + /* fix? set all % partitions to size 0? */ + } + } + /* give anything remaining to the hog partition */ + if (hog_part != -1) + { + lp->d_partitions[hog_part].p_size = lp->d_secperunit - total_size; + total_size = lp->d_secperunit; + } + + /* Now set the offsets for each partition */ + current_offset = 0; /* in sectors */ + seen_default_offset = 0; + for (i = 0; i < lp->d_npartitions; i++) { + part = 'a' + i; + pp = &lp->d_partitions[i]; + if (part_set[i]) + { + if (part_offset_type[i] == '*') + { + /* partition 2 ('c') is special */ + if (i == FULL_DISK_PART) + pp->p_offset = 0; + else + { + pp->p_offset = current_offset; + seen_default_offset = 1; + } + } + else + { + /* allow them to be out of order for old-style tables */ + /* partition 2 ('c') is special */ + if (pp->p_offset < current_offset && seen_default_offset && + i != FULL_DISK_PART) + { + fprintf(stderr, + "Offset %ld for partition %c overlaps previous partition which ends at %ld\n", + pp->p_offset,i+'a',current_offset); + fprintf(stderr, + "Labels with any *'s for offset must be in ascending order by sector\n"); + errors++; + } + else if (pp->p_offset != current_offset && + i != FULL_DISK_PART && seen_default_offset) + { + /* this may give unneeded warnings if partitions are out-of-order */ + Warning("Offset %ld for partition %c doesn't match expected value %ld", + pp->p_offset,i+'a',current_offset); + } + } + /* partition 2 ('c') is special */ + if (i != FULL_DISK_PART) + current_offset = pp->p_offset + pp->p_size; + } + } + for (i = 0; i < lp->d_npartitions; i++) { part = 'a' + i; pp = &lp->d_partitions[i]; *************** *** 1311,1316 **** --- 1567,1596 ---- part); errors++; } + + /* check for overlaps */ + { + int j; + register struct partition *pp2; + + /* this will check for all possible overlaps once and only once */ + for (j = 0; j < i; j++) { + /* partition 2 ('c') is special */ + if (j != FULL_DISK_PART && i != FULL_DISK_PART && + part_set[i] && part_set[j]) + { + pp2 = &lp->d_partitions[j]; + if (pp2->p_offset < pp->p_offset + pp->p_size && + (pp2->p_offset + pp2->p_size > pp->p_offset || + pp2->p_offset >= pp->p_offset)) + { + fprintf(stderr,"partitions %c and %c overlap!\n", + j+'a', i+'a'); + errors++; + } + } + } + } } for (; i < MAXPARTITIONS; i++) { part = 'a' + i; *************** *** 1421,1445 **** fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: disklabel [-r] disk", "\t\t(to read label)", ! " disklabel -w [-r] disk type [ packid ]", "\t\t(to write label with existing boot program)", ! " disklabel -e [-r] disk", "\t\t(to edit label)", ! " disklabel -R [-r] disk protofile", "\t\t(to restore label with existing boot program)", #if NUMBOOT > 1 ! " disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]", "\t\t(to install boot program with existing label)", ! " disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]", "\t\t(to write label and boot program)", ! " disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]", "\t\t(to restore label and boot program)", #else ! " disklabel -B [ -b bootprog ] disk [ type ]", "\t\t(to install boot program with existing on-disk label)", ! " disklabel -w -B [ -b bootprog ] disk type [ packid ]", "\t\t(to write label and install boot program)", ! " disklabel -R -B [ -b bootprog ] disk protofile [ type ]", "\t\t(to restore label and install boot program)", #endif " disklabel [-NW] disk", --- 1701,1725 ---- fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: disklabel [-r] disk", "\t\t(to read label)", ! " disklabel -w [-r] [-n] disk type [ packid ]", "\t\t(to write label with existing boot program)", ! " disklabel -e [-r] [-n] disk", "\t\t(to edit label)", ! " disklabel -R [-r] [-n] disk protofile", "\t\t(to restore label with existing boot program)", #if NUMBOOT > 1 ! " disklabel -B [-n] [ -b boot1 [ -s boot2 ] ] disk [ type ]", "\t\t(to install boot program with existing label)", ! " disklabel -w -B [-n] [ -b boot1 [ -s boot2 ] ] disk type [ packid ]", "\t\t(to write label and boot program)", ! " disklabel -R -B [-n] [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]", "\t\t(to restore label and boot program)", #else ! " disklabel -B [-n] [ -b bootprog ] disk [ type ]", "\t\t(to install boot program with existing on-disk label)", ! " disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]", "\t\t(to write label and install boot program)", ! " disklabel -R -B [-n] [ -b bootprog ] disk protofile [ type ]", "\t\t(to restore label and install boot program)", #endif " disklabel [-NW] disk", *************** *** 1447,1457 **** #else fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: disklabel [-r] disk", "(to read label)", ! " disklabel -w [-r] disk type [ packid ]", "\t\t(to write label)", ! " disklabel -e [-r] disk", "\t\t(to edit label)", ! " disklabel -R [-r] disk protofile", "\t\t(to restore label)", " disklabel [-NW] disk", "\t\t(to write disable/enable label)"); --- 1727,1737 ---- #else fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", "usage: disklabel [-r] disk", "(to read label)", ! " disklabel -w [-r] [-n] disk type [ packid ]", "\t\t(to write label)", ! " disklabel -e [-r] [-n] disk", "\t\t(to edit label)", ! " disklabel -R [-r] [-n] disk protofile", "\t\t(to restore label)", " disklabel [-NW] disk", "\t\t(to write disable/enable label)"); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message