[sheepdog] [PATCH v4 4/8] sheepdev: add sheep.c to process the sheepdog protocol

levin li levin108 at gmail.com
Wed Jan 23 08:56:28 CET 2013


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


Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 sheepdev/Kbuild     |   3 +-
 sheepdev/sheep.c    | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 sheepdev/sheepdev.h |   8 +++
 3 files changed, 196 insertions(+), 1 deletion(-)
 create mode 100644 sheepdev/sheep.c

diff --git a/sheepdev/Kbuild b/sheepdev/Kbuild
index 16bac26..20855c6 100644
--- a/sheepdev/Kbuild
+++ b/sheepdev/Kbuild
@@ -5,8 +5,9 @@ ccflags-y := -I$(PWD)/../include
 
 obj-m := $(MODULE_NAME).o
 
-sheepdev-objs := device.o proc.o connect.o
+sheepdev-objs := device.o proc.o connect.o sheep.o
 
 device.o : sheepdev.h sheepdog_proto.h
 proc.o : sheepdev.h
+sheep.o : sheepdev.h sheepdog_proto.h
 connect.o : sheepdev.h sheepdog_proto.h
diff --git a/sheepdev/sheep.c b/sheepdev/sheep.c
new file mode 100644
index 0000000..39f00f9
--- /dev/null
+++ b/sheepdev/sheep.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2013 Taobao Inc.
+ *
+ * Levin Li <xingke.lwp at taobao.com>
+ *
+ * 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 "sheepdev.h"
+
+static int read_object(struct sheepdev *dev, uint64_t oid, void *data,
+		       unsigned int datalen, uint64_t offset)
+{
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+	hdr.opcode = SD_OP_READ_OBJ;
+	hdr.id = 0;
+	hdr.data_length = datalen;
+
+	hdr.obj.oid = oid;
+	hdr.obj.offset = offset;
+
+	ret = exec_req(dev->sock, &hdr, data);
+
+	if (ret < 0) {
+		DBPRT("Failed to read object %llx\n", oid);
+		return SD_RES_EIO;
+	}
+
+	if (rsp->result != SD_RES_SUCCESS) {
+		DBPRT("Failed to read object %llx,%d\n", oid,
+		      rsp->result);
+		return SD_RES_EIO;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
+int send_read_req(struct sheepdev *dev, uint64_t oid,
+		  unsigned int datalen, uint64_t offset)
+{
+	struct sd_req hdr;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+	hdr.opcode = SD_OP_READ_OBJ;
+	hdr.id = dev->req_id;
+	hdr.data_length = datalen;
+
+	hdr.obj.oid = oid;
+	hdr.obj.offset = offset;
+
+	ret = send_req(dev->sock, &hdr, NULL, 0);
+
+	if (dev->req_id > UINT_MAX)
+		dev->req_id = 1;
+	else
+		dev->req_id++;
+
+	if (ret < 0) {
+		DBPRT("Failed to read object %llx\n", oid);
+		return SD_RES_EIO;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
+int send_write_req(struct sheepdev *dev, uint64_t oid, uint64_t cow_oid,
+		   void *data, unsigned int datalen, uint64_t offset,
+		   int create)
+{
+	struct sd_req hdr;
+	int ret;
+
+	memset(&hdr, 0, sizeof(hdr));
+	if (create)
+		hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+	else
+		hdr.opcode = SD_OP_WRITE_OBJ;
+
+	hdr.id = dev->req_id;
+	hdr.data_length = datalen;
+	hdr.flags = SD_FLAG_CMD_WRITE | SD_FLAG_CMD_DIRECT;
+	if (cow_oid)
+		hdr.flags |= SD_FLAG_CMD_COW;
+
+	hdr.obj.oid = oid;
+	hdr.obj.cow_oid = cow_oid;
+	hdr.obj.offset = offset;
+	hdr.obj.copies = dev->inode->nr_copies;
+
+	ret = send_req(dev->sock, &hdr, data, datalen);
+
+	if (dev->req_id > UINT_MAX)
+		dev->req_id = 1;
+	else
+		dev->req_id++;
+
+	if (ret < 0) {
+		DBPRT("Failed to write object %llx\n", oid);
+		return SD_RES_EIO;
+	}
+
+	return SD_RES_SUCCESS;
+}
+
+static int find_vdi_name(struct sheepdev *dev, const char *vdiname,
+			 uint32_t snapid, const char *tag)
+{
+	int ret;
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+	char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
+
+	memset(buf, 0, sizeof(buf));
+	strncpy(buf, vdiname, SD_MAX_VDI_LEN);
+	strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
+
+	memset(&hdr, 0, sizeof(hdr));
+	hdr.opcode = SD_OP_LOCK_VDI;
+	hdr.data_length = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
+	hdr.flags = SD_FLAG_CMD_WRITE;
+	hdr.vdi.snapid = snapid;
+
+	ret = exec_req(dev->sock, &hdr, buf);
+	if (ret)
+		return -EIO;
+
+	if (rsp->result != SD_RES_SUCCESS) {
+		DBPRT("Cannot get VDI info for %s %d %s\n",
+		      vdiname, snapid, tag);
+		return -EIO;
+	}
+
+	dev->vid = rsp->vdi.vdi_id;
+
+	return 0;
+}
+
+int sheep_vdi_setup(struct sheepdev *dev)
+{
+	int ret;
+	struct sheepdog_inode *inode;
+
+	inode = vmalloc(sizeof(*inode));
+	if (!inode)
+		return -ENOMEM;
+	memset(inode, 0 , sizeof(*inode));
+
+	ret = connect_to(&dev->sock, dev->ip_addr, dev->port);
+	if (ret) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	ret = find_vdi_name(dev, dev->vdiname, dev->snapshot_id,
+			    dev->snapshot_tag);
+	if (ret)
+		goto out;
+
+	ret = read_object(dev, vid_to_vdi_oid(dev->vid), inode,
+			  SD_INODE_SIZE, 0);
+	if (ret != SD_RES_SUCCESS) {
+		ret = -EIO;
+		goto out;
+	}
+
+	dev->size = inode->vdi_size;
+	dev->sectors = dev->size / KERNEL_SECTOR_SIZE;
+	dev->snapshot_id = inode->snap_id;
+	strncpy(dev->snapshot_tag, inode->tag, SD_MAX_VDI_TAG_LEN);
+	dev->inode = inode;
+
+	return 0;
+out:
+	vfree(inode);
+	return ret;
+}
diff --git a/sheepdev/sheepdev.h b/sheepdev/sheepdev.h
index 323178c..91a55ea 100644
--- a/sheepdev/sheepdev.h
+++ b/sheepdev/sheepdev.h
@@ -92,4 +92,12 @@ int exec_req(struct socket *sock, struct sd_req *hdr, void *data);
 int sheep_proc_init(void);
 void sheep_proc_destroy(void);
 
+/* sheep.c */
+int send_read_req(struct sheepdev *sheepdev, uint64_t oid,
+		  unsigned int datalen, uint64_t offset);
+int send_write_req(struct sheepdev *sheepdev, uint64_t oid, uint64_t cow_oid,
+		   void *data, unsigned int datalen, uint64_t offset,
+		   int create);
+int sheep_vdi_setup(struct sheepdev *sheep_dev);
+
 #endif
-- 
1.7.11.7




More information about the sheepdog mailing list