diff options
Diffstat (limited to 'src/import/pull-raw.c')
-rw-r--r-- | src/import/pull-raw.c | 168 |
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) |