I like this a lot. Can we use stronum() and avoid the manual
operator processing?
.... Ken
On Sat, May 21, 2011 at 10:01:01PM +0200, Otto Moerbeek wrote:
> Hi,
>
> it is already possible to resize auto alloctaed labels using the R
> command in disklabel. But a problem quite a few persons mentioned is
> that the R command only takes a relative size currently. This changes
> that to allow for both absolute and relative size changes.
>
> An example session to get the hang of it:
>
> # obj/disklabel -E sd1
> Label editor (enter '?' for help at any prompt)
>
> * auto allocate and print in gigabytes *
> > A
> > p g
> OpenBSD area: 64-195366465; size: 93.2G; free: 0.0G
> # size offset fstype [fsize bsize cpg]
> a: 1.0G 64 4.2BSD 2048 16384 1 # /
> b: 0.5G 2097216 swap
> c: 93.2G 0 unused
> d: 4.0G 3144000 4.2BSD 2048 16384 1 # /tmp
> e: 4.5G 11532576 4.2BSD 2048 16384 1 # /var
> f: 2.0G 20967936 4.2BSD 2048 16384 1 # /usr
> g: 1.0G 25162240 4.2BSD 2048 16384 1 # /usr/X11R6
> h: 10.0G 27259392 4.2BSD 2048 16384 1 # /usr/local
> i: 2.0G 48230912 4.2BSD 2048 16384 1 # /usr/src
> j: 2.0G 52425216 4.2BSD 2048 16384 1 # /usr/obj
> k: 66.2G 56619520 4.2BSD 2048 16384 1 # /home
>
> * now delete /usr/X11R6 and /usr/local, and resize /usr to 20g and / to 100m *
> > d g
> > d h
> > R f
> [+|-]new size (with unit): [4194304] 20g
> Partition k shrunk to make room
> > R a
> [+|-]new size (with unit): [2097152] 100m
>
> * print what we got now *
> > p g
> OpenBSD area: 64-195366465; size: 93.2G; free: 0.9G
> # size offset fstype [fsize bsize cpg]
> a: 0.1G 64 4.2BSD 2048 16384 1 # /
> b: 0.5G 204864 swap
> c: 93.2G 0 unused
> d: 4.0G 1251632 4.2BSD 2048 16384 1 # /tmp
> e: 4.5G 9640208 4.2BSD 2048 16384 1 # /var
> f: 20.0G 19075568 4.2BSD 2048 16384 1 # /usr
> i: 2.0G 61018608 4.2BSD 2048 16384 1 # /usr/src
> j: 2.0G 65212912 4.2BSD 2048 16384 1 # /usr/obj
> k: 59.2G 69407216 4.2BSD 2048 16384 1 # /home
>
> * now resize /home to be 20G *
> > R k
> [+|-]new size (with unit): [124066881] 20g
>
> * and add 70% of the free space to /var
> > R e
> [+|-]new size (with unit): [9435360] +70&
> > p g
> OpenBSD area: 64-195366465; size: 93.2G; free: 12.0G
> # size offset fstype [fsize bsize cpg]
> a: 0.1G 64 4.2BSD 2048 16384 1 # /
> b: 0.5G 204864 swap
> c: 93.2G 0 unused
> d: 4.0G 1251632 4.2BSD 2048 16384 1 # /tmp
> e: 32.5G 9640208 4.2BSD 2048 16384 1 # /var
> f: 20.0G 77886914 4.2BSD 2048 16384 1 # /usr
> i: 2.0G 119829954 4.2BSD 2048 16384 1 # /usr/src
> j: 2.0G 124024258 4.2BSD 2048 16384 1 # /usr/obj
> k: 20.0G 128218562 4.2BSD 2048 16384 1 # /home
> >
>
>
> Comments and tests appreciated.
>
> (One thing that's needed is a smarter rounding to 4k boundaries, if
> you work in units of M or G this works all out by itself, but above
> you can see that the partitions after /var end up on a non-4k boundary
> due to the relative 70% of free space change. Luckily this doesn't
> matter at all for most disks)
>
> -Otto
>
> Index: editor.c
> ===================================================================
> RCS file: /cvs/src/sbin/disklabel/editor.c,v
> retrieving revision 1.252
> diff -u -p -r1.252 editor.c
> --- editor.c 16 Apr 2011 23:01:17 -0000 1.252
> +++ editor.c 21 May 2011 19:59:49 -0000
> @@ -733,11 +733,11 @@ editor_resize(struct disklabel *lp, char
> fputs("Cannot resize spoofed partition\n", stderr);
> return;
> }
> - secs = getuint(lp, "grow (+) or shrink (-) (with unit)",
> - "amount to grow (+) or shrink (-) partition including unit",
> - 0, editor_countfree(lp), 0, DO_CONVERSIONS);
> + secs = getuint(lp, "[+|-]new size (with unit)",
> + "new size or amount to grow (+) or shrink (-) partition including
> unit",
> + sz, editor_countfree(lp), 0, DO_CONVERSIONS);
>
> - if (secs == 0 || secs == -1) {
> + if (secs <= 0) {
> fputs("Command aborted\n", stderr);
> return;
> }
> @@ -749,16 +749,12 @@ editor_resize(struct disklabel *lp, char
> else
> secs = ((secs - cylsecs + 1) / cylsecs) * cylsecs;
> #endif
> - if (DL_GETPOFFSET(pp) + sz + secs > ending_sector) {
> + if (DL_GETPOFFSET(pp) + secs > ending_sector) {
> fputs("Amount too big\n", stderr);
> return;
> }
> - if (sz + secs < 0) {
> - fputs("Amount too small\n", stderr);
> - return;
> - }
>
> - DL_SETPSIZE(pp, sz + secs);
> + DL_SETPSIZE(pp, secs);
>
> /*
> * Pack partitions above the resized partition, leaving unused
> @@ -1201,13 +1197,19 @@ getuint(struct disklabel *lp, char *prom
> break;
> case '%':
> buf[--n] = '\0';
> - percent = strtod(buf, NULL) / 100.0;
> + p = &buf[0];
> + if (*p == '+' || *p == '-')
> + operator = *p++;
> + percent = strtod(p, NULL) / 100.0;
> snprintf(buf, sizeof(buf), "%lld",
> DL_GETDSIZE(lp));
> break;
> case '&':
> buf[--n] = '\0';
> - percent = strtod(buf, NULL) / 100.0;
> + p = &buf[0];
> + if (*p == '+' || *p == '-')
> + operator = *p++;
> + percent = strtod(p, NULL) / 100.0;
> snprintf(buf, sizeof(buf), "%lld",
> maxval);
> break;
> @@ -1750,19 +1752,19 @@ editor_help(void)
> {
> puts("Available commands:");
> puts(
> -" ? | h - show help n [part] - set mount point\n"
> -" A - auto partition all space p [unit] - print partitions\n"
> -" a [part] - add partition q - quit & save changes\n"
> -" b - set OpenBSD boundaries R [part] - resize a partition\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 all changes\n"
> -" e - edit drive parameters u - undo last change\n"
> -" g [d|u] - [d]isk or [u]ser geometry w - write label to disk\n"
> -" i - modify disklabel UID 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"
> +" ? | h - show help n [part] - set mount point\n"
> +" A - auto partition all space p [unit] - print partitions\n"
> +" a [part] - add partition q - quit & save changes\n"
> +" b - set OpenBSD boundaries R [part] - resize auto allocated
> partition\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 all changes\n"
> +" e - edit drive parameters u - undo last change\n"
> +" g [d|u] - [d]isk or [u]ser geometry w - write label to disk\n"
> +" i - modify disklabel UID 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"
> "\n"
> "Suffixes can be used to indicate units other than sectors:\n"
> "\t'b' (bytes), 'k' (kilobytes), 'm' (megabytes), 'g' (gigabytes)\n"