There are 3 cases of VDI releasing:
1. client processes (QEMU and tgt) releases explicitly
2. client processes (QEMU and tgt) die suddenly
3. node leaves

All of them must be handled in a single policy because they must have
same effect. Currently, the case 1 and 3 are supported. This patch
makes the mechanism general and lets destroy_client() use for
supporting the case 2.

Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp>
---
 sheep/ops.c        |   15 ++++++++-------
 sheep/request.c    |    4 ++++
 sheep/sheep_priv.h |    1 +
 sheep/vdi.c        |   43 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/sheep/ops.c b/sheep/ops.c
index 26335cc..519e708 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -381,7 +381,7 @@ static int cluster_get_vdi_attr(struct request *req)
        return ret;
 }
 
-static int local_release_vdi(struct request *req)
+static int cluster_release_vdi_work(struct request *req)
 {
        uint32_t vid = req->rq.vdi.base_vdi_id;
        int ret;
@@ -1401,6 +1401,13 @@ static struct sd_op_template sd_ops[] = {
                .process_main = cluster_lock_vdi,
        },
 
+       [SD_OP_RELEASE_VDI] = {
+               .name = "RELEASE_VDI",
+               .type = SD_OP_TYPE_CLUSTER,
+               .process_work = cluster_release_vdi_work,
+               .process_main = cluster_release_vdi_main,
+       },
+
        [SD_OP_REWEIGHT] = {
                .name = "REWEIGHT",
                .type = SD_OP_TYPE_CLUSTER,
@@ -1437,12 +1444,6 @@ static struct sd_op_template sd_ops[] = {
        },
 
        /* local operations */
-       [SD_OP_RELEASE_VDI] = {
-               .name = "RELEASE_VDI",
-               .type = SD_OP_TYPE_LOCAL,
-               .process_work = local_release_vdi,
-       },
-
        [SD_OP_GET_STORE_LIST] = {
                .name = "GET_STORE_LIST",
                .type = SD_OP_TYPE_LOCAL,
diff --git a/sheep/request.c b/sheep/request.c
index 96500b9..5619225 100644
--- a/sheep/request.c
+++ b/sheep/request.c
@@ -886,6 +886,10 @@ static void destroy_client(struct client_info *ci)
        sd_debug("connection from: %s:%d", ci->conn.ipstr, ci->conn.port);
        close(ci->conn.fd);
        list_del(&ci->list);
+       if (ci->locking_interest_vid) {
+               sd_debug("unlocking VDI %"PRIx32, ci->interest_vid);
+               notify_release_vdi(ci->interest_vid);
+       }
        free(ci);
 }
 
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index f2d03b4..fc174d4 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -353,6 +353,7 @@ int sd_create_hyper_volume(const char *name, uint32_t 
*vdi_id);
 bool lock_vdi(uint32_t vid, const struct node_id *owner);
 bool unlock_vdi(uint32_t vid, const struct node_id *owner);
 void unlock_all_vdis(const struct node_id *owner);
+void notify_release_vdi(uint32_t vid);
 
 extern int ec_max_data_strip;
 
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 7c23bab..c36692f 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -1204,3 +1204,46 @@ int sd_create_hyper_volume(const char *name, uint32_t 
*vdi_id)
 out:
        return ret;
 }
+
+struct release_work {
+       struct work work;
+
+       uint32_t vid;
+};
+
+static void notify_release_vdi_work(struct work *work)
+{
+       struct release_work *rw =
+               container_of(work, struct release_work, work);
+
+       struct sd_req hdr;
+       int ret;
+
+       sd_debug("releasing VDI: %"PRIx32, rw->vid);
+       sd_init_req(&hdr, SD_OP_RELEASE_VDI);
+       hdr.vdi.base_vdi_id = rw->vid;
+
+       ret = exec_local_req(&hdr, &sys->this_node);
+       if (ret != SD_RES_SUCCESS)
+               sd_err("failed to release VDI: %"PRIx32, rw->vid);
+}
+
+static void notify_release_vdi_done(struct work *work)
+{
+       struct release_work *rw =
+               container_of(work, struct release_work, work);
+
+       sd_debug("releasing VDI: %"PRIx32" done", rw->vid);
+       free(rw);
+}
+
+void notify_release_vdi(uint32_t vid)
+{
+       struct release_work *w;
+
+       w = xzalloc(sizeof(*w));
+       w->work.fn = notify_release_vdi_work;
+       w->work.done = notify_release_vdi_done;
+       w->vid = vid;
+       queue_work(sys->gateway_wqueue, &w->work);
+}
-- 
1.7.1

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

Reply via email to