static int raw_pull_job_on_open_disk_settings(PullJob *j) { RawPull *i; int r; assert(j); assert(j->userdata); i = j->userdata; assert(i->settings_job == j); assert(!i->settings_path); assert(!i->settings_temp_path); r = pull_make_path(j->url, j->etag, i->image_root, ".settings-", NULL, &i->settings_path); if (r < 0) return log_oom(); r = tempfn_random(i->settings_path, NULL, &i->settings_temp_path); if (r < 0) return log_oom(); mkdir_parents_label(i->settings_temp_path, 0700); j->disk_fd = open(i->settings_temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664); if (j->disk_fd < 0) return log_error_errno(errno, "Failed to create %s: %m", i->settings_temp_path); return 0; }
static int raw_pull_job_on_open_disk_raw(PullJob *j) { RawPull *i; int r; assert(j); assert(j->userdata); i = j->userdata; assert(i->raw_job == j); assert(!i->final_path); assert(!i->temp_path); r = pull_make_path(j->url, j->etag, i->image_root, ".raw-", ".raw", &i->final_path); if (r < 0) return log_oom(); r = tempfn_random(i->final_path, NULL, &i->temp_path); if (r < 0) return log_oom(); (void) mkdir_parents_label(i->temp_path, 0700); j->disk_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664); if (j->disk_fd < 0) return log_error_errno(errno, "Failed to create %s: %m", i->temp_path); r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL); if (r < 0) log_warning_errno(errno, "Failed to set file attributes on %s: %m", i->temp_path); return 0; }
static int tar_pull_make_local_copy(TarPull *i) { int r; assert(i); assert(i->tar_job); if (!i->local) return 0; if (!i->final_path) { r = pull_make_path(i->tar_job->url, i->tar_job->etag, i->image_root, ".tar-", NULL, &i->final_path); if (r < 0) return log_oom(); } r = pull_make_local_copy(i->final_path, i->image_root, i->local, i->force_local); if (r < 0) return r; if (i->settings) { const char *local_settings; assert(i->settings_job); if (!i->settings_path) { r = pull_make_path(i->settings_job->url, i->settings_job->etag, i->image_root, ".settings-", NULL, &i->settings_path); if (r < 0) return log_oom(); } local_settings = strjoina(i->image_root, "/", i->local, ".nspawn"); r = copy_file_atomic(i->settings_path, local_settings, 0664, i->force_local, 0); if (r == -EEXIST) log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings); else if (r < 0 && r != -ENOENT) log_warning_errno(r, "Failed to copy settings files %s: %m", local_settings); log_info("Create new settings file '%s.nspawn'", i->local); } return 0; }
static int raw_pull_determine_path(RawPull *i, const char *suffix, char **field) { int r; assert(i); assert(field); if (*field) return 0; assert(i->raw_job); r = pull_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", suffix, field); if (r < 0) return log_oom(); return 1; }
static int tar_pull_make_local_copy(TarPull *i) { int r; assert(i); assert(i->tar_job); if (!i->local) return 0; if (!i->final_path) { r = pull_make_path(i->tar_job->url, i->tar_job->etag, i->image_root, ".tar-", NULL, &i->final_path); if (r < 0) return log_oom(); } r = pull_make_local_copy(i->final_path, i->image_root, i->local, i->force_local); if (r < 0) return r; return 0; }
static int tar_pull_job_on_open_disk_tar(PullJob *j) { TarPull *i; int r; assert(j); assert(j->userdata); i = j->userdata; assert(i->tar_job == j); assert(!i->final_path); assert(!i->temp_path); assert(i->tar_pid <= 0); r = pull_make_path(j->url, j->etag, i->image_root, ".tar-", NULL, &i->final_path); if (r < 0) return log_oom(); r = tempfn_random(i->final_path, NULL, &i->temp_path); if (r < 0) return log_oom(); mkdir_parents_label(i->temp_path, 0700); r = btrfs_subvol_make(i->temp_path); if (r == -ENOTTY) { if (mkdir(i->temp_path, 0755) < 0) return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path); } else if (r < 0) return log_error_errno(errno, "Failed to create subvolume %s: %m", i->temp_path); else (void) import_assign_pool_quota_and_warn(i->temp_path); j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid); if (j->disk_fd < 0) return j->disk_fd; return 0; }
static int raw_pull_make_local_copy(RawPull *i) { _cleanup_free_ char *tp = NULL; _cleanup_close_ int dfd = -1; const char *p; int r; assert(i); assert(i->raw_job); if (!i->local) return 0; if (!i->final_path) { r = pull_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", ".raw", &i->final_path); if (r < 0) return log_oom(); } if (i->raw_job->etag_exists) { /* We have downloaded this one previously, reopen it */ assert(i->raw_job->disk_fd < 0); i->raw_job->disk_fd = open(i->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC); if (i->raw_job->disk_fd < 0) return log_error_errno(errno, "Failed to open vendor image: %m"); } else { /* We freshly downloaded the image, use it */ assert(i->raw_job->disk_fd >= 0); if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) == (off_t) -1) return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m"); } p = strjoina(i->image_root, "/", i->local, ".raw"); if (i->force_local) (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME); r = tempfn_random(p, NULL, &tp); if (r < 0) return log_oom(); dfd = open(tp, 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"); /* 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. */ r = chattr_fd(dfd, FS_NOCOW_FL, FS_NOCOW_FL); if (r < 0) log_warning_errno(errno, "Failed to set file attributes on %s: %m", tp); r = copy_bytes(i->raw_job->disk_fd, dfd, (off_t) -1, true); if (r < 0) { unlink(tp); return log_error_errno(r, "Failed to make writable copy of image: %m"); } (void) copy_times(i->raw_job->disk_fd, dfd); (void) copy_xattr(i->raw_job->disk_fd, dfd); dfd = safe_close(dfd); r = rename(tp, p); if (r < 0) { unlink(tp); return log_error_errno(errno, "Failed to move writable image into place: %m"); } log_info("Created new local image '%s'.", i->local); if (i->settings) { const char *local_settings; assert(i->settings_job); if (!i->settings_path) { r = pull_make_path(i->settings_job->url, i->settings_job->etag, i->image_root, ".settings-", NULL, &i->settings_path); if (r < 0) return log_oom(); } local_settings = strjoina(i->image_root, "/", i->local, ".nspawn"); r = copy_file_atomic(i->settings_path, local_settings, 0644, i->force_local, 0); if (r == -EEXIST) log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings); else if (r < 0 && r != -ENOENT) log_warning_errno(r, "Failed to copy settings files %s: %m", local_settings); log_info("Create new settings file '%s.nspawn'", i->local); } return 0; }