summaryrefslogtreecommitdiffstats
path: root/src/import/pull-raw.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 03:50:40 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 03:50:40 +0000
commitfc53809803cd2bc2434e312b19a18fa36776da12 (patch)
treeb4b43bd6538f51965ce32856e9c053d0f90919c8 /src/import/pull-raw.c
parentAdding upstream version 255.5. (diff)
downloadsystemd-fc53809803cd2bc2434e312b19a18fa36776da12.tar.xz
systemd-fc53809803cd2bc2434e312b19a18fa36776da12.zip
Adding upstream version 256.upstream/256
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/import/pull-raw.c')
-rw-r--r--src/import/pull-raw.c168
1 files changed, 93 insertions, 75 deletions
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 66c3f65..f3e6b3a 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -42,7 +42,7 @@ struct RawPull {
sd_event *event;
CurlGlue *glue;
- PullFlags flags;
+ ImportFlags flags;
ImportVerify verify;
char *image_root;
@@ -60,7 +60,7 @@ struct RawPull {
void *userdata;
char *local; /* In PULL_DIRECT mode the path we are supposed to place things in, otherwise the
- * machine name of the final copy we make */
+ * image name of the final copy we make */
char *final_path;
char *temp_path;
@@ -127,8 +127,9 @@ int raw_pull_new(
int r;
assert(ret);
+ assert(image_root);
- root = strdup(image_root ?: "/var/lib/machines");
+ root = strdup(image_root);
if (!root)
return -ENOMEM;
@@ -244,9 +245,9 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
assert(i);
assert(i->raw_job);
- assert(!FLAGS_SET(i->flags, PULL_DIRECT));
+ assert(!FLAGS_SET(i->flags, IMPORT_DIRECT));
- if (!FLAGS_SET(i->flags, PULL_CONVERT_QCOW2))
+ if (!FLAGS_SET(i->flags, IMPORT_CONVERT_QCOW2))
return 0;
assert(i->final_path);
@@ -310,7 +311,7 @@ static int raw_pull_copy_auxiliary_file(
const char *suffix,
char **path /* input + output (!) */) {
- const char *local;
+ _cleanup_free_ char *local = NULL;
int r;
assert(i);
@@ -321,21 +322,29 @@ static int raw_pull_copy_auxiliary_file(
if (r < 0)
return r;
- local = strjoina(i->image_root, "/", i->local, suffix);
+ local = strjoin(i->image_root, "/", i->local, suffix);
+ if (!local)
+ return log_oom();
- r = copy_file_atomic(
- *path,
- local,
- 0644,
- COPY_REFLINK |
- (FLAGS_SET(i->flags, PULL_FORCE) ? COPY_REPLACE : 0) |
- (FLAGS_SET(i->flags, PULL_SYNC) ? COPY_FSYNC_FULL : 0));
+ if (FLAGS_SET(i->flags, IMPORT_PULL_KEEP_DOWNLOAD))
+ r = copy_file_atomic(
+ *path,
+ local,
+ 0644,
+ COPY_REFLINK |
+ (FLAGS_SET(i->flags, IMPORT_FORCE) ? COPY_REPLACE : 0) |
+ (FLAGS_SET(i->flags, IMPORT_SYNC) ? COPY_FSYNC_FULL : 0));
+ else
+ r = install_file(AT_FDCWD, *path,
+ AT_FDCWD, local,
+ (i->flags & IMPORT_FORCE ? INSTALL_REPLACE : 0) |
+ (i->flags & IMPORT_SYNC ? INSTALL_SYNCFS : 0));
if (r == -EEXIST)
log_warning_errno(r, "File %s already exists, not replacing.", local);
else if (r == -ENOENT)
log_debug_errno(r, "Skipping creation of auxiliary file, since none was found.");
else if (r < 0)
- log_warning_errno(r, "Failed to copy file %s, ignoring: %m", local);
+ log_warning_errno(r, "Failed to install file %s, ignoring: %m", local);
else
log_info("Created new file %s.", local);
@@ -344,14 +353,12 @@ static int raw_pull_copy_auxiliary_file(
static int raw_pull_make_local_copy(RawPull *i) {
_cleanup_(unlink_and_freep) char *tp = NULL;
- _cleanup_free_ char *f = NULL;
- _cleanup_close_ int dfd = -EBADF;
- const char *p;
+ _cleanup_free_ char *p = NULL;
int r;
assert(i);
assert(i->raw_job);
- assert(!FLAGS_SET(i->flags, PULL_DIRECT));
+ assert(!FLAGS_SET(i->flags, IMPORT_DIRECT));
if (!i->local)
return 0;
@@ -374,62 +381,73 @@ static int raw_pull_make_local_copy(RawPull *i) {
return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
}
- p = strjoina(i->image_root, "/", i->local, ".raw");
-
- r = tempfn_random(p, NULL, &f);
- if (r < 0)
+ p = strjoin(i->image_root, "/", i->local, ".raw");
+ if (!p)
return log_oom();
- dfd = open(f, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
- if (dfd < 0)
- return log_error_errno(errno, "Failed to create writable copy of image: %m");
+ const char *source;
+ if (FLAGS_SET(i->flags, IMPORT_PULL_KEEP_DOWNLOAD)) {
+ _cleanup_close_ int dfd = -EBADF;
+ _cleanup_free_ char *f = NULL;
- tp = TAKE_PTR(f);
+ r = tempfn_random(p, NULL, &f);
+ if (r < 0)
+ return log_oom();
- /* Turn off COW writing. This should greatly improve performance on COW file systems like btrfs,
- * since it reduces fragmentation caused by not allowing in-place writes. */
- (void) import_set_nocow_and_log(dfd, tp);
+ dfd = open(f, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
+ if (dfd < 0)
+ return log_error_errno(errno, "Failed to create writable copy of image: %m");
- r = copy_bytes(i->raw_job->disk_fd, dfd, UINT64_MAX, COPY_REFLINK);
- if (r < 0)
- return log_error_errno(r, "Failed to make writable copy of image: %m");
+ tp = TAKE_PTR(f);
- (void) copy_times(i->raw_job->disk_fd, dfd, COPY_CRTIME);
- (void) copy_xattr(i->raw_job->disk_fd, NULL, dfd, NULL, 0);
+ /* Turn off COW writing. This should greatly improve performance on COW file systems like btrfs,
+ * since it reduces fragmentation caused by not allowing in-place writes. */
+ (void) import_set_nocow_and_log(dfd, tp);
- dfd = safe_close(dfd);
+ r = copy_bytes(i->raw_job->disk_fd, dfd, UINT64_MAX, COPY_REFLINK);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make writable copy of image: %m");
+
+ (void) copy_times(i->raw_job->disk_fd, dfd, COPY_CRTIME);
+ (void) copy_xattr(i->raw_job->disk_fd, NULL, dfd, NULL, 0);
+
+ dfd = safe_close(dfd);
+
+ source = tp;
+ } else
+ source = i->final_path;
- r = install_file(AT_FDCWD, tp,
+ r = install_file(AT_FDCWD, source,
AT_FDCWD, p,
- (i->flags & PULL_FORCE ? INSTALL_REPLACE : 0) |
- (i->flags & PULL_READ_ONLY ? INSTALL_READ_ONLY : 0) |
- (i->flags & PULL_SYNC ? INSTALL_FSYNC_FULL : 0));
+ (i->flags & IMPORT_FORCE ? INSTALL_REPLACE : 0) |
+ (i->flags & IMPORT_READ_ONLY ? INSTALL_READ_ONLY : 0) |
+ (i->flags & IMPORT_SYNC ? INSTALL_FSYNC_FULL : 0));
if (r < 0)
- return log_error_errno(errno, "Failed to move local image into place '%s': %m", p);
+ return log_error_errno(r, "Failed to move local image into place '%s': %m", p);
tp = mfree(tp);
log_info("Created new local image '%s'.", i->local);
- if (FLAGS_SET(i->flags, PULL_SETTINGS)) {
+ if (FLAGS_SET(i->flags, IMPORT_PULL_SETTINGS)) {
r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
if (r < 0)
return r;
}
- if (FLAGS_SET(i->flags, PULL_ROOTHASH)) {
+ if (FLAGS_SET(i->flags, IMPORT_PULL_ROOTHASH)) {
r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path);
if (r < 0)
return r;
}
- if (FLAGS_SET(i->flags, PULL_ROOTHASH_SIGNATURE)) {
+ if (FLAGS_SET(i->flags, IMPORT_PULL_ROOTHASH_SIGNATURE)) {
r = raw_pull_copy_auxiliary_file(i, ".roothash.p7s", &i->roothash_signature_path);
if (r < 0)
return r;
}
- if (FLAGS_SET(i->flags, PULL_VERITY)) {
+ if (FLAGS_SET(i->flags, IMPORT_PULL_VERITY)) {
r = raw_pull_copy_auxiliary_file(i, ".verity", &i->verity_path);
if (r < 0)
return r;
@@ -485,7 +503,7 @@ static int raw_pull_rename_auxiliary_file(
AT_FDCWD, *temp_path,
AT_FDCWD, *path,
INSTALL_READ_ONLY|
- (i->flags & PULL_SYNC ? INSTALL_FSYNC_FULL : 0));
+ (i->flags & IMPORT_SYNC ? INSTALL_FSYNC_FULL : 0));
if (r < 0)
return log_error_errno(r, "Failed to move '%s' into place: %m", *path);
@@ -495,7 +513,6 @@ static int raw_pull_rename_auxiliary_file(
static void raw_pull_job_on_finished(PullJob *j) {
RawPull *i;
- PullJob *jj;
int r;
assert(j);
@@ -568,8 +585,9 @@ static void raw_pull_job_on_finished(PullJob *j) {
}
}
+ PullJob *jj;
/* Let's close these auxiliary files now, we don't need access to them anymore. */
- FOREACH_POINTER(jj, i->settings_job, i->roothash_job, i->roothash_signature_job, i->verity_job)
+ FOREACH_ARGUMENT(jj, i->settings_job, i->roothash_job, i->roothash_signature_job, i->verity_job)
pull_job_close_disk_fd(jj);
if (!i->raw_job->etag_exists) {
@@ -588,7 +606,7 @@ static void raw_pull_job_on_finished(PullJob *j) {
goto finish;
}
- if (i->flags & PULL_DIRECT) {
+ if (i->flags & IMPORT_DIRECT) {
assert(!i->settings_job);
assert(!i->roothash_job);
assert(!i->roothash_signature_job);
@@ -599,8 +617,8 @@ static void raw_pull_job_on_finished(PullJob *j) {
if (i->local) {
r = install_file(AT_FDCWD, i->local,
AT_FDCWD, NULL,
- ((i->flags & PULL_READ_ONLY) && i->offset == UINT64_MAX ? INSTALL_READ_ONLY : 0) |
- (i->flags & PULL_SYNC ? INSTALL_FSYNC_FULL : 0));
+ ((i->flags & IMPORT_READ_ONLY) && i->offset == UINT64_MAX ? INSTALL_READ_ONLY : 0) |
+ (i->flags & IMPORT_SYNC ? INSTALL_FSYNC_FULL : 0));
if (r < 0) {
log_error_errno(r, "Failed to finalize raw file to '%s': %m", i->local);
goto finish;
@@ -627,8 +645,8 @@ static void raw_pull_job_on_finished(PullJob *j) {
r = install_file(AT_FDCWD, i->temp_path,
AT_FDCWD, i->final_path,
- INSTALL_READ_ONLY|
- (i->flags & PULL_SYNC ? INSTALL_FSYNC_FULL : 0));
+ (i->flags & IMPORT_PULL_KEEP_DOWNLOAD ? INSTALL_READ_ONLY : 0) |
+ (i->flags & IMPORT_SYNC ? INSTALL_FSYNC_FULL : 0));
if (r < 0) {
log_error_errno(r, "Failed to move raw file to '%s': %m", i->final_path);
goto finish;
@@ -694,7 +712,7 @@ static int raw_pull_job_on_open_disk_generic(
assert(extra);
assert(temp_path);
- assert(!FLAGS_SET(i->flags, PULL_DIRECT));
+ assert(!FLAGS_SET(i->flags, IMPORT_DIRECT));
if (!*temp_path) {
r = tempfn_random_child(i->image_root, extra, temp_path);
@@ -722,7 +740,7 @@ static int raw_pull_job_on_open_disk_raw(PullJob *j) {
assert(i->raw_job == j);
assert(j->disk_fd < 0);
- if (i->flags & PULL_DIRECT) {
+ if (i->flags & IMPORT_DIRECT) {
if (!i->local) { /* If no local name specified, the pull job will write its data to stdout */
j->disk_fd = STDOUT_FILENO;
@@ -816,11 +834,10 @@ int raw_pull_start(
const char *local,
uint64_t offset,
uint64_t size_max,
- PullFlags flags,
+ ImportFlags flags,
ImportVerify verify,
const char *checksum) {
- PullJob *j;
int r;
assert(i);
@@ -828,10 +845,10 @@ int raw_pull_start(
assert(verify == _IMPORT_VERIFY_INVALID || verify < _IMPORT_VERIFY_MAX);
assert(verify == _IMPORT_VERIFY_INVALID || verify >= 0);
assert((verify < 0) || !checksum);
- assert(!(flags & ~PULL_FLAGS_MASK_RAW));
- assert(offset == UINT64_MAX || FLAGS_SET(flags, PULL_DIRECT));
- assert(!(flags & (PULL_SETTINGS|PULL_ROOTHASH|PULL_ROOTHASH_SIGNATURE|PULL_VERITY)) || !(flags & PULL_DIRECT));
- assert(!(flags & (PULL_SETTINGS|PULL_ROOTHASH|PULL_ROOTHASH_SIGNATURE|PULL_VERITY)) || !checksum);
+ assert(!(flags & ~IMPORT_PULL_FLAGS_MASK_RAW));
+ assert(offset == UINT64_MAX || FLAGS_SET(flags, IMPORT_DIRECT));
+ assert(!(flags & (IMPORT_PULL_SETTINGS|IMPORT_PULL_ROOTHASH|IMPORT_PULL_ROOTHASH_SIGNATURE|IMPORT_PULL_VERITY)) || !(flags & IMPORT_DIRECT));
+ assert(!(flags & (IMPORT_PULL_SETTINGS|IMPORT_PULL_ROOTHASH|IMPORT_PULL_ROOTHASH_SIGNATURE|IMPORT_PULL_VERITY)) || !checksum);
if (!http_url_is_valid(url) && !file_url_is_valid(url))
return -EINVAL;
@@ -881,7 +898,7 @@ int raw_pull_start(
if (offset != UINT64_MAX)
i->raw_job->offset = i->offset = offset;
- if (!FLAGS_SET(flags, PULL_DIRECT)) {
+ if (!FLAGS_SET(flags, IMPORT_DIRECT)) {
r = pull_find_old_etags(url, i->image_root, DT_REG, ".raw-", ".raw", &i->raw_job->old_etags);
if (r < 0)
return r;
@@ -899,7 +916,7 @@ int raw_pull_start(
if (r < 0)
return r;
- if (FLAGS_SET(flags, PULL_SETTINGS)) {
+ if (FLAGS_SET(flags, IMPORT_PULL_SETTINGS)) {
r = pull_make_auxiliary_job(
&i->settings_job,
url,
@@ -914,7 +931,7 @@ int raw_pull_start(
return r;
}
- if (FLAGS_SET(flags, PULL_ROOTHASH)) {
+ if (FLAGS_SET(flags, IMPORT_PULL_ROOTHASH)) {
r = pull_make_auxiliary_job(
&i->roothash_job,
url,
@@ -929,7 +946,7 @@ int raw_pull_start(
return r;
}
- if (FLAGS_SET(flags, PULL_ROOTHASH_SIGNATURE)) {
+ if (FLAGS_SET(flags, IMPORT_PULL_ROOTHASH_SIGNATURE)) {
r = pull_make_auxiliary_job(
&i->roothash_signature_job,
url,
@@ -944,7 +961,7 @@ int raw_pull_start(
return r;
}
- if (FLAGS_SET(flags, PULL_VERITY)) {
+ if (FLAGS_SET(flags, IMPORT_PULL_VERITY)) {
r = pull_make_auxiliary_job(
&i->verity_job,
url,
@@ -959,20 +976,21 @@ int raw_pull_start(
return r;
}
- FOREACH_POINTER(j,
- i->raw_job,
- i->checksum_job,
- i->signature_job,
- i->settings_job,
- i->roothash_job,
- i->roothash_signature_job,
- i->verity_job) {
+ PullJob *j;
+ FOREACH_ARGUMENT(j,
+ i->raw_job,
+ i->checksum_job,
+ i->signature_job,
+ i->settings_job,
+ i->roothash_job,
+ i->roothash_signature_job,
+ i->verity_job) {
if (!j)
continue;
j->on_progress = raw_pull_job_on_progress;
- j->sync = FLAGS_SET(flags, PULL_SYNC);
+ j->sync = FLAGS_SET(flags, IMPORT_SYNC);
r = pull_job_begin(j);
if (r < 0)