[stgt] [PATCH 3/3] bs_sheepdog.c: support reconnection for updating sheepdog
Hitoshi Mitake
mitake.hitoshi at gmail.com
Sun Oct 6 17:27:52 CEST 2013
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 at lab.ntt.co.jp>
---
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 at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the stgt
mailing list