From d59f08f3acbc12b2de53f032ea8b415293275c46 Mon Sep 17 00:00:00 2001 From: Christian Brauner 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 --- 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, -- 2.47.2