Pino Toscano
2015-Jul-15 10:13 UTC
[Libguestfs] [PATCH 1/2] actions: tar_out: add xattrs and selinux optargs
Add additional arguments for tar, so extended attributes and/or SELinux contexts can be saved in output tars. --- daemon/tar.c | 18 +++++++++++++----- generator/actions.ml | 10 +++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/daemon/tar.c b/daemon/tar.c index d6f8f2f..68af749 100644 --- a/daemon/tar.c +++ b/daemon/tar.c @@ -311,7 +311,7 @@ make_exclude_from_file (char *const *excludes) /* Takes optional arguments, consult optargs_bitmask. */ int do_tar_out (const char *dir, const char *compress, int numericowner, - char *const *excludes) + char *const *excludes, int xattrs, int selinux) { CLEANUP_FREE char *buf = NULL; struct stat statbuf; @@ -349,6 +349,12 @@ do_tar_out (const char *dir, const char *compress, int numericowner, return -1; } + if (!(optargs_bitmask & GUESTFS_TAR_OUT_XATTRS_BITMASK)) + xattrs = 0; + + if (!(optargs_bitmask & GUESTFS_TAR_OUT_SELINUX_BITMASK)) + selinux = 0; + /* Check the filename exists and is a directory (RHBZ#908322). */ buf = sysroot_path (dir); if (buf == NULL) { @@ -367,12 +373,14 @@ do_tar_out (const char *dir, const char *compress, int numericowner, } /* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */ - if (asprintf_nowarn (&cmd, "%s -C %Q%s%s%s%s -cf - .", + if (asprintf_nowarn (&cmd, "%s -C %Q%s%s%s%s%s%s -cf - .", str_tar, buf, filter, numericowner ? " --numeric-owner" : "", exclude_from_file ? " -X " : "", - exclude_from_file ? exclude_from_file : "") == -1) { + exclude_from_file ? exclude_from_file : "", + xattrs ? " --xattrs" : "", + selinux ? " --selinux" : "") == -1) { reply_with_perror ("asprintf"); return -1; } @@ -423,7 +431,7 @@ int do_tgz_out (const char *dir) { optargs_bitmask = GUESTFS_TAR_OUT_COMPRESS_BITMASK; - return do_tar_out (dir, "gzip", 0, NULL); + return do_tar_out (dir, "gzip", 0, NULL, 0, 0); } /* Has one FileOut parameter. */ @@ -431,5 +439,5 @@ int do_txz_out (const char *dir) { optargs_bitmask = GUESTFS_TAR_OUT_COMPRESS_BITMASK; - return do_tar_out (dir, "xz", 0, NULL); + return do_tar_out (dir, "xz", 0, NULL, 0, 0); } diff --git a/generator/actions.ml b/generator/actions.ml index 16aeb4b..b336f56 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -4824,7 +4824,7 @@ compression types)." }; { defaults with name = "tar_out"; added = (1, 0, 3); - style = RErr, [String "directory"; FileOut "tarfile"], [OString "compress"; OBool "numericowner"; OStringList "excludes"]; + style = RErr, [String "directory"; FileOut "tarfile"], [OString "compress"; OBool "numericowner"; OStringList "excludes"; OBool "xattrs"; OBool "selinux"]; proc_nr = Some 70; once_had_no_optargs = true; cancellable = true; @@ -4854,6 +4854,14 @@ wildcards. If set to true, the output tar file will contain UID/GID numbers instead of user/group names. +=item C<xattrs> + +If set to true, extended attributes are saved in the output tar. + +=item C<selinux> + +If set to true, SELinux contexts are saved in the output tar. + =back" }; { defaults with -- 2.1.0
Pino Toscano
2015-Jul-15 10:13 UTC
[Libguestfs] [PATCH 2/2] actions: tar_in: add xattrs and selinux optargs
Add additional arguments for tar, so extended attributes and/or SELinux contexts can be restored from input tars. --- daemon/tar.c | 16 ++++++++++++---- generator/actions.ml | 24 +++++++++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/daemon/tar.c b/daemon/tar.c index 68af749..2e8ed10 100644 --- a/daemon/tar.c +++ b/daemon/tar.c @@ -129,7 +129,7 @@ write_cb (void *fd_ptr, const void *buf, size_t len) /* Has one FileIn parameter. */ /* Takes optional arguments, consult optargs_bitmask. */ int -do_tar_in (const char *dir, const char *compress) +do_tar_in (const char *dir, const char *compress, int xattrs, int selinux) { const char *filter; int err, r; @@ -160,6 +160,12 @@ do_tar_in (const char *dir, const char *compress) } else filter = ""; + if (!(optargs_bitmask & GUESTFS_TAR_IN_XATTRS_BITMASK)) + xattrs = 0; + + if (!(optargs_bitmask & GUESTFS_TAR_IN_SELINUX_BITMASK)) + selinux = 0; + fd = mkstemp (error_file); if (fd == -1) { err = errno; @@ -172,10 +178,12 @@ do_tar_in (const char *dir, const char *compress) close (fd); /* "tar -C /sysroot%s -xf -" but we have to quote the dir. */ - if (asprintf_nowarn (&cmd, "%s -C %R%s -xf - %s2> %s", + if (asprintf_nowarn (&cmd, "%s -C %R%s -xf - %s%s%s2> %s", str_tar, dir, filter, chown_supported ? "" : "--no-same-owner ", + xattrs ? "--xattrs " : "", + selinux ? "--selinux " : "", error_file) == -1) { err = errno; r = cancel_receive (); @@ -240,7 +248,7 @@ int do_tgz_in (const char *dir) { optargs_bitmask = GUESTFS_TAR_IN_COMPRESS_BITMASK; - return do_tar_in (dir, "gzip"); + return do_tar_in (dir, "gzip", 0, 0); } /* Has one FileIn parameter. */ @@ -248,7 +256,7 @@ int do_txz_in (const char *dir) { optargs_bitmask = GUESTFS_TAR_IN_COMPRESS_BITMASK; - return do_tar_in (dir, "xz"); + return do_tar_in (dir, "xz", 0, 0); } /* Turn list 'excludes' into a temporary file, and return a string diff --git a/generator/actions.ml b/generator/actions.ml index b336f56..d9e3bc7 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -4793,22 +4793,22 @@ To get the checksums for many files, use C<guestfs_checksums_out>." }; { defaults with name = "tar_in"; added = (1, 0, 3); - style = RErr, [FileIn "tarfile"; Pathname "directory"], [OString "compress"]; + style = RErr, [FileIn "tarfile"; Pathname "directory"], [OString "compress"; OBool "xattrs"; OBool "selinux"]; proc_nr = Some 69; once_had_no_optargs = true; cancellable = true; tests = [ InitScratchFS, Always, TestResultString ( [["mkdir"; "/tar_in"]; - ["tar_in"; "$srcdir/../data/helloworld.tar"; "/tar_in"; "NOARG"]; + ["tar_in"; "$srcdir/../data/helloworld.tar"; "/tar_in"; "NOARG"; ""; ""]; ["cat"; "/tar_in/hello"]], "hello\n"), []; InitScratchFS, Always, TestResultString ( [["mkdir"; "/tar_in_gz"]; - ["tar_in"; "$srcdir/../data/helloworld.tar.gz"; "/tar_in_gz"; "gzip"]; + ["tar_in"; "$srcdir/../data/helloworld.tar.gz"; "/tar_in_gz"; "gzip"; ""; ""]; ["cat"; "/tar_in_gz/hello"]], "hello\n"), []; InitScratchFS, IfAvailable "xz", TestResultString ( [["mkdir"; "/tar_in_xz"]; - ["tar_in"; "$srcdir/../data/helloworld.tar.xz"; "/tar_in_xz"; "xz"]; + ["tar_in"; "$srcdir/../data/helloworld.tar.xz"; "/tar_in_xz"; "xz"; ""; ""]; ["cat"; "/tar_in_xz/hello"]], "hello\n"), [] ]; shortdesc = "unpack tarfile to directory"; @@ -4820,7 +4820,21 @@ 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)." }; +compression types). + +The other optional arguments are: + +=over 4 + +=item C<xattrs> + +If set to true, extended attributes are restored from the tar file. + +=item C<selinux> + +If set to true, SELinux contexts are restored from the tar file. + +=back" }; { defaults with name = "tar_out"; added = (1, 0, 3); -- 2.1.0