@@ -23,6 +23,7 @@
#include <getopt.h>
#include <errno.h>
#include <stdbool.h>
+#include <ctype.h>
#include <uuid/uuid.h>
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
@@ -63,6 +64,37 @@ static int set_super_incompat_flags(struct btrfs_root *root, u64 flags)
return ret;
}
+static bool array_append(char **dest, char *src, int *cnt)
+{
+ char *this_tok = strtok(src, ",");
+ int ret_cnt = *cnt;
+
+ while(this_tok != NULL) {
+ ret_cnt++;
+ dest = realloc(dest, sizeof(char *) * ret_cnt);
+ if (!dest)
+ return false;
+
+ dest[ret_cnt - 1] = strdup(this_tok);
+ *cnt = ret_cnt;
+
+ this_tok = strtok(NULL, ",");
+ }
+
+ return true;
+}
+
+static void free_array(char **prt, int cnt)
+{
+ if (!prt)
+ return;
+
+ for (int i = 0; i < cnt; i++)
+ free(prt[i]);
+
+ free(prt);
+}
+
static int convert_to_fst(struct btrfs_fs_info *fs_info)
{
int ret;
@@ -117,6 +149,7 @@ static const char * const tune_usage[] = {
"",
"General:",
OPTLINE("-f", "allow dangerous operations, make sure that you are aware of the dangers"),
+ OPTLINE("--device", "devices or regular-files of the filesystem to be scanned"),
OPTLINE("--help", "print this help"),
#if EXPERIMENTAL
"",
@@ -144,6 +177,8 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
bool to_bg_tree = false;
bool to_fst = false;
int csum_type = -1;
+ int argc_devices = 0;
+ char **argv_devices = NULL;
char *new_fsid_str = NULL;
int ret = 1;
u64 super_flags = 0;
@@ -155,7 +190,8 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
enum { GETOPT_VAL_CSUM = GETOPT_VAL_FIRST,
GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE,
GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE,
- GETOPT_VAL_ENABLE_FREE_SPACE_TREE };
+ GETOPT_VAL_ENABLE_FREE_SPACE_TREE,
+ GETOPT_VAL_DEVICE };
static const struct option long_options[] = {
{ "help", no_argument, NULL, GETOPT_VAL_HELP},
{ "convert-to-block-group-tree", no_argument, NULL,
@@ -167,6 +203,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
#if EXPERIMENTAL
{ "csum", required_argument, NULL, GETOPT_VAL_CSUM },
#endif
+ { "device", required_argument, NULL, GETOPT_VAL_DEVICE },
{ NULL, 0, NULL, 0 }
};
int c = getopt_long(argc, argv, "S:rxfuU:nmM:", long_options, NULL);
@@ -210,6 +247,21 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
case GETOPT_VAL_ENABLE_BLOCK_GROUP_TREE:
to_bg_tree = true;
break;
+ case GETOPT_VAL_DEVICE:
+ if (!argv_devices) {
+ argv_devices = malloc(sizeof(char *));
+ if (!argv_devices) {
+ error("memory alloc failed");
+ return 1;
+ }
+ }
+
+ if (!array_append(argv_devices, optarg,
+ &argc_devices)) {
+ error("memory alloc failed");
+ goto free_out;
+ }
+ break;
case GETOPT_VAL_DISABLE_BLOCK_GROUP_TREE:
to_extent_tree = true;
break;
@@ -285,6 +337,16 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
goto free_out;
}
+ /*
+ * check_mounted_where() with noscan == true frees the scanned devices
+ * scan the command line provided device list now.
+ */
+ if (argv_devices) {
+ ret = btrfs_scan_argv_devices(0, argc_devices, argv_devices);
+ if (ret)
+ goto free_out;
+ }
+
root = open_ctree_fd(fd, device, 0, ctree_flags);
if (!root) {
@@ -438,5 +500,6 @@ out:
btrfs_close_all_devices();
free_out:
+ free_array(argv_devices, argc_devices);
return ret;
}
As of now, btrfstune only accepts one device from the command line and then scans the system to find other parter devices if any. However, this method mandates always accessing the file raw image as a loop device. This patch modifies btrfstune to accept other devices or reg-files from the command line using an option --device and scans/registers them. For example: btrfstune -m --device /tdev/td1,/tdev/td2 /tdev/td3 or btrfstune -m --device /tdev/td1 --device /tdev/td2 /tdev/td3 Signed-off-by: Anand Jain <anand.jain@oracle.com> --- tune/main.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-)