diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2009-03-22 19:01:33 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2009-03-22 19:01:33 +0000 |
commit | 8cb079ae55ab72da01dc67f6a1f427af4486d064 (patch) | |
tree | a770b2b307fa675a55aa06a2ca15f3b2ad99ca05 | |
parent | 8ffc7c509407f9484d596eeec08bc6e8c772487a (diff) |
Add 'A' command to Editor mode, and -A flag to automatically execute it
on disks without an existing label. The 'A' command allocates all space
on the disk into a reasonable partition scheme for a root disk.
Feedback from several, time to work on it in-tree.
Prodded (repeatedly) by and ok deraadt@
-rw-r--r-- | sbin/disklabel/disklabel.8 | 10 | ||||
-rw-r--r-- | sbin/disklabel/disklabel.c | 14 | ||||
-rw-r--r-- | sbin/disklabel/editor.c | 173 | ||||
-rw-r--r-- | sbin/disklabel/extern.h | 4 |
4 files changed, 172 insertions, 29 deletions
diff --git a/sbin/disklabel/disklabel.8 b/sbin/disklabel/disklabel.8 index c99c04d8668..b8d35d13e40 100644 --- a/sbin/disklabel/disklabel.8 +++ b/sbin/disklabel/disklabel.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: disklabel.8,v 1.71 2008/08/10 13:00:25 sobrado Exp $ +.\" $OpenBSD: disklabel.8,v 1.72 2009/03/22 19:01:32 krw Exp $ .\" $NetBSD: disklabel.8,v 1.9 1995/03/18 14:54:38 cgd Exp $ .\" .\" Copyright (c) 1987, 1988, 1991, 1993 @@ -33,7 +33,7 @@ .\" .\" @(#)disklabel.8 8.2 (Berkeley) 4/19/94 .\" -.Dd $Mdocdate: August 10 2008 $ +.Dd $Mdocdate: March 22 2009 $ .Dt DISKLABEL 8 .Os .Sh NAME @@ -58,6 +58,7 @@ .Ar disk .Nm disklabel .Fl E +.Op Fl A .Op Fl c | d .Op Fl nv .Op Fl f Ar tempfile @@ -105,6 +106,9 @@ locate the filesystems resident on the disk. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl A +If no disklabel is found on entering the Editor, prime label as if the +'A' command had been entered. .It Fl B Install bootstrap code. .It Fl b Ar boot1 @@ -290,6 +294,8 @@ may be specified to get more detailed help. There is also .Pq simple context-sensitive help available at most prompts. +.It Cm A +Allocate all the disk space in the recommended manner. .It Cm a Op Ar part Add new partition. This option adds a new BSD partition. diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index 500f42c7f15..5eac5ddb29f 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disklabel.c,v 1.138 2009/02/15 21:07:00 krw Exp $ */ +/* $OpenBSD: disklabel.c,v 1.139 2009/03/22 19:01:32 krw Exp $ */ /* * Copyright (c) 1987, 1993 @@ -39,7 +39,7 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.138 2009/02/15 21:07:00 krw Exp $"; +static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.139 2009/03/22 19:01:32 krw Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -105,6 +105,7 @@ enum { UNSPEC, EDIT, EDITOR, READ, RESTORE, SETWRITEABLE, WRITE, WRITEBOOT } op = UNSPEC; +int aflag; int cflag; int dflag; int tflag; @@ -145,8 +146,11 @@ main(int argc, char *argv[]) char print_unit = 0; FILE *t; - while ((ch = getopt(argc, argv, "BEf:NRWb:cdenp:s:tvw")) != -1) + while ((ch = getopt(argc, argv, "ABEf:NRWb:cdenp:s:tvw")) != -1) switch (ch) { + case 'A': + ++aflag; + break; #if NUMBOOT > 0 case 'B': ++installboot; @@ -278,7 +282,7 @@ main(int argc, char *argv[]) usage(); if ((lp = readlabel(f)) == NULL) exit(1); - error = editor(lp, f, specname, fstabfile); + error = editor(lp, f, specname, fstabfile, aflag); break; case READ: if (argc != 1) @@ -1724,7 +1728,7 @@ usage(void) fprintf(stderr, " disklabel -e [-c | -d] [-nv] disk\t\t\t(edit)\n"); fprintf(stderr, - " disklabel -E [-c | -d] [-nv] [-f tempfile] disk\t\t(simple editor)\n"); + " disklabel -E [-A] [-c | -d] [-nv] [-f tempfile] disk\t\t(simple editor)\n"); fprintf(stderr, " disklabel -R [-nv] disk protofile\t\t\t(restore)\n"); fprintf(stderr, diff --git a/sbin/disklabel/editor.c b/sbin/disklabel/editor.c index 0797f57eecd..c3802ba3dc5 100644 --- a/sbin/disklabel/editor.c +++ b/sbin/disklabel/editor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: editor.c,v 1.175 2009/03/07 02:12:00 krw Exp $ */ +/* $OpenBSD: editor.c,v 1.176 2009/03/22 19:01:32 krw Exp $ */ /* * Copyright (c) 1997-2000 Todd C. Miller <Todd.Miller@courtesan.com> @@ -17,7 +17,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: editor.c,v 1.175 2009/03/07 02:12:00 krw Exp $"; +static char rcsid[] = "$OpenBSD: editor.c,v 1.176 2009/03/22 19:01:32 krw Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -61,7 +61,36 @@ struct mountinfo { int partno; }; +/* used when allocating all space according to recommendations */ + +struct space_allocation { + daddr64_t minblks; + daddr64_t maxblks; + int rate; /* % of extra space to use */ + char *mp; +}; + +struct space_allocation alloc[MAXPARTITIONS] = { + { 156250, 1953125, 5, "/" }, /* a 80MB -> 1GB */ + { 1953125, 7812500, 5, "swap" }, /* b 1GB -> 4GB */ + { 0, 0, 0, "" }, /* c */ + { 156250, 1953125, 5, "/tmp" }, /* d 80MB -> 1GB */ + { 156250, 1953125, 5, "/var" }, /* e 80MB -> 1GB */ + { 0, 0, 0, "" }, /* f */ + { 3906250, 19531250, 20, "/usr" }, /* g 2GB -> 10GB */ + { 1000000, 1953125, 5, "/usr/X11R6" }, /* h 512MB -> 1GB */ + { 0, 0, 0, "" }, /* i */ + { 3906250, 5859375, 5, "/usr/local" }, /* j 2GB -> 3GB */ + { 1953, 1953125000, 50, "/home" }, /* k 512MB -> 1TB */ + { 0, 0, 0, "" }, /* l */ + { 0, 0, 0, "" }, /* m */ + { 0, 0, 0, "" }, /* n */ + { 0, 0, 0, "" }, /* o */ + { 0, 0, 0, "" } /* p */ +}; + void edit_parms(struct disklabel *); +void editor_allocspace(struct disklabel *, char **, int); void editor_add(struct disklabel *, char **, char *); void editor_change(struct disklabel *, char *); u_int64_t editor_countfree(struct disklabel *); @@ -103,7 +132,7 @@ static int expert; * Simple partition editor. Primarily intended for new labels. */ int -editor(struct disklabel *lp, int f, char *dev, char *fstabfile) +editor(struct disklabel *lp, int f, char *dev, char *fstabfile, int aflag) { struct disklabel lastlabel, tmplabel, label = *lp; struct disklabel *disk_geop; @@ -164,6 +193,9 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile) if (label.d_interleave == 0) label.d_interleave = 1; + if (aflag) + editor_allocspace(&label, mountpoints, 0); + puts("Initial label editor (enter '?' for help at any prompt)"); lastlabel = label; for (;;) { @@ -184,6 +216,9 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile) editor_help(arg ? arg : ""); break; + case 'A': + editor_allocspace(&label, mountpoints, 1); + break; case 'a': tmplabel = lastlabel; lastlabel = label; @@ -437,6 +472,107 @@ editor(struct disklabel *lp, int f, char *dev, char *fstabfile) } /* + * Allocate all disk space according to standard recommendations for a + * root disk. + */ +void +editor_allocspace(struct disklabel *lp, char **mp, int forcealloc) +{ + struct partition *pp; + daddr64_t blks, cylblks, totblks, xtrablks; + int i, lastpart; + + cylblks = DL_SECTOBLK(lp, lp->d_secpercyl); + xtrablks = totblks = DL_SECTOBLK(lp, ending_sector - starting_sector); + + pp = &lp->d_partitions[0]; + for (i = 0; i < MAXPARTITIONS; i++, pp++) { + blks = alloc[i].minblks; + if (i == RAW_PART) + continue; + if (DL_GETPSIZE(pp) != 0 && !forcealloc) + return; + if (blks == 0) + continue; + xtrablks -= blks; + lastpart = i; + } + + lp->d_npartitions = MAXPARTITIONS; + + pp = &lp->d_partitions[0]; + for (i = 0; i <= lastpart; i++, pp++) { + switch (i) { + case 0: + DL_SETPSIZE(pp, 0); + DL_SETPOFFSET(pp, starting_sector); + break; + case RAW_PART: + continue; + case RAW_PART+1: + DL_SETPSIZE(pp, 0); + DL_SETPOFFSET(pp,DL_GETPOFFSET(pp-2)+DL_GETPSIZE(pp-2)); + break; + default: + DL_SETPSIZE(pp, 0); + DL_SETPOFFSET(pp,DL_GETPOFFSET(pp-1)+DL_GETPSIZE(pp-1)); + break; + } + if (i == lastpart) { + if (totblks > alloc[i].maxblks) + blks = alloc[i].maxblks; + else + blks = totblks; + } else { + blks = alloc[i].minblks; + if (xtrablks > 0) + blks += (xtrablks / 100) * alloc[i].rate; + if (blks > alloc[i].maxblks) + blks = alloc[i].maxblks; + blks = ((blks + cylblks - 1) / cylblks) * cylblks; + totblks -= blks; + while (totblks < 0) { + blks -= cylblks; + totblks += cylblks; + } + if (i == 0 && blks > DL_SECTOBLK(lp, starting_sector)) { + blks -= DL_SECTOBLK(lp, starting_sector); + totblks += DL_SECTOBLK(lp, starting_sector); + } + } + if (blks < alloc[i].minblks) { + totblks += blks; + fprintf(stderr, "no space to auto allocate '%c'" + " (%s)\n", 'a'+i, alloc[i].mp); + if (i == 0) + break; + else + continue; + } + DL_SETPSIZE(pp, DL_BLKTOSEC(lp, blks)); + pp->p_fstype = (i == 1) ? FS_SWAP : FS_BSDFFS; +#if defined (__sparc__) && !defined(__sparc64__) + /* can't boot from > 8k boot blocks */ + pp->p_fragblock = + DISKLABELV1_FFS_FRAGBLOCK(i == 0 ? 1024 : 2048, 8); +#else + pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(2048, 8); +#endif + pp->p_cpg = 1; + if (mp && alloc[i].mp[0] == '/') { + free(mp[i]); + if ((mp[i] = strdup(alloc[i].mp)) == NULL) + errx(4, "out of memory"); + } + } + + /* Zap remaining, unallocated partitions. */ + for (; i < MAXPARTITIONS; i++, pp++) + if (i != RAW_PART) + memset(pp, 0, sizeof(*pp)); +} + +/* * Add a new partition. */ void @@ -1578,17 +1714,17 @@ editor_help(char *arg) default: puts("Available commands:"); puts( -" ? [command] - show help n [part] - set mount point\n" -" a [part] - add partition p [unit] - print partitions\n" -" b - set OpenBSD boundaries q - quit & save changes\n" -" c [part] - change partition size r - display free space\n" -" D - reset label to default s [path] - save label to file\n" -" d [part] - delete partition u - undo last change\n" -" e - edit drive parameters w - write label to disk\n" -" g [d | u] - [d]isk or [u]ser geometry X - toggle expert mode\n" -" l [unit] - print disk label header x - exit & lose changes\n" -" M - disklabel(8) man page z - delete all partitions\n" -" m [part] - modify partition\n" +" ? [cmd] - show help m [part] - modify partition\n" +" A - auto partition all space n [part] - set mount point\n" +" a [part] - add partition p [unit] - print partitions\n" +" b - set OpenBSD boundaries q - quit & save changes\n" +" c [part] - change partition size s [path] - save label to file\n" +" D - reset label to default r - display free space\n" +" d [part] - delete partition u - undo last change\n" +" e - edit drive parameters w - write label to disk\n" +" g [d|u] - [d]isk or [u]ser geometry X - toggle expert mode\n" +" l [unit] - print disk label header x - exit & lose changes\n" +" M - disklabel(8) man page z - delete all partitions\n" "\n" "Suffixes can be used to indicate units other than sectors:\n" "\t'b' (bytes), 'k' (kilobytes), 'm' (megabytes), 'g' (gigabytes)\n" @@ -1917,16 +2053,13 @@ get_mp(struct disklabel *lp, char **mp, int partno) return(1); } if (strcasecmp(p, "none") == 0) { - if (mp[partno] != NULL) { - free(mp[partno]); - mp[partno] = NULL; - } + free(mp[partno]); + mp[partno] = NULL; break; } if (*p == '/') { /* XXX - might as well realloc */ - if (mp[partno] != NULL) - free(mp[partno]); + free(mp[partno]); if ((mp[partno] = strdup(p)) == NULL) errx(4, "out of memory"); break; diff --git a/sbin/disklabel/extern.h b/sbin/disklabel/extern.h index b42a5a6fc25..b30e1fdd5b2 100644 --- a/sbin/disklabel/extern.h +++ b/sbin/disklabel/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.8 2009/01/11 19:44:57 miod Exp $ */ +/* $OpenBSD: extern.h,v 1.9 2009/03/22 19:01:32 krw Exp $ */ /* * Copyright (c) 2003 Theo de Raadt <deraadt@openbsd.org> @@ -24,7 +24,7 @@ void display_partition(FILE *, struct disklabel *, char **, int, char); struct disklabel *readlabel(int); struct disklabel *makebootarea(char *, struct disklabel *, int); -int editor(struct disklabel *, int, char *, char *); +int editor(struct disklabel *, int, char *, char *, int); int writelabel(int, char *, struct disklabel *); extern char bootarea[], *specname; |