From: Philip Withnall Date: Wed, 31 Dec 2025 00:36:22 +0000 (+0000) Subject: sysupdate: Factor out temporary path computation for transfers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba9687adefa46e1b0f1f111248e74cd7dec75ff6;p=thirdparty%2Fsystemd.git sysupdate: Factor out temporary path computation for transfers This helper function will be reused in a following commit. This introduces no functional changes. Signed-off-by: Philip Withnall Helps: https://github.com/systemd/systemd/issues/34814 --- diff --git a/src/sysupdate/sysupdate-transfer.c b/src/sysupdate/sysupdate-transfer.c index f624a50cf40..5af2f4cf301 100644 --- a/src/sysupdate/sysupdate-transfer.c +++ b/src/sysupdate/sysupdate-transfer.c @@ -1168,27 +1168,15 @@ static int run_callout( return sd_event_loop(event); } -int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, void *userdata) { - _cleanup_free_ char *formatted_pattern = NULL, *digest = NULL; - _cleanup_free_ char *formatted_partial_pattern = NULL; - _cleanup_free_ char *formatted_pending_pattern = NULL; - char offset[DECIMAL_STR_MAX(uint64_t)+1], max_size[DECIMAL_STR_MAX(uint64_t)+1]; - const char *where = NULL; - InstanceMetadata f; - Instance *existing; +/* Build the filenames and paths which is normally done by transfer_acquire_instance(), but for partial + * and pending instances which are about to be installed (in which case, transfer_acquire_instance() is + * skipped). */ +static int transfer_compute_temporary_paths(Transfer *t, Instance *i, InstanceMetadata *f) { + _cleanup_free_ char *formatted_pattern = NULL, *formatted_partial_pattern = NULL, *formatted_pending_pattern = NULL; int r; assert(t); assert(i); - assert(i->resource == &t->source); - assert(cb); - - /* Does this instance already exist in the target? Then we don't need to acquire anything */ - existing = resource_find_instance(&t->target, i->metadata.version); - if (existing) { - log_info("No need to acquire '%s', already installed.", i->path); - return 0; - } assert(!t->final_path); assert(!t->temporary_partial_path); @@ -1199,8 +1187,8 @@ int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, voi assert(!strv_isempty(t->target.patterns)); /* Format the target name using the first pattern specified */ - compile_pattern_fields(t, i, &f); - r = pattern_format(t->target.patterns[0], &f, &formatted_pattern); + compile_pattern_fields(t, i, f); + r = pattern_format(t->target.patterns[0], f, &formatted_pattern); if (r < 0) return log_error_errno(r, "Failed to format target pattern: %m"); @@ -1214,10 +1202,6 @@ int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, voi if (!t->final_path) return log_oom(); - r = mkdir_parents(t->final_path, 0755); - if (r < 0) - return log_error_errno(r, "Cannot create target directory: %m"); - /* Build the paths for the partial and pending files, which hold the resource while it’s * being acquired and after it’s been acquired (but before it’s moved to the final_path * when it’s installed). @@ -1238,19 +1222,9 @@ int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, voi if (!t->temporary_partial_path) return log_oom(); - r = mkdir_parents(t->temporary_partial_path, 0755); - if (r < 0) - return log_error_errno(r, "Cannot create target directory: %m"); - t->temporary_pending_path = path_join(final_dir, pending_filename); if (!t->temporary_pending_path) return log_oom(); - - r = mkdir_parents(t->temporary_pending_path, 0755); - if (r < 0) - return log_error_errno(r, "Cannot create target directory: %m"); - - where = t->final_path; } if (t->target.type == RESOURCE_PARTITION) { @@ -1281,7 +1255,55 @@ int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, voi free_and_replace(t->temporary_pending_partition_label, formatted_pending_pattern); t->final_partition_label = TAKE_PTR(formatted_pattern); + } + + return 0; +} +int transfer_acquire_instance(Transfer *t, Instance *i, TransferProgress cb, void *userdata) { + _cleanup_free_ char *digest = NULL; + char offset[DECIMAL_STR_MAX(uint64_t)+1], max_size[DECIMAL_STR_MAX(uint64_t)+1]; + const char *where = NULL; + InstanceMetadata f; + Instance *existing; + int r; + + assert(t); + assert(i); + assert(i->resource == &t->source); + assert(cb); + + /* Does this instance already exist in the target? Then we don't need to acquire anything */ + existing = resource_find_instance(&t->target, i->metadata.version); + if (existing && (existing->is_partial || existing->is_pending)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to acquire '%s', instance is already partial or pending in the target.", i->path); + if (existing) { + log_info("No need to acquire '%s', already installed.", i->path); + return 0; + } + + /* Compute up the temporary paths */ + r = transfer_compute_temporary_paths(t, i, &f); + if (r < 0) + return r; + + if (RESOURCE_IS_FILESYSTEM(t->target.type)) { + r = mkdir_parents(t->temporary_partial_path, 0755); + if (r < 0) + return log_error_errno(r, "Cannot create target directory: %m"); + + r = mkdir_parents(t->temporary_pending_path, 0755); + if (r < 0) + return log_error_errno(r, "Cannot create target directory: %m"); + + r = mkdir_parents(t->final_path, 0755); + if (r < 0) + return log_error_errno(r, "Cannot create target directory: %m"); + + where = t->final_path; + } + + if (t->target.type == RESOURCE_PARTITION) { r = find_suitable_partition( t->target.path, i->metadata.size,