From 235072c2ee48de073afda9dedd2802eab8ff4e08 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Wed, 13 May 2015 16:42:21 +0200 Subject: btrfs-progs: Introduce change_uuid function This function does all the needed things for changing filesystem uuid. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- btrfstune.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'btrfstune.c') diff --git a/btrfstune.c b/btrfstune.c index 9a63f41b..7b8090ab 100644 --- a/btrfstune.c +++ b/btrfstune.c @@ -23,11 +23,14 @@ #include #include #include +#include + #include "kerncompat.h" #include "ctree.h" #include "disk-io.h" #include "transaction.h" #include "utils.h" +#include "volumes.h" static char *device; static int force = 0; @@ -290,6 +293,72 @@ static int change_fsid_done(struct btrfs_fs_info *fs_info) return write_all_supers(fs_info->tree_root); } +static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid, + const char *new_chunk_uuid) +{ + int ret = 0; + + /* caller should do extra check on passed uuid */ + if (new_fsid) { + /* allocated mem will be freed at close_ctree() */ + fs_info->new_fsid = malloc(BTRFS_FSID_SIZE); + if (!fs_info->new_fsid) { + ret = -ENOMEM; + goto out; + } + ret = uuid_parse(new_fsid, fs_info->new_fsid); + if (ret < 0) + goto out; + } + + if (new_chunk_uuid) { + /* allocated mem will be freed at close_ctree() */ + fs_info->new_chunk_tree_uuid = malloc(BTRFS_UUID_SIZE); + if (!fs_info->new_chunk_tree_uuid) { + ret = -ENOMEM; + goto out; + } + ret = uuid_parse(new_chunk_uuid, fs_info->new_chunk_tree_uuid); + if (ret < 0) + goto out; + } + + /* Now we can begin fsid change */ + ret = change_fsid_prepare(fs_info); + if (ret < 0) + goto out; + + /* Change extents first */ + ret = change_extents_uuid(fs_info); + if (ret < 0) { + fprintf(stderr, "Failed to change UUID of metadata\n"); + goto out; + } + + /* Then devices */ + ret = change_devices_uuid(fs_info); + if (ret < 0) { + fprintf(stderr, "Failed to change UUID of devices\n"); + goto out; + } + + /* Last, change fsid in super, only fsid change needs this */ + if (new_fsid) { + memcpy(fs_info->fs_devices->fsid, fs_info->new_fsid, + BTRFS_FSID_SIZE); + memcpy(fs_info->super_copy->fsid, fs_info->new_fsid, + BTRFS_FSID_SIZE); + ret = write_all_supers(fs_info->tree_root); + if (ret < 0) + goto out; + } + + /* Now fsid change is done */ + ret = change_fsid_done(fs_info); +out: + return ret; +} + static void print_usage(void) { fprintf(stderr, "usage: btrfstune [options] device\n"); -- cgit v1.2.3