[lxc-devel] [lxc/master] storage: fix clone

brauner on Github lxc-bot at linuxcontainers.org
Sat Jul 15 13:37:07 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170715/93c346d1/attachment.bin>
-------------- next part --------------
From 85687ea6b57b231306a6a39d45c2c5e3ba0c9062 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 15 Jul 2017 15:31:43 +0200
Subject: [PATCH 1/4] utils: move some helpers from cgfsng.c

- must_realloc()
- must_copy_string()
- must_make_path()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 53 ------------------------------------------------
 src/lxc/utils.c          | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/utils.h          |  4 ++++
 3 files changed, 55 insertions(+), 53 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 1192d575f..b3f4ca742 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -118,36 +118,12 @@ static void free_string_list(char **clist)
 	}
 }
 
-/* Re-alllocate a pointer, do not fail */
-static void *must_realloc(void *orig, size_t sz)
-{
-	void *ret;
-
-	do {
-		ret = realloc(orig, sz);
-	} while (!ret);
-	return ret;
-}
-
 /* Allocate a pointer, do not fail */
 static void *must_alloc(size_t sz)
 {
 	return must_realloc(NULL, sz);
 }
 
-/* return copy of string @entry;  do not fail. */
-static char *must_copy_string(const char *entry)
-{
-	char *ret;
-
-	if (!entry)
-		return NULL;
-	do {
-		ret = strdup(entry);
-	} while (!ret);
-	return ret;
-}
-
 /*
  * This is a special case - return a copy of @entry
  * prepending 'name='.  I.e. turn systemd into name=systemd.
@@ -259,8 +235,6 @@ struct hierarchy *get_hierarchy(const char *c)
 	return NULL;
 }
 
-static char *must_make_path(const char *first, ...) __attribute__((sentinel));
-
 #define BATCH_SIZE 50
 static void batch_realloc(char **mem, size_t oldlen, size_t newlen)
 {
@@ -1187,33 +1161,6 @@ static void *cgfsng_init(const char *name)
 	return NULL;
 }
 
-/*
- * Concatenate all passed-in strings into one path.  Do not fail.  If any piece is
- * not prefixed with '/', add a '/'.
- */
-static char *must_make_path(const char *first, ...)
-{
-	va_list args;
-	char *cur, *dest;
-	size_t full_len = strlen(first);
-
-	dest = must_copy_string(first);
-
-	va_start(args, first);
-	while ((cur = va_arg(args, char *)) != NULL) {
-		full_len += strlen(cur);
-		if (cur[0] != '/')
-			full_len++;
-		dest = must_realloc(dest, full_len + 1);
-		if (cur[0] != '/')
-			strcat(dest, "/");
-		strcat(dest, cur);
-	}
-	va_end(args);
-
-	return dest;
-}
-
 static int cgroup_rmdir(char *dirname)
 {
 	struct dirent *direntp;
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 5b61cba00..49e68cf9b 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -2337,3 +2337,54 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
 
 	return fret;
 }
+
+/* Re-alllocate a pointer, do not fail */
+void *must_realloc(void *orig, size_t sz)
+{
+	void *ret;
+
+	do {
+		ret = realloc(orig, sz);
+	} while (!ret);
+	return ret;
+}
+
+/* return copy of string @entry;  do not fail. */
+char *must_copy_string(const char *entry)
+{
+	char *ret;
+
+	if (!entry)
+		return NULL;
+	do {
+		ret = strdup(entry);
+	} while (!ret);
+	return ret;
+}
+
+/*
+ * Concatenate all passed-in strings into one path.  Do not fail.  If any piece is
+ * not prefixed with '/', add a '/'.
+ */
+char *must_make_path(const char *first, ...)
+{
+	va_list args;
+	char *cur, *dest;
+	size_t full_len = strlen(first);
+
+	dest = must_copy_string(first);
+
+	va_start(args, first);
+	while ((cur = va_arg(args, char *)) != NULL) {
+		full_len += strlen(cur);
+		if (cur[0] != '/')
+			full_len++;
+		dest = must_realloc(dest, full_len + 1);
+		if (cur[0] != '/')
+			strcat(dest, "/");
+		strcat(dest, cur);
+	}
+	va_end(args);
+
+	return dest;
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 916ee56a6..96ef6dc07 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -375,4 +375,8 @@ int lxc_unstack_mountpoint(const char *path, bool lazy);
  */
 int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args);
 
+void *must_realloc(void *orig, size_t sz);
+char *must_copy_string(const char *entry);
+char *must_make_path(const char *first, ...) __attribute__((sentinel));
+
 #endif /* __LXC_UTILS_H */

From f425f0d6d7c4d51f8114def433cbcd24a1a0e257 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 15 Jul 2017 15:32:52 +0200
Subject: [PATCH 2/4] storage: default to orig type on identical paths

otherwise default to "dir"

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/bdev/bdev.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/lxc/bdev/bdev.c b/src/lxc/bdev/bdev.c
index 1bc8afcd0..bef79f70f 100644
--- a/src/lxc/bdev/bdev.c
+++ b/src/lxc/bdev/bdev.c
@@ -270,6 +270,9 @@ static struct bdev *do_bdev_create(const char *dest, const char *type,
 
 	struct bdev *bdev;
 
+	if (!type)
+		type = "dir";
+
 	bdev = bdev_get(type);
 	if (!bdev)
 		return NULL;
@@ -389,7 +392,11 @@ struct bdev *bdev_copy(struct lxc_container *c0, const char *cname,
 		*needs_rdep = 1;
 	}
 
-	new = bdev_get(bdevtype ? bdevtype : orig->type);
+	if (strcmp(oldpath, lxcpath) && !bdevtype)
+		bdevtype = "dir";
+	else if (!bdevtype)
+		bdevtype = orig->type;
+	new = bdev_get(bdevtype);
 	if (!new) {
 		ERROR("no such block device type: %s",
 		      bdevtype ? bdevtype : orig->type);

From 92554dc03516a05b607c4237adec82df2840031b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 15 Jul 2017 15:34:21 +0200
Subject: [PATCH 3/4] lxccontainer: use snprintf()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/lxccontainer.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index fa04becb6..6373f581e 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -3332,7 +3332,11 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
 	saved_unexp_conf = NULL;
 	c->lxc_conf->unexpanded_len = saved_unexp_len;
 
-	sprintf(newpath, "%s/%s/rootfs", lxcpath, newname);
+	ret = snprintf(newpath, MAXPATHLEN, "%s/%s/rootfs", lxcpath, newname);
+	if (ret < 0 || ret >= MAXPATHLEN) {
+		SYSERROR("clone: failed making rootfs pathname");
+		goto out;
+	}
 	if (mkdir(newpath, 0755) < 0) {
 		SYSERROR("error creating %s", newpath);
 		goto out;

From 065ac3afe90889932262d5257d9af31119e821a7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 15 Jul 2017 15:34:39 +0200
Subject: [PATCH 4/4] btrfs: simplify + bugfix

Closes #1698.
Closes #1703.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/bdev/lxcbtrfs.c | 33 +++++++++------------------------
 1 file changed, 9 insertions(+), 24 deletions(-)

diff --git a/src/lxc/bdev/lxcbtrfs.c b/src/lxc/bdev/lxcbtrfs.c
index 1defa76ee..194506672 100644
--- a/src/lxc/bdev/lxcbtrfs.c
+++ b/src/lxc/bdev/lxcbtrfs.c
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <sys/types.h>
 #include <sys/vfs.h>
 
@@ -39,7 +40,7 @@
 #include "log.h"
 #include "lxcbtrfs.h"
 #include "lxcrsync.h"
-#include "utils.h"
+#include "../utils.h"
 
 lxc_log_define(lxcbtrfs, lxc);
 
@@ -380,29 +381,13 @@ int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname,
 	if (!orig->dest || !orig->src)
 		return -1;
 
-	if (strcmp(orig->type, "btrfs")) {
-		int len, ret;
-		if (snap) {
-			ERROR("btrfs snapshot from %s backing store is not supported",
-				orig->type);
-			return -1;
-		}
-
-		len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 6 + 3;
-		new->src = malloc(len);
-		if (!new->src)
-			return -1;
-
-		ret = snprintf(new->src, len, "btrfs:%s/%s/rootfs", lxcpath, cname);
-		if (ret < 0 || ret >= len)
-			return -1;
-	} else {
-		/* In case rootfs is in custom path, reuse it. */
-		new->src = dir_new_path(orig->src, oldname, cname, oldpath, lxcpath);
-		if (!new->src)
-			return -1;
-
-	}
+	new->src = lxc_string_join(
+	    "/",
+	    (const char *[]){"btrfs:", *lxcpath != '/' ? lxcpath : ++lxcpath,
+			     cname, "rootfs", NULL},
+	    false);
+	if (!new->src)
+		return -1;
 
 	src = lxc_storage_get_path(new->src, "btrfs");
 	new->dest = strdup(src);


More information about the lxc-devel mailing list