]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18462 from poettering/copy-time
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 4 Feb 2021 05:04:37 +0000 (14:04 +0900)
committerGitHub <noreply@github.com>
Thu, 4 Feb 2021 05:04:37 +0000 (14:04 +0900)
timestamp fixes in copy.c

24 files changed:
src/basic/path-util.c
src/import/export.c
src/import/import-common.c
src/import/import-fs.c
src/import/import.c
src/import/pull-job.c
src/import/pull.c
src/machine/image-dbus.c
src/machine/machined-dbus.c
src/machine/machined.c
src/nspawn/nspawn.c
src/portable/portable.c
src/portable/portablectl.c
src/portable/portabled-bus.c
src/portable/portabled-image-bus.c
src/portable/portabled-image-bus.h
src/portable/portabled-image.h
src/shared/discover-image.c [moved from src/shared/machine-image.c with 99% similarity]
src/shared/discover-image.h [moved from src/shared/machine-image.h with 100% similarity]
src/shared/meson.build
src/shared/os-util.c
src/sysext/sysext.c
src/test/test-path-util.c
src/test/test-tables.c

index 3dff09b15198f12460be3760339d4e1ab123f9f2..f7498d012568538681e51cb60435232270b1d608 100644 (file)
@@ -891,7 +891,7 @@ bool filename_is_valid(const char *p) {
         if (*e != 0)
                 return false;
 
-        if (e - p > FILENAME_MAX) /* FILENAME_MAX is counted *without* the trailing NUL byte */
+        if (e - p > NAME_MAX) /* NAME_MAX is counted *without* the trailing NUL byte */
                 return false;
 
         return true;
@@ -902,10 +902,25 @@ bool path_is_valid(const char *p) {
         if (isempty(p))
                 return false;
 
-        if (strlen(p) >= PATH_MAX) /* PATH_MAX is counted *with* the trailing NUL byte */
-                return false;
+        for (const char *e = p;;) {
+                size_t n;
 
-        return true;
+                /* Skip over slashes */
+                e += strspn(e, "/");
+                if (e - p >= PATH_MAX) /* Already reached the maximum length for a path? (PATH_MAX is counted
+                                        * *with* the trailing NUL byte) */
+                        return false;
+                if (*e == 0)           /* End of string? Yay! */
+                        return true;
+
+                /* Skip over one component */
+                n = strcspn(e, "/");
+                if (n > NAME_MAX)      /* One component larger than NAME_MAX? (NAME_MAX is counted *without* the
+                                        * trailing NUL byte) */
+                        return false;
+
+                e += n;
+        }
 }
 
 bool path_is_normalized(const char *p) {
index 9c44fcf35cc746e19dd1dfeba31332f9a02eff73..5faf4ccc06b0516577f752c776369b59c22e72e5 100644 (file)
@@ -7,13 +7,13 @@
 #include "sd-id128.h"
 
 #include "alloc-util.h"
+#include "discover-image.h"
 #include "export-raw.h"
 #include "export-tar.h"
 #include "fd-util.h"
 #include "fs-util.h"
 #include "hostname-util.h"
 #include "import-util.h"
-#include "machine-image.h"
 #include "main-func.h"
 #include "signal-util.h"
 #include "string-util.h"
index bbe0ba719cd7bb8adac4f882c9f4f29ad17ab8e9..f77564c41dc53f8fa8ca5cf3270083f42a37639c 100644 (file)
@@ -8,6 +8,7 @@
 #include "alloc-util.h"
 #include "btrfs-util.h"
 #include "capability-util.h"
+#include "chattr-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -22,6 +23,7 @@
 #include "util.h"
 
 int import_make_read_only_fd(int fd) {
+        struct stat st;
         int r;
 
         assert(fd >= 0);
@@ -29,25 +31,34 @@ int import_make_read_only_fd(int fd) {
         /* First, let's make this a read-only subvolume if it refers
          * to a subvolume */
         r = btrfs_subvol_set_read_only_fd(fd, true);
-        if (IN_SET(r, -ENOTTY, -ENOTDIR, -EINVAL)) {
-                struct stat st;
+        if (r >= 0)
+                return 0;
 
-                /* This doesn't refer to a subvolume, or the file
-                 * system isn't even btrfs. In that, case fall back to
-                 * chmod()ing */
+        if (!ERRNO_IS_NOT_SUPPORTED(r) && !IN_SET(r, -ENOTDIR, -EINVAL))
+                return log_error_errno(r, "Failed to make subvolume read-only: %m");
 
-                r = fstat(fd, &st);
-                if (r < 0)
-                        return log_error_errno(errno, "Failed to stat temporary image: %m");
+        /* This doesn't refer to a subvolume, or the file system isn't even btrfs. In that, case fall back to
+         * chmod()ing */
+
+        r = fstat(fd, &st);
+        if (r < 0)
+                return log_error_errno(errno, "Failed to stat image: %m");
 
-                /* Drop "w" flag */
-                if (fchmod(fd, st.st_mode & 07555) < 0)
-                        return log_error_errno(errno, "Failed to chmod() final image: %m");
+        if (S_ISDIR(st.st_mode)) {
+                /* For directories set the immutable flag on the dir itself */
 
-                return 0;
+                r = chattr_fd(fd, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL, NULL);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to set +i attribute on directory image: %m");
 
-        } else if (r < 0)
-                return log_error_errno(r, "Failed to make subvolume read-only: %m");
+        } else if (S_ISREG(st.st_mode)) {
+                /* For regular files drop "w" flags */
+
+                if ((st.st_mode & 0222) != 0)
+                        if (fchmod(fd, st.st_mode & 07555) < 0)
+                                return log_error_errno(errno, "Failed to chmod() image: %m");
+        } else
+                return log_error_errno(SYNTHETIC_ERRNO(EBADFD), "Image of unexpected type");
 
         return 0;
 }
index 1fe5a257dbd66b720b2b86b1e4a31494e719b000..a12ee77ef9fc7fb6bdc85ad9d15ed85d7449b4a3 100644 (file)
@@ -5,13 +5,13 @@
 
 #include "alloc-util.h"
 #include "btrfs-util.h"
+#include "discover-image.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "fs-util.h"
 #include "hostname-util.h"
 #include "import-common.h"
 #include "import-util.h"
-#include "machine-image.h"
 #include "mkdir.h"
 #include "ratelimit.h"
 #include "rm-rf.h"
index 934074a7b0abd22eba5d7611732bd96449106c53..661fa2888c58b41f5f1b39b9cf29cbb49b15b4b0 100644 (file)
@@ -7,13 +7,13 @@
 #include "sd-id128.h"
 
 #include "alloc-util.h"
+#include "discover-image.h"
 #include "fd-util.h"
 #include "fs-util.h"
 #include "hostname-util.h"
 #include "import-raw.h"
 #include "import-tar.h"
 #include "import-util.h"
-#include "machine-image.h"
 #include "main-func.h"
 #include "signal-util.h"
 #include "string-util.h"
index d1e61ba601f0e964e6798b467c4c70810331c452..908546b96839af76e449a2c58ee38b5f4ec2e7b1 100644 (file)
@@ -433,6 +433,16 @@ fail:
         return 0;
 }
 
+static int http_status_ok(CURLcode status) {
+        /* Consider all HTTP status code in the 2xx range as OK */
+        return status >= 200 && status <= 299;
+}
+
+static int http_status_etag_exists(CURLcode status) {
+        /* This one is special, it's triggered by our etag mgmt logic */
+        return status == 304;
+}
+
 static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
         _cleanup_free_ char *length = NULL, *last_modified = NULL, *etag = NULL;
         size_t sz = size * nmemb;
@@ -458,28 +468,31 @@ static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb
                 goto fail;
         }
 
-        if (status < 200 || status >= 300)
-                /* If this is not HTTP 2xx, let's skip these headers, they are probably for
-                 * some redirect or so, and we are not interested in the headers of those. */
-                return sz;
+        if (http_status_ok(status) || http_status_etag_exists(status)) {
+                /* Check Etag on OK and etag exists responses. */
 
-        r = curl_header_strdup(contents, sz, "ETag:", &etag);
-        if (r < 0) {
-                log_oom();
-                goto fail;
-        }
-        if (r > 0) {
-                free_and_replace(j->etag, etag);
+                r = curl_header_strdup(contents, sz, "ETag:", &etag);
+                if (r < 0) {
+                        log_oom();
+                        goto fail;
+                }
+                if (r > 0) {
+                        free_and_replace(j->etag, etag);
+
+                        if (strv_contains(j->old_etags, j->etag)) {
+                                log_info("Image already downloaded. Skipping download. (%s)", j->etag);
+                                j->etag_exists = true;
+                                pull_job_finish(j, 0);
+                                return sz;
+                        }
 
-                if (strv_contains(j->old_etags, j->etag)) {
-                        log_info("Image already downloaded. Skipping download.");
-                        j->etag_exists = true;
-                        pull_job_finish(j, 0);
                         return sz;
                 }
+        }
 
+        if (!http_status_ok(status)) /* Let's ignore the rest here, these requests are probably redirects and
+                                      * stuff where the headers aren't interesting to us */
                 return sz;
-        }
 
         r = curl_header_strdup(contents, sz, "Content-Length:", &length);
         if (r < 0) {
index a54f968cd76eb2c8934f66408e1931487de0d501..dc0bf20201daec125f2b57f49b80ce2ee204138e 100644 (file)
@@ -7,9 +7,9 @@
 #include "sd-id128.h"
 
 #include "alloc-util.h"
+#include "discover-image.h"
 #include "hostname-util.h"
 #include "import-util.h"
-#include "machine-image.h"
 #include "main-func.h"
 #include "parse-util.h"
 #include "pull-raw.h"
index f74cabd7fb753a85ae4d1bdf247f9d73a0eeb7de..539b4c802a62e640c5f60d1c6207cb5198f179f5 100644 (file)
@@ -8,6 +8,7 @@
 #include "bus-label.h"
 #include "bus-polkit.h"
 #include "copy.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -15,7 +16,6 @@
 #include "image-dbus.h"
 #include "io-util.h"
 #include "loop-util.h"
-#include "machine-image.h"
 #include "missing_capability.h"
 #include "mount-util.h"
 #include "process-util.h"
index a65f9b6a8e5628ea604504fd30c966ae2dfb6c07..08179eb4006cc277b01ad9155e09bd50d8f38490 100644 (file)
@@ -12,6 +12,7 @@
 #include "bus-locator.h"
 #include "bus-polkit.h"
 #include "cgroup-util.h"
+#include "discover-image.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -20,7 +21,6 @@
 #include "image-dbus.h"
 #include "io-util.h"
 #include "machine-dbus.h"
-#include "machine-image.h"
 #include "machine-pool.h"
 #include "machined.h"
 #include "missing_capability.h"
index 6a5bf391e6b24d477d302c215315e697210a3157..1d820599858298194af13d206e1f19ebe66ddc11 100644 (file)
 #include "bus-polkit.h"
 #include "cgroup-util.h"
 #include "dirent-util.h"
+#include "discover-image.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "hostname-util.h"
 #include "label.h"
-#include "machine-image.h"
 #include "machined-varlink.h"
 #include "machined.h"
 #include "main-func.h"
index aa3bcdb7a299ab50444e08f23a289481c3a60106..a702af8e3bd95af2b08d58cec04acce997e060c4 100644 (file)
@@ -36,6 +36,7 @@
 #include "copy.h"
 #include "cpu-set-util.h"
 #include "dev-setup.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "env-util.h"
 #include "escape.h"
@@ -53,7 +54,6 @@
 #include "log.h"
 #include "loop-util.h"
 #include "loopback-setup.h"
-#include "machine-image.h"
 #include "macro.h"
 #include "main-func.h"
 #include "missing_sched.h"
index d74e498d596d67f19e7a5c29eca892a6b0b75ee7..d18e03afd4fd1adf20cd94e196bc0ba788269c78 100644 (file)
@@ -8,6 +8,7 @@
 #include "copy.h"
 #include "def.h"
 #include "dirent-util.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -16,7 +17,6 @@
 #include "io-util.h"
 #include "locale-util.h"
 #include "loop-util.h"
-#include "machine-image.h"
 #include "mkdir.h"
 #include "nulstr-util.h"
 #include "os-util.h"
index 0b329134de5926ca64206b1c18e72babef97f08c..ee1c7b696510f2844369f8e45570006509ab2d24 100644 (file)
 #include "bus-wait-for-jobs.h"
 #include "def.h"
 #include "dirent-util.h"
+#include "discover-image.h"
 #include "env-file.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-table.h"
 #include "fs-util.h"
 #include "locale-util.h"
-#include "machine-image.h"
 #include "main-func.h"
 #include "pager.h"
 #include "parse-util.h"
index cf50d58c71dff5da8e53b9b805456ace19920d05..20a33dc6716c0931a11b19208389cf5ccad68f59 100644 (file)
@@ -4,9 +4,9 @@
 #include "btrfs-util.h"
 #include "bus-common-errors.h"
 #include "bus-polkit.h"
+#include "discover-image.h"
 #include "fd-util.h"
 #include "io-util.h"
-#include "machine-image.h"
 #include "missing_capability.h"
 #include "portable.h"
 #include "portabled-bus.h"
index 76b6ddebde374068beb41508f0b79ffd67e79abf..babdf4197fa51383d6d333ba0bfff2bc997b6a1d 100644 (file)
 #include "bus-label.h"
 #include "bus-polkit.h"
 #include "bus-util.h"
+#include "discover-image.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "io-util.h"
-#include "machine-image.h"
 #include "missing_capability.h"
 #include "portable.h"
 #include "portabled-bus.h"
index aa2a3ade7706723c1f4edb6f6e0460026ed73ab0..8442baf232c0753c7ea0e62750bc7f71890c47a0 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "sd-bus.h"
 
-#include "machine-image.h"
+#include "discover-image.h"
 #include "portabled.h"
 
 int bus_image_common_get_os_release(Manager *m, sd_bus_message *message, const char *name_or_path, Image *image, sd_bus_error *error);
index eeefffee64e3180d214bdd8d45e1b0db9cfcaa2b..753f389f80d24df8a6181748ba54cd99709a7086 100644 (file)
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include "discover-image.h"
 #include "hashmap.h"
-#include "machine-image.h"
 #include "portabled.h"
 
 Image *manager_image_cache_get(Manager *m, const char *name_or_path);
similarity index 99%
rename from src/shared/machine-image.c
rename to src/shared/discover-image.c
index d2b726efc4c4a6f45eaa63bc468fa8dc2d93b1a7..1f5e4c6f86b345b211f9bd0600418023a33d48c2 100644 (file)
@@ -16,6 +16,7 @@
 #include "chattr-util.h"
 #include "copy.h"
 #include "dirent-util.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "env-file.h"
 #include "env-util.h"
@@ -27,7 +28,6 @@
 #include "lockfile-util.h"
 #include "log.h"
 #include "loop-util.h"
-#include "machine-image.h"
 #include "macro.h"
 #include "mkdir.h"
 #include "nulstr-util.h"
@@ -1065,7 +1065,6 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
                         r = asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino);
                 else
                         return -ENOTTY;
-
                 if (r < 0)
                         return -ENOMEM;
         }
@@ -1220,11 +1219,16 @@ int image_read_metadata(Image *i) {
 }
 
 int image_name_lock(const char *name, int operation, LockFile *ret) {
+        const char *p;
+
         assert(name);
         assert(ret);
 
         /* Locks an image name, regardless of the precise path used. */
 
+        if (streq(name, ".host"))
+                return -EBUSY;
+
         if (!image_name_is_valid(name))
                 return -EINVAL;
 
@@ -1233,11 +1237,9 @@ int image_name_lock(const char *name, int operation, LockFile *ret) {
                 return 0;
         }
 
-        if (streq(name, ".host"))
-                return -EBUSY;
-
-        const char *p = strjoina("/run/systemd/nspawn/locks/name-", name);
         (void) mkdir_p("/run/systemd/nspawn/locks", 0700);
+
+        p = strjoina("/run/systemd/nspawn/locks/name-", name);
         return make_lock_file(p, operation, ret);
 }
 
index f301a9f610d107d3be65ed1f1a1ca0c862b5fc5d..b1a8ea9ac64a941447cd0068bd2d03af78e730a0 100644 (file)
@@ -79,6 +79,8 @@ shared_sources = files('''
         dev-setup.c
         dev-setup.h
         devnode-acl.h
+        discover-image.c
+        discover-image.h
         dissect-image.c
         dissect-image.h
         dm-util.c
@@ -172,8 +174,6 @@ shared_sources = files('''
         loopback-setup.h
         machine-id-setup.c
         machine-id-setup.h
-        machine-image.c
-        machine-image.h
         machine-pool.c
         machine-pool.h
         macvlan-util.c
index d1cf41283b1b6768dc1b27b3fffc52bbf9e9d1a5..45c10ca9c5600812b686a5be6a63553d2e1472d7 100644 (file)
@@ -1,12 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "alloc-util.h"
+#include "discover-image.h"
 #include "env-file.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "macro.h"
-#include "machine-image.h"
 #include "os-util.h"
 #include "string-util.h"
 #include "strv.h"
index 601fd63a1442a573c816ce02e21546eb12f39dc8..ee38e49ec92da73c1c2638531b5f8481088be006 100644 (file)
@@ -6,6 +6,7 @@
 #include <unistd.h>
 
 #include "capability-util.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "escape.h"
 #include "fd-util.h"
@@ -14,7 +15,6 @@
 #include "fs-util.h"
 #include "hashmap.h"
 #include "log.h"
-#include "machine-image.h"
 #include "main-func.h"
 #include "missing_magic.h"
 #include "mkdir.h"
index 206f5fd436db154cdebad9063343048ad42974f3..58b185494df3f456ef1389f97b93ea38a64e425a 100644 (file)
@@ -604,8 +604,7 @@ static void test_path_extract_filename(void) {
 }
 
 static void test_filename_is_valid(void) {
-        char foo[FILENAME_MAX+2];
-        int i;
+        char foo[NAME_MAX+2];
 
         log_info("/* %s */", __func__);
 
@@ -618,9 +617,8 @@ static void test_filename_is_valid(void) {
         assert_se(!filename_is_valid("bar/foo/"));
         assert_se(!filename_is_valid("bar//"));
 
-        for (i=0; i<FILENAME_MAX+1; i++)
-                foo[i] = 'a';
-        foo[FILENAME_MAX+1] = '\0';
+        memset(foo, 'a', sizeof(foo) - 1);
+        char_array_0(foo);
 
         assert_se(!filename_is_valid(foo));
 
@@ -628,6 +626,38 @@ static void test_filename_is_valid(void) {
         assert_se(filename_is_valid("o.o"));
 }
 
+static void test_path_is_valid(void) {
+        char foo[PATH_MAX+2];
+        const char *c;
+
+        log_info("/* %s */", __func__);
+
+        assert_se(!path_is_valid(""));
+        assert_se(path_is_valid("/bar/foo"));
+        assert_se(path_is_valid("/bar/foo/"));
+        assert_se(path_is_valid("/bar/foo/"));
+        assert_se(path_is_valid("//bar//foo//"));
+        assert_se(path_is_valid("/"));
+        assert_se(path_is_valid("/////"));
+        assert_se(path_is_valid("/////.///.////...///..//."));
+        assert_se(path_is_valid("."));
+        assert_se(path_is_valid(".."));
+        assert_se(path_is_valid("bar/foo"));
+        assert_se(path_is_valid("bar/foo/"));
+        assert_se(path_is_valid("bar//"));
+
+        memset(foo, 'a', sizeof(foo) -1);
+        char_array_0(foo);
+
+        assert_se(!path_is_valid(foo));
+
+        c = strjoina("/xxx/", foo, "/yyy");
+        assert_se(!path_is_valid(c));
+
+        assert_se(path_is_valid("foo_bar-333"));
+        assert_se(path_is_valid("o.o"));
+}
+
 static void test_hidden_or_backup_file(void) {
         log_info("/* %s */", __func__);
 
@@ -761,6 +791,7 @@ int main(int argc, char **argv) {
         test_last_path_component();
         test_path_extract_filename();
         test_filename_is_valid();
+        test_path_is_valid();
         test_hidden_or_backup_file();
         test_skip_dev_prefix();
         test_empty_or_root();
index e25cf9e5d91287727ad6da85d4c76557ca0955ac..641cadec858b20ae54cc9f18980387ff0a7bc30a 100644 (file)
@@ -8,6 +8,7 @@
 #include "condition.h"
 #include "device-private.h"
 #include "device.h"
+#include "discover-image.h"
 #include "execute.h"
 #include "import-util.h"
 #include "install.h"
@@ -18,7 +19,6 @@
 #include "locale-util.h"
 #include "log.h"
 #include "logs-show.h"
-#include "machine-image.h"
 #include "mount.h"
 #include "path.h"
 #include "process-util.h"