aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch')
-rw-r--r--recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch255
1 files changed, 255 insertions, 0 deletions
diff --git a/recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch b/recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch
new file mode 100644
index 0000000..a3a72ad
--- /dev/null
+++ b/recipes-core/swupd-server/swupd-server/0001-create_pack-rely-less-on-previous-builds.patch
@@ -0,0 +1,255 @@
+From ecd62bee2dc3df9a181319a3f55c9cccab838aaf Mon Sep 17 00:00:00 2001
+From: Patrick Ohly <patrick.ohly@intel.com>
+Date: Wed, 16 Nov 2016 14:26:30 +0100
+Subject: [PATCH 1/3] create_pack: rely less on previous builds
+
+When a file has not been modified in the current build, then by
+definition the current copy of the file is the same as in the build
+were it was last changed and thus it does not matter whether we use
+<current build>/full/<file> or <last change>/full/<file>. But using
+the current copy is better for a CI system which starts without local
+access to older rootfs directories. It might also be a bit more
+efficient (file access less scattered between different "full"
+directories).
+
+Staging directories is better than staging .tar archives containing
+those directories for the same reason (the .tar archive might not be
+available in the CI system) and probably also improves efficiency (no
+need to invoke bsdtar just to create a directory; impact not
+measured).
+
+Also fix a slight flaw in the "target file exists already" handling:
+when that occured for whatever reason (likely only during manual
+debugging), the code would add the original fullfile .tar although it
+isn't needed. Clearing the "ret" variable in that particular error
+case avoids that.
+
+make_pack_full_files() and make_final_pack() used the exact same code
+for populating the "staged" directory. Now that common code is in
+stage_entry().
+
+Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
+---
+ include/swupd.h | 2 +-
+ src/delta.c | 4 +--
+ src/pack.c | 105 +++++++++++++++++++++++++++++++-------------------------
+ 3 files changed, 62 insertions(+), 49 deletions(-)
+
+diff --git a/include/swupd.h b/include/swupd.h
+index c1c0e96..cf384e3 100644
+--- a/include/swupd.h
++++ b/include/swupd.h
+@@ -244,7 +244,7 @@ extern void type_change_detection(struct manifest *manifest);
+
+ extern void rename_detection(struct manifest *manifest, int last_change, GList *last_versions_list);
+ extern void link_renames(GList *newfiles, struct manifest *from_manifest);
+-extern void __create_delta(struct file *file, int from_version);
++extern void __create_delta(struct file *file, int from_version, int to_version);
+
+ extern void account_delta_hit(void);
+ extern void account_delta_miss(void);
+diff --git a/src/delta.c b/src/delta.c
+index 7e978b1..8fff4c9 100644
+--- a/src/delta.c
++++ b/src/delta.c
+@@ -35,7 +35,7 @@
+ #include "swupd.h"
+ #include "xattrs.h"
+
+-void __create_delta(struct file *file, int from_version)
++void __create_delta(struct file *file, int from_version, int to_version)
+ {
+ char *original = NULL, *newfile = NULL, *outfile = NULL, *dotfile = NULL, *testnewfile = NULL;
+ char *tmpdir = NULL;
+@@ -60,7 +60,7 @@ void __create_delta(struct file *file, int from_version)
+ }
+
+ conf = config_image_base();
+- string_or_die(&newfile, "%s/%i/full/%s", conf, file->last_change, file->filename);
++ string_or_die(&newfile, "%s/%i/full/%s", conf, to_version, file->filename);
+
+ string_or_die(&original, "%s/%i/full/%s", conf, from_version, file->peer->filename);
+
+diff --git a/src/pack.c b/src/pack.c
+index 984c2d6..ccb28bd 100644
+--- a/src/pack.c
++++ b/src/pack.c
+@@ -37,6 +37,7 @@
+ #include <unistd.h>
+
+ #include "swupd.h"
++#include "xattrs.h"
+
+ static void empty_pack_stage(int full, int from_version, int to_version, char *module)
+ {
+@@ -149,6 +150,51 @@ static void prepare_pack(struct packdata *pack)
+ link_renames(pack->end_manifest->files, manifest);
+ }
+
++static int stage_entry(struct file *file,
++ const char *fullfrom, const char *fullto,
++ const char *tarfrom, const char *tarto,
++ const char *packname)
++{
++ int ret;
++
++ /* Prefer to hardlink uncompressed files or replicate
++ * directories first, and fall back to the compressed
++ * versions if that failed.
++ */
++ if (!file->is_dir) {
++ ret = link(fullfrom, fullto);
++ if (ret && errno == EEXIST) {
++ ret = 0;
++ } else if (ret) {
++ LOG(NULL, "Failure to link for pack", "%s: %s to %s (%s) %i", packname, fullfrom, fullto, strerror(errno), errno);
++ }
++ } else {
++ /* Replicate directory. */
++ struct stat st;
++ if ((stat(fullfrom, &st) ||
++ mkdir(fullto, 0) ||
++ chmod(fullto, st.st_mode) ||
++ chown(fullto, st.st_uid, st.st_gid) ||
++ (xattrs_copy(fullfrom, fullto), false)) &&
++ errno != EEXIST) {
++ LOG(NULL, "Failure to replicate dir for pack", "%s: %s to %s (%s) %i", packname, fullfrom, fullto, strerror(errno), errno);
++ rmdir(fullto);
++ ret = -1;
++ } else {
++ ret = 0;
++ }
++ }
++
++ if (ret) {
++ ret = link(tarfrom, tarto);
++ if (ret && errno != EEXIST) {
++ LOG(NULL, "Failure to link for fullfile pack", "%s to %s (%s) %i", tarfrom, tarto, strerror(errno), errno);
++ }
++ }
++
++ return ret;
++}
++
+ static void make_pack_full_files(struct packdata *pack)
+ {
+ GList *item;
+@@ -168,32 +214,18 @@ static void make_pack_full_files(struct packdata *pack)
+ char *fullfrom, *fullto;
+
+ /* hardlink each file that is in <end> but not in <X> */
+- string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
++ string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, pack->to, file->filename);
+ string_or_die(&fullto, "%s/%s/%i_to_%i/staged/%s", packstage_dir,
+ pack->module, pack->from, pack->to, file->hash);
+ string_or_die(&from, "%s/%i/files/%s.tar", staging_dir, file->last_change, file->hash);
+ string_or_die(&to, "%s/%s/%i_to_%i/staged/%s.tar", packstage_dir,
+ pack->module, pack->from, pack->to, file->hash);
+
+- ret = -1;
+- errno = 0;
+-
+- /* Prefer to hardlink uncompressed files (excluding
+- * directories) first, and fall back to the compressed
+- * versions if the hardlink fails.
++ /* Prefer to hardlink uncompressed files or replicate
++ * directories first, and fall back to the compressed
++ * versions if that failed.
+ */
+- if (!file->is_dir) {
+- ret = link(fullfrom, fullto);
+- if (ret && errno != EEXIST) {
+- LOG(NULL, "Failure to link for fullfile pack", "%s to %s (%s) %i", fullfrom, fullto, strerror(errno), errno);
+- }
+- }
+- if (ret) {
+- ret = link(from, to);
+- if (ret && errno != EEXIST) {
+- LOG(NULL, "Failure to link for fullfile pack", "%s to %s (%s) %i", from, to, strerror(errno), errno);
+- }
+- }
++ ret = stage_entry(file, fullfrom, fullto, from, to, "fullfile");
+
+ if (ret == 0) {
+ pack->fullcount++;
+@@ -270,17 +302,18 @@ static GList *consolidate_packs_delta_files(GList *files, struct packdata *pack)
+ return files;
+ }
+
+-static void create_delta(gpointer data, __unused__ gpointer user_data)
++static void create_delta(gpointer data, gpointer user_data)
+ {
+ struct file *file = data;
++ int *to_version = user_data;
+
+ /* if the file was not found in the from version, skip delta creation */
+ if (file->peer) {
+- __create_delta(file, file->peer->last_change);
++ __create_delta(file, file->peer->last_change, *to_version);
+ }
+ }
+
+-static void make_pack_deltas(GList *files)
++static void make_pack_deltas(GList *files, int to_version)
+ {
+ GThreadPool *threadpool;
+ GList *item;
+@@ -292,7 +325,7 @@ static void make_pack_deltas(GList *files)
+ sysconf(_SC_NPROCESSORS_ONLN);
+
+ LOG(NULL, "pack deltas threadpool", "%d threads", numthreads);
+- threadpool = g_thread_pool_new(create_delta, NULL,
++ threadpool = g_thread_pool_new(create_delta, &to_version,
+ numthreads, FALSE, NULL);
+
+ item = g_list_first(files);
+@@ -367,7 +400,7 @@ static int make_final_pack(struct packdata *pack)
+ file->last_change, file->hash);
+ string_or_die(&tarto, "%s/%s/%i_to_%i/staged/%s.tar", packstage_dir,
+ pack->module, pack->from, pack->to, file->hash);
+- string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
++ string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, pack->to, file->filename);
+ string_or_die(&fullto, "%s/%s/%i_to_%i/staged/%s", packstage_dir,
+ pack->module, pack->from, pack->to, file->hash);
+
+@@ -401,27 +434,7 @@ static int make_final_pack(struct packdata *pack)
+ }
+ }
+ } else {
+- ret = -1;
+- errno = 0;
+-
+- /* Prefer to hardlink uncompressed files (excluding
+- * directories) first, and fall back to the compressed
+- * versions if the hardlink fails.
+- */
+- if (!file->is_dir) {
+- ret = link(fullfrom, fullto);
+- if (ret && errno != EEXIST) {
+- LOG(NULL, "Failure to link for final pack", "%s to %s (%s) %i\n", fullfrom, fullto, strerror(errno), errno);
+- }
+- }
+-
+- if (ret) {
+- ret = link(tarfrom, tarto);
+- if (ret && errno != EEXIST) {
+- LOG(NULL, "Failure to link for final pack", "%s to %s (%s) %i\n", tarfrom, tarto, strerror(errno), errno);
+- }
+- }
+-
++ ret = stage_entry(file, fullfrom, fullto, tarfrom, tarto, "final");
+ if (ret == 0) {
+ pack->fullcount++;
+ }
+@@ -539,7 +552,7 @@ int make_pack(struct packdata *pack)
+
+ /* step 2: consolidate delta list & create all delta files*/
+ delta_list = consolidate_packs_delta_files(delta_list, pack);
+- make_pack_deltas(delta_list);
++ make_pack_deltas(delta_list, pack->to);
+ g_list_free(delta_list);
+
+ /* step 3: complete pack creation */
+--
+2.1.4
+