[Libguestfs] [PATCH 1/7] Add optional compress flag to tar-in, tar-out APIs.

Richard W.M. Jones rjones at redhat.com
Tue Aug 14 14:51:07 UTC 2012


From: "Richard W.M. Jones" <rjones at redhat.com>

The compress flag can be used to control compression, one of: (none),
"compress", "gzip", "bzip2", "xz", "lzop".  Thus these calls can now
be used instead of tgz-in/tgz-out/txz-in/txz-out, and also support
more compression types.

Mark these APIs as once_had_no_optargs so that compatibility code is
generated.
---
 daemon/tar.c                      |   81 +++++++++++++++++++++++++------------
 generator/generator_actions.ml    |   49 ++++++++++++++--------
 gobject/Makefile.inc              |    4 ++
 po/POTFILES                       |    2 +
 tests/btrfs/test-btrfs-devices.sh |    8 ++--
 tools/virt-tar                    |    4 +-
 6 files changed, 101 insertions(+), 47 deletions(-)

diff --git a/daemon/tar.c b/daemon/tar.c
index 83e68dd..8d78283 100644
--- a/daemon/tar.c
+++ b/daemon/tar.c
@@ -113,9 +113,11 @@ write_cb (void *fd_ptr, const void *buf, size_t len)
 }
 
 /* Has one FileIn parameter. */
-static int
-do_tXz_in (const char *dir, const char *filter)
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_tar_in (const char *dir, const char *compress)
 {
+  const char *filter;
   int err, r;
   FILE *fp;
   char *cmd;
@@ -126,6 +128,24 @@ do_tXz_in (const char *dir, const char *filter)
   if (chown_supported == -1)
     return -1;
 
+  if ((optargs_bitmask & GUESTFS_TAR_IN_COMPRESS_BITMASK)) {
+    if (STREQ (compress, "compress"))
+      filter = " --compress";
+    else if (STREQ (compress, "gzip"))
+      filter = " --gzip";
+    else if (STREQ (compress, "bzip2"))
+      filter = " --bzip2";
+    else if (STREQ (compress, "xz"))
+      filter = " --xz";
+    else if (STREQ (compress, "lzop"))
+      filter = " --lzop";
+    else {
+      reply_with_error ("unknown compression type: %s", compress);
+      return -1;
+    }
+  } else
+    filter = "";
+
   fd = mkstemp (error_file);
   if (fd == -1) {
     reply_with_perror ("mkstemp");
@@ -135,7 +155,7 @@ do_tXz_in (const char *dir, const char *filter)
   close (fd);
 
   /* "tar -C /sysroot%s -xf -" but we have to quote the dir. */
-  if (asprintf_nowarn (&cmd, "tar -C %R -%sxf - %s2> %s",
+  if (asprintf_nowarn (&cmd, "tar -C %R%s -xf - %s2> %s",
                        dir, filter,
                        chown_supported ? "" : "--no-same-owner ",
                        error_file) == -1) {
@@ -203,36 +223,52 @@ do_tXz_in (const char *dir, const char *filter)
 
 /* Has one FileIn parameter. */
 int
-do_tar_in (const char *dir)
-{
-  return do_tXz_in (dir, "");
-}
-
-/* Has one FileIn parameter. */
-int
 do_tgz_in (const char *dir)
 {
-  return do_tXz_in (dir, "z");
+  optargs_bitmask = GUESTFS_TAR_IN_COMPRESS_BITMASK;
+  return do_tar_in (dir, "gzip");
 }
 
 /* Has one FileIn parameter. */
 int
 do_txz_in (const char *dir)
 {
-  return do_tXz_in (dir, "J");
+  optargs_bitmask = GUESTFS_TAR_IN_COMPRESS_BITMASK;
+  return do_tar_in (dir, "xz");
 }
 
 /* Has one FileOut parameter. */
-static int
-do_tXz_out (const char *dir, const char *filter)
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_tar_out (const char *dir, const char *compress)
 {
+  const char *filter;
   int r;
   FILE *fp;
   char *cmd;
   char buf[GUESTFS_MAX_CHUNK_SIZE];
 
-  /* "tar -C /sysroot%s -zcf - ." but we have to quote the dir. */
-  if (asprintf_nowarn (&cmd, "tar -C %R -%scf - .", dir, filter) == -1) {
+  if ((optargs_bitmask & GUESTFS_TAR_OUT_COMPRESS_BITMASK)) {
+    if (STREQ (compress, "compress"))
+      filter = " --compress";
+    else if (STREQ (compress, "gzip"))
+      filter = " --gzip";
+    else if (STREQ (compress, "bzip2"))
+      filter = " --bzip2";
+    else if (STREQ (compress, "xz"))
+      filter = " --xz";
+    else if (STREQ (compress, "lzop"))
+      filter = " --lzop";
+    else {
+      reply_with_error ("unknown compression type: %s", compress);
+      return -1;
+    }
+  } else
+    filter = "";
+
+  /* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */
+  if (asprintf_nowarn (&cmd, "tar -C %R%s -cf - .",
+                       dir, filter) == -1) {
     reply_with_perror ("asprintf");
     return -1;
   }
@@ -282,21 +318,16 @@ do_tXz_out (const char *dir, const char *filter)
 
 /* Has one FileOut parameter. */
 int
-do_tar_out (const char *dir)
-{
-  return do_tXz_out (dir, "");
-}
-
-/* Has one FileOut parameter. */
-int
 do_tgz_out (const char *dir)
 {
-  return do_tXz_out (dir, "z");
+  optargs_bitmask = GUESTFS_TAR_OUT_COMPRESS_BITMASK;
+  return do_tar_out (dir, "gzip");
 }
 
 /* Has one FileOut parameter. */
 int
 do_txz_out (const char *dir)
 {
-  return do_tXz_out (dir, "J");
+  optargs_bitmask = GUESTFS_TAR_OUT_COMPRESS_BITMASK;
+  return do_tar_out (dir, "bzip2");
 }
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 3c72e96..a29a685 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -3402,40 +3402,58 @@ To get the checksums for many files, use C<guestfs_checksums_out>." };
 
   { defaults with
     name = "tar_in";
-    style = RErr, [FileIn "tarfile"; Pathname "directory"], [];
+    style = RErr, [FileIn "tarfile"; Pathname "directory"], [OString "compress"];
     proc_nr = Some 69;
+    once_had_no_optargs = true;
     cancellable = true;
     tests = [
       InitScratchFS, Always, TestOutput (
         [["mkdir"; "/tar_in"];
-         ["tar_in"; "../data/helloworld.tar"; "/tar_in"];
-         ["cat"; "/tar_in/hello"]], "hello\n")
+         ["tar_in"; "../data/helloworld.tar"; "/tar_in"; "NOARG"];
+         ["cat"; "/tar_in/hello"]], "hello\n");
+      InitScratchFS, Always, TestOutput (
+        [["mkdir"; "/tar_in_gz"];
+         ["tar_in"; "../data/helloworld.tar.gz"; "/tar_in_gz"; "gzip"];
+         ["cat"; "/tar_in_gz/hello"]], "hello\n");
+      InitScratchFS, Always, TestOutput (
+        [["mkdir"; "/tar_in_xz"];
+         ["tar_in"; "../data/helloworld.tar.xz"; "/tar_in_xz"; "xz"];
+         ["cat"; "/tar_in_xz/hello"]], "hello\n")
     ];
     shortdesc = "unpack tarfile to directory";
     longdesc = "\
-This command uploads and unpacks local file C<tarfile> (an
-I<uncompressed> tar file) into C<directory>.
+This command uploads and unpacks local file C<tarfile> into C<directory>.
 
-To upload a compressed tarball, use C<guestfs_tgz_in>
-or C<guestfs_txz_in>." };
+The optional C<compress> flag controls compression.  If not given,
+then the input should be an uncompressed tar file.  Otherwise one
+of the following strings may be given to select the compression
+type of the input file: C<compress>, C<gzip>, C<bzip2>, C<xz>, C<lzop>.
+(Note that not all builds of libguestfs will support all of these
+compression types)." };
 
   { defaults with
     name = "tar_out";
-    style = RErr, [String "directory"; FileOut "tarfile"], [];
+    style = RErr, [String "directory"; FileOut "tarfile"], [OString "compress"];
     proc_nr = Some 70;
+    once_had_no_optargs = true;
     cancellable = true;
     shortdesc = "pack directory into tarfile";
     longdesc = "\
 This command packs the contents of C<directory> and downloads
 it to local file C<tarfile>.
 
-To download a compressed tarball, use C<guestfs_tgz_out>
-or C<guestfs_txz_out>." };
+The optional C<compress> flag controls compression.  If not given,
+then the output will be an uncompressed tar file.  Otherwise one
+of the following strings may be given to select the compression
+type of the output file: C<compress>, C<gzip>, C<bzip2>, C<xz>, C<lzop>.
+(Note that not all builds of libguestfs will support all of these
+compression types)." };
 
   { defaults with
     name = "tgz_in";
     style = RErr, [FileIn "tarball"; Pathname "directory"], [];
     proc_nr = Some 71;
+    deprecated_by = Some "tar_in";
     cancellable = true;
     tests = [
       InitScratchFS, Always, TestOutput (
@@ -3446,21 +3464,18 @@ or C<guestfs_txz_out>." };
     shortdesc = "unpack compressed tarball to directory";
     longdesc = "\
 This command uploads and unpacks local file C<tarball> (a
-I<gzip compressed> tar file) into C<directory>.
-
-To upload an uncompressed tarball, use C<guestfs_tar_in>." };
+I<gzip compressed> tar file) into C<directory>." };
 
   { defaults with
     name = "tgz_out";
     style = RErr, [Pathname "directory"; FileOut "tarball"], [];
     proc_nr = Some 72;
+    deprecated_by = Some "tar_out";
     cancellable = true;
     shortdesc = "pack directory into compressed tarball";
     longdesc = "\
 This command packs the contents of C<directory> and downloads
-it to local file C<tarball>.
-
-To download an uncompressed tarball, use C<guestfs_tar_out>." };
+it to local file C<tarball>." };
 
   { defaults with
     name = "mount_ro";
@@ -6764,6 +6779,7 @@ or growing unnecessarily." };
     name = "txz_in";
     style = RErr, [FileIn "tarball"; Pathname "directory"], [];
     proc_nr = Some 229;
+    deprecated_by = Some "tar_in";
     optional = Some "xz"; cancellable = true;
     tests = [
       InitScratchFS, Always, TestOutput (
@@ -6780,6 +6796,7 @@ I<xz compressed> tar file) into C<directory>." };
     name = "txz_out";
     style = RErr, [Pathname "directory"; FileOut "tarball"], [];
     proc_nr = Some 230;
+    deprecated_by = Some "tar_out";
     optional = Some "xz"; cancellable = true;
     shortdesc = "pack directory into compressed tarball";
     longdesc = "\
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 8c4b2d1..49f9538 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -47,6 +47,8 @@ guestfs_gobject_headers= \
   include/guestfs-gobject/optargs-mount_local.h \
   include/guestfs-gobject/optargs-umount_local.h \
   include/guestfs-gobject/optargs-umount.h \
+  include/guestfs-gobject/optargs-tar_in.h \
+  include/guestfs-gobject/optargs-tar_out.h \
   include/guestfs-gobject/optargs-grep.h \
   include/guestfs-gobject/optargs-mkfs.h \
   include/guestfs-gobject/optargs-mount_9p.h \
@@ -99,6 +101,8 @@ guestfs_gobject_sources= \
   src/optargs-mount_local.c \
   src/optargs-umount_local.c \
   src/optargs-umount.c \
+  src/optargs-tar_in.c \
+  src/optargs-tar_out.c \
   src/optargs-grep.c \
   src/optargs-mkfs.c \
   src/optargs-mount_9p.c \
diff --git a/po/POTFILES b/po/POTFILES
index d1fcc4d..08d2ab8 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -162,6 +162,8 @@ gobject/src/optargs-rsync.c
 gobject/src/optargs-rsync_in.c
 gobject/src/optargs-rsync_out.c
 gobject/src/optargs-set_e2attrs.c
+gobject/src/optargs-tar_in.c
+gobject/src/optargs-tar_out.c
 gobject/src/optargs-tune2fs.c
 gobject/src/optargs-umount.c
 gobject/src/optargs-umount_local.c
diff --git a/tests/btrfs/test-btrfs-devices.sh b/tests/btrfs/test-btrfs-devices.sh
index d2de6f6..d1f1ce7 100755
--- a/tests/btrfs/test-btrfs-devices.sh
+++ b/tests/btrfs/test-btrfs-devices.sh
@@ -51,7 +51,7 @@ mkfs-btrfs "/dev/sda1 /dev/sdb1"
 mount /dev/sda1 /
 
 mkdir /data1
-txz-in ../data/filesanddirs-10M.tar.xz /data1
+tar-in ../data/filesanddirs-10M.tar.xz /data1 compress:xz
 
 # In btrfs-progs 0.19, a test was added which prevents us from
 # deleting the mount device (/dev/sda1) although that restriction
@@ -64,7 +64,7 @@ btrfs-device-add "/dev/sdb1" /
 btrfs-device-delete "/dev/sdc1 /dev/sdd1" /
 
 mkdir /data2
-txz-in ../data/filesanddirs-10M.tar.xz /data2
+tar-in ../data/filesanddirs-10M.tar.xz /data2 compress:xz
 
 btrfs-device-add "/dev/sdc1 /dev/sdd1" /
 btrfs-device-delete "/dev/sdb1" /
@@ -72,7 +72,7 @@ btrfs-device-add "/dev/sdb1" /
 btrfs-device-delete "/dev/sdc1 /dev/sdd1" /
 
 mkdir /data3
-txz-in ../data/filesanddirs-10M.tar.xz /data3
+tar-in ../data/filesanddirs-10M.tar.xz /data3 compress:xz
 
 btrfs-device-add "/dev/sdc1 /dev/sdd1" /
 btrfs-device-delete "/dev/sdb1" /
@@ -80,7 +80,7 @@ btrfs-device-add "/dev/sdb1" /
 btrfs-device-delete "/dev/sdc1 /dev/sdd1" /
 
 mkdir /data4
-txz-in ../data/filesanddirs-10M.tar.xz /data4
+tar-in ../data/filesanddirs-10M.tar.xz /data4 compress:xz
 
 btrfs-device-add "/dev/sdc1 /dev/sdd1" /
 btrfs-device-delete "/dev/sdb1" /
diff --git a/tools/virt-tar b/tools/virt-tar
index 801104f..053231c 100755
--- a/tools/virt-tar
+++ b/tools/virt-tar
@@ -267,13 +267,13 @@ foreach (@fses) {
 # Do the tar command.
 if ($mode eq "x") {
     if ($gzip) {
-        $g->tgz_out ($directory, $tarball);
+        $g->tar_out ($directory, $tarball, compress => "gzip");
     } else {
         $g->tar_out ($directory, $tarball);
     }
 } else { # mode eq "u"
     if ($gzip) {
-        $g->tgz_in ($tarball, $directory);
+        $g->tar_in ($tarball, $directory, compress => "gzip");
     } else {
         $g->tar_in ($tarball, $directory);
     }
-- 
1.7.10.4




More information about the Libguestfs mailing list