#include <unistd.h>
#include <dirent.h>
#include <uuid/uuid.h>
+#include <getopt.h>
#include "kerncompat.h"
#include "ctree.h"
int same_chunk_tree_uuid = 1;
int ret;
- /* Check for whether we need to change fs/chunk id */
- if (!fs_info->new_fsid && !fs_info->new_chunk_tree_uuid)
- return 0;
- if (fs_info->new_fsid)
- same_fsid = !memcmp_extent_buffer(eb, fs_info->new_fsid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
- if (fs_info->new_chunk_tree_uuid)
- same_chunk_tree_uuid =
- !memcmp_extent_buffer(eb, fs_info->new_chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(eb),
- BTRFS_UUID_SIZE);
+ same_fsid = !memcmp_extent_buffer(eb, fs_info->new_fsid,
+ btrfs_header_fsid(), BTRFS_FSID_SIZE);
+ same_chunk_tree_uuid =
+ !memcmp_extent_buffer(eb, fs_info->new_chunk_tree_uuid,
+ btrfs_header_chunk_tree_uuid(eb),
+ BTRFS_UUID_SIZE);
if (same_fsid && same_chunk_tree_uuid)
return 0;
if (!same_fsid)
struct btrfs_key key = {0, 0, 0};
int ret = 0;
- if (!fs_info->new_fsid && !fs_info->new_chunk_tree_uuid)
- return 0;
-
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
int ret = 0;
di = btrfs_item_ptr(eb, slot, struct btrfs_dev_item);
- if (fs_info->new_fsid) {
- if (!memcmp_extent_buffer(eb, fs_info->new_fsid,
- (unsigned long)btrfs_device_fsid(di),
- BTRFS_FSID_SIZE))
- return ret;
- write_extent_buffer(eb, fs_info->new_fsid,
- (unsigned long)btrfs_device_fsid(di),
- BTRFS_FSID_SIZE);
- ret = write_tree_block(NULL, root, eb);
- }
+ if (!memcmp_extent_buffer(eb, fs_info->new_fsid,
+ (unsigned long)btrfs_device_fsid(di),
+ BTRFS_FSID_SIZE))
+ return ret;
+
+ write_extent_buffer(eb, fs_info->new_fsid,
+ (unsigned long)btrfs_device_fsid(di),
+ BTRFS_FSID_SIZE);
+ ret = write_tree_block(NULL, root, eb);
+
return ret;
}
struct btrfs_key key = {0, 0, 0};
int ret = 0;
- /*
- * Unlike change_extents_uuid, we only need to change fsid in dev_item
- */
- if (!fs_info->new_fsid)
- return 0;
-
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
u64 flags = btrfs_super_flags(fs_info->super_copy);
int ret = 0;
- if (!fs_info->new_fsid && !fs_info->new_chunk_tree_uuid)
- return 0;
-
- if (fs_info->new_fsid)
- flags |= BTRFS_SUPER_FLAG_CHANGING_FSID;
+ flags |= BTRFS_SUPER_FLAG_CHANGING_FSID;
btrfs_set_super_flags(fs_info->super_copy, flags);
memcpy(fs_info->super_copy->fsid, fs_info->new_fsid, BTRFS_FSID_SIZE);
{
u64 flags = btrfs_super_flags(fs_info->super_copy);
- if (!fs_info->new_fsid && !fs_info->new_chunk_tree_uuid)
- return 0;
-
- if (fs_info->new_fsid)
- flags &= ~BTRFS_SUPER_FLAG_CHANGING_FSID;
+ flags &= ~BTRFS_SUPER_FLAG_CHANGING_FSID;
btrfs_set_super_flags(fs_info->super_copy, flags);
return write_all_supers(fs_info->tree_root);
{
uuid_t new_fsid;
uuid_t new_chunk_id;
+ uuid_t old_fsid;
char uuid_buf[BTRFS_UUID_UNPARSED_SIZE];
int ret = 0;
fs_info->new_fsid = new_fsid;
fs_info->new_chunk_tree_uuid = new_chunk_id;
- uuid_unparse_upper(new_fsid, uuid_buf);
- printf("Changing fsid to %s\n", uuid_buf);
+ memcpy(old_fsid, (const char*)fs_info->fsid, BTRFS_UUID_SIZE);
+ uuid_unparse(old_fsid, uuid_buf);
+ printf("Current fsid: %s\n", uuid_buf);
+
+ uuid_unparse(new_fsid, uuid_buf);
+ printf("New fsid: %s\n", uuid_buf);
/* Now we can begin fsid change */
+ printf("Set superblock flag CHANGING_FSID\n");
ret = change_fsid_prepare(fs_info);
if (ret < 0)
goto out;
/* Change extents first */
+ printf("Change fsid in extents\n");
ret = change_extents_uuid(fs_info);
if (ret < 0) {
fprintf(stderr, "Failed to change UUID of metadata\n");
}
/* Then devices */
+ printf("Change fsid on devices\n");
ret = change_devices_uuid(fs_info);
if (ret < 0) {
fprintf(stderr, "Failed to change UUID of devices\n");
goto out;
/* Now fsid change is done */
+ printf("Clear superblock flag CHANGING_FSID\n");
ret = change_fsid_done(fs_info);
fs_info->new_fsid = NULL;
fs_info->new_chunk_tree_uuid = NULL;
- printf("Fsid changed to %s\n", uuid_buf);
+ printf("Fsid change finished\n");
out:
return ret;
}
int ret;
u64 super_flags = 0;
- optind = 1;
while(1) {
- int c = getopt(argc, argv, "S:rxfuU:n");
+ static const struct option long_options[] = {
+ { "help", no_argument, NULL, GETOPT_VAL_HELP},
+ { NULL, 0, NULL, 0 }
+ };
+ int c = getopt_long(argc, argv, "S:rxfuU:n", long_options, NULL);
+
if (c < 0)
break;
switch(c) {
ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH;
random_fsid = 1;
break;
+ case GETOPT_VAL_HELP:
default:
print_usage();
- return 1;
+ return c != GETOPT_VAL_HELP;
}
}
set_argv0(argv);
- argc = argc - optind;
device = argv[optind];
- if (check_argc_exact(argc, 1)) {
+ if (check_argc_exact(argc - optind, 1)) {
print_usage();
return 1;
}
}
out:
close_ctree(root);
+ btrfs_close_all_devices();
return ret;
}