Pino Toscano
2015-Jul-13 15:35 UTC
[Libguestfs] [PATCH 1/2] utils: import parse_size from libguestfs
--- src/utils.ml | 21 +++++++++++++++++++++ src/utils.mli | 3 +++ 2 files changed, 24 insertions(+) diff --git a/src/utils.ml b/src/utils.ml index 3e81c21..7ae24bd 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -204,3 +204,24 @@ let compare_architecture a1 a2 exit 1 in compare (index_of_architecture a1) (index_of_architecture a2) + +(* Parse a size field, eg. "10G". *) +let parse_size + let const_re = Str.regexp "^\\([.0-9]+\\)\\([bKMG]\\)$" in + fun field -> + let matches rex = Str.string_match rex field 0 in + let sub i = Str.matched_group i field in + let size_scaled f = function + | "b" -> Int64.of_float f + | "K" -> Int64.of_float (f *. 1024.) + | "M" -> Int64.of_float (f *. 1024. *. 1024.) + | "G" -> Int64.of_float (f *. 1024. *. 1024. *. 1024.) + | _ -> assert false + in + + if matches const_re then ( + size_scaled (float_of_string (sub 1)) (sub 2) + ) else ( + eprintf "supermin: cannot parse size field '%s'\n" field; + exit 1 + ) diff --git a/src/utils.mli b/src/utils.mli index 5de940d..7896e34 100644 --- a/src/utils.mli +++ b/src/utils.mli @@ -90,3 +90,6 @@ val compare_version : string -> string -> int val compare_architecture : string -> string -> int (** Compare two architecture strings. *) + +val parse_size : string -> int64 +(** Parse a size field, eg. [10G] *) -- 2.1.0
Pino Toscano
2015-Jul-13 15:35 UTC
[Libguestfs] [PATCH 2/2] Add --size for ext2 filesystem
Add a --size option to setting the size of the ext2 filesystem, so it is possible to create ext2 appliances with smaller disk images. The default is like the previously hardcoded value of 4GB. --- src/build.ml | 4 ++-- src/ext2.ml | 19 ++++++++++--------- src/prepare.ml | 2 +- src/supermin.ml | 9 +++++++-- src/supermin.pod | 15 +++++++++++++++ 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/build.ml b/src/build.ml index d7d0781..fb2e6d3 100644 --- a/src/build.ml +++ b/src/build.ml @@ -59,7 +59,7 @@ and string_of_file_content = function let rec build debug (copy_kernel, dtb_wildcard, format, host_cpu, - packager_config, tmpdir, use_installed) + packager_config, tmpdir, use_installed, size) inputs outputdir if debug >= 1 then printf "supermin: build: %s\n%!" (String.concat " " inputs); @@ -210,7 +210,7 @@ let rec build debug and initrd = outputdir // "initrd" in let kernel_version, modpath Kernel.build_kernel debug host_cpu dtb_wildcard copy_kernel kernel dtb in - Ext2.build_ext2 debug basedir files modpath kernel_version appliance; + Ext2.build_ext2 debug basedir files modpath kernel_version appliance size; Ext2_initrd.build_initrd debug tmpdir modpath initrd and read_appliance debug basedir appliance = function diff --git a/src/ext2.ml b/src/ext2.ml index d5c26a7..79539a3 100644 --- a/src/ext2.ml +++ b/src/ext2.ml @@ -23,26 +23,27 @@ open Utils open Ext2fs open Package_handler -(* The ext2 image that we build always has a fixed size, and we 'hope' - * that the files fit in (otherwise we'll get an error). Note that - * the file is sparsely allocated. +(* The ext2 image that we build has a size of 4GB if not specified, + * and we 'hope' that the files fit in (otherwise we'll get an error). + * Note that the file is sparsely allocated. * * The downside of allocating a very large initial disk is that the * fixed overhead of ext2 is larger (since ext2 calculates it based on * the size of the disk). For a 4GB disk the overhead is * approximately 66MB. - * - * In future, make this configurable, or determine it from the input - * files (XXX). *) -let appliance_size = 4L *^ 1024L *^ 1024L *^ 1024L +let default_appliance_size = 4L *^ 1024L *^ 1024L *^ 1024L -let build_ext2 debug basedir files modpath kernel_version appliance +let build_ext2 debug basedir files modpath kernel_version appliance size if debug >= 1 then printf "supermin: ext2: creating empty ext2 filesystem '%s'\n%!" appliance; let fd = openfile appliance [O_WRONLY;O_CREAT;O_TRUNC;O_NOCTTY] 0o644 in - LargeFile.ftruncate fd appliance_size; + let size + match size with + | None -> default_appliance_size + | Some s -> s in + LargeFile.ftruncate fd size; close fd; let cmd diff --git a/src/prepare.ml b/src/prepare.ml index 75f21dc..7e522e9 100644 --- a/src/prepare.ml +++ b/src/prepare.ml @@ -22,7 +22,7 @@ open Package_handler open Utils let prepare debug (copy_kernel, dtb_wildcard, format, host_cpu, - packager_config, tmpdir, use_installed) + packager_config, tmpdir, use_installed, size) inputs outputdir if debug >= 1 then printf "supermin: prepare: %s\n%!" (String.concat " " inputs); diff --git a/src/supermin.ml b/src/supermin.ml index 14261d6..9623229 100644 --- a/src/supermin.ml +++ b/src/supermin.ml @@ -94,6 +94,7 @@ let main () let outputdir = ref "" in let packager_config = ref "" in let use_installed = ref false in + let size = ref None in let set_debug () = incr debug in @@ -118,6 +119,8 @@ let main () exit 1 in + let set_size arg = size := Some (parse_size arg) in + let error_supermin_5 () eprintf "supermin: *** error: This is supermin version 5.\n"; eprintf "supermin: *** It looks like you are looking for supermin version 4.\n"; @@ -143,6 +146,7 @@ let main () "-o", Arg.Set_string outputdir, "OUTPUTDIR Set output directory"; "--packager-config", Arg.Set_string packager_config, "CONFIGFILE Set packager config file"; "--prepare", Arg.Unit set_prepare_mode, " Prepare a supermin appliance"; + "--size", Arg.String set_size, " Set the size of the ext2 filesystem"; "--use-installed", Arg.Set use_installed, " Use installed files instead of accessing network"; "-v", Arg.Unit set_debug, " Enable debugging messages"; "--verbose", Arg.Unit set_debug, ditto; @@ -165,6 +169,7 @@ let main () let packager_config match !packager_config with "" -> None | s -> Some s in let use_installed = !use_installed in + let size = !size in let format match mode, !format with @@ -184,7 +189,7 @@ let main () debug, mode, if_newer, inputs, lockfile, outputdir, (copy_kernel, dtb_wildcard, format, host_cpu, - packager_config, tmpdir, use_installed) in + packager_config, tmpdir, use_installed, size) in if debug >= 1 then printf "supermin: version: %s\n" Config.package_version; @@ -192,7 +197,7 @@ let main () * This fails with an error if one could not be located. *) let () - let (_, _, _, _, packager_config, tmpdir, _) = args in + let (_, _, _, _, packager_config, tmpdir, _, _) = args in let settings = { debug = debug; tmpdir = tmpdir; diff --git a/src/supermin.pod b/src/supermin.pod index f2e8446..f9b7395 100644 --- a/src/supermin.pod +++ b/src/supermin.pod @@ -189,6 +189,9 @@ appliance to C<OUTPUTDIR/initrd>, and the ext2 filesystem image to C<OUTPUTDIR/root>. (Where C<OUTPUTDIR> is specified by the I<-o> option). +The filesystem (C<OUTPUTDIR/root>) has a default size of 4 GB +(see also the I<--size> option). + =back =item B<--host-cpu> CPU @@ -283,6 +286,18 @@ However this option is useful in some controlled situations: for example when using supermin inside a freshly installed chroot, or if you have no network access during the build. +=item B<--size> SIZE + +(I<--build> mode only) + +Select the size of the output ext2 filesystem, where the size can be +specified using common names such as C<32G> (32 gigabytes) etc. + +If the size is not specified, a default size of 4 GB is used. + +To specify size in bytes, the number must be followed by the lowercase +letter I<b>, eg: S<C<--size 10737418240b>>. + =item B<-v> =item B<--verbose> -- 2.1.0
Richard W.M. Jones
2015-Jul-13 18:25 UTC
Re: [Libguestfs] [PATCH 2/2] Add --size for ext2 filesystem
On Mon, Jul 13, 2015 at 05:35:56PM +0200, Pino Toscano wrote:> Add a --size option to setting the size of the ext2 filesystem, > so it is possible to create ext2 appliances with smaller disk images. > > The default is like the previously hardcoded value of 4GB. > --- > src/build.ml | 4 ++-- > src/ext2.ml | 19 ++++++++++--------- > src/prepare.ml | 2 +- > src/supermin.ml | 9 +++++++-- > src/supermin.pod | 15 +++++++++++++++ > 5 files changed, 35 insertions(+), 14 deletions(-) > > diff --git a/src/build.ml b/src/build.ml > index d7d0781..fb2e6d3 100644 > --- a/src/build.ml > +++ b/src/build.ml > @@ -59,7 +59,7 @@ and string_of_file_content = function > > let rec build debug > (copy_kernel, dtb_wildcard, format, host_cpu, > - packager_config, tmpdir, use_installed) > + packager_config, tmpdir, use_installed, size) > inputs outputdir > if debug >= 1 then > printf "supermin: build: %s\n%!" (String.concat " " inputs); > @@ -210,7 +210,7 @@ let rec build debug > and initrd = outputdir // "initrd" in > let kernel_version, modpath > Kernel.build_kernel debug host_cpu dtb_wildcard copy_kernel kernel dtb in > - Ext2.build_ext2 debug basedir files modpath kernel_version appliance; > + Ext2.build_ext2 debug basedir files modpath kernel_version appliance size; > Ext2_initrd.build_initrd debug tmpdir modpath initrd > > and read_appliance debug basedir appliance = function > diff --git a/src/ext2.ml b/src/ext2.ml > index d5c26a7..79539a3 100644 > --- a/src/ext2.ml > +++ b/src/ext2.ml > @@ -23,26 +23,27 @@ open Utils > open Ext2fs > open Package_handler > > -(* The ext2 image that we build always has a fixed size, and we 'hope' > - * that the files fit in (otherwise we'll get an error). Note that > - * the file is sparsely allocated. > +(* The ext2 image that we build has a size of 4GB if not specified, > + * and we 'hope' that the files fit in (otherwise we'll get an error). > + * Note that the file is sparsely allocated. > * > * The downside of allocating a very large initial disk is that the > * fixed overhead of ext2 is larger (since ext2 calculates it based on > * the size of the disk). For a 4GB disk the overhead is > * approximately 66MB. > - * > - * In future, make this configurable, or determine it from the input > - * files (XXX). > *) > -let appliance_size = 4L *^ 1024L *^ 1024L *^ 1024L > +let default_appliance_size = 4L *^ 1024L *^ 1024L *^ 1024L > > -let build_ext2 debug basedir files modpath kernel_version appliance > +let build_ext2 debug basedir files modpath kernel_version appliance size > if debug >= 1 then > printf "supermin: ext2: creating empty ext2 filesystem '%s'\n%!" appliance; > > let fd = openfile appliance [O_WRONLY;O_CREAT;O_TRUNC;O_NOCTTY] 0o644 in > - LargeFile.ftruncate fd appliance_size; > + let size > + match size with > + | None -> default_appliance_size > + | Some s -> s in > + LargeFile.ftruncate fd size; > close fd; > > let cmd > diff --git a/src/prepare.ml b/src/prepare.ml > index 75f21dc..7e522e9 100644 > --- a/src/prepare.ml > +++ b/src/prepare.ml > @@ -22,7 +22,7 @@ open Package_handler > open Utils > > let prepare debug (copy_kernel, dtb_wildcard, format, host_cpu, > - packager_config, tmpdir, use_installed) > + packager_config, tmpdir, use_installed, size) > inputs outputdir > if debug >= 1 then > printf "supermin: prepare: %s\n%!" (String.concat " " inputs); > diff --git a/src/supermin.ml b/src/supermin.ml > index 14261d6..9623229 100644 > --- a/src/supermin.ml > +++ b/src/supermin.ml > @@ -94,6 +94,7 @@ let main () > let outputdir = ref "" in > let packager_config = ref "" in > let use_installed = ref false in > + let size = ref None in > > let set_debug () = incr debug in > > @@ -118,6 +119,8 @@ let main () > exit 1 > in > > + let set_size arg = size := Some (parse_size arg) in > + > let error_supermin_5 () > eprintf "supermin: *** error: This is supermin version 5.\n"; > eprintf "supermin: *** It looks like you are looking for supermin version 4.\n"; > @@ -143,6 +146,7 @@ let main () > "-o", Arg.Set_string outputdir, "OUTPUTDIR Set output directory"; > "--packager-config", Arg.Set_string packager_config, "CONFIGFILE Set packager config file"; > "--prepare", Arg.Unit set_prepare_mode, " Prepare a supermin appliance"; > + "--size", Arg.String set_size, " Set the size of the ext2 filesystem"; > "--use-installed", Arg.Set use_installed, " Use installed files instead of accessing network"; > "-v", Arg.Unit set_debug, " Enable debugging messages"; > "--verbose", Arg.Unit set_debug, ditto; > @@ -165,6 +169,7 @@ let main () > let packager_config > match !packager_config with "" -> None | s -> Some s in > let use_installed = !use_installed in > + let size = !size in > > let format > match mode, !format with > @@ -184,7 +189,7 @@ let main () > > debug, mode, if_newer, inputs, lockfile, outputdir, > (copy_kernel, dtb_wildcard, format, host_cpu, > - packager_config, tmpdir, use_installed) in > + packager_config, tmpdir, use_installed, size) in > > if debug >= 1 then printf "supermin: version: %s\n" Config.package_version; > > @@ -192,7 +197,7 @@ let main () > * This fails with an error if one could not be located. > *) > let () > - let (_, _, _, _, packager_config, tmpdir, _) = args in > + let (_, _, _, _, packager_config, tmpdir, _, _) = args in > let settings = { > debug = debug; > tmpdir = tmpdir; > diff --git a/src/supermin.pod b/src/supermin.pod > index f2e8446..f9b7395 100644 > --- a/src/supermin.pod > +++ b/src/supermin.pod > @@ -189,6 +189,9 @@ appliance to C<OUTPUTDIR/initrd>, and the ext2 filesystem image to > C<OUTPUTDIR/root>. (Where C<OUTPUTDIR> is specified by the I<-o> > option). > > +The filesystem (C<OUTPUTDIR/root>) has a default size of 4 GB > +(see also the I<--size> option). > + > =back > > =item B<--host-cpu> CPU > @@ -283,6 +286,18 @@ However this option is useful in some controlled situations: for > example when using supermin inside a freshly installed chroot, or if > you have no network access during the build. > > +=item B<--size> SIZE > + > +(I<--build> mode only) > + > +Select the size of the output ext2 filesystem, where the size can be > +specified using common names such as C<32G> (32 gigabytes) etc. > + > +If the size is not specified, a default size of 4 GB is used. > + > +To specify size in bytes, the number must be followed by the lowercase > +letter I<b>, eg: S<C<--size 10737418240b>>. > + > =item B<-v> > > =item B<--verbose> > -- > 2.1.0ACK series. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/