From 864ef706a84c7c87a62f776d4b2e82a6f959ae14 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 14 Aug 2012 09:04:51 +0100 Subject: Add optional compress flag to tar-in, tar-out APIs. 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 83e68dd3..8d78283e 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) { @@ -201,38 +221,54 @@ do_tXz_in (const char *dir, const char *filter) return 0; } -/* 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; } @@ -280,23 +316,18 @@ do_tXz_out (const char *dir, const char *filter) return 0; } -/* 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 3c72e960..a29a6855 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -3402,40 +3402,58 @@ To get the checksums for many files, use C." }; { 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 (an -I tar file) into C. +This command uploads and unpacks local file C into C. -To upload a compressed tarball, use C -or C." }; +The optional C 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, C, C, C, C. +(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 and downloads it to local file C. -To download a compressed tarball, use C -or C." }; +The optional C 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, C, C, C, C. +(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." }; shortdesc = "unpack compressed tarball to directory"; longdesc = "\ This command uploads and unpacks local file C (a -I tar file) into C. - -To upload an uncompressed tarball, use C." }; +I tar file) into C." }; { 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 and downloads -it to local file C. - -To download an uncompressed tarball, use C." }; +it to local file C." }; { 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 tar file) into C." }; 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 8c4b2d13..49f95387 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 d1fcc4d8..08d2ab86 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 d2de6f63..d1f1ce73 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 801104fe..053231c1 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); } -- cgit