| 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 | } |