[lxc-devel] [PATCH] implement backend drivers and container clone API (v2)

Serge Hallyn serge.hallyn at ubuntu.com
Thu Apr 25 00:03:44 UTC 2013


After this patch, I'd like to only re-introduce the original lxc-clone
bash script's command line options in the new c program, then push to
staging.

Subject: [PATCH 2/3] on copy-clone of btrfs, create a subvolume

so that it can be snapshotted.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/bdev.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 10 deletions(-)

diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index 25d2650..68e8d3d 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -681,14 +681,23 @@ int btrfs_umount(struct bdev *bdev)
 	return umount(bdev->dest);
 }
 
+#define BTRFS_SUBVOL_NAME_MAX 4039
+#define BTRFS_PATH_NAME_MAX 4087
+
+struct btrfs_ioctl_vol_args {
+	signed long long fd;
+	char name[BTRFS_PATH_NAME_MAX + 1];
+};
+
 #define BTRFS_IOCTL_MAGIC 0x94
 #define BTRFS_IOC_SUBVOL_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 24, \
                                    struct btrfs_ioctl_vol_args_v2)
 #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
                                    struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \
+                                   struct btrfs_ioctl_vol_args)
 
 #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0)
-#define BTRFS_SUBVOL_NAME_MAX 4039
 
 struct btrfs_ioctl_vol_args_v2 {
 	signed long long fd;
@@ -705,6 +714,42 @@ struct btrfs_ioctl_vol_args_v2 {
 	char name[BTRFS_SUBVOL_NAME_MAX + 1];
 };
 
+static int btrfs_subvolume_create(const char *path)
+{
+	int ret, fd = -1;
+	struct btrfs_ioctl_vol_args  args;
+	char *p, *newfull = strdup(path);
+
+	if (!newfull) {
+		ERROR("Error: out of memory");
+		return -1;
+	}
+
+	p = rindex(newfull, '/');
+	if (!p) {
+		free(newfull);
+		ERROR("bad path: %s", path);
+		return -1;
+	}
+	*p = '\0';
+
+	if ((fd = open(newfull, O_RDONLY)) < 0) {
+		ERROR("Error opening %s", newfull);
+		free(newfull);
+		return -1;
+	}
+
+	memset(&args, 0, sizeof(args));
+	strncpy(args.name, p+1, BTRFS_SUBVOL_NAME_MAX);
+	args.name[BTRFS_SUBVOL_NAME_MAX-1] = 0;
+	ret = ioctl(fd, BTRFS_IOC_SUBVOL_CREATE, &args);
+	INFO("btrfs: snapshot create ioctl returned %d", ret);
+
+	free(newfull);
+	close(fd);
+	return ret;
+}
+
 static int btrfs_snapshot(const char *orig, const char *new)
 {
 	int fd = -1, fddst = -1, ret = -1;
@@ -755,24 +800,27 @@ static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *old
 		const char *cname, const char *oldpath, const char *lxcpath, int snap,
 		unsigned long newsize)
 {
-	if (!snap)
-		return dir_clonepaths(orig, new, oldname, cname, oldpath, lxcpath,
-				snap, newsize);
-
-	if (!orig->src || !orig->dest)
+	if (!orig->dest || !orig->src)
 		return -1;
 
-	new->dest = dir_new_path(orig->dest, oldname, cname, oldpath, lxcpath);
-	if (!new->dest)
+	if ((new->dest = dir_new_path(orig->dest, oldname, cname, oldpath, lxcpath)) == NULL)
 		return -1;
 
 	if ((new->src = strdup(new->dest)) == NULL)
 		return -1;
 
-	if (btrfs_snapshot(orig->dest, new->dest) < 0)
+	if (orig->data && (new->data = strdup(orig->data)) == NULL)
 		return -1;
 
-	return 0;
+	if (snap)
+		return btrfs_snapshot(orig->dest, new->dest);
+
+	if (rmdir(new->dest) < 0 && errno != -ENOENT) {
+		SYSERROR("removing %s\n", new->dest);
+		return -1;
+	}
+
+	return btrfs_subvolume_create(new->dest);
 }
 
 struct bdev_ops btrfs_ops = {
-- 
1.8.1.2





More information about the lxc-devel mailing list