Current bs_sheepdog.c rises error when connection for sheep daemon is closed. This is not suitable when administrators want to update sheepdog. This patch implements reconnection functionality in bs_sheepdog.c for this purpose. Signed-off-by: Hitoshi Mitake <mitake.hitoshi@xxxxxxxxxxxxx> --- usr/bs_sheepdog.c | 141 +++++++++++++++++++++--------------------------------- 1 file changed, 55 insertions(+), 86 deletions(-) diff --git a/usr/bs_sheepdog.c b/usr/bs_sheepdog.c index 329cebb..4b5a951 100644 --- a/usr/bs_sheepdog.c +++ b/usr/bs_sheepdog.c @@ -516,69 +516,70 @@ static int send_req(int sockfd, struct sheepdog_req *hdr, void *data, return ret; } -static int do_req(int sockfd, struct sheepdog_req *hdr, void *data, - unsigned int *wlen, unsigned int *rlen) +static int do_req(struct sheepdog_access_info *ai, struct sheepdog_req *hdr, + void *data, unsigned int *wlen, unsigned int *rlen) { - int ret; + int ret, sockfd, count = 0; - ret = send_req(sockfd, hdr, data, wlen); - if (ret) { - ret = -1; - goto out; +retry: + if (count++) { + eprintf("retrying to reconnect (%d)\n", count); + if (0 <= sockfd) + close_my_fd(ai, sockfd); + + sleep(1); } + sockfd = get_my_fd(ai); + if (sockfd < 0) + goto retry; + + ret = send_req(sockfd, hdr, data, wlen); + if (ret) + goto retry; + + /* FIXME: retrying COW request should be handled in graceful way */ ret = do_read(sockfd, hdr, sizeof(*hdr)); - if (ret) { - eprintf("failed to get a rsp, %s\n", strerror(errno)); - ret = -1; - goto out; - } + if (ret) + goto retry; if (hdr->data_length < *rlen) *rlen = hdr->data_length; if (*rlen) { ret = do_read(sockfd, data, *rlen); - if (ret) { - eprintf("failed to get the data, %s\n", - strerror(errno)); - ret = -1; - goto out; - } + if (ret) + goto retry; } - ret = 0; -out: - return ret; + + return 0; } -static int find_vdi_name(char *filename, uint32_t snapid, - char *tag, uint32_t *vid, int for_snapshot); -static int read_object(int fd, char *buf, uint64_t oid, int copies, - unsigned int datalen, uint64_t offset); +static int find_vdi_name(struct sheepdog_access_info *ai, char *filename, + uint32_t snapid, char *tag, uint32_t *vid, + int for_snapshot); +static int read_object(struct sheepdog_access_info *ai, char *buf, uint64_t oid, + int copies, unsigned int datalen, uint64_t offset); static int reload_inode(struct sheepdog_access_info *ai) { int ret; char tag[SD_MAX_VDI_TAG_LEN]; uint32_t vid; - int fd; memset(tag, 0, sizeof(tag)); - ret = find_vdi_name(ai->inode.name, CURRENT_VDI_ID, tag, &vid, 0); + ret = find_vdi_name(ai, ai->inode.name, CURRENT_VDI_ID, tag, &vid, 0); if (ret) return -1; - fd = get_my_fd(ai); - if (fd < 0) - return -1; - - read_object(fd, (char *)&ai->inode, vid_to_vdi_oid(vid), + read_object(ai, (char *)&ai->inode, vid_to_vdi_oid(vid), ai->inode.nr_copies, SD_INODE_SIZE, 0); return 0; } -static int read_write_object(int fd, char *buf, uint64_t oid, int copies, +static int read_write_object(struct sheepdog_access_info *ai, char *buf, + uint64_t oid, int copies, unsigned int datalen, uint64_t offset, int write, int create, uint64_t old_oid, uint16_t flags, int *need_reload) @@ -612,7 +613,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, hdr.offset = offset; hdr.copies = copies; - ret = do_req(fd, (struct sheepdog_req *)&hdr, buf, &wlen, &rlen); + ret = do_req(ai, (struct sheepdog_req *)&hdr, buf, &wlen, &rlen); if (ret) { eprintf("failed to send a request to the sheep\n"); return -1; @@ -632,18 +633,20 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, } } -static int read_object(int fd, char *buf, uint64_t oid, int copies, +static int read_object(struct sheepdog_access_info *ai, char *buf, + uint64_t oid, int copies, unsigned int datalen, uint64_t offset) { - return read_write_object(fd, buf, oid, copies, datalen, offset, + return read_write_object(ai, buf, oid, copies, datalen, offset, 0, 0, 0, 0, NULL); } -static int write_object(int fd, char *buf, uint64_t oid, int copies, +static int write_object(struct sheepdog_access_info *ai, char *buf, + uint64_t oid, int copies, unsigned int datalen, uint64_t offset, int create, uint64_t old_oid, uint16_t flags, int *need_reload) { - return read_write_object(fd, buf, oid, copies, datalen, offset, 1, + return read_write_object(ai, buf, oid, copies, datalen, offset, 1, create, old_oid, flags, need_reload); } @@ -653,7 +656,6 @@ static int sd_sync(struct sheepdog_access_info *ai) struct sheepdog_obj_req hdr; struct sheepdog_obj_rsp *rsp = (struct sheepdog_obj_rsp *)&hdr; unsigned int wlen = 0, rlen; - int fd; memset(&hdr, 0, sizeof(hdr)); @@ -661,11 +663,7 @@ static int sd_sync(struct sheepdog_access_info *ai) hdr.opcode = SD_OP_FLUSH_VDI; hdr.oid = vid_to_vdi_oid(ai->inode.vdi_id); - fd = get_my_fd(ai); - if (fd < 0) - return -1; - - ret = do_req(fd, (struct sheepdog_req *)&hdr, NULL, &wlen, &rlen); + ret = do_req(ai, (struct sheepdog_req *)&hdr, NULL, &wlen, &rlen); if (ret) { eprintf("failed to send a request to the sheep\n"); return -1; @@ -690,7 +688,6 @@ static int update_inode(struct sheepdog_access_info *ai) int ret = 0; uint64_t oid = vid_to_vdi_oid(ai->inode.vdi_id); uint32_t min, max, offset, data_len; - int fd; min = ai->min_dirty_data_idx; max = ai->max_dirty_data_idx; @@ -702,12 +699,7 @@ static int update_inode(struct sheepdog_access_info *ai) min * sizeof(ai->inode.data_vdi_id[0]); data_len = (max - min + 1) * sizeof(ai->inode.data_vdi_id[0]); - fd = get_my_fd(ai); - if (fd < 0) { - ret = -1; - goto end; - } - ret = write_object(fd, (char *)&ai->inode + offset, oid, + ret = write_object(ai, (char *)&ai->inode + offset, oid, ai->inode.nr_copies, data_len, offset, 0, 0, 0, NULL); if (ret < 0) @@ -734,11 +726,6 @@ static int sd_io(struct sheepdog_access_info *ai, int write, char *buf, int len, uint16_t flags = 0; int need_update_inode = 0, need_reload_inode; int nr_copies = ai->inode.nr_copies; - int fd; - - fd = get_my_fd(ai); - if (fd < 0) - return -1; if (write) pthread_rwlock_wrlock(&ai->inode_lock); @@ -777,7 +764,7 @@ retry: } need_reload_inode = 0; - ret = write_object(fd, buf + (len - rest), + ret = write_object(ai, buf + (len - rest), oid, nr_copies, size, obj_offset, create, old_oid, flags, &need_reload_inode); @@ -799,7 +786,7 @@ retry: goto done; } - ret = read_object(fd, buf + (len - rest), + ret = read_object(ai, buf + (len - rest), oid, nr_copies, size, obj_offset); } @@ -822,19 +809,16 @@ done: return ret; } -static int find_vdi_name(char *filename, uint32_t snapid, - char *tag, uint32_t *vid, int for_snapshot) +static int find_vdi_name(struct sheepdog_access_info *ai, char *filename, + uint32_t snapid, char *tag, uint32_t *vid, + int for_snapshot) { - int ret, fd; + int ret; struct sheepdog_vdi_req hdr; struct sheepdog_vdi_rsp *rsp = (struct sheepdog_vdi_rsp *)&hdr; unsigned int wlen, rlen = 0; char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN]; - fd = connect_to_sdog(NULL, NULL); - if (fd < 0) - return -1; - memset(buf, 0, sizeof(buf)); strncpy(buf, filename, SD_MAX_VDI_LEN); strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); @@ -851,7 +835,7 @@ static int find_vdi_name(char *filename, uint32_t snapid, hdr.snapid = snapid; hdr.flags = SD_FLAG_CMD_WRITE; - ret = do_req(fd, (struct sheepdog_req *)&hdr, buf, &wlen, &rlen); + ret = do_req(ai, (struct sheepdog_req *)&hdr, buf, &wlen, &rlen); if (ret) { ret = -1; goto out; @@ -866,33 +850,27 @@ static int find_vdi_name(char *filename, uint32_t snapid, *vid = rsp->vdi_id; ret = 0; + out: - close(fd); return ret; } static int sd_open(struct sheepdog_access_info *ai, char *filename, int flags) { - int ret, fd; + int ret; uint32_t vid = 0; char tag[SD_MAX_VDI_TAG_LEN]; memset(tag, 0, sizeof(tag)); - ret = find_vdi_name(filename, CURRENT_VDI_ID, tag, &vid, 0); + ret = find_vdi_name(ai, filename, CURRENT_VDI_ID, tag, &vid, 0); if (ret) goto out; - fd = get_my_fd(ai); - if (fd < 0) { - eprintf("failed to connect\n"); - goto out; - } - ai->min_dirty_data_idx = UINT32_MAX; ai->max_dirty_data_idx = 0; - ret = read_object(fd, (char *)&ai->inode, vid_to_vdi_oid(vid), + ret = read_object(ai, (char *)&ai->inode, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0); if (ret) @@ -909,26 +887,17 @@ static void sd_close(struct sheepdog_access_info *ai) struct sheepdog_vdi_rsp *rsp = (struct sheepdog_vdi_rsp *)&hdr; unsigned int wlen = 0, rlen; int ret; - int fd; memset(&hdr, 0, sizeof(hdr)); hdr.opcode = SD_OP_RELEASE_VDI; hdr.vdi_id = ai->inode.vdi_id; - fd = get_my_fd(ai); - if (fd < 0) { - eprintf("couldn't acquire fd for closing sheepdog VDI\n"); - return; - } - - ret = do_req(fd, (struct sheepdog_req *)&hdr, NULL, &wlen, &rlen); + ret = do_req(ai, (struct sheepdog_req *)&hdr, NULL, &wlen, &rlen); if (!ret && rsp->result != SD_RES_SUCCESS && rsp->result != SD_RES_VDI_NOT_LOCKED) eprintf("%s, %s", sd_strerror(rsp->result), ai->inode.name); - - close_my_fd(ai, fd); } static void set_medium_error(int *result, uint8_t *key, uint16_t *asc) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html