[Sheepdog] [PATCH 4/4] add SD_OP_SO_READ_VDIS
FUJITA Tomonori
fujita.tomonori at lab.ntt.co.jp
Mon Dec 21 09:04:17 CET 2009
It is necessary to parse vdis (shepherd).
TODO: handling many vdis.
Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
collie/net.c | 1 +
collie/store.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++
collie/vdi.c | 6 ++--
include/meta.h | 9 -----
include/net.h | 2 +-
include/sheepdog_proto.h | 1 +
lib/net.c | 26 +++++++++++----
shepherd/shepherd.c | 11 ++++--
8 files changed, 113 insertions(+), 23 deletions(-)
diff --git a/collie/net.c b/collie/net.c
index be2d084..5505613 100644
--- a/collie/net.c
+++ b/collie/net.c
@@ -64,6 +64,7 @@ static void queue_request(struct request *req)
case SD_OP_SO:
case SD_OP_SO_NEW_VDI:
case SD_OP_SO_LOOKUP_VDI:
+ case SD_OP_SO_READ_VDIS:
req->work.fn = so_queue_request;
break;
default:
diff --git a/collie/store.c b/collie/store.c
index 41a8dc5..9f14d00 100644
--- a/collie/store.c
+++ b/collie/store.c
@@ -323,6 +323,83 @@ out:
close(fd);
}
+static int so_read_vdis(struct request *req)
+{
+ struct sd_so_rsp *rsp = (struct sd_so_rsp *)&req->rp;
+ DIR *dir, *vdir;
+ struct dirent *dent, *vdent;
+ char *p;
+ int fd, ret;
+ uint64_t coid;
+ char path[1024], vpath[1024];
+ struct sheepdog_dir_entry *sde = req->data;
+
+ memset(path, 0, sizeof(path));
+ snprintf(path, sizeof(path), "%s/vdi", obj_dir);
+
+ dir = opendir(path);
+
+ while ((dent = readdir(dir))) {
+ if (!strcmp(dent->d_name, ".") ||
+ !strcmp(dent->d_name, ".."))
+ continue;
+
+ memcpy(vpath, path, sizeof(vpath));
+ snprintf(vpath + strlen(vpath), sizeof(vpath) - strlen(vpath),
+ "/%s", dent->d_name);
+
+ fd = open(vpath, O_RDONLY);
+ if (fd < 0) {
+ eprintf("%m\n");
+ return SD_RES_EIO;
+ }
+
+ ret = fgetxattr(fd, ANAME_CURRENT, &coid,
+ sizeof(coid));
+ if (ret != sizeof(coid)) {
+ close(fd);
+ eprintf("%s, %m\n", path);
+ return SD_RES_EIO;
+ }
+
+ dprintf("%lx\n", coid);
+
+ close(fd);
+
+ vdir = opendir(vpath);
+ while ((vdent = readdir(vdir))) {
+ if (!strcmp(vdent->d_name, ".") ||
+ !strcmp(vdent->d_name, ".."))
+ continue;
+
+ p = strchr(vdent->d_name, '-');
+ if (!p) {
+ eprintf("bug %s\n", vdent->d_name);
+ continue;
+ }
+
+ dprintf("%s\n", vdent->d_name);
+
+ *p = '\0';
+
+ sde->oid = strtoull(vdent->d_name, NULL, 16);
+ sde->tag = strtoull(p + 1, NULL, 16);
+
+ if (sde->oid == coid)
+ sde->flags = FLAG_CURRENT;
+
+ sde->name_len = strlen(dent->d_name);
+ strcpy(sde->name, dent->d_name);
+ sde = next_entry(sde);
+ }
+ }
+
+ rsp->data_length = (char *)sde - (char *)req->data;
+ dprintf("%d\n", rsp->data_length);
+
+ return SD_RES_SUCCESS;
+}
+
static int so_lookup_vdi(struct request *req)
{
struct sd_so_req *hdr = (struct sd_so_req *)&req->rq;
@@ -519,6 +596,9 @@ void so_queue_request(struct work *work, int idx)
case SD_OP_SO_LOOKUP_VDI:
ret = so_lookup_vdi(req);
break;
+ case SD_OP_SO_READ_VDIS:
+ ret = so_read_vdis(req);
+ break;
}
out:
diff --git a/collie/vdi.c b/collie/vdi.c
index cf8d9ac..b822d1d 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -109,7 +109,7 @@ int add_vdi(struct cluster_info *ci, char *name, int len, uint64_t size,
req.tag = tag;
ret = exec_reqs(entries, nr_nodes, ci->epoch,
- SD_DIR_OID, (struct sd_req *)&req, name, len, copies);
+ SD_DIR_OID, (struct sd_req *)&req, name, len, 0, copies);
/* todo: error handling */
@@ -157,7 +157,7 @@ int lookup_vdi(struct cluster_info *ci,
req.tag = tag;
ret = exec_reqs(entries, nr_nodes, ci->epoch,
- SD_DIR_OID, (struct sd_req *)&req, filename, strlen(filename), copies);
+ SD_DIR_OID, (struct sd_req *)&req, filename, strlen(filename), 0, copies);
*oid = rsp->oid;
if (rsp->flags & SD_VDI_RSP_FLAG_CURRENT)
@@ -187,7 +187,7 @@ int make_super_object(struct cluster_info *ci, struct sd_vdi_req *hdr)
nr_nodes = build_node_list(&ci->node_list, entries);
ret = exec_reqs(entries, nr_nodes, ci->epoch,
- SD_DIR_OID, (struct sd_req *)&req, NULL, 0, req.copies);
+ SD_DIR_OID, (struct sd_req *)&req, NULL, 0, 0, req.copies);
return ret;
}
diff --git a/include/meta.h b/include/meta.h
index 73b63de..e0b05cd 100644
--- a/include/meta.h
+++ b/include/meta.h
@@ -48,15 +48,6 @@ static inline int is_data_obj(uint64_t oid)
#define SHEEPDOG_SUPER_OBJ_SIZE (UINT64_C(1) << 12)
-struct sheepdog_super_block {
- uint64_t ctime;
- uint8_t default_nr_copies;
- uint8_t pad1[7];
-
- uint8_t pad2[SHEEPDOG_SUPER_OBJ_SIZE - 16];
- uint8_t pad3[1 << 24];
-};
-
#define FLAG_CURRENT 1
struct sheepdog_dir_entry {
diff --git a/include/net.h b/include/net.h
index 7205f6a..b0e3df0 100644
--- a/include/net.h
+++ b/include/net.h
@@ -46,7 +46,7 @@ int read_object(struct sheepdog_node_list_entry *e,
int exec_reqs(struct sheepdog_node_list_entry *e,
int nodes, uint32_t node_version, uint64_t oid, struct sd_req *hdr,
- char *wdata, unsigned int wdatalen, int nr);
+ char *data, unsigned int wdatalen, unsigned int rdatalen, int nr);
int create_listen_ports(int port, int (*callback)(int fd, void *), void *data);
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 2f3bad4..b55f2e2 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -48,6 +48,7 @@
#define SD_OP_SO_NEW_VDI 0x61
#define SD_OP_SO_DEL_VDI 0x62
#define SD_OP_SO_LOOKUP_VDI 0x63
+#define SD_OP_SO_READ_VDIS 0x64
#define SD_OP_STAT_SHEEP 0xB0
diff --git a/lib/net.c b/lib/net.c
index 4f05cb9..9c17ea7 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -433,14 +433,15 @@ int read_object(struct sheepdog_node_list_entry *e,
/* TODO: clean up with the above functions */
int exec_reqs(struct sheepdog_node_list_entry *e,
int nodes, uint32_t node_version, uint64_t oid, struct sd_req *hdr,
- char *wdata, unsigned int wdatalen, int nr)
+ char *data, unsigned int wdatalen, unsigned int rdatalen, int nr)
{
char name[128];
int i = 0, n, fd, ret;
int success = 0;
+ struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
for (i = 0; i < nr; i++) {
- unsigned wlen = wdatalen, rlen = 0;
+ unsigned wlen = wdatalen, rlen = rdatalen;
n = obj_to_sheep(e, nodes, oid, i);
@@ -454,16 +455,27 @@ int exec_reqs(struct sheepdog_node_list_entry *e,
if (fd < 0)
return -1;
+ rsp->result = 0;
hdr->epoch = node_version;
- if (wdatalen)
+ if (wdatalen) {
hdr->flags = SD_FLAG_CMD_WRITE;
- hdr->data_length = wlen;
+ hdr->data_length = wdatalen;
+ } else if (rdatalen)
+ hdr->data_length = rdatalen;
+ else
+ hdr->data_length = 0;
- ret = exec_req(fd, hdr, wdata, &wlen, &rlen);
+ ret = exec_req(fd, hdr, data, &wlen, &rlen);
close(fd);
- if (!ret)
- success++;
+ if (rdatalen) {
+ if (!ret) {
+ if (rsp->result == SD_RES_SUCCESS)
+ return rlen;
+ }
+ } else
+ if (!ret)
+ success++;
}
return !success;
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index 4ac7e4a..7cf4243 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -388,14 +388,19 @@ int parse_vdi(vdi_parser_func_t func, void *data)
char *buf;
int rest, ret;
struct sheepdog_inode i;
+ struct sd_so_req req;
+
+ memset(&req, 0, sizeof(req));
buf = zalloc(DIR_BUF_LEN);
if (!buf)
return 1;
- ret = read_object(node_list_entries, nr_nodes, node_list_version,
- SD_DIR_OID, buf, DIR_BUF_LEN,
- sizeof(struct sheepdog_super_block), nr_nodes);
+ req.opcode = SD_OP_SO_READ_VDIS;
+
+ ret = exec_reqs(node_list_entries, nr_nodes, node_list_version,
+ SD_DIR_OID, (struct sd_req *)&req, buf, 0, DIR_BUF_LEN,nr_nodes);
+
if (ret < 0) {
ret = 1;
goto out;
--
1.5.6.5
More information about the sheepdog
mailing list