[sheepdog] [PATCH v3 05/10] sheep: store the VDI copies data in disk in case of sheep restarts

levin li levin108 at gmail.com
Tue Aug 7 13:20:52 CEST 2012


From: levin li <xingke.lwp at taobao.com>

If we only store the copies data in memory, then after restart the
copies data is lost, and we can only try to read the inode data to
get the copies data, which is expensive

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 sheep/sheep_priv.h |    2 +
 sheep/store.c      |   21 ++++++++++++
 sheep/vdi.c        |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 114 insertions(+), 1 deletions(-)

diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 86c4c56..3f763c4 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -182,6 +182,7 @@ extern char *obj_path;
 extern char *mnt_path;
 extern char *jrnl_path;
 extern char *epoch_path;
+extern char *vdi_path;
 extern mode_t def_fmode;
 extern mode_t def_dmode;
 extern struct sd_node joining_nodes[];
@@ -205,6 +206,7 @@ int get_obj_copy_number(uint64_t oid);
 int get_max_copy_number(void);
 int get_req_copy_number(struct request *req);
 int add_vdi_copies(uint32_t vid, int nr_copies);
+int load_vdi_copies(void);
 int vdi_exist(uint32_t vid);
 int add_vdi(struct vdi_iocb *iocb, uint32_t *new_vid);
 
diff --git a/sheep/store.c b/sheep/store.c
index b093916..bebb2c0 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -40,6 +40,7 @@ char *obj_path;
 char *mnt_path;
 char *jrnl_path;
 char *epoch_path;
+char *vdi_path;
 static char *config_path;
 
 mode_t def_dmode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
@@ -342,6 +343,18 @@ static int init_epoch_path(const char *base_path)
 	return init_path(epoch_path, &new);
 }
 
+#define VDI_PATCH "/vdi/"
+
+static int init_vdi_path(const char *base_path)
+{
+	int new;
+
+	vdi_path = xzalloc(strlen(base_path) + strlen(VDI_PATCH) + 1);
+	sprintf(vdi_path, "%s" VDI_PATCH, base_path);
+
+	return init_path(vdi_path, &new);
+}
+
 static int init_mnt_path(const char *base_path)
 {
 	int ret;
@@ -491,6 +504,10 @@ int init_store(const char *d, int enable_write_cache)
 	if (ret)
 		return ret;
 
+	ret = init_vdi_path(d);
+	if (ret)
+		return ret;
+
 	ret = init_mnt_path(d);
 	if (ret)
 		return ret;
@@ -507,6 +524,10 @@ int init_store(const char *d, int enable_write_cache)
 	if (ret)
 		return ret;
 
+	ret = load_vdi_copies();
+	if (ret)
+		return ret;
+
 	if (!sys->gateway_only) {
 		ret = init_store_driver();
 		if (ret)
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 4ea76e5..dd3d3af 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -12,6 +12,8 @@
 #include <stdlib.h>
 #include <pthread.h>
 #include <sys/time.h>
+#include <sys/file.h>
+#include <dirent.h>
 
 #include "sheepdog_proto.h"
 #include "sheep_priv.h"
@@ -107,9 +109,58 @@ int get_max_copy_number(void)
 	return uatomic_read(&max_copies);
 }
 
+static int read_vdi_copies(uint32_t vid, unsigned int *nr_copies)
+{
+	char path[PATH_MAX];
+	int fd, flags = O_RDONLY, ret;
+
+	sprintf(path, "%s%" PRIx32, vdi_path, vid);
+
+	fd = open(path, flags, def_fmode);
+	if (fd < 0) {
+		eprintf("fail: %m\n");
+		return SD_RES_EIO;
+	}
+
+	ret = xpread(fd, nr_copies, sizeof(*nr_copies), 0);
+	close(fd);
+	if (ret < 0) {
+		eprintf("pread: %m\n");
+		return SD_RES_EIO;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
+static int log_vdi_copies(uint32_t vid, unsigned int nr_copies)
+{
+	int fd, flags, ret;
+	char path[PATH_MAX];
+
+	sprintf(path, "%s%" PRIx32, vdi_path, vid);
+
+	flags = O_CREAT | O_TRUNC | O_DSYNC | O_RDWR;
+
+	fd = open(path, flags, def_fmode);
+	if (fd < 0) {
+		dprintf("fail: %m\n");
+		return SD_RES_EIO;
+	}
+
+	ret = xpwrite(fd, (void *)&nr_copies, sizeof(nr_copies), 0);
+	close(fd);
+	if (ret < 0) {
+		dprintf("%m\n");
+		return SD_RES_EIO;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
 int add_vdi_copies(uint32_t vid, int nr_copies)
 {
 	struct vdi_copy_entry *entry;
+	int ret;
 
 	entry = xzalloc(sizeof(*entry));
 	entry->vid = vid;
@@ -128,7 +179,46 @@ int add_vdi_copies(uint32_t vid, int nr_copies)
 		uatomic_set(&max_copies, nr_copies);
 	pthread_rwlock_unlock(&vdi_copy_lock);
 
-	return SD_RES_SUCCESS;
+	ret = log_vdi_copies(vid, nr_copies);
+
+	return ret;
+}
+
+int load_vdi_copies(void)
+{
+	DIR *dir;
+	struct dirent *d;
+	uint32_t vid;
+	struct strbuf vid_buf;
+	int ret = 0;
+	unsigned int nr_copies;
+
+	strbuf_init(&vid_buf, PATH_MAX);
+	strbuf_addstr(&vid_buf, vdi_path);
+
+	dir = opendir(vid_buf.buf);
+	if (!dir) {
+		dprintf("%m\n");
+		ret = -1;
+		goto out;
+	}
+
+	while ((d = readdir(dir))) {
+		if (!strncmp(d->d_name, ".", 1))
+			continue;
+		vid = strtoul(d->d_name, NULL, 16);
+		if (vid == ULLONG_MAX)
+			continue;
+		ret = read_vdi_copies(vid, &nr_copies);
+		dprintf("load %" PRIx32 ", %d\n", vid, nr_copies);
+		if (ret != SD_RES_SUCCESS)
+			goto out;
+		add_vdi_copies(vid, nr_copies);
+	}
+
+out:
+	strbuf_release(&vid_buf);
+	return ret;
 }
 
 int vdi_exist(uint32_t vid)
-- 
1.7.1




More information about the sheepdog mailing list