This patch associates client info and locked vdi. The association is required for releasing locked VDI in a case of unexpected death of clients.
Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp> --- sheep/ops.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- sheep/request.c | 12 ++++++++++++ sheep/sheep_priv.h | 4 ++++ 3 files changed, 64 insertions(+), 1 deletions(-) diff --git a/sheep/ops.c b/sheep/ops.c index 1056935..26335cc 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -235,6 +235,18 @@ static int cluster_get_vdi_info(struct request *req) return ret; } +static int cluster_lock_vdi_work(struct request *req) +{ + int ret; + + ret = cluster_get_vdi_info(req); + if (ret != SD_RES_SUCCESS) + return ret; + + req->ci->interest_vid = req->rp.vdi.vdi_id; + return ret; +} + static int remove_epoch(uint32_t epoch) { int ret; @@ -1254,6 +1266,41 @@ static int cluster_lock_vdi(const struct sd_req *req, struct sd_rsp *rsp, return SD_RES_VDI_NOT_LOCKED; } + if (!memcmp(&sender->nid, &sys->this_node.nid, + sizeof(struct node_id))) { + struct client_info *ci = lookup_interested_client(vid); + ci->locking_interest_vid = true; + + sd_debug("client with fd: %d is interested in VDI: %"PRIx32, + ci->conn.fd, vid); + } + + return SD_RES_SUCCESS; +} + +static int cluster_release_vdi_main(const struct sd_req *req, + struct sd_rsp *rsp, void *data, + const struct sd_node *sender) +{ + uint32_t vid = req->vdi.base_vdi_id; + + sd_info("node: %s is unlocking VDI: %"PRIx32, node_to_str(sender), vid); + + unlock_vdi(vid, &sender->nid); + + if (node_is_local(sender)) { + struct client_info *ci = lookup_interested_client(vid); + + if (!ci) /* client is already destroyed */ + return SD_RES_SUCCESS; + + ci->locking_interest_vid = false; + ci->interest_vid = 0; + + sd_debug("client with fd: %d is unlocking VDI: %"PRIx32, + ci->conn.fd, vid); + } + return SD_RES_SUCCESS; } @@ -1350,7 +1397,7 @@ static struct sd_op_template sd_ops[] = { [SD_OP_LOCK_VDI] = { .name = "LOCK_VDI", .type = SD_OP_TYPE_CLUSTER, - .process_work = cluster_get_vdi_info, + .process_work = cluster_lock_vdi_work, .process_main = cluster_lock_vdi, }, diff --git a/sheep/request.c b/sheep/request.c index 6a6b61f..96500b9 100644 --- a/sheep/request.c +++ b/sheep/request.c @@ -913,6 +913,18 @@ static void clear_client_info(struct client_info *ci) static LIST_HEAD(client_list); +struct client_info *lookup_interested_client(uint32_t vid) +{ + struct client_info *ci; + + list_for_each_entry(ci, &client_list, list) { + if (ci->interest_vid == vid) + return ci; + } + + return NULL; +} + static struct client_info *create_client(int fd, struct cluster_info *cluster) { struct client_info *ci; diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index fdf07e0..f2d03b4 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -77,6 +77,9 @@ struct client_info { refcnt_t refcnt; struct list_node list; + + bool locking_interest_vid; + uint32_t interest_vid; }; enum REQUST_STATUS { @@ -322,6 +325,7 @@ static inline bool is_aligned_to_pagesize(void *p) int create_listen_port(const char *bindaddr, int port); int init_unix_domain_socket(const char *dir); void unregister_listening_fds(void); +struct client_info *lookup_interested_client(uint32_t vid); int init_store_driver(bool is_gateway); int init_global_pathnames(const char *d, char *); -- 1.7.1 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog