aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>2016-03-23 10:47:19 +0200
committerJoshua Lock <joshua.g.lock@intel.com>2016-03-30 21:36:58 +0100
commit40e43db58f41779d368abf71e5dcd5e26a5a9149 (patch)
tree88982d1c112316a5678f7158ad330c8a68bc056d
parentbca8b080378389c49fa5c7b0382c4b5e947589c2 (diff)
downloadmeta-swupd-40e43db58f41779d368abf71e5dcd5e26a5a9149.tar.gz
meta-swupd-40e43db58f41779d368abf71e5dcd5e26a5a9149.tar.bz2
meta-swupd-40e43db58f41779d368abf71e5dcd5e26a5a9149.zip
swupd-client: Update the client and server to use bsdtar
This patch adds bsdtar support to swupd-client and swupd-server and enables it. The reason why it's done this way is that: - bsdtar works better with IMA (opens files only once and then updates content and xattrs together); - swupd remains fully functional, including xattrs support, even when a distro disables GPLv3 licensed code. Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
-rw-r--r--recipes-core/swupd-client/swupd-client/0005-swupd-client-Add-existence-check-to-staging-target.patch96
-rw-r--r--recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch157
-rw-r--r--recipes-core/swupd-client/swupd-client/0007-Add-compatibility-with-libarchive-s-bsdtar-command.patch183
-rw-r--r--recipes-core/swupd-client/swupd-client_2.87.bb9
-rw-r--r--recipes-core/swupd-server/swupd-server/0007-Clean-up-tar-options-drop-a-for-the-extract-mode.patch31
-rw-r--r--recipes-core/swupd-server/swupd-server/0008-Clean-up-tar-commands-always-put-files-after-options.patch44
-rw-r--r--recipes-core/swupd-server/swupd-server/0009-Add-compatibility-with-libarchive-s-bsdtar-command.patch168
-rw-r--r--recipes-core/swupd-server/swupd-server_2.53.bb9
8 files changed, 692 insertions, 5 deletions
diff --git a/recipes-core/swupd-client/swupd-client/0005-swupd-client-Add-existence-check-to-staging-target.patch b/recipes-core/swupd-client/swupd-client/0005-swupd-client-Add-existence-check-to-staging-target.patch
new file mode 100644
index 0000000..512105e
--- /dev/null
+++ b/recipes-core/swupd-client/swupd-client/0005-swupd-client-Add-existence-check-to-staging-target.patch
@@ -0,0 +1,96 @@
+From 1f37511e52754f7231c52489ba4f7d8f7de1e2af Mon Sep 17 00:00:00 2001
+From: "Brad T. Peters" <brad.t.peters@intel.com>
+Date: Thu, 7 Jan 2016 14:37:17 -0800
+Subject: [PATCH] swupd-client: Add existence check to staging target
+
+Patch adds an stat() check to ensure that:
+1. target path for a staged file exists, and
+2. target path is indeed a directory
+
+Follow-on patch will add correct corrective behavior once
+verify_fix_path() is implemented
+
+Upstream-Status: Accepted
+
+Signed-off-by: Brad T. Peters <brad.t.peters@intel.com>
+---
+ src/staging.c | 39 ++++++++++++++++++++++++++++++++-------
+ 1 file changed, 32 insertions(+), 7 deletions(-)
+
+diff --git a/src/staging.c b/src/staging.c
+index 3a847e2..b8545c1 100644
+--- a/src/staging.c
++++ b/src/staging.c
+@@ -277,9 +277,11 @@ int do_staging(struct file *file)
+ #if SWUPD_LINUX_ROOTFS
+ char *original = NULL;
+ char *target = NULL;
++ char *targetpath = NULL;
++ char *symbase = NULL;
+ #endif
+ int ret;
+- struct stat stat;
++ struct stat s;
+
+ tmp = strdup(file->filename);
+ tmp2 = strdup(file->filename);
+@@ -294,6 +296,29 @@ int do_staging(struct file *file)
+ string_or_die(&original, "%s/staged/%s", STATE_DIR, file->hash);
+
+ #if SWUPD_LINUX_ROOTFS
++ string_or_die(&targetpath, "%s%s", path_prefix, rel_dir);
++ ret = stat(targetpath, &s);
++
++ if (S_ISLNK(s.st_mode)) {
++ /* Follow symlink to ultimate target and redo stat */
++ symbase = realpath(targetpath, NULL);
++ if (symbase != NULL) {
++ free(targetpath);
++ targetpath = strdup(symbase);
++ ret = stat(targetpath, &s);
++ free(symbase);
++ }
++ }
++
++ /* For now, just report on error conditions. Once we implement
++ * verify_fix_path(char *path, int targetversion), we'll want to call it here */
++ if ((ret == -1) && (errno == ENOENT)) {
++ printf("Error: Update target directory does not exist: %s\n", targetpath);
++ } else if (!S_ISDIR(s.st_mode)) {
++ printf("Error: Update target exists but is NOT a directory: %s\n", targetpath);
++ }
++
++ free(targetpath);
+ string_or_die(&target, "%s%s/.update.%s", path_prefix, rel_dir, base);
+ ret = swupd_rm(target);
+ if (ret == 0)
+@@ -306,12 +331,12 @@ int do_staging(struct file *file)
+ string_or_die(&statfile, "%s/%s/%s", STAGING_SUBVOL, rel_dir, base);
+ #endif
+
+- memset(&stat, 0, sizeof(struct stat));
+- ret = lstat(statfile, &stat);
++ memset(&s, 0, sizeof(struct stat));
++ ret = lstat(statfile, &s);
+ if (ret == 0) {
+- if ((file->is_dir && !S_ISDIR(stat.st_mode)) ||
+- (file->is_link && !S_ISLNK(stat.st_mode)) ||
+- (file->is_file && !S_ISREG(stat.st_mode))) {
++ if ((file->is_dir && !S_ISDIR(s.st_mode)) ||
++ (file->is_link && !S_ISLNK(s.st_mode)) ||
++ (file->is_file && !S_ISREG(s.st_mode))) {
+ LOG_INFO(file, "Type changed!", class_osvol_staging, "%s", statfile);
+ //file type changed, move old out of the way for new
+ ret = swupd_rm(statfile);
+@@ -325,7 +350,7 @@ int do_staging(struct file *file)
+ free(statfile);
+
+ #if SWUPD_LINUX_ROOTFS
+- if (file->is_dir || S_ISDIR(stat.st_mode)) {
++ if (file->is_dir || S_ISDIR(s.st_mode)) {
+ /* In the btrfs only scenario there is an implicit
+ * "create_or_update_dir()" via un-tar-ing a directory.tar after
+ * download and the untar happens in the staging subvolume which
+--
+2.5.0
+
diff --git a/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch b/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch
new file mode 100644
index 0000000..ab3a39f
--- /dev/null
+++ b/recipes-core/swupd-client/swupd-client/0006-Backport-Use-rename-instead-of-tar-transform.patch
@@ -0,0 +1,157 @@
+From e9ad32a273efe2d177c1bbd394ae944ae598fd50 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+Date: Mon, 8 Feb 2016 18:12:48 +0200
+Subject: [PATCH] Backport: Use rename instead of tar transform
+
+This patch is a backport from swupd-client v2.88
+Author: William Douglas <william.douglas@intel.com>
+Subject: Use rename instead of tar transform
+
+In order to prevent issues with transform name escaping, update logic
+for moving an object from staging. First rename the object in the
+staging path to its final name (in case of a directory the rename places
+it in a seperate directory first to avoid hash colisions), then use tar
+to update or create the object in the filesystem. Once finished rename
+the object back to the hash name so it can be reused as needed.
+
+This also fixes up some issues with the SWUPD_LINUX_ROOTFS checks not
+always encapsulating variable use within the do_staging function.
+
+Note: the SWUPD_LINUX_ROOTFS checks have been removed entirely, since
+they are not used anywhere in the code at present.
+
+Upstream-Status: Backported [v2.88]
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ src/staging.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 67 insertions(+), 6 deletions(-)
+
+diff --git a/src/staging.c b/src/staging.c
+index b8545c1..16dafbb 100644
+--- a/src/staging.c
++++ b/src/staging.c
+@@ -36,6 +36,31 @@
+ #include "swupd-build-variant.h"
+ #include <swupd.h>
+
++/* clean then recreate temporary folder for tar renames */
++static int create_staging_renamedir(char *rename_tmpdir)
++{
++ int ret;
++ char *rmcommand = NULL;
++
++ string_or_die(&rmcommand, "rm -fr %s", rename_tmpdir);
++ if (!system(rmcommand)) {
++ /* Not fatal but pretty scary, likely to really fail at the
++ * next command too. Pass for now as printing may just cause
++ * confusion */
++ ;
++ }
++ free(rmcommand);
++
++ ret = mkdir(rename_tmpdir, S_IRWXU);
++ if (ret == -1 && errno != EEXIST) {
++ ret = -errno;
++ } else {
++ ret = 0;
++ }
++
++ return ret;
++}
++
+ #ifdef SWUPD_WITH_BTRFS
+ static int create_staging_subvol_from(const char *version)
+ {
+@@ -269,6 +294,9 @@ int prepare(bool UNUSED_PARAM *is_corrupted, int UNUSED_PARAM current_version, i
+ #endif
+
+ /* Do the staging of new files into the filesystem */
++#warning do_staging is currently not able to be run in parallel
++/* Consider adding a remove_leftovers() that runs in verify/fix in order to
++ * allow this function to mkdtemp create folders for parallel build */
+ int do_staging(struct file *file)
+ {
+ char *statfile = NULL, *tmp = NULL, *tmp2 = NULL;
+@@ -280,6 +308,8 @@ int do_staging(struct file *file)
+ char *targetpath = NULL;
+ char *symbase = NULL;
+ #endif
++ char *rename_target = NULL;
++ char *rename_tmpdir = NULL;
+ int ret;
+ struct stat s;
+
+@@ -360,12 +390,28 @@ int do_staging(struct file *file)
+ * attributes and it includes internal logic that does the
+ * right thing to overlay a directory onto something
+ * pre-existing: */
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/%s/\" 2> /dev/null",
+- STATE_DIR, file->hash, path_prefix, rel_dir, file->hash, base);
++ /* In order to avoid tar transforms with directories, rename
++ * the directory before and after the tar command */
++ string_or_die(&rename_tmpdir, "%s/tmprenamedir", STATE_DIR);
++ ret = create_staging_renamedir(rename_tmpdir);
++ if (ret) {
++ goto out;
++ }
++ string_or_die(&rename_target, "%s/%s", rename_tmpdir, base);
++ if (rename(original, rename_target)) {
++ ret = -errno;
++ goto out;
++ }
++ string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
++ "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
++ rename_tmpdir, base, path_prefix, rel_dir);
+ LOG_DEBUG(file, "directory overwrite", class_osvol_staging, "%s", tarcommand);
+ ret = system(tarcommand);
+ free(tarcommand);
++ if (rename(rename_target, original)) {
++ ret = -errno;
++ goto out;
++ }
+ if (ret < 0) {
+ LOG_ERROR(file, "Failed directory overwrite", class_osvol_staging, "%s", strerror(errno));
+ ret = -EDIR_OVERWRITE;
+@@ -386,12 +432,25 @@ int do_staging(struct file *file)
+ }
+ if (ret < 0) {
+ /* either the hardlink failed, or it was undesirable (config), do a tar-tar dance */
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/.update.%s/\" 2> /dev/null",
+- STATE_DIR, file->hash, path_prefix, rel_dir, file->hash, base);
++ /* In order to avoid tar transforms, rename the file
++ * before and after the tar command */
++ string_or_die(&rename_target, "%s/staged/.update.%s", STATE_DIR, base);
++ ret = rename(original, rename_target);
++ if (ret) {
++ ret = -errno;
++ goto out;
++ }
++ string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - .update.%s 2> /dev/null | "
++ "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
++ STATE_DIR, base, path_prefix, rel_dir);
+ LOG_DEBUG(file, "dotfile install", class_osvol_staging, "%s", tarcommand);
+ ret = system(tarcommand);
+ free(tarcommand);
++ ret = rename(rename_target, original);
++ if (ret) {
++ ret = -errno;
++ goto out;
++ }
+ }
+ if (ret < 0) {
+ LOG_ERROR(file, "Failed tar dotfile install", class_osvol_staging,
+@@ -436,6 +495,8 @@ int do_staging(struct file *file)
+ out:
+ free(target);
+ free(original);
++ free(rename_target);
++ free(rename_tmpdir);
+ free(tmp);
+ free(tmp2);
+
+--
+2.5.0
+
diff --git a/recipes-core/swupd-client/swupd-client/0007-Add-compatibility-with-libarchive-s-bsdtar-command.patch b/recipes-core/swupd-client/swupd-client/0007-Add-compatibility-with-libarchive-s-bsdtar-command.patch
new file mode 100644
index 0000000..6d03ee3
--- /dev/null
+++ b/recipes-core/swupd-client/swupd-client/0007-Add-compatibility-with-libarchive-s-bsdtar-command.patch
@@ -0,0 +1,183 @@
+From 29e2fefaf67bfd6db77db87d22782a31c7284982 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+Date: Mon, 8 Feb 2016 16:42:23 +0200
+Subject: [PATCH] Add compatibility with libarchive's bsdtar command
+
+Since GNU tar fails to extract files with xattrs preserved when
+Integrity Measurement Architecture (IMA) is enabled some vendors
+may choose to install libarchive-based tar (bsdtar) on their embedded
+devices, so the swupd server needs to be able to create archives
+in its format.
+
+This patch adds one compile-time options --enable-bsdtar that is used
+to enable/disable GNU tar specific options.
+
+Upstream-Status: Accepted
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ configure.ac | 9 +++++++++
+ include/swupd-build-variant.h | 12 ++++++++++--
+ src/download.c | 4 ++--
+ src/esp.c | 4 ++--
+ src/manifest.c | 3 ++-
+ src/packs.c | 2 +-
+ src/staging.c | 12 ++++++------
+ 7 files changed, 32 insertions(+), 14 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b11ef0a..930f64c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -29,6 +29,15 @@ AS_IF([test "x$enable_bzip2" = "xyes" ],
+ [AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression])]
+ )
+
++AC_ARG_ENABLE(
++ [bsdtar],
++ AS_HELP_STRING([--enable-bsdtar], [Use alternative bsdtar command (uses tar by default)])
++)
++AS_IF([test "x$enable_bsdtar" = "xyes" ],
++ [AC_DEFINE(SWUPD_WITH_BSDTAR, 1, [Use bsdtar])],
++ [AC_DEFINE(SWUPD_WITHOUT_BSDTAR, 1, [Use default tar])]
++)
++
+ AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
+ [path to systemd system service dir @<:@default=/usr/lib/systemd/system@:>@]), [unitpath=${withval}],
+ [unitpath="$($PKG_CONFIG --variable=systemdsystemunitdir systemd)"])
+diff --git a/include/swupd-build-variant.h b/include/swupd-build-variant.h
+index f2103a2..0c15dca 100644
+--- a/include/swupd-build-variant.h
++++ b/include/swupd-build-variant.h
+@@ -13,10 +13,18 @@
+ #define VERIFY_FAILED_MAX_VERSIONS_COUNT 20
+ #endif
+
++#ifdef SWUPD_WITH_BSDTAR
++#define TAR_COMMAND "bsdtar"
++#define TAR_XATTR_ARGS ""
++#else
++#define TAR_COMMAND "tar"
++#define TAR_XATTR_ARGS "--xattrs --xattrs-include='*'"
++#endif
++
+ #ifdef SWUPD_WITH_SELINUX
+-#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*' --selinux"
++#define TAR_PERM_ATTR_ARGS "--preserve-permissions --selinux " TAR_XATTR_ARGS
+ #else /* SWUPD_WITHOUT_SELINUX */
+-#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*'"
++#define TAR_PERM_ATTR_ARGS "--preserve-permissions " TAR_XATTR_ARGS
+ #endif
+
+ #ifdef SWUPD_WITH_REPAIR
+diff --git a/src/download.c b/src/download.c
+index cb6d1a2..211ee24 100644
+--- a/src/download.c
++++ b/src/download.c
+@@ -194,7 +194,7 @@ static int check_tarfile_content(struct file *file, const char *tarfilename)
+ int count = 0;
+
+ /* we're using -a because the server side has a choice between different compression methods */
+- string_or_die(&tarcommand, "tar -tf %s/download/%s.tar 2> /dev/null", STATE_DIR, file->hash);
++ string_or_die(&tarcommand, TAR_COMMAND " -tf %s/download/%s.tar 2> /dev/null", STATE_DIR, file->hash);
+
+ err = access(tarfilename, R_OK);
+ if (err) {
+@@ -300,7 +300,7 @@ static void untar_full_download(void *data)
+ }
+
+ /* modern tar will automatically determine the compression type used */
+- string_or_die(&tarcommand, "tar -C %s/staged/ " TAR_PERM_ATTR_ARGS " -xf %s 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged/ " TAR_PERM_ATTR_ARGS " -xf %s 2> /dev/null",
+ STATE_DIR, tarfile);
+
+ LOG_DEBUG(file, "Doing tar operation", class_file_compression, "%s", tarcommand);
+diff --git a/src/esp.c b/src/esp.c
+index e2b2ae9..3483f55 100644
+--- a/src/esp.c
++++ b/src/esp.c
+@@ -231,8 +231,8 @@ int copy_files_to_esp(int target_version)
+
+ progress_step(PROGRESS_MSG_UPDATE_ESP);
+
+- string_or_die(&tarcommand, "tar -C %s/%d/system/vendor/intel/ -cf - esp 2> /dev/null | "
+- "tar -C %s/ -xf - --no-same-permissions --no-same-owner --transform=\"s/esp//\" 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s/%d/system/vendor/intel/ -cf - esp 2> /dev/null | "
++ TAR_COMMAND " -C %s/ -xf - --no-same-permissions --no-same-owner --transform=\"s/esp//\" 2> /dev/null",
+ MOUNT_POINT, target_version, ESP_MOUNT);
+
+ ret = system(tarcommand);
+diff --git a/src/manifest.c b/src/manifest.c
+index 5757e9f..7c356d7 100644
+--- a/src/manifest.c
++++ b/src/manifest.c
+@@ -34,6 +34,7 @@
+ #include <fcntl.h>
+
+ #include "config.h"
++#include "swupd-build-variant.h"
+ #include <swupd.h>
+ #include <xattrs.h>
+ #include "progress.h"
+@@ -519,7 +520,7 @@ static int retrieve_manifests(int current, int version, char *component, struct
+ goto out;
+ }
+
+- string_or_die(&tar, "tar -C %s/%i -xf %s/%i/Manifest.%s.tar 2> /dev/null",
++ string_or_die(&tar, TAR_COMMAND " -C %s/%i -xf %s/%i/Manifest.%s.tar 2> /dev/null",
+ STATE_DIR, version, STATE_DIR, version, component);
+
+ LOG_DEBUG(NULL, "tar", class_file_compression, "running %s", tar);
+diff --git a/src/packs.c b/src/packs.c
+index b176b74..91a83c5 100644
+--- a/src/packs.c
++++ b/src/packs.c
+@@ -83,7 +83,7 @@ static int download_pack(int oldversion, int newversion, char *module)
+ free(url);
+
+ progress_step(PROGRESS_MSG_EXTRACTING_PACK);
+- string_or_die(&tar, "tar -C %s " TAR_PERM_ATTR_ARGS " -xf %s/pack-%s-from-%i-to-%i.tar 2> /dev/null",
++ string_or_die(&tar, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -xf %s/pack-%s-from-%i-to-%i.tar 2> /dev/null",
+ STATE_DIR, STATE_DIR, module, oldversion, newversion);
+
+ LOG_INFO(NULL, "Untar of delta pack", class_file_compression, "%s", tar);
+diff --git a/src/staging.c b/src/staging.c
+index 16dafbb..742e8a2 100644
+--- a/src/staging.c
++++ b/src/staging.c
+@@ -402,8 +402,8 @@ int do_staging(struct file *file)
+ ret = -errno;
+ goto out;
+ }
+- string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
++ TAR_COMMAND " -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
+ rename_tmpdir, base, path_prefix, rel_dir);
+ LOG_DEBUG(file, "directory overwrite", class_osvol_staging, "%s", tarcommand);
+ ret = system(tarcommand);
+@@ -440,8 +440,8 @@ int do_staging(struct file *file)
+ ret = -errno;
+ goto out;
+ }
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - .update.%s 2> /dev/null | "
+- "tar -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - .update.%s 2> /dev/null | "
++ TAR_COMMAND " -C %s%s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
+ STATE_DIR, base, path_prefix, rel_dir);
+ LOG_DEBUG(file, "dotfile install", class_osvol_staging, "%s", tarcommand);
+ ret = system(tarcommand);
+@@ -485,8 +485,8 @@ int do_staging(struct file *file)
+ /* For initial simplicity replace the file. Ideally this would be
+ * an intelligent btrfs reflink to maximize block level reuse. */
+ //TODO: prove btrfs reflink ioctl works in general, then try using them here
+- string_or_die(&tarcommand, "tar -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
+- "tar -C %s/%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/%s/\" 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s/staged " TAR_PERM_ATTR_ARGS " -cf - %s 2> /dev/null | "
++ TAR_COMMAND " -C %s/%s " TAR_PERM_ATTR_ARGS " -xf - --transform=\"s/%s/%s/\" 2> /dev/null",
+ STATE_DIR, file->hash, STAGING_SUBVOL, rel_dir, file->hash, base);
+ ret = system(tarcommand);
+ free(tarcommand);
+--
+2.5.0
+
diff --git a/recipes-core/swupd-client/swupd-client_2.87.bb b/recipes-core/swupd-client/swupd-client_2.87.bb
index 8226624..3356ae6 100644
--- a/recipes-core/swupd-client/swupd-client_2.87.bb
+++ b/recipes-core/swupd-client/swupd-client_2.87.bb
@@ -9,20 +9,23 @@ SRC_URI = "\
file://Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch \
file://Change-systemctl-path-to-OE-systemctl-path.patch \
file://0001-Tolerate-quotes-in-os-release-files.patch \
+ file://0005-swupd-client-Add-existence-check-to-staging-target.patch \
+ file://0006-Backport-Use-rename-instead-of-tar-transform.patch \
+ file://0007-Add-compatibility-with-libarchive-s-bsdtar-command.patch \
"
SRC_URI[md5sum] = "5d272c62edb8a9c576005ac5e1182ea3"
SRC_URI[sha256sum] = "45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1c66fb8"
DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
-RDEPENDS_${PN} = "gzip bzip2 tar xz"
-RDEPENDS_${PN}_class-target = "oe-swupd-helpers"
+RDEPENDS_${PN} = "gzip bzip2 xz"
+RDEPENDS_${PN}_class-target = "oe-swupd-helpers bsdtar"
# We check /etc/os-release for the current OS version number
RRECOMMENDS_${PN}_class-target = "os-release"
inherit pkgconfig autotools-brokensep systemd
-EXTRA_OECONF = "--with-systemdsystemunitdir=${systemd_system_unitdir}"
+EXTRA_OECONF = "--with-systemdsystemunitdir=${systemd_system_unitdir} --enable-bsdtar"
#TODO: create and install /var/lib/swupd/{delta,staged/download}
do_install_append () {
diff --git a/recipes-core/swupd-server/swupd-server/0007-Clean-up-tar-options-drop-a-for-the-extract-mode.patch b/recipes-core/swupd-server/swupd-server/0007-Clean-up-tar-options-drop-a-for-the-extract-mode.patch
new file mode 100644
index 0000000..2f933d0
--- /dev/null
+++ b/recipes-core/swupd-server/swupd-server/0007-Clean-up-tar-options-drop-a-for-the-extract-mode.patch
@@ -0,0 +1,31 @@
+From 4431ad34734632c439881a30ca90617a1fd1dde4 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+Date: Tue, 23 Feb 2016 14:50:37 +0200
+Subject: [PATCH] Clean up tar options: drop -a for the extract mode.
+
+The -a option is not needed for the extract mode since tar
+auto-detects compression type from file format.
+
+Upstream-Status: Accepted
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ src/pack.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/pack.c b/src/pack.c
+index 5bb99b8..e5203d0 100644
+--- a/src/pack.c
++++ b/src/pack.c
+@@ -114,7 +114,7 @@ static void explode_pack_stage(int version, char *module)
+ * time on the client...
+ */
+ string_or_die(&tar, "tar --directory=%s/%s/%i/staged --warning=no-timestamp "
+- TAR_PERM_ATTR_ARGS " -axf %s", packstage_dir, module, version, path);
++ TAR_PERM_ATTR_ARGS " -xf %s", packstage_dir, module, version, path);
+ ret = system(tar);
+ if (!ret) {
+ unlink(path);
+--
+2.5.0
+
diff --git a/recipes-core/swupd-server/swupd-server/0008-Clean-up-tar-commands-always-put-files-after-options.patch b/recipes-core/swupd-server/swupd-server/0008-Clean-up-tar-commands-always-put-files-after-options.patch
new file mode 100644
index 0000000..3dabcc8
--- /dev/null
+++ b/recipes-core/swupd-server/swupd-server/0008-Clean-up-tar-commands-always-put-files-after-options.patch
@@ -0,0 +1,44 @@
+From 9ecb744f0ca6faca02cc7be7539802c040cd2922 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+Date: Tue, 23 Feb 2016 15:01:25 +0200
+Subject: [PATCH] Clean up tar commands: always put files after options
+
+Unify tar commands to have files enumerated always at the end of
+the commands. This would follow the scheme used in tar's man page
+and simplify adoption of other tar implementation should the need
+arise.
+
+Upstream-Status: Accepted
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ src/fullfiles.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/fullfiles.c b/src/fullfiles.c
+index fa78293..23e95db 100644
+--- a/src/fullfiles.c
++++ b/src/fullfiles.c
+@@ -93,7 +93,7 @@ static void create_fullfile(struct file *file)
+ assert(0);
+ }
+
+- string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - '%s' --exclude='%s'/* 2> /dev/null | "
++ string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - --exclude='%s'/* '%s' 2> /dev/null | "
+ "tar -C %s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
+ dir, base, base, rename_tmpdir);
+ if (system(tarcommand) != 0) {
+@@ -111,8 +111,8 @@ static void create_fullfile(struct file *file)
+ free(rename_source);
+
+ /* for a directory file, tar up simply with gzip */
+- string_or_die(&tarcommand, "tar -C %s %s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar",
+- rename_tmpdir, file->hash, outdir, file->last_change, file->hash);
++ string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar %s",
++ rename_tmpdir, outdir, file->last_change, file->hash, file->hash);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+ assert(0);
+--
+2.5.0
+
diff --git a/recipes-core/swupd-server/swupd-server/0009-Add-compatibility-with-libarchive-s-bsdtar-command.patch b/recipes-core/swupd-server/swupd-server/0009-Add-compatibility-with-libarchive-s-bsdtar-command.patch
new file mode 100644
index 0000000..7821938
--- /dev/null
+++ b/recipes-core/swupd-server/swupd-server/0009-Add-compatibility-with-libarchive-s-bsdtar-command.patch
@@ -0,0 +1,168 @@
+From e72a040628d7b8b5fd193653c13304f47cba611b Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+Date: Tue, 23 Feb 2016 15:11:58 +0200
+Subject: [PATCH] Add compatibility with libarchive's bsdtar command
+
+Since GNU tar fails to extract files with xattrs preserved when
+Integrity Measurement Architecture (IMA) is enabled some vendors
+may choose to install libarchive-based tar (bsdtar) on their embedded
+devices, so the swupd server needs to be able to create archives
+in its format.
+
+This patch adds one compile-time options --enable-bsdtar that is used
+to enable/disable GNU tar specific options. Also it harmonizes
+the command strings to be compatible with both GNU tar and bsdtar.
+Particularly it
+- changes --exclude pattern from '%s'/* to more explicit '%s/?*' because
+ bsdtar's pattern matching is greedier than in tar: it uses tcsh's
+ globbing where '*' can be anything including the null string and the
+ original pattern would include the directory itself;
+- OS file names are escaped with leading ./ to avoid collisions with
+ file names starting with @ which has special meaning in bsdtar.
+
+Upstream-Status: Accepted
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
+---
+ configure.ac | 8 ++++++++
+ include/swupd.h | 14 ++++++++++++--
+ src/fullfiles.c | 12 ++++++------
+ src/manifest.c | 2 +-
+ src/pack.c | 4 ++--
+ 5 files changed, 29 insertions(+), 11 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 47256b6..32d1412 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -15,6 +15,14 @@ PKG_CHECK_MODULES([openssl], [libcrypto >= 0.9.8])
+ AC_CHECK_LIB([magic], [magic_open], [], [AC_MSG_ERROR([the magic library is missing])])
+ AC_CHECK_PROGS(TAR, tar)
+ AC_ARG_ENABLE(
++ bsdtar,
++ AS_HELP_STRING([--enable-bsdtar],[Use alternative bsdtar command (uses tar by default)]),
++ AS_IF([test "x$enable_bsdtar" = "xyes"],
++ AC_DEFINE([SWUPD_WITH_BSDTAR], 1, [Use alternative bsdtar]),
++ AC_DEFINE([SWUPD_WITH_BSDTAR], 0, [Use default tar command])),
++ AC_DEFINE([SWUPD_WITH_BSDTAR], 0, [Use default tar command])
++)
++AC_ARG_ENABLE(
+ bzip2,
+ AS_HELP_STRING([--disable-bzip2],[Do not use bzip2 compression (uses bzip2 by default)]),
+ AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression]) ,
+diff --git a/include/swupd.h b/include/swupd.h
+index d45ca9c..b049135 100644
+--- a/include/swupd.h
++++ b/include/swupd.h
+@@ -17,10 +17,20 @@
+
+ #define SWUPD_SERVER_STATE_DIR "/var/lib/update"
+
++#if SWUPD_WITH_BSDTAR
++#define TAR_COMMAND "bsdtar"
++#define TAR_XATTR_ARGS ""
++#define TAR_WARN_ARGS ""
++#else
++#define TAR_COMMAND "tar"
++#define TAR_XATTR_ARGS "--xattrs --xattrs-include='*'"
++#define TAR_WARN_ARGS "--warning=no-timestamp"
++#endif
++
+ #if SWUPD_WITH_SELINUX
+-#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*' --selinux"
++#define TAR_PERM_ATTR_ARGS "--preserve-permissions --selinux " TAR_XATTR_ARGS
+ #else
+-#define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*'"
++#define TAR_PERM_ATTR_ARGS "--preserve-permissions " TAR_XATTR_ARGS
+ #endif
+
+ #if SWUPD_WITH_STATELESS
+diff --git a/src/fullfiles.c b/src/fullfiles.c
+index 23e95db..cf77e74 100644
+--- a/src/fullfiles.c
++++ b/src/fullfiles.c
+@@ -93,8 +93,8 @@ static void create_fullfile(struct file *file)
+ assert(0);
+ }
+
+- string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -cf - --exclude='%s'/* '%s' 2> /dev/null | "
+- "tar -C %s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -cf - --exclude='%s/?*' './%s' 2> /dev/null | "
++ TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
+ dir, base, base, rename_tmpdir);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+@@ -111,7 +111,7 @@ static void create_fullfile(struct file *file)
+ free(rename_source);
+
+ /* for a directory file, tar up simply with gzip */
+- string_or_die(&tarcommand, "tar -C %s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar %s",
++ string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar %s",
+ rename_tmpdir, outdir, file->last_change, file->hash, file->hash);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+@@ -146,7 +146,7 @@ static void create_fullfile(struct file *file)
+
+ /* step 2a: tar it with each compression type */
+ // lzma
+- string_or_die(&tarcommand, "tar --directory=%s " TAR_PERM_ATTR_ARGS " -Jcf %s/%i/files/%s.tar.xz %s",
++ string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -Jcf %s/%i/files/%s.tar.xz %s",
+ empty, outdir, file->last_change, file->hash, file->hash);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+@@ -154,7 +154,7 @@ static void create_fullfile(struct file *file)
+ }
+ free(tarcommand);
+ // gzip
+- string_or_die(&tarcommand, "tar --directory=%s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar.gz %s",
++ string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar.gz %s",
+ empty, outdir, file->last_change, file->hash, file->hash);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+@@ -162,7 +162,7 @@ static void create_fullfile(struct file *file)
+ }
+ free(tarcommand);
+ #ifdef SWUPD_WITH_BZIP2
+- string_or_die(&tarcommand, "tar --directory=%s " TAR_PERM_ATTR_ARGS " -jcf %s/%i/files/%s.tar.bz2 %s",
++ string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -jcf %s/%i/files/%s.tar.bz2 %s",
+ empty, outdir, file->last_change, file->hash, file->hash);
+ if (system(tarcommand) != 0) {
+ LOG(NULL, "Failed to run command:", "%s", tarcommand);
+diff --git a/src/manifest.c b/src/manifest.c
+index e878288..cf0cabf 100644
+--- a/src/manifest.c
++++ b/src/manifest.c
+@@ -750,7 +750,7 @@ static int write_manifest_tar(struct manifest *manifest)
+
+ /* now, tar the thing up for efficient full file download */
+ /* and put the signature of the plain manifest into the archive, too */
+- string_or_die(&tarcmd, "tar --directory=%s/%i " TAR_PERM_ATTR_ARGS " -Jcf "
++ string_or_die(&tarcmd, TAR_COMMAND " --directory=%s/%i " TAR_PERM_ATTR_ARGS " -Jcf "
+ "%s/%i/Manifest.%s.tar Manifest.%s Manifest.%s.signed",
+ conf, manifest->version, conf, manifest->version, manifest->component,
+ manifest->component, manifest->component);
+diff --git a/src/pack.c b/src/pack.c
+index e5203d0..1a11a03 100644
+--- a/src/pack.c
++++ b/src/pack.c
+@@ -113,7 +113,7 @@ static void explode_pack_stage(int version, char *module)
+ * the resulting pack is slightly smaller, and in addition, we're saving CPU
+ * time on the client...
+ */
+- string_or_die(&tar, "tar --directory=%s/%s/%i/staged --warning=no-timestamp "
++ string_or_die(&tar, TAR_COMMAND " --directory=%s/%s/%i/staged " TAR_WARN_ARGS " "
+ TAR_PERM_ATTR_ARGS " -xf %s", packstage_dir, module, version, path);
+ ret = system(tar);
+ if (!ret) {
+@@ -442,7 +442,7 @@ static int make_final_pack(struct packdata *pack)
+
+ /* tar the staging directory up */
+ LOG(NULL, "starting tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
+- string_or_die(&tar, "tar " TAR_PERM_ATTR_ARGS " --directory=%s/%s/%i/ "
++ string_or_die(&tar, TAR_COMMAND " " TAR_PERM_ATTR_ARGS " --directory=%s/%s/%i/ "
+ "--numeric-owner -Jcf %s/%i/pack-%s-from-%i.tar delta staged",
+ packstage_dir, pack->module, pack->from, staging_dir, pack->to, pack->module, pack->from);
+ ret = system(tar);
+--
+2.5.0
+
diff --git a/recipes-core/swupd-server/swupd-server_2.53.bb b/recipes-core/swupd-server/swupd-server_2.53.bb
index a57f2cf..321fadc 100644
--- a/recipes-core/swupd-server/swupd-server_2.53.bb
+++ b/recipes-core/swupd-server/swupd-server_2.53.bb
@@ -13,6 +13,9 @@ SRC_URI = "\
file://0004-Fix-regression-that-introduced-a-directory-named.patch \
file://0005-xattrs.c-Avoid-freeing-dangling-pointers.patch \
file://0006-Always-use-xattrs-when.patch \
+ file://0007-Clean-up-tar-options-drop-a-for-the-extract-mode.patch \
+ file://0008-Clean-up-tar-commands-always-put-files-after-options.patch \
+ file://0009-Add-compatibility-with-libarchive-s-bsdtar-command.patch \
"
SRC_URI[md5sum] = "14f25677b5a4f0b33785910b03860939"
@@ -20,7 +23,7 @@ SRC_URI[sha256sum] = "c2d0e595444fe198c4092dd83d20a929fd1402a13b66b410b76677ed3a
inherit autotools
-EXTRA_OECONF = "--enable-bzip2 --enable-lzma --disable-stateless"
+EXTRA_OECONF = "--enable-bzip2 --enable-lzma --disable-stateless --enable-bsdtar"
# safer-calls-to-system-utilities.patch uses for loop initial declaration
CFLAGS_append = " -std=c99"
@@ -30,6 +33,8 @@ do_install_append () {
install -m 0755 ${S}/test/signature/* ${D}${sysconfdir}/swupd-certs/
}
-RDEPENDS_${PN} = "tar rsync"
+# Work around lack of "RPROVIDES = bsdtar-native" in libarchive-native.
+RDEPENDS_${PN}_class-target = "bsdtar rsync"
+RDEPENDS_${PN}_class-native = "libarchive rsync"
BBCLASSEXTEND = "native"