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"

Reply via email to