import-raw.c revision 85dbc41dc67ff49fd8a843dbac5b8b5cb0b61155
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/***
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen This file is part of systemd.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Copyright 2014 Lennart Poettering
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is free software; you can redistribute it and/or modify it
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen under the terms of the GNU Lesser General Public License as published by
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen (at your option) any later version.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is distributed in the hope that it will be useful, but
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Lesser General Public License for more details.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen You should have received a copy of the GNU Lesser General Public License
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen***/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#include <sys/xattr.h>
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include <linux/fs.h>
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen#include <curl/curl.h>
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include <gcrypt.h>
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "utf8.h"
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#include "strv.h"
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#include "copy.h"
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include "btrfs-util.h"
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#include "util.h"
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen#include "macro.h"
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen#include "mkdir.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "curl-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "qcow2-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "import-job.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "import-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "import-raw.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersentypedef struct RawImportFile RawImportFile;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenstruct RawImport {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen sd_event *event;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen CurlGlue *glue;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen char *image_root;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen ImportJob *raw_job;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen ImportJob *sha256sums_job;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen RawImportFinished on_finished;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen void *userdata;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen char *local;
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen bool force_local;
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen char *temp_path;
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen char *final_path;
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen};
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom GundersenRawImport* raw_import_unref(RawImport *i) {
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen if (!i)
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen return NULL;
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen import_job_unref(i->raw_job);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen curl_glue_unref(i->glue);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen sd_event_unref(i->event);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (i->temp_path) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen (void) unlink(i->temp_path);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(i->temp_path);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(i->final_path);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(i->image_root);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(i->local);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(i);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen}
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenint raw_import_new(RawImport **ret, sd_event *event, const char *image_root, RawImportFinished on_finished, void *userdata) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen _cleanup_(raw_import_unrefp) RawImport *i = NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen int r;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(ret);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i = new0(RawImport, 1);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (!i)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return -ENOMEM;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i->on_finished = on_finished;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i->userdata = userdata;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i->image_root = strdup(image_root ?: "/var/lib/machines");
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (!i->image_root)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return -ENOMEM;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (event)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i->event = sd_event_ref(event);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen else {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen r = sd_event_default(&i->event);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (r < 0)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return r;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen r = curl_glue_new(&i->glue, i->event);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (r < 0)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return r;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen i->glue->on_finished = import_job_curl_on_finished;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen i->glue->userdata = i;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen *ret = i;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen i = NULL;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return 0;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen}
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenstatic int raw_import_maybe_convert_qcow2(RawImport *i) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen _cleanup_close_ int converted_fd = -1;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen _cleanup_free_ char *t = NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen int r;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(i);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(i->raw_job);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen r = qcow2_detect(i->raw_job->disk_fd);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return log_error_errno(r, "Failed to detect whether this is a QCOW2 image: %m");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r == 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return 0;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen /* This is a QCOW2 image, let's convert it */
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen r = tempfn_random(i->final_path, &t);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return log_oom();
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen converted_fd = open(t, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0644);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (converted_fd < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return log_error_errno(errno, "Failed to create %s: %m", t);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen r = chattr_fd(converted_fd, true, FS_NOCOW_FL);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0)
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen log_warning_errno(errno, "Failed to set file attributes on %s: %m", t);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen log_info("Unpacking QCOW2 file.");
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen r = qcow2_convert(i->raw_job->disk_fd, converted_fd);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen unlink(t);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return log_error_errno(r, "Failed to convert qcow2 image: %m");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen }
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen unlink(i->temp_path);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen free(i->temp_path);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen i->temp_path = t;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen t = NULL;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen safe_close(i->raw_job->disk_fd);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen i->raw_job->disk_fd = converted_fd;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen converted_fd = -1;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return 1;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen}
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersenstatic int raw_import_make_local_copy(RawImport *i) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen _cleanup_free_ char *tp = NULL;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen _cleanup_close_ int dfd = -1;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen const char *p;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen int r;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen assert(i);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen assert(i->raw_job);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (!i->local)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return 0;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (i->raw_job->etag_exists) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen /* We have downloaded this one previously, reopen it */
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen assert(i->raw_job->disk_fd < 0);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (!i->final_path) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen r = import_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", ".raw", &i->final_path);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return log_oom();
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen i->raw_job->disk_fd = open(i->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (i->raw_job->disk_fd < 0)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return log_error_errno(errno, "Failed to open vendor image: %m");
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen } else {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen /* We freshly downloaded the image, use it */
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen assert(i->raw_job->disk_fd >= 0);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) == (off_t) -1)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen p = strappenda(i->image_root, "/", i->local, ".raw");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (i->force_local) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen (void) btrfs_subvol_remove(p);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen (void) rm_rf_dangerous(p, false, true, false);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = tempfn_random(p, &tp);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_oom();
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen dfd = open(tp, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (dfd < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_error_errno(errno, "Failed to create writable copy of image: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* Turn off COW writing. This should greatly improve
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * performance on COW file systems like btrfs, since it
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * reduces fragmentation caused by not allowing in-place
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * writes. */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = chattr_fd(dfd, true, FS_NOCOW_FL);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_warning_errno(errno, "Failed to set file attributes on %s: %m", tp);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = copy_bytes(i->raw_job->disk_fd, dfd, (off_t) -1, true);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen unlink(tp);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_error_errno(r, "Failed to make writable copy of image: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen (void) copy_times(i->raw_job->disk_fd, dfd);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen (void) copy_xattr(i->raw_job->disk_fd, dfd);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen dfd = safe_close(dfd);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = rename(tp, p);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen unlink(tp);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_error_errno(errno, "Failed to move writable image into place: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_info("Created new local image '%s'.", i->local);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return 0;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic int raw_import_verify_sha256sum(RawImport *i) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen _cleanup_free_ char *fn = NULL;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen const char *p, *line;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->raw_job);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->raw_job->sha256);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->sha256sums_job);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->sha256sums_job->payload);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->sha256sums_job->payload_size > 0);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = import_url_last_component(i->raw_job->url, &fn);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_oom();
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!filename_is_valid(fn)) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Cannot verify checksum, could not determine valid server-side file name.");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return -EBADMSG;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen line = strappenda(i->raw_job->sha256, " *", fn, "\n");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen p = memmem(i->sha256sums_job->payload,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen i->sha256sums_job->payload_size,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen line,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen strlen(line));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!p || (p != (char*) i->sha256sums_job->payload && p[-1] != '\n')) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error("Checksum did not check out, payload has been tempered with.");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return -EBADMSG;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_info("SHA256 checksum of %s is valid.", i->raw_job->url);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return 0;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic int raw_import_finalize(RawImport *i) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!IMPORT_JOB_STATE_IS_COMPLETE(i->raw_job) ||
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen !IMPORT_JOB_STATE_IS_COMPLETE(i->sha256sums_job))
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return 0;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!i->raw_job->etag_exists) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->temp_path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->final_path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i->raw_job->disk_fd >= 0);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = raw_import_verify_sha256sum(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = rename(i->temp_path, i->final_path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return log_error_errno(errno, "Failed to move RAW file into place: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen free(i->temp_path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen i->temp_path = NULL;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = raw_import_make_local_copy(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen i->raw_job->disk_fd = safe_close(i->raw_job->disk_fd);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return 1;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic void raw_import_invoke_finished(RawImport *i, int r) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (i->on_finished)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen i->on_finished(i, r, i->userdata);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen else
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen sd_event_exit(i->event, r);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic void raw_import_raw_job_on_finished(ImportJob *j) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen RawImport *i;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(j);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(j->userdata);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen i = j->userdata;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (j->error != 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = j->error;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen goto finish;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* This is invoked if either the download completed
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * successfully, or the download was skipped because we
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * already have the etag. In this case ->etag_exists is
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * true. */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!j->etag_exists) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(j->disk_fd >= 0);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = raw_import_maybe_convert_qcow2(i);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen goto finish;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = import_make_read_only_fd(j->disk_fd);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen goto finish;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen }
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = raw_import_finalize(i);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen goto finish;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r == 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = 0;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersenfinish:
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen raw_import_invoke_finished(i, r);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen}
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersenstatic void raw_import_sha256sums_job_on_finished(ImportJob *j) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen RawImport *i;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen int r;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen assert(j);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen assert(j->userdata);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen i = j->userdata;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (j->error != 0) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = j->error;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen goto finish;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = raw_import_finalize(i);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen goto finish;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r == 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = 0;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersenfinish:
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen raw_import_invoke_finished(i, r);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen}
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersenstatic int raw_import_raw_job_on_open_disk(ImportJob *j) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen RawImport *i;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen int r;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen assert(j);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen assert(j->userdata);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen i = j->userdata;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = import_make_path(j->url, j->etag, i->image_root, ".raw-", ".raw", &i->final_path);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return log_oom();
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = tempfn_random(i->final_path, &i->temp_path);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r <0)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return log_oom();
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen mkdir_parents_label(i->temp_path, 0700);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen j->disk_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0644);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (j->disk_fd < 0)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return log_error_errno(errno, "Failed to create %s: %m", i->temp_path);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = chattr_fd(j->disk_fd, true, FS_NOCOW_FL);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r < 0)
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen log_warning_errno(errno, "Failed to set file attributes on %s: %m", i->temp_path);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return 0;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen}
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersenint raw_import_pull(RawImport *i, const char *url, const char *local, bool force_local) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen _cleanup_free_ char *sha256sums_url = NULL;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen int r;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen assert(i);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (i->raw_job)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return -EBUSY;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (!http_url_is_valid(url))
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return -EINVAL;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (local && !machine_name_is_valid(local))
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return -EINVAL;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen r = free_and_strdup(&i->local, local);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (r < 0)
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return r;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen i->force_local = force_local;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen /* Queue job for the image itself */
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen r = import_job_new(&i->raw_job, url, i->glue, i);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (r < 0)
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return r;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen i->raw_job->on_finished = raw_import_raw_job_on_finished;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen i->raw_job->on_open_disk = raw_import_raw_job_on_open_disk;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen i->raw_job->calc_hash = true;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = import_find_old_etags(url, i->image_root, DT_REG, ".raw-", ".raw", &i->raw_job->old_etags);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r < 0)
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen return r;
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen /* Queue job for the SHA256SUMS file for the image */
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen r = import_url_change_last_component(url, "SHA256SUMS", &sha256sums_url);
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen if (r < 0)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return r;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = import_job_new(&i->sha256sums_job, sha256sums_url, i->glue, i);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r < 0)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen return r;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen i->sha256sums_job->on_finished = raw_import_sha256sums_job_on_finished;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen i->sha256sums_job->uncompressed_max = i->sha256sums_job->compressed_max = 1ULL * 1024ULL * 1024ULL;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = import_job_begin(i->raw_job);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r < 0)
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen return r;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = import_job_begin(i->sha256sums_job);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r < 0)
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen return r;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen return 0;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen}
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen