]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
bcaachefs device set-state can now work by id
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 3 Apr 2021 03:20:00 +0000 (23:20 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Sat, 3 Apr 2021 03:35:05 +0000 (23:35 -0400)
cmd_device.c
libbcachefs.c
libbcachefs.h

index 161e669256163e2523f64307c9cc49da5b581a4e..f9e975abc2b93916e0ea820aac1d3845e241a416 100644 (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 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;
 }
@@ -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;
 }
 
index 1ae9b9ab1da9dc8904e0164dea4a66036d1ff76c..e917c6cacccc60dadd65c97db2904305f2870dcf 100644 (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);
index 59c62df33592ca39ee3aeb72d225a9a57cd9244e..45d2f8740a41479e852411103e38e24a20394b9f 100644 (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)
 {