[Libguestfs] [supermin PATCH 2/2] prepare: create a really empty base.tar.gz with no config files

Pino Toscano ptoscano at redhat.com
Mon Dec 3 16:17:33 UTC 2018


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;
+  )
-- 
2.17.2




More information about the Libguestfs mailing list