summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2009-03-22 19:01:33 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2009-03-22 19:01:33 +0000
commit8cb079ae55ab72da01dc67f6a1f427af4486d064 (patch)
treea770b2b307fa675a55aa06a2ca15f3b2ad99ca05
parent8ffc7c509407f9484d596eeec08bc6e8c772487a (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.810
-rw-r--r--sbin/disklabel/disklabel.c14
-rw-r--r--sbin/disklabel/editor.c173
-rw-r--r--sbin/disklabel/extern.h4
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;