From 137c6c6b36597f687ebdaf5c5321ef33d54f4ebe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 Jan 2020 21:10:31 +0100 Subject: [PATCH 1/3] import: don't complain if FS_NOCOW_FL is not available Let's downgrade the log message to LOG_DEBUG if triggered by an fs that doesn't support the flag. --- src/import/import-raw.c | 10 ++-------- src/import/pull-raw.c | 20 +++++--------------- src/shared/import-util.c | 14 ++++++++++++++ src/shared/import-util.h | 2 ++ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/import/import-raw.c b/src/import/import-raw.c index a12a6d63b1..0606cf5406 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -7,7 +7,6 @@ #include "alloc-util.h" #include "btrfs-util.h" -#include "chattr-util.h" #include "copy.h" #include "fd-util.h" #include "fs-util.h" @@ -174,9 +173,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) { if (converted_fd < 0) return log_error_errno(errno, "Failed to create %s: %m", t); - r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to set file attributes on %s: %m", t); + (void) import_set_nocow_and_log(converted_fd, t); log_info("Unpacking QCOW2 file."); @@ -259,10 +256,7 @@ static int raw_import_open_disk(RawImport *i) { if (i->output_fd < 0) return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path); - r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path); - + (void) import_set_nocow_and_log(i->output_fd, i->temp_path); return 0; } diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c index 4f76421bc7..51c12444e0 100644 --- a/src/import/pull-raw.c +++ b/src/import/pull-raw.c @@ -8,7 +8,6 @@ #include "alloc-util.h" #include "btrfs-util.h" -#include "chattr-util.h" #include "copy.h" #include "curl-util.h" #include "fd-util.h" @@ -242,9 +241,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) { if (converted_fd < 0) return log_error_errno(errno, "Failed to create %s: %m", t); - r = chattr_fd(converted_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to set file attributes on %s: %m", t); + (void) import_set_nocow_and_log(converted_fd, t); log_info("Unpacking QCOW2 file."); @@ -354,13 +351,9 @@ static int raw_pull_make_local_copy(RawPull *i) { if (dfd < 0) return log_error_errno(errno, "Failed to create writable copy of image: %m"); - /* Turn off COW writing. This should greatly improve - * performance on COW file systems like btrfs, since it - * reduces fragmentation caused by not allowing in-place - * writes. */ - r = chattr_fd(dfd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to set file attributes on %s: %m", tp); + /* Turn off COW writing. This should greatly improve performance on COW file systems like btrfs, + * since it reduces fragmentation caused by not allowing in-place writes. */ + (void) import_set_nocow_and_log(dfd, tp); r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, COPY_REFLINK); if (r < 0) { @@ -600,10 +593,7 @@ static int raw_pull_job_on_open_disk_raw(PullJob *j) { if (r < 0) return r; - r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); - if (r < 0) - log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", i->temp_path); - + (void) import_set_nocow_and_log(j->disk_fd, i->temp_path); return 0; } diff --git a/src/shared/import-util.c b/src/shared/import-util.c index f7770e7df5..0a57c08990 100644 --- a/src/shared/import-util.c +++ b/src/shared/import-util.c @@ -4,6 +4,8 @@ #include "alloc-util.h" #include "btrfs-util.h" +#include "chattr-util.h" +#include "errno-util.h" #include "import-util.h" #include "log.h" #include "macro.h" @@ -163,3 +165,15 @@ int import_assign_pool_quota_and_warn(const char *path) { return 0; } + +int import_set_nocow_and_log(int fd, const char *path) { + int r; + + r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); + if (r < 0) + return log_full_errno( + ERRNO_IS_NOT_SUPPORTED(r) ? LOG_DEBUG : LOG_WARNING, + r, "Failed to set file attributes on %s: %m", path); + + return 0; +} diff --git a/src/shared/import-util.h b/src/shared/import-util.h index 0f2a5170c8..d85aa565cc 100644 --- a/src/shared/import-util.h +++ b/src/shared/import-util.h @@ -23,3 +23,5 @@ int tar_strip_suffixes(const char *name, char **ret); int raw_strip_suffixes(const char *name, char **ret); int import_assign_pool_quota_and_warn(const char *path); + +int import_set_nocow_and_log(int fd, const char *path); From d076f9fd56c9791457c2a2ea6603c1fe94966593 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 Jan 2020 22:02:14 +0100 Subject: [PATCH 2/3] import: put a time-out on downloads Let's abort downloads when they are stuck by setting a download speed threshold (as suggested in the CURL docs) Fixes: #14215 --- src/import/curl-util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/import/curl-util.c b/src/import/curl-util.c index 96cf696652..eea5ca395f 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -247,6 +247,12 @@ int curl_glue_make(CURL **ret, const char *url, void *userdata) { if (curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK) return -EIO; + if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_TIME, 60L) != CURLE_OK) + return -EIO; + + if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_LIMIT, 30L) != CURLE_OK) + return -EIO; + *ret = TAKE_PTR(c); return 0; } From f85df81817279c0804a3b1bf135b579272731c9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 20 Jan 2020 22:05:53 +0100 Subject: [PATCH 3/3] import: let's disable UNIX signal generation from curl --- src/import/curl-util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/import/curl-util.c b/src/import/curl-util.c index eea5ca395f..5f21033db5 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -247,6 +247,9 @@ int curl_glue_make(CURL **ret, const char *url, void *userdata) { if (curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK) return -EIO; + if (curl_easy_setopt(c, CURLOPT_NOSIGNAL, 1L) != CURLE_OK) + return -EIO; + if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_TIME, 60L) != CURLE_OK) return -EIO;