From bafbac4e85a5eefd4b57a5cd0eb61885fb60edc9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Dec 2016 12:24:11 +0100 Subject: [PATCH] machined: when renaming/removing/cloning images, always take care of .roothash file too Since nspawn looks for them, importd now downloads them, and mkosi generates them, let's make sure they also processed correctly on all machined operations. --- src/shared/machine-image.c | 49 ++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 712aff65b9..7bc5c0a128 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -99,6 +99,16 @@ static char **image_settings_path(Image *image) { return ret; } +static char *image_roothash_path(Image *image) { + const char *fn; + + assert(image); + + fn = strjoina(image->name, ".roothash"); + + return file_in_same_dir(image->path, fn); +} + static int image_new( ImageType t, const char *pretty, @@ -397,6 +407,7 @@ void image_hashmap_free(Hashmap *map) { int image_remove(Image *i) { _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; _cleanup_strv_free_ char **settings = NULL; + _cleanup_free_ char *roothash = NULL; char **j; int r; @@ -409,6 +420,10 @@ int image_remove(Image *i) { if (!settings) return -ENOMEM; + roothash = image_roothash_path(i); + if (!roothash) + return -ENOMEM; + /* Make sure we don't interfere with a running nspawn */ r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); if (r < 0) @@ -445,14 +460,17 @@ int image_remove(Image *i) { log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j); } + if (unlink(roothash) < 0 && errno != ENOENT) + log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", roothash); + return 0; } -static int rename_settings_file(const char *path, const char *new_name) { +static int rename_auxiliary_file(const char *path, const char *new_name, const char *suffix) { _cleanup_free_ char *rs = NULL; const char *fn; - fn = strjoina(new_name, ".nspawn"); + fn = strjoina(new_name, suffix); rs = file_in_same_dir(path, fn); if (!rs) @@ -463,7 +481,7 @@ static int rename_settings_file(const char *path, const char *new_name) { int image_rename(Image *i, const char *new_name) { _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT; - _cleanup_free_ char *new_path = NULL, *nn = NULL; + _cleanup_free_ char *new_path = NULL, *nn = NULL, *roothash = NULL; _cleanup_strv_free_ char **settings = NULL; unsigned file_attr = 0; char **j; @@ -481,6 +499,10 @@ int image_rename(Image *i, const char *new_name) { if (!settings) return -ENOMEM; + roothash = image_roothash_path(i); + if (!roothash) + return -ENOMEM; + /* Make sure we don't interfere with a running nspawn */ r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); if (r < 0) @@ -550,19 +572,23 @@ int image_rename(Image *i, const char *new_name) { nn = NULL; STRV_FOREACH(j, settings) { - r = rename_settings_file(*j, new_name); + r = rename_auxiliary_file(*j, new_name, ".nspawn"); if (r < 0 && r != -ENOENT) log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j); } + r = rename_auxiliary_file(roothash, new_name, ".roothash"); + if (r < 0 && r != -ENOENT) + log_debug_errno(r, "Failed to rename roothash file %s, ignoring: %m", roothash); + return 0; } -static int clone_settings_file(const char *path, const char *new_name) { +static int clone_auxiliary_file(const char *path, const char *new_name, const char *suffix) { _cleanup_free_ char *rs = NULL; const char *fn; - fn = strjoina(new_name, ".nspawn"); + fn = strjoina(new_name, suffix); rs = file_in_same_dir(path, fn); if (!rs) @@ -574,6 +600,7 @@ static int clone_settings_file(const char *path, const char *new_name) { int image_clone(Image *i, const char *new_name, bool read_only) { _cleanup_release_lock_file_ LockFile name_lock = LOCK_FILE_INIT; _cleanup_strv_free_ char **settings = NULL; + _cleanup_free_ char *roothash = NULL; const char *new_path; char **j; int r; @@ -587,6 +614,10 @@ int image_clone(Image *i, const char *new_name, bool read_only) { if (!settings) return -ENOMEM; + roothash = image_roothash_path(i); + if (!roothash) + return -ENOMEM; + /* Make sure nobody takes the new name, between the time we * checked it is currently unused in all search paths, and the * time we take possession of it */ @@ -636,11 +667,15 @@ int image_clone(Image *i, const char *new_name, bool read_only) { return r; STRV_FOREACH(j, settings) { - r = clone_settings_file(*j, new_name); + r = clone_auxiliary_file(*j, new_name, ".nspawn"); if (r < 0 && r != -ENOENT) log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j); } + r = clone_auxiliary_file(roothash, new_name, ".roothash"); + if (r < 0 && r != -ENOENT) + log_debug_errno(r, "Failed to clone root hash file %s, ignoring: %m", roothash); + return 0; }