File: | build-scan/../src/import/pull-raw.c |
Warning: | line 132, column 25 Potential leak of memory pointed to by 'i' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
34 | typedef enum RawProgress { | |||
35 | RAW_DOWNLOADING, | |||
36 | RAW_VERIFYING, | |||
37 | RAW_UNPACKING, | |||
38 | RAW_FINALIZING, | |||
39 | RAW_COPYING, | |||
40 | } RawProgress; | |||
41 | ||||
42 | struct 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 | ||||
75 | RawPull* 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 | ||||
111 | int 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 | ||||
156 | static 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 | ||||
217 | static 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 | ||||
261 | static 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 | ||||
279 | static 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 | ||||
310 | static 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); | |||
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 | ||||
395 | static 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 | ||||
413 | static 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 | ||||
446 | static 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 | ||||
549 | finish: | |||
550 | if (i->on_finished) | |||
551 | i->on_finished(i, r, i->userdata); | |||
552 | else | |||
553 | sd_event_exit(i->event, r); | |||
554 | } | |||
555 | ||||
556 | static 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 | ||||
584 | static 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 | ||||
605 | static 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 | ||||
617 | static 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 | ||||
629 | static 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 | ||||
640 | int 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 | } |