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"
"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"
@ -148,14 +146,10 @@ int cmd_device_remove(int argc, char *argv[])
};
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;
@ -167,32 +161,31 @@ int cmd_device_remove(int argc, char *argv[])
}
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 a device");
char *dev_str = arg_pop();
if (!dev_str)
die("Please supply device id");
char *end;
dev_idx = strtoul(dev_str, &end, 10);
if (*dev_str && !*end)
by_id = true;
errno = 0;
dev_idx = strtoul(dev_str, NULL, 10);
if (errno)
die("Error parsing device id: %m");
char *fs_path = arg_pop();
if (fs_path) {
fs = bcache_fs_open(fs_path);
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 {
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;
}
@ -227,7 +220,7 @@ int cmd_device_online(int argc, char *argv[])
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;
@ -272,7 +265,7 @@ int cmd_device_offline(int argc, char *argv[])
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;
@ -308,7 +301,7 @@ int cmd_device_evacuate(int argc, char *argv[])
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);
@ -331,7 +324,10 @@ int cmd_device_evacuate(int argc, char *argv[])
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"
@ -349,7 +345,9 @@ int cmd_device_set_state(int argc, char *argv[])
{ "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)
@ -365,10 +363,6 @@ int cmd_device_set_state(int argc, char *argv[])
}
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");
@ -376,20 +370,25 @@ int cmd_device_set_state(int argc, char *argv[])
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;
@ -399,8 +398,27 @@ int cmd_device_set_state(int argc, char *argv[])
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;
}

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
* 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;
@ -944,6 +944,17 @@ struct bchfs_handle bchu_fs_open_by_dev(const char *path, unsigned *idx)
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 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);
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)
{