]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machined: support non-btrfs file systems with "machinectl clone"
authorLennart Poettering <lennart@poettering.net>
Fri, 29 Apr 2016 18:06:20 +0000 (20:06 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 2 May 2016 09:15:30 +0000 (11:15 +0200)
Fall back to a normal copy operation when the backing file system isn't btrfs,
and hence doesn't support cheap snapshotting. Of course, this will be slow, but
given that the execution is asynchronous now, this should be OK.

Fixes: #1308
src/basic/copy.c
src/basic/copy.h
src/shared/machine-image.c

index 79b9a0e1a0e3cdf6e4a1bbcd00647c694a022703..c3586728d09fd909050ffff0fcebc32d34ec2666 100644 (file)
@@ -423,6 +423,21 @@ int copy_directory_fd(int dirfd, const char *to, bool merge) {
         return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
 }
 
+int copy_directory(const char *from, const char *to, bool merge) {
+        struct stat st;
+
+        assert(from);
+        assert(to);
+
+        if (lstat(from, &st) < 0)
+                return -errno;
+
+        if (!S_ISDIR(st.st_mode))
+                return -ENOTDIR;
+
+        return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
+}
+
 int copy_file_fd(const char *from, int fdt, bool try_reflink) {
         _cleanup_close_ int fdf = -1;
         int r;
index 3e5eb525064440cca67c4a718acf600c6b041e85..b5d08ebafe6a23117e7783c77a76fc38d5e420e1 100644 (file)
@@ -30,6 +30,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
 int copy_tree(const char *from, const char *to, bool merge);
 int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
 int copy_directory_fd(int dirfd, const char *to, bool merge);
+int copy_directory(const char *from, const char *to, bool merge);
 int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
 int copy_times(int fdf, int fdt);
 int copy_xattr(int fdf, int fdt);
index eb8f6ee4385af4850d1451165ea9dd197f5b541d..66f58ecd924a97e8f1e8a2ff4da2083fbed5824a 100644 (file)
@@ -603,12 +603,20 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
 
         case IMAGE_SUBVOLUME:
         case IMAGE_DIRECTORY:
+                /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
+                 * directory.*/
+
                 new_path = strjoina("/var/lib/machines/", new_name);
 
                 r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
-
-                /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
-                if (r >= 0)
+                if (r == -EOPNOTSUPP) {
+                        /* No btrfs snapshots supported, create a normal directory then. */
+
+                        r = copy_directory(i->path, new_path, false);
+                        if (r >= 0)
+                                (void) chattr_path(new_path, read_only ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
+                } else if (r >= 0)
+                        /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
                         (void) btrfs_subvol_auto_qgroup(new_path, 0, true);
 
                 break;