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);
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");
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).
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) {
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,