File: | build-scan/../src/import/import-raw.c |
Warning: | line 114, 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 <linux1/fs.h> | |||
4 | ||||
5 | #include "sd-daemon.h" | |||
6 | #include "sd-event.h" | |||
7 | ||||
8 | #include "alloc-util.h" | |||
9 | #include "btrfs-util.h" | |||
10 | #include "chattr-util.h" | |||
11 | #include "copy.h" | |||
12 | #include "fd-util.h" | |||
13 | #include "fileio.h" | |||
14 | #include "fs-util.h" | |||
15 | #include "hostname-util.h" | |||
16 | #include "import-common.h" | |||
17 | #include "import-compress.h" | |||
18 | #include "import-raw.h" | |||
19 | #include "io-util.h" | |||
20 | #include "machine-pool.h" | |||
21 | #include "mkdir.h" | |||
22 | #include "path-util.h" | |||
23 | #include "qcow2-util.h" | |||
24 | #include "ratelimit.h" | |||
25 | #include "rm-rf.h" | |||
26 | #include "string-util.h" | |||
27 | #include "util.h" | |||
28 | ||||
29 | struct RawImport { | |||
30 | sd_event *event; | |||
31 | ||||
32 | char *image_root; | |||
33 | ||||
34 | RawImportFinished on_finished; | |||
35 | void *userdata; | |||
36 | ||||
37 | char *local; | |||
38 | bool_Bool force_local; | |||
39 | bool_Bool read_only; | |||
40 | bool_Bool grow_machine_directory; | |||
41 | ||||
42 | char *temp_path; | |||
43 | char *final_path; | |||
44 | ||||
45 | int input_fd; | |||
46 | int output_fd; | |||
47 | ||||
48 | ImportCompress compress; | |||
49 | ||||
50 | uint64_t written_since_last_grow; | |||
51 | ||||
52 | sd_event_source *input_event_source; | |||
53 | ||||
54 | uint8_t buffer[16*1024]; | |||
55 | size_t buffer_size; | |||
56 | ||||
57 | uint64_t written_compressed; | |||
58 | uint64_t written_uncompressed; | |||
59 | ||||
60 | struct stat st; | |||
61 | ||||
62 | unsigned last_percent; | |||
63 | RateLimit progress_rate_limit; | |||
64 | }; | |||
65 | ||||
66 | RawImport* raw_import_unref(RawImport *i) { | |||
67 | if (!i) | |||
68 | return NULL((void*)0); | |||
69 | ||||
70 | sd_event_unref(i->event); | |||
71 | ||||
72 | if (i->temp_path) { | |||
73 | (void) unlink(i->temp_path); | |||
74 | free(i->temp_path); | |||
75 | } | |||
76 | ||||
77 | import_compress_free(&i->compress); | |||
78 | ||||
79 | sd_event_source_unref(i->input_event_source); | |||
80 | ||||
81 | safe_close(i->output_fd); | |||
82 | ||||
83 | free(i->final_path); | |||
84 | free(i->image_root); | |||
85 | free(i->local); | |||
86 | return mfree(i); | |||
87 | } | |||
88 | ||||
89 | int raw_import_new( | |||
90 | RawImport **ret, | |||
91 | sd_event *event, | |||
92 | const char *image_root, | |||
93 | RawImportFinished on_finished, | |||
94 | void *userdata) { | |||
95 | ||||
96 | _cleanup_(raw_import_unrefp)__attribute__((cleanup(raw_import_unrefp))) RawImport *i = NULL((void*)0); | |||
97 | int r; | |||
98 | ||||
99 | assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ret"), "../src/import/import-raw.c", 99 , __PRETTY_FUNCTION__); } while (0); | |||
| ||||
100 | ||||
101 | i = new0(RawImport, 1)((RawImport*) calloc((1), sizeof(RawImport))); | |||
102 | if (!i) | |||
103 | return -ENOMEM12; | |||
104 | ||||
105 | i->input_fd = i->output_fd = -1; | |||
106 | i->on_finished = on_finished; | |||
107 | i->userdata = userdata; | |||
108 | ||||
109 | RATELIMIT_INIT(i->progress_rate_limit, 100 * USEC_PER_MSEC, 1)do { RateLimit *_r = &(i->progress_rate_limit); _r-> interval = (100 * ((usec_t) 1000ULL)); _r->burst = (1); _r ->num = 0; _r->begin = 0; } while (0); | |||
110 | i->last_percent = (unsigned) -1; | |||
111 | ||||
112 | i->image_root = strdup(image_root ?: "/var/lib/machines"); | |||
113 | if (!i->image_root) | |||
114 | return -ENOMEM12; | |||
| ||||
115 | ||||
116 | i->grow_machine_directory = path_startswith(i->image_root, "/var/lib/machines"); | |||
117 | ||||
118 | if (event) | |||
119 | i->event = sd_event_ref(event); | |||
120 | else { | |||
121 | r = sd_event_default(&i->event); | |||
122 | if (r < 0) | |||
123 | return r; | |||
124 | } | |||
125 | ||||
126 | *ret = TAKE_PTR(i)({ typeof(i) _ptr_ = (i); (i) = ((void*)0); _ptr_; }); | |||
127 | ||||
128 | return 0; | |||
129 | } | |||
130 | ||||
131 | static void raw_import_report_progress(RawImport *i) { | |||
132 | unsigned percent; | |||
133 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 133, __PRETTY_FUNCTION__); } while (0); | |||
134 | ||||
135 | /* We have no size information, unless the source is a regular file */ | |||
136 | if (!S_ISREG(i->st.st_mode)((((i->st.st_mode)) & 0170000) == (0100000))) | |||
137 | return; | |||
138 | ||||
139 | if (i->written_compressed >= (uint64_t) i->st.st_size) | |||
140 | percent = 100; | |||
141 | else | |||
142 | percent = (unsigned) ((i->written_compressed * UINT64_C(100)100UL) / (uint64_t) i->st.st_size); | |||
143 | ||||
144 | if (percent == i->last_percent) | |||
145 | return; | |||
146 | ||||
147 | if (!ratelimit_below(&i->progress_rate_limit)) | |||
148 | return; | |||
149 | ||||
150 | sd_notifyf(false0, "X_IMPORT_PROGRESS=%u", percent); | |||
151 | log_info("Imported %u%%.", percent)({ 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/import-raw.c", 151, __func__, "Imported %u%%." , percent) : -abs(_e); }); | |||
152 | ||||
153 | i->last_percent = percent; | |||
154 | } | |||
155 | ||||
156 | static int raw_import_maybe_convert_qcow2(RawImport *i) { | |||
157 | _cleanup_close___attribute__((cleanup(closep))) int converted_fd = -1; | |||
158 | _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0); | |||
159 | int r; | |||
160 | ||||
161 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 161, __PRETTY_FUNCTION__); } while (0); | |||
162 | ||||
163 | r = qcow2_detect(i->output_fd); | |||
164 | if (r < 0) | |||
165 | 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/import-raw.c", 165, __func__, "Failed to detect whether this is a QCOW2 image: %m" ) : -abs(_e); }); | |||
166 | if (r == 0) | |||
167 | return 0; | |||
168 | ||||
169 | /* This is a QCOW2 image, let's convert it */ | |||
170 | r = tempfn_random(i->final_path, NULL((void*)0), &t); | |||
171 | if (r < 0) | |||
172 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/import-raw.c" , 172, __func__); | |||
173 | ||||
174 | converted_fd = open(t, O_RDWR02|O_CREAT0100|O_EXCL0200|O_NOCTTY0400|O_CLOEXEC02000000, 0664); | |||
175 | if (converted_fd < 0) | |||
176 | 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/import-raw.c", 176, __func__ , "Failed to create %s: %m", t) : -abs(_e); }); | |||
177 | ||||
178 | r = chattr_fd(converted_fd, FS_NOCOW_FL0x00800000, FS_NOCOW_FL0x00800000); | |||
179 | if (r < 0) | |||
180 | 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/import-raw.c", 180, __func__, "Failed to set file attributes on %s: %m" , t) : -abs(_e); }); | |||
181 | ||||
182 | 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/import-raw.c", 182, __func__, "Unpacking QCOW2 file." ) : -abs(_e); }); | |||
183 | ||||
184 | r = qcow2_convert(i->output_fd, converted_fd); | |||
185 | if (r < 0) { | |||
186 | unlink(t); | |||
187 | 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/import-raw.c", 187, __func__, "Failed to convert qcow2 image: %m" ) : -abs(_e); }); | |||
188 | } | |||
189 | ||||
190 | (void) unlink(i->temp_path); | |||
191 | free_and_replace(i->temp_path, t)({ free(i->temp_path); (i->temp_path) = (t); (t) = ((void *)0); 0; }); | |||
192 | ||||
193 | safe_close(i->output_fd); | |||
194 | i->output_fd = TAKE_FD(converted_fd)({ int _fd_ = (converted_fd); (converted_fd) = -1; _fd_; }); | |||
195 | ||||
196 | return 1; | |||
197 | } | |||
198 | ||||
199 | static int raw_import_finish(RawImport *i) { | |||
200 | int r; | |||
201 | ||||
202 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 202, __PRETTY_FUNCTION__); } while (0); | |||
203 | assert(i->output_fd >= 0)do { if ((__builtin_expect(!!(!(i->output_fd >= 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->output_fd >= 0" ), "../src/import/import-raw.c", 203, __PRETTY_FUNCTION__); } while (0); | |||
204 | assert(i->temp_path)do { if ((__builtin_expect(!!(!(i->temp_path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i->temp_path"), "../src/import/import-raw.c" , 204, __PRETTY_FUNCTION__); } while (0); | |||
205 | assert(i->final_path)do { if ((__builtin_expect(!!(!(i->final_path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i->final_path"), "../src/import/import-raw.c" , 205, __PRETTY_FUNCTION__); } while (0); | |||
206 | ||||
207 | /* In case this was a sparse file, make sure the file system is right */ | |||
208 | if (i->written_uncompressed > 0) { | |||
209 | if (ftruncate(i->output_fd, i->written_uncompressed) < 0) | |||
210 | return log_error_errno(errno, "Failed to truncate file: %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/import-raw.c", 210, __func__ , "Failed to truncate file: %m") : -abs(_e); }); | |||
211 | } | |||
212 | ||||
213 | r = raw_import_maybe_convert_qcow2(i); | |||
214 | if (r < 0) | |||
215 | return r; | |||
216 | ||||
217 | if (S_ISREG(i->st.st_mode)((((i->st.st_mode)) & 0170000) == (0100000))) { | |||
218 | (void) copy_times(i->input_fd, i->output_fd); | |||
219 | (void) copy_xattr(i->input_fd, i->output_fd); | |||
220 | } | |||
221 | ||||
222 | if (i->read_only) { | |||
223 | r = import_make_read_only_fd(i->output_fd); | |||
224 | if (r < 0) | |||
225 | return r; | |||
226 | } | |||
227 | ||||
228 | if (i->force_local) | |||
229 | (void) rm_rf(i->final_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME); | |||
230 | ||||
231 | r = rename_noreplace(AT_FDCWD-100, i->temp_path, AT_FDCWD-100, i->final_path); | |||
232 | if (r < 0) | |||
233 | return log_error_errno(r, "Failed to move image into place: %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/import-raw.c", 233, __func__, "Failed to move image into place: %m" ) : -abs(_e); }); | |||
234 | ||||
235 | i->temp_path = mfree(i->temp_path); | |||
236 | ||||
237 | return 0; | |||
238 | } | |||
239 | ||||
240 | static int raw_import_open_disk(RawImport *i) { | |||
241 | int r; | |||
242 | ||||
243 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 243, __PRETTY_FUNCTION__); } while (0); | |||
244 | ||||
245 | assert(!i->final_path)do { if ((__builtin_expect(!!(!(!i->final_path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("!i->final_path"), "../src/import/import-raw.c" , 245, __PRETTY_FUNCTION__); } while (0); | |||
246 | assert(!i->temp_path)do { if ((__builtin_expect(!!(!(!i->temp_path)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("!i->temp_path"), "../src/import/import-raw.c" , 246, __PRETTY_FUNCTION__); } while (0); | |||
247 | assert(i->output_fd < 0)do { if ((__builtin_expect(!!(!(i->output_fd < 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->output_fd < 0" ), "../src/import/import-raw.c", 247, __PRETTY_FUNCTION__); } while (0); | |||
248 | ||||
249 | i->final_path = strjoin(i->image_root, "/", i->local, ".raw")strjoin_real((i->image_root), "/", i->local, ".raw", (( void*)0)); | |||
250 | if (!i->final_path) | |||
251 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/import-raw.c" , 251, __func__); | |||
252 | ||||
253 | r = tempfn_random(i->final_path, NULL((void*)0), &i->temp_path); | |||
254 | if (r < 0) | |||
255 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/import/import-raw.c" , 255, __func__); | |||
256 | ||||
257 | (void) mkdir_parents_label(i->temp_path, 0700); | |||
258 | ||||
259 | i->output_fd = open(i->temp_path, O_RDWR02|O_CREAT0100|O_EXCL0200|O_NOCTTY0400|O_CLOEXEC02000000, 0664); | |||
260 | if (i->output_fd < 0) | |||
261 | return log_error_errno(errno, "Failed to open destination %s: %m", i->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/import-raw.c", 261, __func__ , "Failed to open destination %s: %m", i->temp_path) : -abs (_e); }); | |||
262 | ||||
263 | r = chattr_fd(i->output_fd, FS_NOCOW_FL0x00800000, FS_NOCOW_FL0x00800000); | |||
264 | if (r < 0) | |||
265 | log_warning_errno(r, "Failed to set file attributes on %s: %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/import-raw.c", 265, __func__, "Failed to set file attributes on %s: %m" , i->temp_path) : -abs(_e); }); | |||
266 | ||||
267 | return 0; | |||
268 | } | |||
269 | ||||
270 | static int raw_import_try_reflink(RawImport *i) { | |||
271 | off_t p; | |||
272 | int r; | |||
273 | ||||
274 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 274, __PRETTY_FUNCTION__); } while (0); | |||
275 | assert(i->input_fd >= 0)do { if ((__builtin_expect(!!(!(i->input_fd >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->input_fd >= 0" ), "../src/import/import-raw.c", 275, __PRETTY_FUNCTION__); } while (0); | |||
276 | assert(i->output_fd >= 0)do { if ((__builtin_expect(!!(!(i->output_fd >= 0)),0)) ) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("i->output_fd >= 0" ), "../src/import/import-raw.c", 276, __PRETTY_FUNCTION__); } while (0); | |||
277 | ||||
278 | if (i->compress.type != IMPORT_COMPRESS_UNCOMPRESSED) | |||
279 | return 0; | |||
280 | ||||
281 | if (!S_ISREG(i->st.st_mode)((((i->st.st_mode)) & 0170000) == (0100000))) | |||
282 | return 0; | |||
283 | ||||
284 | p = lseek(i->input_fd, 0, SEEK_CUR1); | |||
285 | if (p == (off_t) -1) | |||
286 | return log_error_errno(errno, "Failed to read file offset of input file: %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/import-raw.c", 286, __func__ , "Failed to read file offset of input file: %m") : -abs(_e); }); | |||
287 | ||||
288 | /* Let's only try a btrfs reflink, if we are reading from the beginning of the file */ | |||
289 | if ((uint64_t) p != (uint64_t) i->buffer_size) | |||
290 | return 0; | |||
291 | ||||
292 | r = btrfs_reflink(i->input_fd, i->output_fd); | |||
293 | if (r >= 0) | |||
294 | return 1; | |||
295 | ||||
296 | return 0; | |||
297 | } | |||
298 | ||||
299 | static int raw_import_write(const void *p, size_t sz, void *userdata) { | |||
300 | RawImport *i = userdata; | |||
301 | ssize_t n; | |||
302 | ||||
303 | if (i->grow_machine_directory && i->written_since_last_grow >= GROW_INTERVAL_BYTES(10UL * 1024UL * 1024UL)) { | |||
304 | i->written_since_last_grow = 0; | |||
305 | grow_machine_directory(); | |||
306 | } | |||
307 | ||||
308 | n = sparse_write(i->output_fd, p, sz, 64); | |||
309 | if (n < 0) | |||
310 | return -errno(*__errno_location ()); | |||
311 | if ((size_t) n < sz) | |||
312 | return -EIO5; | |||
313 | ||||
314 | i->written_uncompressed += sz; | |||
315 | i->written_since_last_grow += sz; | |||
316 | ||||
317 | return 0; | |||
318 | } | |||
319 | ||||
320 | static int raw_import_process(RawImport *i) { | |||
321 | ssize_t l; | |||
322 | int r; | |||
323 | ||||
324 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 324, __PRETTY_FUNCTION__); } while (0); | |||
325 | assert(i->buffer_size < sizeof(i->buffer))do { if ((__builtin_expect(!!(!(i->buffer_size < sizeof (i->buffer))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("i->buffer_size < sizeof(i->buffer)"), "../src/import/import-raw.c" , 325, __PRETTY_FUNCTION__); } while (0); | |||
326 | ||||
327 | l = read(i->input_fd, i->buffer + i->buffer_size, sizeof(i->buffer) - i->buffer_size); | |||
328 | if (l < 0) { | |||
329 | if (errno(*__errno_location ()) == EAGAIN11) | |||
330 | return 0; | |||
331 | ||||
332 | r = log_error_errno(errno, "Failed to read input file: %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/import-raw.c", 332, __func__ , "Failed to read input file: %m") : -abs(_e); }); | |||
333 | goto finish; | |||
334 | } | |||
335 | if (l == 0) { | |||
336 | if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { | |||
337 | log_error("Premature end of file.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/import/import-raw.c", 337, __func__, "Premature end of file." ) : -abs(_e); }); | |||
338 | r = -EIO5; | |||
339 | goto finish; | |||
340 | } | |||
341 | ||||
342 | r = raw_import_finish(i); | |||
343 | goto finish; | |||
344 | } | |||
345 | ||||
346 | i->buffer_size += l; | |||
347 | ||||
348 | if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) { | |||
349 | r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size); | |||
350 | if (r < 0) { | |||
351 | log_error_errno(r, "Failed to detect file compression: %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/import-raw.c", 351, __func__, "Failed to detect file compression: %m" ) : -abs(_e); }); | |||
352 | goto finish; | |||
353 | } | |||
354 | if (r == 0) /* Need more data */ | |||
355 | return 0; | |||
356 | ||||
357 | r = raw_import_open_disk(i); | |||
358 | if (r < 0) | |||
359 | goto finish; | |||
360 | ||||
361 | r = raw_import_try_reflink(i); | |||
362 | if (r < 0) | |||
363 | goto finish; | |||
364 | if (r > 0) { | |||
365 | r = raw_import_finish(i); | |||
366 | goto finish; | |||
367 | } | |||
368 | } | |||
369 | ||||
370 | r = import_uncompress(&i->compress, i->buffer, i->buffer_size, raw_import_write, i); | |||
371 | if (r < 0) { | |||
372 | log_error_errno(r, "Failed to decode and write: %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/import-raw.c", 372, __func__, "Failed to decode and write: %m" ) : -abs(_e); }); | |||
373 | goto finish; | |||
374 | } | |||
375 | ||||
376 | i->written_compressed += i->buffer_size; | |||
377 | i->buffer_size = 0; | |||
378 | ||||
379 | raw_import_report_progress(i); | |||
380 | ||||
381 | return 0; | |||
382 | ||||
383 | finish: | |||
384 | if (i->on_finished) | |||
385 | i->on_finished(i, r, i->userdata); | |||
386 | else | |||
387 | sd_event_exit(i->event, r); | |||
388 | ||||
389 | return 0; | |||
390 | } | |||
391 | ||||
392 | static int raw_import_on_input(sd_event_source *s, int fd, uint32_t revents, void *userdata) { | |||
393 | RawImport *i = userdata; | |||
394 | ||||
395 | return raw_import_process(i); | |||
396 | } | |||
397 | ||||
398 | static int raw_import_on_defer(sd_event_source *s, void *userdata) { | |||
399 | RawImport *i = userdata; | |||
400 | ||||
401 | return raw_import_process(i); | |||
402 | } | |||
403 | ||||
404 | int raw_import_start(RawImport *i, int fd, const char *local, bool_Bool force_local, bool_Bool read_only) { | |||
405 | int r; | |||
406 | ||||
407 | assert(i)do { if ((__builtin_expect(!!(!(i)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("i"), "../src/import/import-raw.c", 407, __PRETTY_FUNCTION__); } while (0); | |||
408 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/import/import-raw.c" , 408, __PRETTY_FUNCTION__); } while (0); | |||
409 | assert(local)do { if ((__builtin_expect(!!(!(local)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("local"), "../src/import/import-raw.c", 409 , __PRETTY_FUNCTION__); } while (0); | |||
410 | ||||
411 | if (!machine_name_is_valid(local)hostname_is_valid(local, 0)) | |||
412 | return -EINVAL22; | |||
413 | ||||
414 | if (i->input_fd >= 0) | |||
415 | return -EBUSY16; | |||
416 | ||||
417 | r = fd_nonblock(fd, true1); | |||
418 | if (r < 0) | |||
419 | return r; | |||
420 | ||||
421 | r = free_and_strdup(&i->local, local); | |||
422 | if (r < 0) | |||
423 | return r; | |||
424 | i->force_local = force_local; | |||
425 | i->read_only = read_only; | |||
426 | ||||
427 | if (fstat(fd, &i->st) < 0) | |||
428 | return -errno(*__errno_location ()); | |||
429 | ||||
430 | r = sd_event_add_io(i->event, &i->input_event_source, fd, EPOLLINEPOLLIN, raw_import_on_input, i); | |||
431 | if (r == -EPERM1) { | |||
432 | /* This fd does not support epoll, for example because it is a regular file. Busy read in that case */ | |||
433 | r = sd_event_add_defer(i->event, &i->input_event_source, raw_import_on_defer, i); | |||
434 | if (r < 0) | |||
435 | return r; | |||
436 | ||||
437 | r = sd_event_source_set_enabled(i->input_event_source, SD_EVENT_ON); | |||
438 | } | |||
439 | if (r < 0) | |||
440 | return r; | |||
441 | ||||
442 | i->input_fd = fd; | |||
443 | return r; | |||
444 | } |