[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