X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fimport%2Fimport-gpt.c;h=d304a399fb86c2845aae74e5387351e6a63c7f72;hp=e1c493bbe3b18cf1704f28e93c29c80edb12cd8f;hb=dfd1520d3ab98cfa376f2d84ed1e7887d013720d;hpb=8620a9a32391fd74d70ddc07c9b79729ad4ec067;ds=sidebyside diff --git a/src/import/import-gpt.c b/src/import/import-gpt.c index e1c493bbe..d304a399f 100644 --- a/src/import/import-gpt.c +++ b/src/import/import-gpt.c @@ -20,6 +20,7 @@ ***/ #include +#include #include #include "hashmap.h" @@ -60,6 +61,7 @@ struct GptImport { sd_event *event; CurlGlue *glue; + char *image_root; Hashmap *files; gpt_import_on_finished on_finished; @@ -129,9 +131,9 @@ static int gpt_import_file_make_final_path(GptImportFile *f) { if (!escaped_etag) return -ENOMEM; - f->final_path = strjoin("/var/lib/container/.gpt-", escaped_url, ".", escaped_etag, ".gpt", NULL); + f->final_path = strjoin(f->import->image_root, "/.gpt-", escaped_url, ".", escaped_etag, ".gpt", NULL); } else - f->final_path = strjoin("/var/lib/container/.gpt-", escaped_url, ".gpt", NULL); + f->final_path = strjoin(f->import->image_root, "/.gpt-", escaped_url, ".gpt", NULL); if (!f->final_path) return -ENOMEM; @@ -164,12 +166,12 @@ static void gpt_import_file_success(GptImportFile *f) { f->disk_fd = open(f->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC); if (f->disk_fd < 0) { - r = log_error_errno(errno, "Failed top open vendor image: %m"); + r = log_error_errno(errno, "Failed to open vendor image: %m"); goto finish; } } - p = strappenda("/var/lib/container/", f->local, ".gpt"); + p = strappenda(f->import->image_root, "/", f->local, ".gpt"); if (f->force_local) (void) rm_rf_dangerous(p, false, true, false); @@ -185,6 +187,14 @@ static void gpt_import_file_success(GptImportFile *f) { goto finish; } + /* 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, true, FS_NOCOW_FL); + if (r < 0) + log_warning_errno(errno, "Failed to set file attributes on %s: %m", f->temp_path); + r = copy_bytes(f->disk_fd, dfd, (off_t) -1, true); if (r < 0) { log_error_errno(r, "Failed to make writable copy of image: %m"); @@ -469,7 +479,7 @@ static int gpt_import_file_find_old_etags(GptImportFile *f) { if (!escaped_url) return -ENOMEM; - d = opendir("/var/lib/container/"); + d = opendir(f->import->image_root); if (!d) { if (errno == ENOENT) return 0; @@ -575,11 +585,12 @@ static int gpt_import_file_begin(GptImportFile *f) { return 0; } -int gpt_import_new(GptImport **import, sd_event *event, gpt_import_on_finished on_finished, void *userdata) { +int gpt_import_new(GptImport **import, sd_event *event, const char *image_root, gpt_import_on_finished on_finished, void *userdata) { _cleanup_(gpt_import_unrefp) GptImport *i = NULL; int r; assert(import); + assert(image_root); i = new0(GptImport, 1); if (!i) @@ -588,6 +599,10 @@ int gpt_import_new(GptImport **import, sd_event *event, gpt_import_on_finished o i->on_finished = on_finished; i->userdata = userdata; + i->image_root = strdup(image_root); + if (!i->image_root) + return -ENOMEM; + if (event) i->event = sd_event_ref(event); else { @@ -622,6 +637,7 @@ GptImport* gpt_import_unref(GptImport *import) { curl_glue_unref(import->glue); sd_event_unref(import->event); + free(import->image_root); free(import); return NULL;