static int raw_import_open_disk(RawImport *i) { int r; assert(i); assert(!i->final_path); assert(!i->temp_path); assert(i->output_fd < 0); i->final_path = strjoin(i->image_root, "/", i->local, ".raw"); if (!i->final_path) 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); i->output_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664); if (i->output_fd < 0) return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path); r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL); if (r < 0) log_warning_errno(r, "Failed to set file attributes on %s: %m", i->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 raw_pull_maybe_convert_qcow2(RawPull *i) { _cleanup_close_ int converted_fd = -1; _cleanup_free_ char *t = NULL; int r; assert(i); assert(i->raw_job); r = qcow2_detect(i->raw_job->disk_fd); if (r < 0) return log_error_errno(r, "Failed to detect whether this is a QCOW2 image: %m"); if (r == 0) return 0; /* This is a QCOW2 image, let's convert it */ r = tempfn_random(i->final_path, NULL, &t); if (r < 0) return log_oom(); converted_fd = open(t, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664); if (converted_fd < 0) return log_error_errno(errno, "Failed to create %s: %m", t); r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL); if (r < 0) log_warning_errno(errno, "Failed to set file attributes on %s: %m", t); log_info("Unpacking QCOW2 file."); r = qcow2_convert(i->raw_job->disk_fd, converted_fd); if (r < 0) { unlink(t); return log_error_errno(r, "Failed to convert qcow2 image: %m"); } (void) unlink(i->temp_path); free(i->temp_path); i->temp_path = t; t = NULL; safe_close(i->raw_job->disk_fd); i->raw_job->disk_fd = converted_fd; converted_fd = -1; return 1; }
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); r = raw_pull_job_on_open_disk_generic(i, j, "raw", &i->temp_path); if (r < 0) return r; r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL); if (r < 0) log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path); 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->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(r, "Failed to set file attributes on %s: %m", tp); r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, COPY_REFLINK); 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) { r = log_error_errno(errno, "Failed to move writable image into place: %m"); unlink(tp); return r; } log_info("Created new local image '%s'.", i->local); if (i->roothash) { r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path); if (r < 0) return r; } if (i->settings) { r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path); if (r < 0) return r; } return 0; }
int efi_set_variable( sd_id128_t vendor, const char *name, const void *value, size_t size) { struct var { uint32_t attr; char buf[]; } _packed_ * _cleanup_free_ buf = NULL; _cleanup_free_ char *p = NULL; _cleanup_close_ int fd = -1; bool saved_flags_valid = false; unsigned saved_flags; int r; assert(name); assert(value || size == 0); if (asprintf(&p, "/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", name, SD_ID128_FORMAT_VAL(vendor)) < 0) return -ENOMEM; /* Newer efivarfs protects variables that are not in a whitelist with FS_IMMUTABLE_FL by default, to protect * them for accidental removal and modification. We are not changing these variables accidentally however, * hence let's unset the bit first. */ r = chattr_path(p, 0, FS_IMMUTABLE_FL, &saved_flags); if (r < 0 && r != -ENOENT) log_debug_errno(r, "Failed to drop FS_IMMUTABLE_FL flag from '%s', ignoring: %m", p); saved_flags_valid = r >= 0; if (size == 0) { if (unlink(p) < 0) { r = -errno; goto finish; } return 0; } fd = open(p, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, 0644); if (fd < 0) { r = -errno; goto finish; } buf = malloc(sizeof(uint32_t) + size); if (!buf) { r = -ENOMEM; goto finish; } buf->attr = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS; memcpy(buf->buf, value, size); r = loop_write(fd, buf, sizeof(uint32_t) + size, false); if (r < 0) goto finish; r = 0; finish: if (saved_flags_valid) { int q; /* Restore the original flags field, just in case */ if (fd < 0) q = chattr_path(p, saved_flags, FS_IMMUTABLE_FL, NULL); else q = chattr_fd(fd, saved_flags, FS_IMMUTABLE_FL, NULL); if (q < 0) log_debug_errno(q, "Failed to restore FS_IMMUTABLE_FL on '%s', ignoring: %m", p); } return r; }