]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Revert "btrfs: simplify"
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 15 Aug 2017 16:12:31 +0000 (18:12 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 15 Aug 2017 16:44:58 +0000 (18:44 +0200)
This reverts commit 36c55bf31c67d5048b6dd7f85ac425f3b2e22fd3.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/bdev/bdev.c

index a99a0517745f97e3061ba7b1a27e71b43ee4d7e8..34d8e78d2181279e63d324adeef26021a267dcf7 100644 (file)
@@ -406,10 +406,6 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
        }
        TRACE("Detected \"%s\" storage driver", new->type);
 
-       if (bdevtype && !strcmp(orig->type, "btrfs") &&
-           !strcmp(new->type, "btrfs"))
-               snap = 1;
-
        if (new->ops->clone_paths(orig, new, oldname, cname, oldpath, lxcpath,
                                  snap, newsize, c0->lxc_conf) < 0) {
                ERROR("Failed getting pathnames for clone of \"%s\"", src);
@@ -431,6 +427,36 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
        if (snap)
                return new;
 
+       /* https://github.com/lxc/lxc/issues/131
+        * Use btrfs snapshot feature instead of rsync to restore if both orig
+        * and new are btrfs.
+        */
+       if (bdevtype && strcmp(orig->type, "btrfs") == 0 &&
+           strcmp(new->type, "btrfs") == 0 &&
+           btrfs_same_fs(orig->dest, new->dest) == 0) {
+               struct rsync_data_char arg;
+
+               if (btrfs_destroy(new) < 0) {
+                       ERROR("Failed to destroy \"%s\" btrfs subvolume", new->dest);
+                       goto err;
+               }
+
+               arg.src = orig->dest;
+               arg.dest = new->dest;
+               if (am_unpriv())
+                       ret = userns_exec_1(c0->lxc_conf, btrfs_snapshot_wrapper,
+                                         &arg, "btrfs_snapshot_wrapper");
+               else
+                       ret = btrfs_snapshot(orig->dest, new->dest);
+               if (ret < 0) {
+                       SYSERROR("Failed to create btrfs snapshot \"%s\" of \"%s\"",
+                                new->dest, orig->dest);
+                       goto err;
+               }
+               bdev_put(orig);
+               return new;
+       }
+
        pid = fork();
        if (pid < 0) {
                SYSERROR("fork");