[sheepdog] [PATCH v6 10/16] collie/farm: implement snap object

Kai Zhang kyle at zelin.io
Tue May 21 12:11:12 CEST 2013


moved snap.c from sheep/farm to collie/farm

Changes:
1. Snap also saves a "tag" to snap_log, so that user can load a snapshot by specify a tag
2. Epoch info is not necessary, use index instead. User can use either tag or index to select a snapshot to load
3. Construct snap_log_path during snap_init(). snap_init() will be called by farm_init().
4. Fix style problems.
5. Replaced sd_xprintf(...) with fprintf(...)

Signed-off-by: Kai Zhang <kyle at zelin.io>
---
 collie/Makefile.am            |    2 +-
 collie/farm/farm.h            |    8 ++++
 {sheep => collie}/farm/snap.c |   75 +++++++++++++++++++---------------------
 include/sheepdog_proto.h      |   10 +++--
 4 files changed, 51 insertions(+), 44 deletions(-)
 rename {sheep => collie}/farm/snap.c (62%)

diff --git a/collie/Makefile.am b/collie/Makefile.am
index 5a705b2..8cab2a3 100644
--- a/collie/Makefile.am
+++ b/collie/Makefile.am
@@ -23,7 +23,7 @@ INCLUDES		= -I$(top_builddir)/include -I$(top_srcdir)/include
 
 sbin_PROGRAMS		= collie
 
-collie_SOURCES		= farm/object_tree.c farm/sha1_file.c \
+collie_SOURCES		= farm/object_tree.c farm/sha1_file.c farm/snap.c \
 			  collie.c common.c treeview.c vdi.c node.c cluster.c
 
 if BUILD_TRACE
diff --git a/collie/farm/farm.h b/collie/farm/farm.h
index cd1fa26..451ebea 100644
--- a/collie/farm/farm.h
+++ b/collie/farm/farm.h
@@ -43,6 +43,14 @@ static inline char *get_object_directory(void)
 typedef int (*object_handler_func_t)(uint64_t oid, int nr_copies, void *buf,
 				     size_t size, void *data);
 
+/* snap.c */
+int snap_init(const char *path);
+void *snap_file_read(unsigned char *sha1, struct sha1_file_hdr *outhdr);
+int snap_file_write(uint32_t idx, unsigned char *trunksha1,
+		    unsigned char *outsha1);
+void *snap_log_read(int *out_nr);
+int snap_log_write(uint32_t idx, const char *tag, unsigned char *sha1);
+
 /* sha1_file.c */
 int sha1_file_write(unsigned char *buf, unsigned len, unsigned char *);
 void *sha1_file_read(const unsigned char *sha1, struct sha1_file_hdr *);
diff --git a/sheep/farm/snap.c b/collie/farm/snap.c
similarity index 62%
rename from sheep/farm/snap.c
rename to collie/farm/snap.c
index 0cc18ba..9f8370e 100644
--- a/sheep/farm/snap.c
+++ b/collie/farm/snap.c
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 2011 Taobao Inc.
+ * Copyright (C) 2013 Zelin.io
  *
  * Liu Yuan <namei.unix at gmail.com>
+ * Kai Zhang <kyle at zelin.io>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version
@@ -12,52 +14,54 @@
  */
 
 /*
- * Snap object is the meta data that describes the snapshot, either triggered
- * by recovery logic or end users.
+ * Snap object is the meta data that describes the cluster snapshot.
  */
 #include <time.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
 #include "farm.h"
-#include "sheep_priv.h"
 
-int snap_init(void)
+static char snap_log_path[PATH_MAX];
+
+int snap_init(const char *farm_dir)
 {
-	int fd, ret = 0;
+	int fd, ret = -1;
 	struct strbuf buf = STRBUF_INIT;
 
 	strbuf_addstr(&buf, farm_dir);
 	strbuf_addf(&buf, "/%s", "user_snap");
 
-	fd = open(buf.buf, O_CREAT | O_EXCL, 0666);
+	if (!strlen(snap_log_path))
+		strbuf_copyout(&buf, snap_log_path, sizeof(snap_log_path));
+
+	fd = open(snap_log_path, O_CREAT | O_EXCL, 0666);
 	if (fd < 0) {
 		if (errno != EEXIST) {
-			ret = -1;
+			fprintf(stderr, "%m\n");
 			goto out;
 		}
-	} else
-		close(fd);
+	}
 
+	ret = 0;
+	close(fd);
 out:
 	strbuf_release(&buf);
 	return ret;
 }
 
-int snap_log_write(uint32_t epoch, unsigned char *sha1)
+int snap_log_write(uint32_t idx, const char *tag, unsigned char *sha1)
 {
 	int fd, ret = -1;
 	struct strbuf buf = STRBUF_INIT;
-	struct snap_log log = { .epoch = epoch,
+	struct snap_log log = { .idx = idx,
 				.time = time(NULL) };
-
+	pstrcpy(log.tag, SD_MAX_SNAPSHOT_TAG_LEN, tag);
 	memcpy(log.sha1, sha1, SHA1_LEN);
-	strbuf_addstr(&buf, farm_dir);
-	strbuf_addf(&buf, "/%s", "user_snap");
 
-	fd = open(buf.buf, O_WRONLY | O_APPEND);
+	fd = open(snap_log_path, O_WRONLY | O_APPEND);
 	if (fd < 0) {
-		sd_dprintf("%m");
+		fprintf(stderr, "%m\n");
 		goto out;
 	}
 
@@ -65,8 +69,10 @@ int snap_log_write(uint32_t epoch, unsigned char *sha1)
 	strbuf_add(&buf, &log, sizeof(log));
 	ret = xwrite(fd, buf.buf, buf.len);
 	if (ret != buf.len)
-		ret = -1;
+		goto out_close;
 
+	ret = 0;
+out_close:
 	close(fd);
 out:
 	strbuf_release(&buf);
@@ -75,21 +81,17 @@ out:
 
 void *snap_log_read(int *out_nr)
 {
-	struct strbuf buf = STRBUF_INIT;
 	struct stat st;
 	void *buffer = NULL;
 	int len, fd;
 
-	strbuf_addstr(&buf, farm_dir);
-	strbuf_addf(&buf, "/%s", "user_snap");
-
-	fd = open(buf.buf, O_RDONLY);
+	fd = open(snap_log_path, O_RDONLY);
 	if (fd < 0) {
-		sd_dprintf("%m");
+		fprintf(stderr, "%m\n");
 		goto out;
 	}
 	if (fstat(fd, &st) < 0) {
-		sd_dprintf("%m");
+		fprintf(stderr, "%m\n");
 		goto out_close;
 	}
 
@@ -105,7 +107,6 @@ void *snap_log_read(int *out_nr)
 out_close:
 	close(fd);
 out:
-	strbuf_release(&buf);
 	return buffer;
 }
 
@@ -113,7 +114,6 @@ void *snap_file_read(unsigned char *sha1, struct sha1_file_hdr *outhdr)
 {
 	void *buffer = NULL;
 
-	sd_dprintf("%s", sha1_to_hex(sha1));
 	buffer = sha1_file_read(sha1, outhdr);
 	if (!buffer)
 		return NULL;
@@ -125,28 +125,25 @@ void *snap_file_read(unsigned char *sha1, struct sha1_file_hdr *outhdr)
 	return buffer;
 }
 
-int snap_file_write(uint32_t epoch, struct sd_node *nodes, int nr_nodes,
-		    unsigned char *trunksha1, unsigned char *outsha1)
+int snap_file_write(uint32_t idx, unsigned char *trunksha1,
+		    unsigned char *outsha1)
 {
-	int ret = 0;
-	struct strbuf buf = STRBUF_INIT;
+	int ret = -1;
 	struct sha1_file_hdr hdr = {};
+	struct strbuf buf = STRBUF_INIT;
 
 	memcpy(hdr.tag, TAG_SNAP, TAG_LEN);
-	hdr.size = nr_nodes * sizeof(*nodes) + SHA1_LEN;
-	hdr.priv = epoch;
+	hdr.size = SHA1_LEN;
+	hdr.priv = idx;
 	hdr.reserved = 0;
 
 	strbuf_add(&buf, &hdr, sizeof(hdr));
 	strbuf_add(&buf, trunksha1, SHA1_LEN);
-	strbuf_add(&buf, (char *)nodes, nr_nodes * sizeof(*nodes));
-	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0) {
-		ret = -1;
-		goto err;
-	}
+	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0)
+		goto out;
 
-	sd_dprintf("epoch: %" PRIu32 ", sha1: %s", epoch, sha1_to_hex(outsha1));
-err:
+	ret = 0;
+out:
 	strbuf_release(&buf);
 	return ret;
 }
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index e211ce3..5440721 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -95,6 +95,7 @@
 #define SD_MAX_VDI_TAG_LEN 256U
 #define SD_MAX_VDI_ATTR_KEY_LEN 256U
 #define SD_MAX_VDI_ATTR_VALUE_LEN 65536U
+#define SD_MAX_SNAPSHOT_TAG_LEN 256U
 #define SD_NR_VDIS   (1U << 24)
 #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
 #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
@@ -221,7 +222,8 @@ struct sheepdog_vdi_attr {
 #define SHA1_LEN        20
 
 struct snap_log {
-	uint32_t epoch;
+	uint32_t idx;
+	char tag[SD_MAX_SNAPSHOT_TAG_LEN];
 	uint64_t time;
 	unsigned char sha1[SHA1_LEN];
 };
@@ -319,9 +321,9 @@ static inline bool vdi_is_snapshot(const struct sd_inode *inode)
 
 static inline __attribute__((used)) void __sd_proto_build_bug_ons(void)
 {
-        /* never called, only for checking BUILD_BUG_ON()s */
-        BUILD_BUG_ON(sizeof(struct sd_req) != SD_REQ_SIZE);
-        BUILD_BUG_ON(sizeof(struct sd_rsp) != SD_RSP_SIZE);
+	/* never called, only for checking BUILD_BUG_ON()s */
+	BUILD_BUG_ON(sizeof(struct sd_req) != SD_REQ_SIZE);
+	BUILD_BUG_ON(sizeof(struct sd_rsp) != SD_RSP_SIZE);
 }
 
 #endif
-- 
1.7.1




More information about the sheepdog mailing list