Bug Summary

File:build-scan/../src/import/pull-raw.c
Warning:line 369, column 9
Value stored to 'dfd' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pull-raw.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-pull.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/import/pull-raw.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <curl/curl.h>
4#include <linux1/fs.h>
5#include <sys/xattr.h>
6
7#include "sd-daemon.h"
8
9#include "alloc-util.h"
10#include "btrfs-util.h"
11#include "chattr-util.h"
12#include "copy.h"
13#include "curl-util.h"
14#include "fd-util.h"
15#include "fileio.h"
16#include "fs-util.h"
17#include "hostname-util.h"
18#include "import-common.h"
19#include "import-util.h"
20#include "macro.h"
21#include "mkdir.h"
22#include "path-util.h"
23#include "pull-common.h"
24#include "pull-job.h"
25#include "pull-raw.h"
26#include "qcow2-util.h"
27#include "rm-rf.h"
28#include "string-util.h"
29#include "strv.h"
30#include "utf8.h"
31#include "util.h"
32#include "web-util.h"
33
34typedef enum RawProgress {
35 RAW_DOWNLOADING,
36 RAW_VERIFYING,
37 RAW_UNPACKING,
38 RAW_FINALIZING,
39 RAW_COPYING,
40} RawProgress;
41
42struct RawPull {
43 sd_event *event;
44 CurlGlue *glue;
45
46 char *image_root;
47
48 PullJob *raw_job;
49 PullJob *roothash_job;
50 PullJob *settings_job;
51 PullJob *checksum_job;
52 PullJob *signature_job;
53
54 RawPullFinished on_finished;
55 void *userdata;
56
57 char *local;
58 bool_Bool force_local;
59 bool_Bool grow_machine_directory;
60 bool_Bool settings;
61 bool_Bool roothash;
62
63 char *final_path;
64 char *temp_path;
65
66 char *settings_path;
67 char *settings_temp_path;
68
69 char *roothash_path;
70 char *roothash_temp_path;
71
72 ImportVerify verify;
73};
74
75RawPull* raw_pull_unref(RawPull *i) {
76 if (!i)
77 return NULL((void*)0);
78
79 pull_job_unref(i->raw_job);
80 pull_job_unref(i->settings_job);
81 pull_job_unref(i->roothash_job);
82 pull_job_unref(i->checksum_job);
83 pull_job_unref(i->signature_job);
84
85 curl_glue_unref(i->glue);
86 sd_event_unref(i->event);
87
88 if (i->temp_path) {
89 (void) unlink(i->temp_path);
90 free(i->temp_path);
91 }
92
93 if (i->roothash_temp_path) {
94 (void) unlink(i->roothash_temp_path);
95 free(i->roothash_temp_path);
96 }
97
98 if (i->settings_temp_path) {
99 (void) unlink(i->settings_temp_path);
100 free(i->settings_temp_path);
101 }
102
103 free(i->final_path);
104 free(i->roothash_path);
105 free(i->settings_path);
106 free(i->image_root);
107 free(i->local);
108 return mfree(i);
109}
110
111int raw_pull_new(
112 RawPull **ret,
113 sd_event *event,
114 const char *image_root,
115 RawPullFinished on_finished,
116 void *userdata) {
117
118 _cleanup_(raw_pull_unrefp)__attribute__((cleanup(raw_pull_unrefp))) RawPull *i = NULL((void*)0);
119 int r;
120
121 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/import/pull-raw.c", 121,
__PRETTY_FUNCTION__); } while (0)
;
122
123 i = new0(RawPull, 1)((RawPull*) calloc((1), sizeof(RawPull)));
124 if (!i)
125 return -ENOMEM12;
126
127 i->on_finished = on_finished;
128 i->userdata = userdata;
129
130 i->image_root = strdup(image_root ?: "/var/lib/machines");
131 if (!i->image_root)
132 return -ENOMEM12;
133
134 i->grow_machine_directory = path_startswith(i->image_root, "/var/lib/machines");
135
136 if (event)
137 i->event = sd_event_ref(event);
138 else {
139 r = sd_event_default(&i->event);
140 if (r < 0)
141 return r;
142 }
143
144 r = curl_glue_new(&i->glue, i->event);
145 if (r < 0)
146 return r;
147
148 i->glue->on_finished = pull_job_curl_on_finished;
149 i->glue->userdata = i;
150
151 *ret = TAKE_PTR(i)({ typeof(i) _ptr_ = (i); (i) = ((void*)0); _ptr_; });
152
153 return 0;
154}
155
156static void raw_pull_report_progress(RawPull *i, RawProgress p) {
157 unsigned percent;
158
159 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 159, __PRETTY_FUNCTION__
); } while (0)
;
160
161 switch (p) {
162
163 case RAW_DOWNLOADING: {
164 unsigned remain = 80;
165
166 percent = 0;
167
168 if (i->settings_job) {
169 percent += i->settings_job->progress_percent * 5 / 100;
170 remain -= 5;
171 }
172
173 if (i->roothash_job) {
174 percent += i->roothash_job->progress_percent * 5 / 100;
175 remain -= 5;
176 }
177
178 if (i->checksum_job) {
179 percent += i->checksum_job->progress_percent * 5 / 100;
180 remain -= 5;
181 }
182
183 if (i->signature_job) {
184 percent += i->signature_job->progress_percent * 5 / 100;
185 remain -= 5;
186 }
187
188 if (i->raw_job)
189 percent += i->raw_job->progress_percent * remain / 100;
190 break;
191 }
192
193 case RAW_VERIFYING:
194 percent = 80;
195 break;
196
197 case RAW_UNPACKING:
198 percent = 85;
199 break;
200
201 case RAW_FINALIZING:
202 percent = 90;
203 break;
204
205 case RAW_COPYING:
206 percent = 95;
207 break;
208
209 default:
210 assert_not_reached("Unknown progress state")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown progress state"), "../src/import/pull-raw.c", 210, __PRETTY_FUNCTION__
); } while (0)
;
211 }
212
213 sd_notifyf(false0, "X_IMPORT_PROGRESS=%u", percent);
214 log_debug("Combined progress %u%%", percent)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 214, __func__, "Combined progress %u%%"
, percent) : -abs(_e); })
;
215}
216
217static int raw_pull_maybe_convert_qcow2(RawPull *i) {
218 _cleanup_close___attribute__((cleanup(closep))) int converted_fd = -1;
219 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
220 int r;
221
222 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 222, __PRETTY_FUNCTION__
); } while (0)
;
223 assert(i->raw_job)do { if ((__builtin_expect(!!(!(i->raw_job)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i->raw_job"), "../src/import/pull-raw.c"
, 223, __PRETTY_FUNCTION__); } while (0)
;
224
225 r = qcow2_detect(i->raw_job->disk_fd);
226 if (r < 0)
227 return log_error_errno(r, "Failed to detect whether this is a QCOW2 image: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 227, __func__, "Failed to detect whether this is a QCOW2 image: %m"
) : -abs(_e); })
;
228 if (r == 0)
229 return 0;
230
231 /* This is a QCOW2 image, let's convert it */
232 r = tempfn_random(i->final_path, NULL((void*)0), &t);
233 if (r < 0)
234 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/pull-raw.c"
, 234, __func__)
;
235
236 converted_fd = open(t, O_RDWR02|O_CREAT0100|O_EXCL0200|O_NOCTTY0400|O_CLOEXEC02000000, 0664);
237 if (converted_fd < 0)
238 return log_error_errno(errno, "Failed to create %s: %m", t)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 238, __func__
, "Failed to create %s: %m", t) : -abs(_e); })
;
239
240 r = chattr_fd(converted_fd, FS_NOCOW_FL0x00800000, FS_NOCOW_FL0x00800000);
241 if (r < 0)
242 log_warning_errno(r, "Failed to set file attributes on %s: %m", t)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 242, __func__, "Failed to set file attributes on %s: %m"
, t) : -abs(_e); })
;
243
244 log_info("Unpacking QCOW2 file.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 244, __func__, "Unpacking QCOW2 file."
) : -abs(_e); })
;
245
246 r = qcow2_convert(i->raw_job->disk_fd, converted_fd);
247 if (r < 0) {
248 unlink(t);
249 return log_error_errno(r, "Failed to convert qcow2 image: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 249, __func__, "Failed to convert qcow2 image: %m"
) : -abs(_e); })
;
250 }
251
252 (void) unlink(i->temp_path);
253 free_and_replace(i->temp_path, t)({ free(i->temp_path); (i->temp_path) = (t); (t) = ((void
*)0); 0; })
;
254
255 safe_close(i->raw_job->disk_fd);
256 i->raw_job->disk_fd = TAKE_FD(converted_fd)({ int _fd_ = (converted_fd); (converted_fd) = -1; _fd_; });
257
258 return 1;
259}
260
261static int raw_pull_determine_path(RawPull *i, const char *suffix, char **field) {
262 int r;
263
264 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 264, __PRETTY_FUNCTION__
); } while (0)
;
265 assert(field)do { if ((__builtin_expect(!!(!(field)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("field"), "../src/import/pull-raw.c", 265
, __PRETTY_FUNCTION__); } while (0)
;
266
267 if (*field)
268 return 0;
269
270 assert(i->raw_job)do { if ((__builtin_expect(!!(!(i->raw_job)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i->raw_job"), "../src/import/pull-raw.c"
, 270, __PRETTY_FUNCTION__); } while (0)
;
271
272 r = pull_make_path(i->raw_job->url, i->raw_job->etag, i->image_root, ".raw-", suffix, field);
273 if (r < 0)
274 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/pull-raw.c"
, 274, __func__)
;
275
276 return 1;
277}
278
279static int raw_pull_copy_auxiliary_file(
280 RawPull *i,
281 const char *suffix,
282 char **path) {
283
284 const char *local;
285 int r;
286
287 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 287, __PRETTY_FUNCTION__
); } while (0)
;
288 assert(suffix)do { if ((__builtin_expect(!!(!(suffix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("suffix"), "../src/import/pull-raw.c", 288
, __PRETTY_FUNCTION__); } while (0)
;
289 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/import/pull-raw.c", 289
, __PRETTY_FUNCTION__); } while (0)
;
290
291 r = raw_pull_determine_path(i, suffix, path);
292 if (r < 0)
293 return r;
294
295 local = strjoina(i->image_root, "/", i->local, suffix)({ const char *_appendees_[] = { i->image_root, "/", i->
local, suffix }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_
; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _len_ += strlen
(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1);
for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr(
!__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
296
297 r = copy_file_atomic(*path, local, 0644, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
298 if (r == -EEXIST17)
299 log_warning_errno(r, "File %s already exists, not replacing.", local)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 299, __func__, "File %s already exists, not replacing."
, local) : -abs(_e); })
;
300 else if (r == -ENOENT2)
301 log_debug_errno(r, "Skipping creation of auxiliary file, since none was found.")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 301, __func__, "Skipping creation of auxiliary file, since none was found."
) : -abs(_e); })
;
302 else if (r < 0)
303 log_warning_errno(r, "Failed to copy file %s, ignoring: %m", local)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 303, __func__, "Failed to copy file %s, ignoring: %m"
, local) : -abs(_e); })
;
304 else
305 log_info("Created new file %s.", local)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 305, __func__, "Created new file %s."
, local) : -abs(_e); })
;
306
307 return 0;
308}
309
310static int raw_pull_make_local_copy(RawPull *i) {
311 _cleanup_free___attribute__((cleanup(freep))) char *tp = NULL((void*)0);
312 _cleanup_close___attribute__((cleanup(closep))) int dfd = -1;
313 const char *p;
314 int r;
315
316 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 316, __PRETTY_FUNCTION__
); } while (0)
;
317 assert(i->raw_job)do { if ((__builtin_expect(!!(!(i->raw_job)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i->raw_job"), "../src/import/pull-raw.c"
, 317, __PRETTY_FUNCTION__); } while (0)
;
318
319 if (!i->local)
320 return 0;
321
322 if (i->raw_job->etag_exists) {
323 /* We have downloaded this one previously, reopen it */
324
325 assert(i->raw_job->disk_fd < 0)do { if ((__builtin_expect(!!(!(i->raw_job->disk_fd <
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->raw_job->disk_fd < 0"
), "../src/import/pull-raw.c", 325, __PRETTY_FUNCTION__); } while
(0)
;
326
327 i->raw_job->disk_fd = open(i->final_path, O_RDONLY00|O_NOCTTY0400|O_CLOEXEC02000000);
328 if (i->raw_job->disk_fd < 0)
329 return log_error_errno(errno, "Failed to open vendor image: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 329, __func__
, "Failed to open vendor image: %m") : -abs(_e); })
;
330 } else {
331 /* We freshly downloaded the image, use it */
332
333 assert(i->raw_job->disk_fd >= 0)do { if ((__builtin_expect(!!(!(i->raw_job->disk_fd >=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->raw_job->disk_fd >= 0"
), "../src/import/pull-raw.c", 333, __PRETTY_FUNCTION__); } while
(0)
;
334
335 if (lseek(i->raw_job->disk_fd, SEEK_SET0, 0) == (off_t) -1)
336 return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 336, __func__
, "Failed to seek to beginning of vendor image: %m") : -abs(_e
); })
;
337 }
338
339 p = strjoina(i->image_root, "/", i->local, ".raw")({ const char *_appendees_[] = { i->image_root, "/", i->
local, ".raw" }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_
; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _len_ += strlen
(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1);
for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr(
!__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
340
341 if (i->force_local)
342 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
343
344 r = tempfn_random(p, NULL((void*)0), &tp);
345 if (r < 0)
346 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/pull-raw.c"
, 346, __func__)
;
347
348 dfd = open(tp, O_WRONLY01|O_CREAT0100|O_EXCL0200|O_NOCTTY0400|O_CLOEXEC02000000, 0664);
349 if (dfd < 0)
350 return log_error_errno(errno, "Failed to create writable copy of image: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 350, __func__
, "Failed to create writable copy of image: %m") : -abs(_e); }
)
;
351
352 /* Turn off COW writing. This should greatly improve
353 * performance on COW file systems like btrfs, since it
354 * reduces fragmentation caused by not allowing in-place
355 * writes. */
356 r = chattr_fd(dfd, FS_NOCOW_FL0x00800000, FS_NOCOW_FL0x00800000);
357 if (r < 0)
358 log_warning_errno(r, "Failed to set file attributes on %s: %m", tp)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 358, __func__, "Failed to set file attributes on %s: %m"
, tp) : -abs(_e); })
;
359
360 r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, COPY_REFLINK);
361 if (r < 0) {
362 unlink(tp);
363 return log_error_errno(r, "Failed to make writable copy of image: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 363, __func__, "Failed to make writable copy of image: %m"
) : -abs(_e); })
;
364 }
365
366 (void) copy_times(i->raw_job->disk_fd, dfd);
367 (void) copy_xattr(i->raw_job->disk_fd, dfd);
368
369 dfd = safe_close(dfd);
Value stored to 'dfd' is never read
370
371 r = rename(tp, p);
372 if (r < 0) {
373 r = log_error_errno(errno, "Failed to move writable image into place: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 373, __func__
, "Failed to move writable image into place: %m") : -abs(_e);
})
;
374 unlink(tp);
375 return r;
376 }
377
378 log_info("Created new local image '%s'.", i->local)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 378, __func__, "Created new local image '%s'."
, i->local) : -abs(_e); })
;
379
380 if (i->roothash) {
381 r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path);
382 if (r < 0)
383 return r;
384 }
385
386 if (i->settings) {
387 r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
388 if (r < 0)
389 return r;
390 }
391
392 return 0;
393}
394
395static bool_Bool raw_pull_is_done(RawPull *i) {
396 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 396, __PRETTY_FUNCTION__
); } while (0)
;
397 assert(i->raw_job)do { if ((__builtin_expect(!!(!(i->raw_job)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i->raw_job"), "../src/import/pull-raw.c"
, 397, __PRETTY_FUNCTION__); } while (0)
;
398
399 if (!PULL_JOB_IS_COMPLETE(i->raw_job)(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){PULL_JOB_DONE, PULL_JOB_FAILED})/sizeof(
int)]; switch((i->raw_job)->state) { case PULL_JOB_DONE
: case PULL_JOB_FAILED: _found = 1; break; default: break; } _found
; }))
)
400 return false0;
401 if (i->roothash_job && !PULL_JOB_IS_COMPLETE(i->roothash_job)(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){PULL_JOB_DONE, PULL_JOB_FAILED})/sizeof(
int)]; switch((i->roothash_job)->state) { case PULL_JOB_DONE
: case PULL_JOB_FAILED: _found = 1; break; default: break; } _found
; }))
)
402 return false0;
403 if (i->settings_job && !PULL_JOB_IS_COMPLETE(i->settings_job)(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){PULL_JOB_DONE, PULL_JOB_FAILED})/sizeof(
int)]; switch((i->settings_job)->state) { case PULL_JOB_DONE
: case PULL_JOB_FAILED: _found = 1; break; default: break; } _found
; }))
)
404 return false0;
405 if (i->checksum_job && !PULL_JOB_IS_COMPLETE(i->checksum_job)(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){PULL_JOB_DONE, PULL_JOB_FAILED})/sizeof(
int)]; switch((i->checksum_job)->state) { case PULL_JOB_DONE
: case PULL_JOB_FAILED: _found = 1; break; default: break; } _found
; }))
)
406 return false0;
407 if (i->signature_job && !PULL_JOB_IS_COMPLETE(i->signature_job)(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){PULL_JOB_DONE, PULL_JOB_FAILED})/sizeof(
int)]; switch((i->signature_job)->state) { case PULL_JOB_DONE
: case PULL_JOB_FAILED: _found = 1; break; default: break; } _found
; }))
)
408 return false0;
409
410 return true1;
411}
412
413static int raw_pull_rename_auxiliary_file(
414 RawPull *i,
415 const char *suffix,
416 char **temp_path,
417 char **path) {
418
419 int r;
420
421 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 421, __PRETTY_FUNCTION__
); } while (0)
;
422 assert(temp_path)do { if ((__builtin_expect(!!(!(temp_path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("temp_path"), "../src/import/pull-raw.c"
, 422, __PRETTY_FUNCTION__); } while (0)
;
423 assert(suffix)do { if ((__builtin_expect(!!(!(suffix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("suffix"), "../src/import/pull-raw.c", 423
, __PRETTY_FUNCTION__); } while (0)
;
424 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/import/pull-raw.c", 424
, __PRETTY_FUNCTION__); } while (0)
;
425
426 /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and we should
427 * incorporate it in the file name if we can */
428 *path = mfree(*path);
429 r = raw_pull_determine_path(i, suffix, path);
430 if (r < 0)
431 return r;
432
433 r = import_make_read_only(*temp_path);
434 if (r < 0)
435 return r;
436
437 r = rename_noreplace(AT_FDCWD-100, *temp_path, AT_FDCWD-100, *path);
438 if (r < 0)
439 return log_error_errno(r, "Failed to rename file %s to %s: %m", *temp_path, *path)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 439, __func__, "Failed to rename file %s to %s: %m"
, *temp_path, *path) : -abs(_e); })
;
440
441 *temp_path = mfree(*temp_path);
442
443 return 1;
444}
445
446static void raw_pull_job_on_finished(PullJob *j) {
447 RawPull *i;
448 int r;
449
450 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 450, __PRETTY_FUNCTION__
); } while (0)
;
451 assert(j->userdata)do { if ((__builtin_expect(!!(!(j->userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j->userdata"), "../src/import/pull-raw.c"
, 451, __PRETTY_FUNCTION__); } while (0)
;
452
453 i = j->userdata;
454 if (j == i->roothash_job) {
455 if (j->error != 0)
456 log_info_errno(j->error, "Root hash file could not be retrieved, proceeding without.")({ int _level = ((6)), _e = ((j->error)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 456, __func__, "Root hash file could not be retrieved, proceeding without."
) : -abs(_e); })
;
457 } else if (j == i->settings_job) {
458 if (j->error != 0)
459 log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.")({ int _level = ((6)), _e = ((j->error)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 459, __func__, "Settings file could not be retrieved, proceeding without."
) : -abs(_e); })
;
460 } else if (j->error != 0 && j != i->signature_job) {
461 if (j == i->checksum_job)
462 log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)")({ int _level = ((3)), _e = ((j->error)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 462, __func__, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)"
) : -abs(_e); })
;
463 else
464 log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)")({ int _level = ((3)), _e = ((j->error)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 464, __func__, "Failed to retrieve image file. (Wrong URL?)"
) : -abs(_e); })
;
465
466 r = j->error;
467 goto finish;
468 }
469
470 /* This is invoked if either the download completed
471 * successfully, or the download was skipped because we
472 * already have the etag. In this case ->etag_exists is
473 * true.
474 *
475 * We only do something when we got all three files */
476
477 if (!raw_pull_is_done(i))
478 return;
479
480 if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
481 log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)")({ int _level = ((3)), _e = ((j->error)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 481, __func__, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)"
) : -abs(_e); })
;
482
483 r = i->signature_job->error;
484 goto finish;
485 }
486
487 if (i->roothash_job)
488 i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
489 if (i->settings_job)
490 i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
491
492 r = raw_pull_determine_path(i, ".raw", &i->final_path);
493 if (r < 0)
494 goto finish;
495
496 if (!i->raw_job->etag_exists) {
497 /* This is a new download, verify it, and move it into place */
498 assert(i->raw_job->disk_fd >= 0)do { if ((__builtin_expect(!!(!(i->raw_job->disk_fd >=
0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->raw_job->disk_fd >= 0"
), "../src/import/pull-raw.c", 498, __PRETTY_FUNCTION__); } while
(0)
;
499
500 raw_pull_report_progress(i, RAW_VERIFYING);
501
502 r = pull_verify(i->raw_job, i->roothash_job, i->settings_job, i->checksum_job, i->signature_job);
503 if (r < 0)
504 goto finish;
505
506 raw_pull_report_progress(i, RAW_UNPACKING);
507
508 r = raw_pull_maybe_convert_qcow2(i);
509 if (r < 0)
510 goto finish;
511
512 raw_pull_report_progress(i, RAW_FINALIZING);
513
514 r = import_make_read_only_fd(i->raw_job->disk_fd);
515 if (r < 0)
516 goto finish;
517
518 r = rename_noreplace(AT_FDCWD-100, i->temp_path, AT_FDCWD-100, i->final_path);
519 if (r < 0) {
520 log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 520, __func__, "Failed to rename raw file to %s: %m"
, i->final_path) : -abs(_e); })
;
521 goto finish;
522 }
523
524 i->temp_path = mfree(i->temp_path);
525
526 if (i->roothash_job &&
527 i->roothash_job->error == 0) {
528 r = raw_pull_rename_auxiliary_file(i, ".roothash", &i->roothash_temp_path, &i->roothash_path);
529 if (r < 0)
530 goto finish;
531 }
532
533 if (i->settings_job &&
534 i->settings_job->error == 0) {
535 r = raw_pull_rename_auxiliary_file(i, ".nspawn", &i->settings_temp_path, &i->settings_path);
536 if (r < 0)
537 goto finish;
538 }
539 }
540
541 raw_pull_report_progress(i, RAW_COPYING);
542
543 r = raw_pull_make_local_copy(i);
544 if (r < 0)
545 goto finish;
546
547 r = 0;
548
549finish:
550 if (i->on_finished)
551 i->on_finished(i, r, i->userdata);
552 else
553 sd_event_exit(i->event, r);
554}
555
556static int raw_pull_job_on_open_disk_generic(
557 RawPull *i,
558 PullJob *j,
559 const char *extra,
560 char **temp_path) {
561
562 int r;
563
564 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 564, __PRETTY_FUNCTION__
); } while (0)
;
565 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 565, __PRETTY_FUNCTION__
); } while (0)
;
566 assert(extra)do { if ((__builtin_expect(!!(!(extra)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("extra"), "../src/import/pull-raw.c", 566
, __PRETTY_FUNCTION__); } while (0)
;
567 assert(temp_path)do { if ((__builtin_expect(!!(!(temp_path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("temp_path"), "../src/import/pull-raw.c"
, 567, __PRETTY_FUNCTION__); } while (0)
;
568
569 if (!*temp_path) {
570 r = tempfn_random_child(i->image_root, extra, temp_path);
571 if (r < 0)
572 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/pull-raw.c"
, 572, __func__)
;
573 }
574
575 (void) mkdir_parents_label(*temp_path, 0700);
576
577 j->disk_fd = open(*temp_path, O_RDWR02|O_CREAT0100|O_EXCL0200|O_NOCTTY0400|O_CLOEXEC02000000, 0664);
578 if (j->disk_fd < 0)
579 return log_error_errno(errno, "Failed to create %s: %m", *temp_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/import/pull-raw.c", 579, __func__
, "Failed to create %s: %m", *temp_path) : -abs(_e); })
;
580
581 return 0;
582}
583
584static int raw_pull_job_on_open_disk_raw(PullJob *j) {
585 RawPull *i;
586 int r;
587
588 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 588, __PRETTY_FUNCTION__
); } while (0)
;
589 assert(j->userdata)do { if ((__builtin_expect(!!(!(j->userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j->userdata"), "../src/import/pull-raw.c"
, 589, __PRETTY_FUNCTION__); } while (0)
;
590
591 i = j->userdata;
592 assert(i->raw_job == j)do { if ((__builtin_expect(!!(!(i->raw_job == j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i->raw_job == j"), "../src/import/pull-raw.c"
, 592, __PRETTY_FUNCTION__); } while (0)
;
593
594 r = raw_pull_job_on_open_disk_generic(i, j, "raw", &i->temp_path);
595 if (r < 0)
596 return r;
597
598 r = chattr_fd(j->disk_fd, FS_NOCOW_FL0x00800000, FS_NOCOW_FL0x00800000);
599 if (r < 0)
600 log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/import/pull-raw.c", 600, __func__, "Failed to set file attributes on %s, ignoring: %m"
, i->temp_path) : -abs(_e); })
;
601
602 return 0;
603}
604
605static int raw_pull_job_on_open_disk_roothash(PullJob *j) {
606 RawPull *i;
607
608 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 608, __PRETTY_FUNCTION__
); } while (0)
;
609 assert(j->userdata)do { if ((__builtin_expect(!!(!(j->userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j->userdata"), "../src/import/pull-raw.c"
, 609, __PRETTY_FUNCTION__); } while (0)
;
610
611 i = j->userdata;
612 assert(i->roothash_job == j)do { if ((__builtin_expect(!!(!(i->roothash_job == j)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->roothash_job == j"
), "../src/import/pull-raw.c", 612, __PRETTY_FUNCTION__); } while
(0)
;
613
614 return raw_pull_job_on_open_disk_generic(i, j, "roothash", &i->roothash_temp_path);
615}
616
617static int raw_pull_job_on_open_disk_settings(PullJob *j) {
618 RawPull *i;
619
620 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 620, __PRETTY_FUNCTION__
); } while (0)
;
621 assert(j->userdata)do { if ((__builtin_expect(!!(!(j->userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j->userdata"), "../src/import/pull-raw.c"
, 621, __PRETTY_FUNCTION__); } while (0)
;
622
623 i = j->userdata;
624 assert(i->settings_job == j)do { if ((__builtin_expect(!!(!(i->settings_job == j)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->settings_job == j"
), "../src/import/pull-raw.c", 624, __PRETTY_FUNCTION__); } while
(0)
;
625
626 return raw_pull_job_on_open_disk_generic(i, j, "settings", &i->settings_temp_path);
627}
628
629static void raw_pull_job_on_progress(PullJob *j) {
630 RawPull *i;
631
632 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/import/pull-raw.c", 632, __PRETTY_FUNCTION__
); } while (0)
;
633 assert(j->userdata)do { if ((__builtin_expect(!!(!(j->userdata)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j->userdata"), "../src/import/pull-raw.c"
, 633, __PRETTY_FUNCTION__); } while (0)
;
634
635 i = j->userdata;
636
637 raw_pull_report_progress(i, RAW_DOWNLOADING);
638}
639
640int raw_pull_start(
641 RawPull *i,
642 const char *url,
643 const char *local,
644 bool_Bool force_local,
645 ImportVerify verify,
646 bool_Bool settings,
647 bool_Bool roothash) {
648
649 int r;
650
651 assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("i"), "../src/import/pull-raw.c", 651, __PRETTY_FUNCTION__
); } while (0)
;
652 assert(verify < _IMPORT_VERIFY_MAX)do { if ((__builtin_expect(!!(!(verify < _IMPORT_VERIFY_MAX
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("verify < _IMPORT_VERIFY_MAX"
), "../src/import/pull-raw.c", 652, __PRETTY_FUNCTION__); } while
(0)
;
653 assert(verify >= 0)do { if ((__builtin_expect(!!(!(verify >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("verify >= 0"), "../src/import/pull-raw.c"
, 653, __PRETTY_FUNCTION__); } while (0)
;
654
655 if (!http_url_is_valid(url))
656 return -EINVAL22;
657
658 if (local && !machine_name_is_valid(local)hostname_is_valid(local, 0))
659 return -EINVAL22;
660
661 if (i->raw_job)
662 return -EBUSY16;
663
664 r = free_and_strdup(&i->local, local);
665 if (r < 0)
666 return r;
667
668 i->force_local = force_local;
669 i->verify = verify;
670 i->settings = settings;
671 i->roothash = roothash;
672
673 /* Queue job for the image itself */
674 r = pull_job_new(&i->raw_job, url, i->glue, i);
675 if (r < 0)
676 return r;
677
678 i->raw_job->on_finished = raw_pull_job_on_finished;
679 i->raw_job->on_open_disk = raw_pull_job_on_open_disk_raw;
680 i->raw_job->on_progress = raw_pull_job_on_progress;
681 i->raw_job->calc_checksum = verify != IMPORT_VERIFY_NO;
682 i->raw_job->grow_machine_directory = i->grow_machine_directory;
683
684 r = pull_find_old_etags(url, i->image_root, DT_REGDT_REG, ".raw-", ".raw", &i->raw_job->old_etags);
685 if (r < 0)
686 return r;
687
688 if (roothash) {
689 r = pull_make_auxiliary_job(&i->roothash_job, url, raw_strip_suffixes, ".roothash", i->glue, raw_pull_job_on_finished, i);
690 if (r < 0)
691 return r;
692
693 i->roothash_job->on_open_disk = raw_pull_job_on_open_disk_roothash;
694 i->roothash_job->on_progress = raw_pull_job_on_progress;
695 i->roothash_job->calc_checksum = verify != IMPORT_VERIFY_NO;
696 }
697
698 if (settings) {
699 r = pull_make_auxiliary_job(&i->settings_job, url, raw_strip_suffixes, ".nspawn", i->glue, raw_pull_job_on_finished, i);
700 if (r < 0)
701 return r;
702
703 i->settings_job->on_open_disk = raw_pull_job_on_open_disk_settings;
704 i->settings_job->on_progress = raw_pull_job_on_progress;
705 i->settings_job->calc_checksum = verify != IMPORT_VERIFY_NO;
706 }
707
708 r = pull_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, raw_pull_job_on_finished, i);
709 if (r < 0)
710 return r;
711
712 r = pull_job_begin(i->raw_job);
713 if (r < 0)
714 return r;
715
716 if (i->roothash_job) {
717 r = pull_job_begin(i->roothash_job);
718 if (r < 0)
719 return r;
720 }
721
722 if (i->settings_job) {
723 r = pull_job_begin(i->settings_job);
724 if (r < 0)
725 return r;
726 }
727
728 if (i->checksum_job) {
729 i->checksum_job->on_progress = raw_pull_job_on_progress;
730 i->checksum_job->style = VERIFICATION_PER_FILE;
731
732 r = pull_job_begin(i->checksum_job);
733 if (r < 0)
734 return r;
735 }
736
737 if (i->signature_job) {
738 i->signature_job->on_progress = raw_pull_job_on_progress;
739
740 r = pull_job_begin(i->signature_job);
741 if (r < 0)
742 return r;
743 }
744
745 return 0;
746}