bcaachefs device set-state can now work by id

This commit is contained in:
Kent Overstreet 2021-04-02 23:20:00 -04:00
parent 98844616f6
commit f46437f06e
3 changed files with 77 additions and 47 deletions

View File

@ -123,11 +123,9 @@ static void device_remove_usage(void)
{ {
puts("bcachefs device_remove - remove a device from a filesystem\n" puts("bcachefs device_remove - remove a device from a filesystem\n"
"Usage:\n" "Usage:\n"
" bcachefs device remove device\n" " bcachefs device remove <device>|<devid> <path>\n"
" bcachefs device remove --by-id path devid\n"
"\n" "\n"
"Options:\n" "Options:\n"
" -i, --by-id Remove device by device id\n"
" -f, --force Force removal, even if some data\n" " -f, --force Force removal, even if some data\n"
" couldn't be migrated\n" " couldn't be migrated\n"
" -F, --force-metadata Force removal, even if some metadata\n" " -F, --force-metadata Force removal, even if some metadata\n"
@ -148,14 +146,10 @@ int cmd_device_remove(int argc, char *argv[])
}; };
struct bchfs_handle fs; struct bchfs_handle fs;
bool by_id = false; bool by_id = false;
int opt, flags = BCH_FORCE_IF_DEGRADED; int opt, flags = BCH_FORCE_IF_DEGRADED, dev_idx;
unsigned dev_idx;
while ((opt = getopt_long(argc, argv, "fh", longopts, NULL)) != -1) while ((opt = getopt_long(argc, argv, "fh", longopts, NULL)) != -1)
switch (opt) { switch (opt) {
case 'i':
by_id = true;
break;
case 'f': case 'f':
flags |= BCH_FORCE_IF_DATA_LOST; flags |= BCH_FORCE_IF_DATA_LOST;
break; break;
@ -167,32 +161,31 @@ int cmd_device_remove(int argc, char *argv[])
} }
args_shift(optind); args_shift(optind);
if (by_id) { char *dev_str = arg_pop();
char *path = arg_pop(); if (!dev_str)
if (!path) die("Please supply a device");
die("Please supply filesystem to remove device from");
char *dev_str = arg_pop(); char *end;
if (!dev_str) dev_idx = strtoul(dev_str, &end, 10);
die("Please supply device id"); if (*dev_str && !*end)
by_id = true;
errno = 0; char *fs_path = arg_pop();
dev_idx = strtoul(dev_str, NULL, 10); if (fs_path) {
if (errno) fs = bcache_fs_open(fs_path);
die("Error parsing device id: %m");
fs = bcache_fs_open(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 { } else {
char *dev = arg_pop(); die("Filesystem path required when specifying device by id");
if (!dev)
die("Please supply a device to remove");
fs = bchu_fs_open_by_dev(dev, &dev_idx);
} }
if (argc)
die("too many arguments");
bchu_disk_remove(fs, dev_idx, flags); bchu_disk_remove(fs, dev_idx, flags);
return 0; return 0;
} }
@ -227,7 +220,7 @@ int cmd_device_online(int argc, char *argv[])
if (argc) if (argc)
die("too many arguments"); die("too many arguments");
unsigned dev_idx; int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx); struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx);
bchu_disk_online(fs, dev); bchu_disk_online(fs, dev);
return 0; return 0;
@ -272,7 +265,7 @@ int cmd_device_offline(int argc, char *argv[])
if (argc) if (argc)
die("too many arguments"); die("too many arguments");
unsigned dev_idx; int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx); struct bchfs_handle fs = bchu_fs_open_by_dev(dev, &dev_idx);
bchu_disk_offline(fs, dev_idx, flags); bchu_disk_offline(fs, dev_idx, flags);
return 0; return 0;
@ -308,7 +301,7 @@ int cmd_device_evacuate(int argc, char *argv[])
if (argc) if (argc)
die("too many arguments"); die("too many arguments");
unsigned dev_idx; int dev_idx;
struct bchfs_handle fs = bchu_fs_open_by_dev(dev_path, &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); struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, dev_idx);
@ -331,7 +324,10 @@ int cmd_device_evacuate(int argc, char *argv[])
static void device_set_state_usage(void) static void device_set_state_usage(void)
{ {
puts("bcachefs device set-state\n" 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" "\n"
"Options:\n" "Options:\n"
" -f, --force Force, if data redundancy will be degraded\n" " -f, --force Force, if data redundancy will be degraded\n"
@ -349,7 +345,9 @@ int cmd_device_set_state(int argc, char *argv[])
{ "help", 0, NULL, 'h' }, { "help", 0, NULL, 'h' },
{ NULL } { NULL }
}; };
int opt, flags = 0; struct bchfs_handle fs;
bool by_id = false;
int opt, flags = 0, dev_idx;
bool offline = false; bool offline = false;
while ((opt = getopt_long(argc, argv, "foh", longopts, NULL)) != -1) while ((opt = getopt_long(argc, argv, "foh", longopts, NULL)) != -1)
@ -365,10 +363,6 @@ int cmd_device_set_state(int argc, char *argv[])
} }
args_shift(optind); args_shift(optind);
char *dev_path = arg_pop();
if (!dev_path)
die("Please supply a device");
char *new_state_str = arg_pop(); char *new_state_str = arg_pop();
if (!new_state_str) if (!new_state_str)
die("Please supply a device state"); die("Please supply a device state");
@ -376,20 +370,25 @@ int cmd_device_set_state(int argc, char *argv[])
unsigned new_state = read_string_list_or_die(new_state_str, unsigned new_state = read_string_list_or_die(new_state_str,
bch2_member_states, "device state"); bch2_member_states, "device state");
if (!offline) { char *dev_str = arg_pop();
unsigned dev_idx; if (!dev_str)
struct bchfs_handle fs = bchu_fs_open_by_dev(dev_path, &dev_idx); 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); if (offline) {
} else {
struct bch_opts opts = bch2_opts_empty(); struct bch_opts opts = bch2_opts_empty();
struct bch_sb_handle sb = { NULL }; 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) 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; struct bch_member *m = bch2_sb_get_members(sb.sb)->members + sb.sb->dev_idx;
@ -399,8 +398,27 @@ int cmd_device_set_state(int argc, char *argv[])
bch2_super_write(sb.bdev->bd_fd, sb.sb); bch2_super_write(sb.bdev->bd_fd, sb.sb);
bch2_free_super(&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; return 0;
} }

View File

@ -900,7 +900,7 @@ struct bchfs_handle bcache_fs_open(const char *path)
* Given a path to a block device, open the filesystem it belongs to; also * Given a path to a block device, open the filesystem it belongs to; also
* return the device's idx: * return the device's idx:
*/ */
struct bchfs_handle bchu_fs_open_by_dev(const char *path, unsigned *idx) struct bchfs_handle bchu_fs_open_by_dev(const char *path, int *idx)
{ {
char buf[1024], *uuid_str; char buf[1024], *uuid_str;
@ -944,6 +944,17 @@ struct bchfs_handle bchu_fs_open_by_dev(const char *path, unsigned *idx)
return bcache_fs_open(uuid_str); return bcache_fs_open(uuid_str);
} }
int bchu_dev_path_to_idx(struct bchfs_handle fs, const char *dev_path)
{
int idx;
struct bchfs_handle fs2 = bchu_fs_open_by_dev(dev_path, &idx);
if (memcmp(&fs.uuid, &fs2.uuid, sizeof(fs.uuid)))
idx = -1;
bcache_fs_close(fs2);
return idx;
}
int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd) int bchu_data(struct bchfs_handle fs, struct bch_ioctl_data cmd)
{ {
int progress_fd = xioctl(fs.ioctl_fd, BCH_IOCTL_DATA, &cmd); int progress_fd = xioctl(fs.ioctl_fd, BCH_IOCTL_DATA, &cmd);

View File

@ -94,7 +94,8 @@ struct bchfs_handle {
void bcache_fs_close(struct bchfs_handle); void bcache_fs_close(struct bchfs_handle);
struct bchfs_handle bcache_fs_open(const char *); struct bchfs_handle bcache_fs_open(const char *);
struct bchfs_handle bchu_fs_open_by_dev(const char *, unsigned *); struct bchfs_handle bchu_fs_open_by_dev(const char *, int *);
int bchu_dev_path_to_idx(struct bchfs_handle, const char *);
static inline void bchu_disk_add(struct bchfs_handle fs, char *dev) static inline void bchu_disk_add(struct bchfs_handle fs, char *dev)
{ {