[Libguestfs] [supermin PATCH 2/2] prepare: create a really empty base.tar.gz with no config files
Richard W.M. Jones
rjones at redhat.com
Mon Dec 3 17:07:42 UTC 2018
On Mon, Dec 03, 2018 at 05:17:33PM +0100, Pino Toscano wrote:
> tar defaults to 10K as block size, and thus it pads the created archives
> to multiples of that size using zero's. Hence, when creating an archive
> with no files, it will be 10K zero's, that is compressed by gzip,
> resulting in few bytes. The issue happens later, during the build
> phase: base.tar.gz is correctly detected as gz, and zcat is run to
> detect its content: since the empty tar was 10K of zero's, the buffer in
> get_compressed_file_content will be filled by zero's, and
> get_file_content will fail to detect anything.
>
> As solution, at least for our own base.tar.gz: in case there are no
> config files to copy, create a gzip file from /dev/null, which is still
> recognized as empty tar.
> ---
> src/mode_prepare.ml | 49 ++++++++++++++++++++++++++++++---------------
> 1 file changed, 33 insertions(+), 16 deletions(-)
>
> diff --git a/src/mode_prepare.ml b/src/mode_prepare.ml
> index 7759c58..8a09315 100644
> --- a/src/mode_prepare.ml
> +++ b/src/mode_prepare.ml
> @@ -149,20 +149,37 @@ let prepare debug (copy_kernel, format, host_cpu,
> printf "supermin: there are %d config files\n"
> (List.length config_files);
>
> - let files_from =
> - (* Put the list of config files into a file, for tar to read. *)
> - let files_from = tmpdir // "files-from.txt" in
> - let chan = open_out files_from in
> - List.iter (fprintf chan ".%s\n") config_files; (* "./filename" *)
> - close_out chan;
> -
> - files_from in
> -
> - (* Write base.tar.gz. *)
> let base = outputdir // "base.tar.gz" in
> - if debug >= 1 then printf "supermin: writing %s\n%!" base;
> - let cmd =
> - sprintf "tar%s -C %s -zcf %s -T %s"
> - (if debug >=1 then " -v" else "")
> - (quote dir) (quote base) (quote files_from) in
> - run_command cmd;
> +
> + if config_files <> [] then (
> + (* There are config files to copy, so create the list with them,
> + * and then compress them with tar.
> + *)
> + let files_from =
> + (* Put the list of config files into a file, for tar to read. *)
> + let files_from = tmpdir // "files-from.txt" in
> + let chan = open_out files_from in
> + List.iter (fprintf chan ".%s\n") config_files; (* "./filename" *)
> + close_out chan;
> +
> + files_from in
> +
> + (* Write base.tar.gz. *)
> + if debug >= 1 then printf "supermin: writing %s\n%!" base;
> + let cmd =
> + sprintf "tar%s -C %s -zcf %s -T %s"
> + (if debug >=1 then " -v" else "")
> + (quote dir) (quote base) (quote files_from) in
> + run_command cmd;
> + )
> + else (
> + (* No config files to copy: create an gzip file from /dev/null,
> + * which will be recognized as empty tar.
> + *)
> + if debug >= 1 then printf "supermin: creating an empty %s\n%!" base;
> + let cmd =
> + sprintf "gzip%s -c /dev/null > %s"
> + (if debug >=1 then " -v" else "")
> + (quote base) in
> + run_command cmd;
> + )
I wonder if we should just create no base.tar.gz at all in this case?
Anyway, it's fine, ACK.
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/
More information about the Libguestfs
mailing list