[sheepdog] [PATCH v3 07/12] collie/farm: implement snap object

Kai Zhang kyle at zelin.io
Tue May 14 09:51:52 CEST 2013


moved snap.c from sheep/farm to collie/farm and made minor modification.

Signed-off-by: Kai Zhang <kyle at zelin.io>
---
 collie/Makefile.am |    3 +-
 collie/farm/farm.h |    9 +++
 collie/farm/snap.c |  150 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+), 1 deletions(-)
 create mode 100644 collie/farm/snap.c

diff --git a/collie/Makefile.am b/collie/Makefile.am
index d185512..49d760c 100644
--- a/collie/Makefile.am
+++ b/collie/Makefile.am
@@ -23,7 +23,8 @@ INCLUDES		= -I$(top_builddir)/include -I$(top_srcdir)/include
 
 sbin_PROGRAMS		= collie
 
-collie_SOURCES		= farm/object_rb_tree.c farm/sha1_file.c farm/farm.c \
+collie_SOURCES		= farm/object_rb_tree.c farm/sha1_file.c farm/snap.c \
+			  farm/farm.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 ca108ca..704a1ba 100644
--- a/collie/farm/farm.h
+++ b/collie/farm/farm.h
@@ -41,6 +41,15 @@ struct sha1_file_hdr {
 int farm_init(const char *path);
 char *get_object_directory(void);
 
+/* 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 epoch, unsigned char *trunksha1,
+		    unsigned char *outsha1);
+int snap_log_truncate(void);
+void *snap_log_read(int *);
+int snap_log_write(uint32_t epoch, 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/collie/farm/snap.c b/collie/farm/snap.c
new file mode 100644
index 0000000..80366c1
--- /dev/null
+++ b/collie/farm/snap.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 Taobao Inc.
+ * Copyright (C) 2013 Zelin Inc.
+ *
+ * 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
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <time.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "farm.h"
+
+static char snap_log_path[PATH_MAX];
+
+int snap_init(const char *farm_dir)
+{
+	int fd, ret = -1;
+	struct strbuf buf = STRBUF_INIT;
+
+	strbuf_addstr(&buf, farm_dir);
+	strbuf_addf(&buf, "/%s", "user_snap");
+
+	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) {
+			sd_eprintf("%m");
+			goto out;
+		}
+	}
+
+	ret = 0;
+	close(fd);
+out:
+	strbuf_release(&buf);
+	return ret;
+}
+
+int snap_log_write(uint32_t epoch, unsigned char *sha1)
+{
+	int fd, ret = -1;
+	struct strbuf buf = STRBUF_INIT;
+	struct snap_log log = { .epoch = epoch,
+				.time = time(NULL) };
+
+	memcpy(log.sha1, sha1, SHA1_LEN);
+
+	fd = open(snap_log_path, O_WRONLY | O_APPEND);
+	if (fd < 0) {
+		sd_eprintf("%m");
+		goto out;
+	}
+
+	strbuf_reset(&buf);
+	strbuf_add(&buf, &log, sizeof(log));
+	ret = xwrite(fd, buf.buf, buf.len);
+	if (ret != buf.len)
+		goto out_close;
+
+	ret = 0;
+out_close:
+	close(fd);
+out:
+	strbuf_release(&buf);
+	return ret;
+}
+
+void *snap_log_read(int *out_nr)
+{
+	struct stat st;
+	void *buffer = NULL;
+	int len, fd;
+
+	fd = open(snap_log_path, O_RDONLY);
+	if (fd < 0) {
+		sd_eprintf("%m");
+		goto out;
+	}
+	if (fstat(fd, &st) < 0) {
+		sd_eprintf("%m");
+		goto out_close;
+	}
+
+	len = st.st_size;
+	buffer = xmalloc(len);
+	len = xread(fd, buffer, len);
+	if (len != st.st_size) {
+		free(buffer);
+		buffer = NULL;
+		goto out_close;
+	}
+	*out_nr = len / sizeof(struct snap_log);
+out_close:
+	close(fd);
+out:
+	return buffer;
+}
+
+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;
+	if (strcmp(outhdr->tag, TAG_SNAP) != 0) {
+		free(buffer);
+		return NULL;
+	}
+
+	return buffer;
+}
+
+int snap_file_write(uint32_t epoch, unsigned char *trunksha1,
+		    unsigned char *outsha1)
+{
+	int ret = -1;
+	struct sha1_file_hdr hdr = {};
+	struct strbuf buf = STRBUF_INIT;
+
+	memcpy(hdr.tag, TAG_SNAP, TAG_LEN);
+	hdr.size = SHA1_LEN;
+	hdr.priv = epoch;
+	hdr.reserved = 0;
+
+	strbuf_add(&buf, &hdr, sizeof(hdr));
+	strbuf_add(&buf, trunksha1, SHA1_LEN);
+	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0)
+		goto out;
+
+	sd_dprintf("epoch: %" PRIu32 ", sha1: %s",
+		epoch, sha1_to_hex(outsha1));
+
+	ret = 0;
+out:
+	strbuf_release(&buf);
+	return ret;
+}
-- 
1.7.1




More information about the sheepdog mailing list