This patch adds a new subcommand "dog vdi lock list". It can be used
for detecting which nodes are locking VDIs.

Cc: Fabian Zimmermann <dev....@gmail.com>
Cc: Valerio Pachera <siri...@gmail.com>
Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp>
---
 dog/treeview.c           | 41 +++++++++++++++++++++++++++++
 dog/treeview.h           |  2 ++
 dog/vdi.c                | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/internal_proto.h | 16 ++++++++++++
 sheep/sheep_priv.h       |  9 -------
 sheep/vdi.c              |  6 -----
 6 files changed, 126 insertions(+), 15 deletions(-)

diff --git a/dog/treeview.c b/dog/treeview.c
index e3b75f4..84cfae6 100644
--- a/dog/treeview.c
+++ b/dog/treeview.c
@@ -39,6 +39,37 @@ static struct vdi_tree *find_vdi(struct vdi_tree *parent, 
uint32_t vid,
        return NULL;
 }
 
+static struct vdi_tree *find_vdi_with_vid(struct vdi_tree *parent, uint32_t 
vid)
+{
+       struct vdi_tree *vdi, *ret;
+
+       list_for_each_entry(vdi, &parent->children, siblings) {
+               if (vdi->vid == vid)
+                       return vdi;
+
+               ret = find_vdi_with_vid(vdi, vid);
+               if (ret)
+                       return ret;
+       }
+       return NULL;
+}
+
+static struct vdi_tree *find_vdi_with_name(struct vdi_tree *parent,
+                                          const char *name)
+{
+       struct vdi_tree *vdi, *ret;
+
+       list_for_each_entry(vdi, &parent->children, siblings) {
+               if (!strcmp(vdi->name, name))
+                       return vdi;
+
+               ret = find_vdi_with_name(vdi, name);
+               if (ret)
+                       return ret;
+       }
+       return NULL;
+}
+
 static struct vdi_tree *new_vdi(const char *name, const char *label,
                                uint64_t vid, uint64_t pvid, bool highlight)
 {
@@ -64,6 +95,16 @@ struct vdi_tree *find_vdi_from_root(uint32_t vid, const char 
*name)
        return find_vdi(root, vid, name);
 }
 
+struct vdi_tree *find_vdi_from_root_with_vid(uint32_t vid)
+{
+       return find_vdi_with_vid(root, vid);
+}
+
+struct vdi_tree *find_vdi_from_root_with_name(const char *name)
+{
+       return find_vdi_with_name(root, name);
+}
+
 void add_vdi_tree(const char *name, const char *label, uint32_t vid,
                  uint32_t pvid, bool highlight)
 {
diff --git a/dog/treeview.h b/dog/treeview.h
index 01443e4..e4f128a 100644
--- a/dog/treeview.h
+++ b/dog/treeview.h
@@ -29,5 +29,7 @@ void add_vdi_tree(const char *label, const char *tag, 
uint32_t vid,
                  uint32_t pvid, bool highlight);
 void dump_tree(void);
 struct vdi_tree *find_vdi_from_root(uint32_t vid, const char *name);
+struct vdi_tree *find_vdi_from_root_with_vid(uint32_t vid);
+struct vdi_tree *find_vdi_from_root_with_name(const char *name);
 
 #endif
diff --git a/dog/vdi.c b/dog/vdi.c
index 739a0af..77d3661 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -2695,6 +2695,71 @@ static int vdi_alter_copy(int argc, char **argv)
        return EXIT_FAILURE;
 }
 
+static int lock_list(int argc, char **argv)
+{
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+       struct vdi_state *vs = NULL;
+       unsigned int rlen;
+       int ret, count;
+
+#define DEFAULT_VDI_STATE_COUNT 512
+       rlen = DEFAULT_VDI_STATE_COUNT * sizeof(struct vdi_state);
+       vs = xzalloc(rlen);
+retry:
+       sd_init_req(&hdr, SD_OP_GET_VDI_COPIES);
+       hdr.data_length = rlen;
+
+       ret = dog_exec_req(&sd_nid, &hdr, (char *)vs);
+       if (ret < 0)
+               return EXIT_SYSFAIL;
+
+       switch (ret) {
+       case SD_RES_SUCCESS:
+               break;
+       case SD_RES_BUFFER_SMALL:
+               rlen *= 2;
+               vs = xrealloc(vs, rlen);
+               goto retry;
+       default:
+               sd_err("failed to execute SD_OP_GET_VDI_COPIES: %s",
+                      sd_strerror(ret));
+               goto out;
+       }
+
+       init_tree();
+       if (parse_vdi(construct_vdi_tree, SD_INODE_HEADER_SIZE, NULL) < 0)
+               return EXIT_SYSFAIL;
+
+       count = rsp->data_length / sizeof(*vs);
+
+       printf("VDI | owner node\n");
+       for (int i = 0; i < count; i++) {
+               struct vdi_tree *vdi;
+
+               if (vs[i].lock_state != LOCK_STATE_LOCKED)
+                       continue;
+
+               vdi = find_vdi_from_root_with_vid(vs[i].vid);
+               printf("%s | %s\n", vdi->name,
+                      node_id_to_str(&vs[i].lock_owner));
+       }
+
+out:
+       free(vs);
+       return ret;
+}
+
+static struct subcommand vdi_lock_cmd[] = {
+       {"list", NULL, NULL, "list locked VDIs", NULL, 0, lock_list},
+       {NULL},
+};
+
+static int vdi_lock(int argc, char **argv)
+{
+       return do_generic_subcommand(vdi_lock_cmd, argc, argv);
+}
+
 static struct subcommand vdi_cmd[] = {
        {"check", "<vdiname>", "seapht", "check and repair image's consistency",
         NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
@@ -2759,6 +2824,8 @@ static struct subcommand vdi_cmd[] = {
         vdi_cache, vdi_options},
        {"alter-copy", "<vdiname>", "capht", "set the vdi's redundancy level",
         NULL, CMD_NEED_ARG|CMD_NEED_NODELIST, vdi_alter_copy, vdi_options},
+       {"lock", NULL, "apht", "See 'dog vdi lock' for more information",
+        vdi_lock_cmd, CMD_NEED_ARG, vdi_lock, vdi_options},
        {NULL,},
 };
 
diff --git a/include/internal_proto.h b/include/internal_proto.h
index b1afc60..3611cc8 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -334,4 +334,20 @@ struct trace_graph_item;
 
 #endif /* HAVE_TRACE */
 
+/* VDI locking state, used by both of sheep and dog */
+enum lock_state {
+       LOCK_STATE_INIT,
+       LOCK_STATE_LOCKED,
+       LOCK_STATE_UNLOCKED,
+};
+
+struct vdi_state {
+       uint32_t vid;
+       uint8_t nr_copies;
+       uint8_t snapshot;
+       uint8_t copy_policy;
+       uint8_t lock_state;
+       struct node_id lock_owner;
+};
+
 #endif /* __INTERNAL_PROTO_H__ */
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index c21aa4d..1a4e53a 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -229,15 +229,6 @@ struct vdi_info {
        uint64_t create_time;
 };
 
-struct vdi_state {
-       uint32_t vid;
-       uint8_t nr_copies;
-       uint8_t snapshot;
-       uint8_t copy_policy;
-       uint8_t lock_state;
-       struct node_id lock_owner;
-};
-
 struct store_driver {
        struct list_node list;
        const char *name;
diff --git a/sheep/vdi.c b/sheep/vdi.c
index a2709db..0b564f2 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -11,12 +11,6 @@
 
 #include "sheep_priv.h"
 
-enum lock_state {
-       LOCK_STATE_INIT,
-       LOCK_STATE_LOCKED,
-       LOCK_STATE_UNLOCKED,
-};
-
 struct vdi_lock_state {
        enum lock_state state;
        struct node_id owner;
-- 
1.8.3.2

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to