{
puts("bcachefs device_remove - remove a device from a filesystem\n"
"Usage:\n"
- " bcachefs device remove device\n"
- " bcachefs device remove --by-id path devid\n"
+ " bcachefs device remove <device>|<devid> <path>\n"
"\n"
"Options:\n"
- " -i, --by-id Remove device by device id\n"
" -f, --force Force removal, even if some data\n"
" couldn't be migrated\n"
" -F, --force-metadata Force removal, even if some metadata\n"
};
struct bchfs_handle fs;
bool by_id = false;
- int opt, flags = BCH_FORCE_IF_DEGRADED;
- unsigned dev_idx;
+ int opt, flags = BCH_FORCE_IF_DEGRADED, dev_idx;
while ((opt = getopt_long(argc, argv, "fh", longopts, NULL)) != -1)
switch (opt) {
- case 'i':
- by_id = true;
- break;
case 'f':
flags |= BCH_FORCE_IF_DATA_LOST;
break;
}
args_shift(optind);
- if (by_id) {
- char *path = arg_pop();
- if (!path)
- die("Please supply filesystem to remove device from");
-
- char *dev_str = arg_pop();
- if (!dev_str)
- die("Please supply device id");
+ char *dev_str = arg_pop();
+ if (!dev_str)
+ die("Please supply a device");
- errno = 0;
- dev_idx = strtoul(dev_str, NULL, 10);
- if (errno)
- die("Error parsing device id: %m");
+ char *end;
+ dev_idx = strtoul(dev_str, &end, 10);
+ if (*dev_str && !*end)
+ by_id = true;
- fs = bcache_fs_open(path);
+ char *fs_path = arg_pop();
+ if (fs_path) {
+ fs = bcache_fs_open(fs_path);
+
+ if (!by_id) {
+ dev_idx = bchu_dev_path_to_idx(fs, dev_str);
+ if (dev_idx < 0)
+ die("%s does not seem to be a member of %s",
+ dev_str, fs_path);
+ }
+ } else if (!by_id) {
+ fs = bchu_fs_open_by_dev(dev_str, &dev_idx);
} else {
- char *dev = arg_pop();
- if (!dev)
- die("Please supply a device to remove");
-
- fs = bchu_fs_open_by_dev(dev, &dev_idx);
+ die("Filesystem path required when specifying device by id");
}
- if (argc)
- die("too many arguments");
-
bchu_disk_remove(fs, dev_idx, flags);
return 0;
}
if (argc)
die("too many arguments");
- unsigned dev_idx;
+ int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx);
bchu_disk_online(fs, dev);
return 0;
if (argc)
die("too many arguments");
- unsigned dev_idx;
+ int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx);
bchu_disk_offline(fs, dev_idx, flags);
return 0;
if (argc)
die("too many arguments");
- unsigned dev_idx;
+ int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev_path, &dev_idx);
struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, dev_idx);
static void device_set_state_usage(void)
{
puts("bcachefs device set-state\n"
- "Usage: bcachefs device set-state device new-state\n"
+ "Usage: bcachefs device set-state <new-state> <device>|<devid> <path>\n"
+ "\n"
+ "<new-state>: one of rw, ro, failed or spare\n"
+ "<path>: path to mounted filesystem, optional unless specifying device by id\n"
"\n"
"Options:\n"
" -f, --force Force, if data redundancy will be degraded\n"
{ "help", 0, NULL, 'h' },
{ NULL }
};
- int opt, flags = 0;
+ struct bchfs_handle fs;
+ bool by_id = false;
+ int opt, flags = 0, dev_idx;
bool offline = false;
while ((opt = getopt_long(argc, argv, "foh", longopts, NULL)) != -1)
}
args_shift(optind);
- char *dev_path = arg_pop();
- if (!dev_path)
- die("Please supply a device");
-
char *new_state_str = arg_pop();
if (!new_state_str)
die("Please supply a device state");
unsigned new_state = read_string_list_or_die(new_state_str,
bch2_member_states, "device state");
- if (!offline) {
- unsigned dev_idx;
- struct bchfs_handle fs = bchu_fs_open_by_dev(dev_path, &dev_idx);
+ char *dev_str = arg_pop();
+ if (!dev_str)
+ die("Please supply a device");
- bchu_disk_set_state(fs, dev_idx, new_state, flags);
+ char *end;
+ dev_idx = strtoul(dev_str, &end, 10);
+ if (*dev_str && !*end)
+ by_id = true;
- bcache_fs_close(fs);
- } else {
+ if (offline) {
struct bch_opts opts = bch2_opts_empty();
struct bch_sb_handle sb = { NULL };
- int ret = bch2_read_super(dev_path, &opts, &sb);
+ if (by_id)
+ die("Cannot specify offline device by id");
+
+ int ret = bch2_read_super(dev_str, &opts, &sb);
if (ret)
- die("error opening %s: %s", dev_path, strerror(-ret));
+ die("error opening %s: %s", dev_str, strerror(-ret));
struct bch_member *m = bch2_sb_get_members(sb.sb)->members + sb.sb->dev_idx;
bch2_super_write(sb.bdev->bd_fd, sb.sb);
bch2_free_super(&sb);
+ return 0;
}
+ char *fs_path = arg_pop();
+ if (fs_path) {
+ fs = bcache_fs_open(fs_path);
+
+ if (!by_id) {
+ dev_idx = bchu_dev_path_to_idx(fs, dev_str);
+ if (dev_idx < 0)
+ die("%s does not seem to be a member of %s",
+ dev_str, fs_path);
+ }
+ } else if (!by_id) {
+ fs = bchu_fs_open_by_dev(dev_str, &dev_idx);
+ } else {
+ die("Filesystem path required when specifying device by id");
+ }
+
+ bchu_disk_set_state(fs, dev_idx, new_state, flags);
+
return 0;
}