]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lvm: generate new UUID for xfs + btrfs filesystems 1922/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 13 Nov 2017 14:01:42 +0000 (15:01 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 13 Nov 2017 14:03:19 +0000 (15:03 +0100)
Closes #1909.

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

index 105377890f2499b78facc6997baf378829280bf1..86ca7670a4ff328b0ae843a331274f7d2e1c0ff5 100644 (file)
@@ -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);
index 6a82f801a688f7b4112645ad4f31f6e2fbda816d..a86387b07cb0cb092542dc8c41a101005055ced3 100644 (file)
@@ -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,