[lxc-devel] [lxc/master] lvm: generate new UUID for xfs + btrfs filesystems

brauner on Github lxc-bot at linuxcontainers.org
Mon Nov 13 14:04:02 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 381 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171113/c8721339/attachment.bin>
-------------- next part --------------
From d59f08f3acbc12b2de53f032ea8b415293275c46 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 13 Nov 2017 15:01:42 +0100
Subject: [PATCH] lvm: generate new UUID for xfs + btrfs filesystems

Closes #1909.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/storage/lvm.c | 57 +++++++++++++++++++++++++++++++++++++++++----------
 src/lxc/storage/lvm.h |  1 -
 2 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/src/lxc/storage/lvm.c b/src/lxc/storage/lvm.c
index 105377890..86ca7670a 100644
--- a/src/lxc/storage/lvm.c
+++ b/src/lxc/storage/lvm.c
@@ -51,6 +51,7 @@ struct lvcreate_args {
 	const char *vg;
 	const char *lv;
 	const char *thinpool;
+	const char *fstype;
 
 	/* snapshot specific arguments */
 	const char *source_lv;
@@ -313,12 +314,27 @@ int lvm_is_thin_pool(const char *path)
 	return lvm_compare_lv_attr(path, 0, 't');
 }
 
-int lvm_snapshot(const char *orig, const char *path, uint64_t size)
+static int lvm_snapshot_create_new_uuid_wrapper(void *data)
+{
+	struct lvcreate_args *args = data;
+
+	if (strcmp(args->fstype, "xfs") == 0)
+		execlp("xfs_admin", "xfs_admin", "-U", "generate", args->lv, (char *)NULL);
+
+	if (strcmp(args->fstype, "btrfs") == 0)
+		execlp("btrfstune", "btrfstune", "-f", "-u", args->lv, (char *)NULL);
+
+	return -1;
+}
+
+static int lvm_snapshot(struct lxc_storage *orig, const char *path, uint64_t size)
 {
 	int ret;
-	char *pathdup, *lv;
+	char *origsrc, *pathdup, *lv;
 	char sz[24];
+	char fstype[100];
 	char cmd_output[MAXPATHLEN];
+	char repairchar;
 	struct lvcreate_args cmd_args = {0};
 
 	ret = snprintf(sz, 24, "%" PRIu64 "b", size);
@@ -339,6 +355,7 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size)
 		free(pathdup);
 		return -1;
 	}
+	repairchar = *lv;
 	*lv = '\0';
 	lv++;
 	TRACE("Parsed logical volume \"%s\"", lv);
@@ -347,24 +364,43 @@ int lvm_snapshot(const char *orig, const char *path, uint64_t size)
 	 * which case we cannot specify a size that's different from the
 	 * original size.
 	 */
-	ret = lvm_is_thin_volume(orig);
+	origsrc = lxc_storage_get_path(orig->src, "lvm");
+	ret = lvm_is_thin_volume(origsrc);
 	if (ret < 0) {
 		free(pathdup);
 		return -1;
 	} else if (ret) {
-		cmd_args.thinpool = orig;
+		cmd_args.thinpool = origsrc;
 	}
 
 	cmd_args.lv = lv;
-	cmd_args.source_lv = orig;
+	cmd_args.source_lv = origsrc;
 	cmd_args.size = sz;
 	TRACE("Creating new lvm snapshot \"%s\" of \"%s\" with size \"%s\"", lv,
-	      orig, sz);
+	      origsrc, sz);
 	ret = run_command(cmd_output, sizeof(cmd_output),
 			  lvm_snapshot_exec_wrapper, (void *)&cmd_args);
 	if (ret < 0) {
-		ERROR("Failed to create logical volume \"%s\": %s", orig,
-		      cmd_output);
+		ERROR("Failed to create logical volume \"%s\": %s", lv, cmd_output);
+		free(pathdup);
+		return -1;
+	}
+
+	if (detect_fs(orig, fstype, 100) < 0) {
+		INFO("Failed to detect filesystem type for \"%s\"", origsrc);
+		free(pathdup);
+		return -1;
+	}
+
+	/* repair path */
+	lv--;
+	*lv = repairchar;
+	cmd_args.lv = pathdup;
+	cmd_args.fstype = fstype;
+	ret = run_command(cmd_output, sizeof(cmd_output),
+			  lvm_snapshot_create_new_uuid_wrapper, (void *)&cmd_args);
+	if (ret < 0) {
+		ERROR("Failed to create new uuid for volume \"%s\": %s", pathdup, cmd_output);
 		free(pathdup);
 		return -1;
 	}
@@ -524,7 +560,7 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
 			 struct lxc_storage *new, uint64_t newsize)
 {
 	int ret;
-	char *newsrc, *origsrc;
+	char *newsrc;
 	uint64_t size = newsize;
 
 	if (is_blktype(orig)) {
@@ -537,10 +573,9 @@ bool lvm_create_snapshot(struct lxc_conf *conf, struct lxc_storage *orig,
 			size = DEFAULT_FS_SIZE;
 	}
 
-	origsrc = lxc_storage_get_path(orig->src, "lvm");
 	newsrc = lxc_storage_get_path(new->src, "lvm");
 
-	ret = lvm_snapshot(origsrc, newsrc, size);
+	ret = lvm_snapshot(orig, newsrc, size);
 	if (ret < 0) {
 		ERROR("Failed to create lvm \"%s\" snapshot of \"%s\"",
 		      new->src, orig->src);
diff --git a/src/lxc/storage/lvm.h b/src/lxc/storage/lvm.h
index 6a82f801a..a86387b07 100644
--- a/src/lxc/storage/lvm.h
+++ b/src/lxc/storage/lvm.h
@@ -40,7 +40,6 @@ extern int lvm_umount(struct lxc_storage *bdev);
 extern int lvm_compare_lv_attr(const char *path, int pos, const char expected);
 extern int lvm_is_thin_volume(const char *path);
 extern int lvm_is_thin_pool(const char *path);
-extern int lvm_snapshot(const char *orig, const char *path, uint64_t size);
 extern int lvm_clonepaths(struct lxc_storage *orig, struct lxc_storage *new,
 			  const char *oldname, const char *cname,
 			  const char *oldpath, const char *lxcpath, int snap,


More information about the lxc-devel mailing list