Richard W.M. Jones
2010-May-21 13:50 UTC
[Libguestfs] [PATCH 0/4] Allow shrinking of ext2, PVs and NTFS
This patch series allows you to shrink various objects, as requested in the following bugs: https://bugzilla.redhat.com/show_bug.cgi?id=585221 # resize2fs https://bugzilla.redhat.com/show_bug.cgi?id=585222 # pvresize https://bugzilla.redhat.com/show_bug.cgi?id=585223 # ntfsresize The first patch provides a consistent way to specify numbers with suffixes to guestfish, eg: truncate-size /foo 1G It also unifies the number parsing code used by 'alloc' and 'sparse' commands to use the same Gnulib function. Patches 2-4 implement the resizing. With all four patches applied you can shrink filesystems even where the container is larger, and you can use suffixes to specify the new filesystem size. Example using resize2fs-size: $ guestfish -N fs:ext3:1G Welcome to guestfish, the libguestfs filesystem interactive shell for editing virtual machine filesystems. Type: 'help' for a list of commands 'man' to read the manual 'quit' to quit the shell ><fs> vfs-type /dev/vda1 ext3 ><fs> blockdev-getsize64 /dev/vda1 1073741312 ><fs> resize2fs-size /dev/vda1 100M ><fs> blockdev-getsize64 /dev/vda1 # container size same 1073741312 ><fs> mount-ro /dev/vda1 / # but filesystem is smaller ><fs> df-h Filesystem Size Used Avail Use% Mounted on /dev/vda1 98M 17M 77M 18% /sysroot Example using pvresize-size: $ guestfish -N part:1G Welcome to guestfish, the libguestfs filesystem interactive shell for editing virtual machine filesystems. Type: 'help' for a list of commands 'man' to read the manual 'quit' to quit the shell ><fs> pvcreate /dev/vda1 ><fs> pvresize-size /dev/vda1 512M ><fs> pvs-full [0] = { [...] pv_size: 536870912 dev_size: 1073741312 [...] } Example using ntfsresize-size: $ guestfish -N fs:ntfs:1G Welcome to guestfish, the libguestfs filesystem interactive shell for editing virtual machine filesystems. Type: 'help' for a list of commands 'man' to read the manual 'quit' to quit the shell ><fs> ntfsresize-size /dev/vda1 512M ><fs> mount-ro /dev/vda1 / ><fs> df-h Filesystem Size Used Avail Use% Mounted on /dev/vda1 512M 5.6M 507M 2% /sysroot Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/
Richard W.M. Jones
2010-May-21 13:52 UTC
[Libguestfs] [PATCH 1/4] fish: Allow suffixes on number parameters (eg. 1M)
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones New in Fedora 11: Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 70 libraries supprt'd http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw -------------- next part -------------->From 5e1aff7856f721bf5737815a5b65c0de23ab0b0c Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at redhat.com> Date: Fri, 21 May 2010 13:07:05 +0100 Subject: [PATCH 1/4] fish: Allow suffixes on number parameters (eg. 1M) This small change uses the gnulib xstrtoll functionality to enable suffixes on integer parameters in guestfish. For example: truncate-size /file 1G (previously you would have had to given the full number). This also applies to the 'alloc' and 'sparse' commands (and indirectly to the -N option). The specification for these commands has changed slightly, in that 'alloc foo 1MB' would now use SI units, allocating 1000000 bytes instead of a true megabyte. All existing uses would use 'alloc foo 1M' which still allocates true megabytes. --- fish/alloc.c | 34 ++----- fish/fish.c | 24 +---- fish/guestfish.pod | 162 ++++++++++++++++++-------------- regressions/rhbz557655-expected.stderr | 2 - regressions/rhbz557655.sh | 6 +- src/generator.ml | 5 +- 6 files changed, 113 insertions(+), 120 deletions(-) diff --git a/fish/alloc.c b/fish/alloc.c index f91c5bb..7533741 100644 --- a/fish/alloc.c +++ b/fish/alloc.c @@ -26,6 +26,8 @@ #include <inttypes.h> #include <errno.h> +#include "xstrtol.h" + #include "fish.h" int @@ -145,30 +147,14 @@ alloc_disk (const char *filename, const char *size_str, int add, int sparse) static int parse_size (const char *str, off_t *size_rtn) { - uint64_t size; - char type; - - /* Note that the parsing here is looser than what is specified in the - * help, but we may tighten it up in future so beware. - */ - if (sscanf (str, "%"SCNu64"%c", &size, &type) == 2) { - switch (type) { - case 'k': case 'K': size *= 1024ULL; break; - case 'm': case 'M': size *= 1024ULL * 1024ULL; break; - case 'g': case 'G': size *= 1024ULL * 1024ULL * 1024ULL; break; - case 't': case 'T': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL; break; - case 'p': case 'P': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; break; - case 'e': case 'E': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; break; - case 's': size *= 512; break; - default: - fprintf (stderr, _("could not parse size specification '%s'\n"), str); - return -1; - } - } - else if (sscanf (str, "%"SCNu64, &size) == 1) - size *= 1024ULL; - else { - fprintf (stderr, _("could not parse size specification '%s'\n"), str); + unsigned long long size; + strtol_error xerr; + + xerr = xstrtoull (str, NULL, 0, &size, "0kKMGTPEZY"); + if (xerr != LONGINT_OK) { + fprintf (stderr, + _("%s: invalid integer parameter (%s returned %d)\n"), + "alloc_disk", "xstrtoull", xerr); return -1; } diff --git a/fish/fish.c b/fish/fish.c index a32ed4d..d38d1c1 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -1069,16 +1069,8 @@ display_builtin_command (const char *cmd) "\n" " For more advanced image creation, see qemu-img utility.\n" "\n" - " Size can be specified (where <nn> means a number):\n" - " <nn> number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " <nn>K or <nn>KB number of kilobytes\n" - " <nn>M or <nn>MB number of megabytes\n" - " <nn>G or <nn>GB number of gigabytes\n" - " <nn>T or <nn>TB number of terabytes\n" - " <nn>P or <nn>PB number of petabytes\n" - " <nn>E or <nn>EB number of exabytes\n" - " <nn>sects number of 512 byte sectors\n")); + " Size can be specified using standard suffixes, eg. '1M'.\n" + )); else if (STRCASEEQ (cmd, "echo")) printf (_("echo - display a line of text\n" " echo [<params> ...]\n" @@ -1168,16 +1160,8 @@ display_builtin_command (const char *cmd) "\n" " For more advanced image creation, see qemu-img utility.\n" "\n" - " Size can be specified (where <nn> means a number):\n" - " <nn> number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " <nn>K or <nn>KB number of kilobytes\n" - " <nn>M or <nn>MB number of megabytes\n" - " <nn>G or <nn>GB number of gigabytes\n" - " <nn>T or <nn>TB number of terabytes\n" - " <nn>P or <nn>PB number of petabytes\n" - " <nn>E or <nn>EB number of exabytes\n" - " <nn>sects number of 512 byte sectors\n")); + " Size can be specified using standard suffixes, eg. '1M'.\n" + )); else if (STRCASEEQ (cmd, "time")) printf (_("time - measure time taken to run command\n" " time <command> [<args> ...]\n" diff --git a/fish/guestfish.pod b/fish/guestfish.pod index 274f1d4..a6d341e 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -320,9 +320,97 @@ must be escaped with a backslash. =head1 NUMBERS -Commands which take integers as parameters use the C convention which -is to use C<0> to prefix an octal number or C<0x> to prefix a -hexadecimal number. For example: +This section applies to all commands which can take integers +as parameters. + +=head2 SIZE SUFFIX + +When the command takes a parameter measured in bytes, you can use one +of the following suffixes to specify kilobytes, megabytes and larger +sizes: + +=over 4 + +=item B<k> or B<K> or B<KiB> + +The size in kilobytes (multiplied by 1024). + +=item B<KB> + +The size in SI 1000 byte units. + +=item B<M> or B<MiB> + +The size in megabytes (multiplied by 1048576). + +=item B<MB> + +The size in SI 1000000 byte units. + +=item B<G> or B<GiB> + +The size in gigabytes (multiplied by 2**30). + +=item B<GB> + +The size in SI 10**9 byte units. + +=item B<T> or B<TiB> + +The size in terabytes (multiplied by 2**40). + +=item B<TB> + +The size in SI 10**12 byte units. + +=item B<P> or B<PiB> + +The size in petabytes (multiplied by 2**50). + +=item B<PB> + +The size in SI 10**15 byte units. + +=item B<E> or B<EiB> + +The size in exabytes (multiplied by 2**60). + +=item B<EB> + +The size in SI 10**18 byte units. + +=item B<Z> or B<ZiB> + +The size in zettabytes (multiplied by 2**70). + +=item B<ZB> + +The size in SI 10**21 byte units. + +=item B<Y> or B<YiB> + +The size in yottabytes (multiplied by 2**80). + +=item B<YB> + +The size in SI 10**24 byte units. + +=back + +For example: + + truncate-size /file 1G + +would truncate the file to 1 gigabyte. + +Be careful because a few commands take sizes in kilobytes or megabytes +(eg. the parameter to L</memsize> is specified in megabytes already). +Adding a suffix will probably not do what you expect. + +=head2 OCTAL AND HEXADECIMAL NUMBERS + +For specifying the radix (base) use the C convention: C<0> to prefix +an octal number or C<0x> to prefix a hexadecimal number. For example: 1234 decimal number 1234 02322 octal number, equivalent to decimal 1234 @@ -600,39 +688,7 @@ so it can be further examined. For more advanced image creation, see L<qemu-img(1)> utility. -Size can be specified (where C<nn> means a number): - -=over 4 - -=item C<nn> or C<nn>K or C<nn>KB - -number of kilobytes, eg: C<1440> = standard 3.5in floppy - -=item C<nn>M or C<nn>MB - -number of megabytes - -=item C<nn>G or C<nn>GB - -number of gigabytes - -=item C<nn>T or C<nn>TB - -number of terabytes - -=item C<nn>P or C<nn>PB - -number of petabytes - -=item C<nn>E or C<nn>EB - -number of exabytes - -=item C<nn>sects - -number of 512 byte sectors - -=back +Size can be specified using standard suffixes, eg. C<1M>. =head2 echo @@ -727,39 +783,7 @@ danger you could run out of real disk space during a write operation. For more advanced image creation, see L<qemu-img(1)> utility. -Size can be specified (where C<nn> means a number): - -=over 4 - -=item C<nn> or C<nn>K or C<nn>KB - -number of kilobytes, eg: C<1440> = standard 3.5in floppy - -=item C<nn>M or C<nn>MB - -number of megabytes - -=item C<nn>G or C<nn>GB - -number of gigabytes - -=item C<nn>T or C<nn>TB - -number of terabytes - -=item C<nn>P or C<nn>PB - -number of petabytes - -=item C<nn>E or C<nn>EB - -number of exabytes - -=item C<nn>sects - -number of 512 byte sectors - -=back +Size can be specified using standard suffixes, eg. C<1M>. =head2 time diff --git a/regressions/rhbz557655-expected.stderr b/regressions/rhbz557655-expected.stderr index c8e02f5..e570cf3 100644 --- a/regressions/rhbz557655-expected.stderr +++ b/regressions/rhbz557655-expected.stderr @@ -5,10 +5,8 @@ set-memsize: memsize: integer out of range set-memsize: memsize: invalid integer parameter (xstrtoll returned 4) set-memsize: memsize: invalid integer parameter (xstrtoll returned 2) set-memsize: memsize: invalid integer parameter (xstrtoll returned 2) -set-memsize: memsize: invalid integer parameter (xstrtoll returned 2) libguestfs: error: truncate_size: ftruncate: /test: File too large truncate-size: size: invalid integer parameter (xstrtoll returned 1) truncate-size: size: invalid integer parameter (xstrtoll returned 4) truncate-size: size: invalid integer parameter (xstrtoll returned 2) truncate-size: size: invalid integer parameter (xstrtoll returned 2) -truncate-size: size: invalid integer parameter (xstrtoll returned 2) diff --git a/regressions/rhbz557655.sh b/regressions/rhbz557655.sh index 228b498..2306147 100755 --- a/regressions/rhbz557655.sh +++ b/regressions/rhbz557655.sh @@ -45,7 +45,6 @@ get-memsize -set-memsize 07777770000000000000 -set-memsize ABC -set-memsize 09 --set-memsize 123K -set-memsize 123L EOF @@ -69,7 +68,6 @@ filesize /test # these should all provoke parse errors: -truncate-size /test ABC -truncate-size /test 09 --truncate-size /test 123K -truncate-size /test 123L EOF @@ -82,6 +80,6 @@ grep -E 'set[-_]memsize|truncate[-_]size' test.err~ | grep -Ev 'proc 200' > test.err rm test.err~ -diff -u test.out rhbz557655-expected.stdout -diff -u test.err rhbz557655-expected.stderr +diff -u rhbz557655-expected.stdout test.out +diff -u rhbz557655-expected.stderr test.err rm test.out test.err test1.img diff --git a/src/generator.ml b/src/generator.ml index d4ef81a..aca56a8 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -7456,6 +7456,9 @@ and generate_fish_cmds () pr "#include \"xstrtol.h\"\n"; pr "#include \"fish.h\"\n"; pr "\n"; + pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n"; + pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n"; + pr "\n"; (* list_commands function, which implements guestfish -h *) pr "void list_commands (void)\n"; @@ -7674,7 +7677,7 @@ and generate_fish_cmds () pr " strtol_error xerr;\n"; pr " %s r;\n" fntyp; pr "\n"; - pr " xerr = %s (argv[%d], NULL, 0, &r, \"\");\n" fn i; + pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i; pr " if (xerr != LONGINT_OK) {\n"; pr " fprintf (stderr,\n"; pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n"; -- 1.6.6.1
Richard W.M. Jones
2010-May-21 13:53 UTC
[Libguestfs] [PATCH 2/4] New API: resize2fs-size to allow shrinking ext2 filesystems (RHBZ#585221).
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/ -------------- next part -------------->From 71b02d6654395ff04689055f3820b3ad4e54ec00 Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at redhat.com> Date: Fri, 21 May 2010 14:13:24 +0100 Subject: [PATCH 2/4] New API: resize2fs-size to allow shrinking ext2 filesystems (RHBZ#585221). --- daemon/ext2.c | 36 ++++++++++++++++++++++++++++++++++++ src/generator.ml | 7 +++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/daemon/ext2.c b/daemon/ext2.c index 3758f4e..3a075e5 100644 --- a/daemon/ext2.c +++ b/daemon/ext2.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> +#include <inttypes.h> #include <string.h> #include <unistd.h> @@ -301,6 +302,41 @@ do_resize2fs (const char *device) } int +do_resize2fs_size (const char *device, int64_t size) +{ + char *err; + int r; + + char prog[] = "resize2fs"; + if (e2prog (prog) == -1) + return -1; + + /* resize2fs itself may impose additional limits. Since we are + * going to use the 'K' suffix however we can only work with whole + * kilobytes. + */ + if (size & 1023) { + reply_with_error ("%" PRIi64 ": size must be a round number of kilobytes", + size); + return -1; + } + size /= 1024; + + char buf[32]; + snprintf (buf, sizeof buf, "%" PRIi64 "K", size); + + r = command (NULL, &err, prog, device, buf, NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (err); + return -1; + } + + free (err); + return 0; +} + +int do_e2fsck_f (const char *device) { char *err; diff --git a/src/generator.ml b/src/generator.ml index aca56a8..b2ba513 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -4686,6 +4686,13 @@ unlikely for regular files in ordinary circumstances. See also C<guestfs_pread>."); + ("resize2fs_size", (RErr, [Device "device"; Int64 "size"]), 248, [], + [], + "resize an ext2/ext3 filesystem (with size)", + "\ +This command is the same as C<guestfs_resize2fs> except that it +allows you to specify the new size (in bytes) explicitly."); + ] let all_functions = non_daemon_functions @ daemon_functions -- 1.6.6.1
Richard W.M. Jones
2010-May-21 13:53 UTC
[Libguestfs] [PATCH 3/4] New API: pvresize-size to allow shrinking PVs (RHBZ#585222).
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://et.redhat.com/~rjones/virt-top -------------- next part -------------->From 9be89728f2a0ff17d54a0dba981015fa6405eb50 Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at redhat.com> Date: Fri, 21 May 2010 14:14:25 +0100 Subject: [PATCH 3/4] New API: pvresize-size to allow shrinking PVs (RHBZ#585222). --- daemon/lvm.c | 24 ++++++++++++++++++++++++ src/generator.ml | 7 +++++++ 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/daemon/lvm.c b/daemon/lvm.c index 18d6519..70c3c90 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> +#include <inttypes.h> #include <string.h> #include <unistd.h> @@ -453,6 +454,29 @@ do_pvresize (const char *device) } int +do_pvresize_size (const char *device, int64_t size) +{ + char *err; + int r; + + char buf[32]; + snprintf (buf, sizeof buf, "%" PRIi64 "b", size); + + r = command (NULL, &err, + "lvm", "pvresize", + "--setphysicalvolumesize", buf, + device, NULL); + if (r == -1) { + reply_with_error ("%s: %s", device, err); + free (err); + return -1; + } + + free (err); + return 0; +} + +int do_vg_activate (int activate, char *const *volgroups) { char *err; diff --git a/src/generator.ml b/src/generator.ml index b2ba513..1032a1a 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -4693,6 +4693,13 @@ See also C<guestfs_pread>."); This command is the same as C<guestfs_resize2fs> except that it allows you to specify the new size (in bytes) explicitly."); + ("pvresize_size", (RErr, [Device "device"; Int64 "size"]), 249, [Optional "lvm2"], + [], + "resize an LVM physical volume (with size)", + "\ +This command is the same as C<guestfs_pvresize> except that it +allows you to specify the new size (in bytes) explicitly."); + ] let all_functions = non_daemon_functions @ daemon_functions -- 1.6.6.1
Richard W.M. Jones
2010-May-21 13:54 UTC
[Libguestfs] [PATCH 4/4] New API: ntfsresize-size to allow shrinking NTFS (RHBZ#585223).
-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://et.redhat.com/~rjones/virt-df/ -------------- next part -------------->From 7cb6fac3074c52ac3c3e9ead5d99e4a2887cf7b1 Mon Sep 17 00:00:00 2001From: Richard Jones <rjones at redhat.com> Date: Fri, 21 May 2010 14:14:59 +0100 Subject: [PATCH 4/4] New API: ntfsresize-size to allow shrinking NTFS (RHBZ#585223). --- daemon/ntfs.c | 21 +++++++++++++++++++++ src/MAX_PROC_NR | 2 +- src/generator.ml | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletions(-) diff --git a/daemon/ntfs.c b/daemon/ntfs.c index 8938dbd..46b8333 100644 --- a/daemon/ntfs.c +++ b/daemon/ntfs.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> +#include <inttypes.h> #include <string.h> #include <unistd.h> @@ -75,3 +76,23 @@ do_ntfsresize (const char *device) return 0; } + +int +do_ntfsresize_size (const char *device, int64_t size) +{ + char *err; + int r; + + char buf[32]; + snprintf (buf, sizeof buf, "%" PRIi64, size); + + r = command (NULL, &err, "ntfsresize", "-P", "--size", buf, + device, NULL); + if (r == -1) { + reply_with_error ("%s: %s", device, err); + free (err); + return -1; + } + + return 0; +} diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index e06108c..cb1a40d 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -247 +250 diff --git a/src/generator.ml b/src/generator.ml index 1032a1a..95a2637 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -4700,6 +4700,13 @@ allows you to specify the new size (in bytes) explicitly."); This command is the same as C<guestfs_pvresize> except that it allows you to specify the new size (in bytes) explicitly."); + ("ntfsresize_size", (RErr, [Device "device"; Int64 "size"]), 250, [Optional "ntfsprogs"], + [], + "resize an NTFS filesystem (with size)", + "\ +This command is the same as C<guestfs_ntfsresize> except that it +allows you to specify the new size (in bytes) explicitly."); + ] let all_functions = non_daemon_functions @ daemon_functions -- 1.6.6.1
Maybe Matching Threads
- [ANNOUNCE] libguestfs 1.4.0 - tools for accessing and modifying disk images and virtual machines
- [PATCH] Generic partition creation interface.
- [PATCH 2/2] resize: shrink/expand swap partitions
- Wrong deficit calculation in virt-resize.
- [PATCH v2 2/2] resize: expand f2fs partitions