[sheepdog] [PATCH v3 15/15] sheepfs: add config entry

Liu Yuan namei.unix at gmail.com
Mon May 21 17:25:59 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

config exports internal state of sheepfs and enable us even to change those
state on the fly.

For e.g, control over which sheep to connect:
echo 192.168.10.113:7000 > sheepfs_dir/config/sheep_info

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheepfs/Makefile.am |    3 +-
 sheepfs/config.c    |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++
 sheepfs/core.c      |   32 +++++++-----
 sheepfs/sheepfs.h   |   21 +++++++-
 sheepfs/volume.c    |   21 ++++++++
 5 files changed, 201 insertions(+), 13 deletions(-)
 create mode 100644 sheepfs/config.c

diff --git a/sheepfs/Makefile.am b/sheepfs/Makefile.am
index 1204559..fd3960e 100644
--- a/sheepfs/Makefile.am
+++ b/sheepfs/Makefile.am
@@ -23,7 +23,8 @@ INCLUDES		= -I$(top_builddir)/include -I$(top_srcdir)/include
 
 sbin_PROGRAMS		= sheepfs
 
-sheepfs_SOURCES		= core.c cluster.c vdi.c shadow_file.c volume.c node.c
+sheepfs_SOURCES		= core.c cluster.c vdi.c shadow_file.c volume.c node.c \
+			  config.c
 
 sheepfs_LDADD	  	= ../lib/libsheepdog.a $(fuse_LIBS) $(LIBS)
 sheepfs_DEPENDENCIES	= ../lib/libsheepdog.a
diff --git a/sheepfs/config.c b/sheepfs/config.c
new file mode 100644
index 0000000..09dae34
--- /dev/null
+++ b/sheepfs/config.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2012 Taobao Inc.
+ *
+ * Liu Yuan <namei.unix at gmail.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 <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <syslog.h>
+
+#include "strbuf.h"
+#include "sheepfs.h"
+#include "net.h"
+
+#define PATH_CONFIG        "/config"
+#define PATH_CONFIG_PCACHE "/config/page_cache"
+#define PATH_CONFIG_OCACHE "/config/object_cache"
+#define PATH_CONFIG_SHEEP  "/config/sheep_info"
+
+int create_config_layout(void)
+{
+	if (shadow_dir_create(PATH_CONFIG) < 0)
+		return -1;
+
+	if (shadow_file_create(PATH_CONFIG_PCACHE) < 0)
+		return -1;
+	if (sheepfs_set_op(PATH_CONFIG_PCACHE, OP_CONFIG_PCACHE) < 0)
+		return -1;
+
+	if (shadow_file_create(PATH_CONFIG_OCACHE) < 0)
+		return -1;
+	if (sheepfs_set_op(PATH_CONFIG_OCACHE, OP_CONFIG_OCACHE) < 0)
+		return -1;
+
+	if (shadow_file_create(PATH_CONFIG_SHEEP) < 0)
+		return -1;
+	if (sheepfs_set_op(PATH_CONFIG_SHEEP, OP_CONFIG_SHEEP) < 0)
+		return -1;
+
+	return 0;
+}
+
+int config_pcache_read(const char *path, char *buf, size_t size, off_t ignore)
+{
+	sprintf(buf, "%d\n", sheepfs_page_cache);
+	return strlen(buf);
+}
+
+int config_pcache_write(const char *path, const char *buf, size_t size,
+			off_t ignore)
+{
+	int value;
+
+	if (sscanf(buf, "%d", &value) != 1)
+		return -EINVAL;
+
+	sheepfs_page_cache = !!value;
+	return size;
+}
+
+size_t config_pcache_get_size(const char *path)
+{
+	return sizeof(int) + 1/* \n */;
+}
+
+int config_ocache_read(const char *path, char *buf, size_t size, off_t ignore)
+{
+	sprintf(buf, "%d\n", sheepfs_object_cache);
+	return strlen(buf);
+}
+
+int config_ocache_write(const char *path, const char *buf, size_t size,
+			off_t ignore)
+{
+	int value;
+
+	if (sscanf(buf, "%d\n", &value) != 1)
+		return -EINVAL;
+
+	sheepfs_object_cache = !!value;
+	return size;
+}
+
+size_t config_ocache_get_size(const char *path)
+{
+	return sizeof(int) + 1;
+}
+
+int config_sheep_info_read(const char *path, char *buf, size_t size,
+			   off_t ignore)
+{
+	sprintf(buf, "%s:%d\n", sdhost, sdport);
+	return strlen(buf);
+}
+
+int config_sheep_info_write(const char *path, const char *buf, size_t size,
+			    off_t ignore)
+{
+	char *ip, *pt;
+	unsigned port;
+
+	ip = strtok((char *)buf, ":");
+	if (!ip)
+		return -EINVAL;
+
+	pt = strtok(NULL, ":");
+	if (!pt)
+		return -EINVAL;
+
+	if (sscanf(pt, "%u", &port) != 1)
+		return -EINVAL;
+
+	memcpy(sdhost, ip, strlen(ip));
+	sdhost[strlen(ip)] = '\0';
+	sdport = port;
+	if (reset_socket_pool() < 0)
+		return -EINVAL;
+
+	return size;
+}
+
+size_t config_sheep_info_get_size(const char *path)
+{
+	return strlen(sdhost) + 1/* : */ + sizeof(sdport) + 1/* \n */;
+}
diff --git a/sheepfs/core.c b/sheepfs/core.c
index 06ba346..47999bb 100644
--- a/sheepfs/core.c
+++ b/sheepfs/core.c
@@ -35,7 +35,7 @@ static int sheepfs_debug;
 static int sheepfs_fg;
 int sheepfs_page_cache = 0;
 int sheepfs_object_cache = 1;
-const char *sdhost = "localhost";
+char sdhost[32] = "localhost";
 int sdport = SD_LISTEN_PORT;
 
 static struct option const long_options[] = {
@@ -58,15 +58,23 @@ static struct sheepfs_file_operation {
 	int (*sync)(const char *path);
 	int (*open)(const char *paht, struct fuse_file_info *);
 } sheepfs_file_ops[] = {
-	[OP_NULL]         = { NULL, NULL, NULL },
-	[OP_CLUSTER_INFO] = { cluster_info_read, NULL, cluster_info_get_size },
-	[OP_VDI_LIST]     = { vdi_list_read, NULL, vdi_list_get_size },
-	[OP_VDI_MOUNT]    = { NULL, vdi_mount_write },
-	[OP_VDI_UNMOUNT]  = { NULL, vdi_unmount_write },
-	[OP_NODE_INFO]    = { node_info_read, NULL, node_info_get_size },
-	[OP_NODE_LIST]    = { node_list_read, NULL, node_list_get_size },
-	[OP_VOLUME]       = { volume_read, volume_write, volume_get_size,
-			      volume_sync, volume_open },
+	[OP_NULL]           = { NULL, NULL, NULL },
+	[OP_CLUSTER_INFO]   = { cluster_info_read, NULL,
+				cluster_info_get_size },
+	[OP_VDI_LIST]       = { vdi_list_read, NULL, vdi_list_get_size },
+	[OP_VDI_MOUNT]      = { NULL, vdi_mount_write },
+	[OP_VDI_UNMOUNT]    = { NULL, vdi_unmount_write },
+	[OP_NODE_INFO]      = { node_info_read, NULL, node_info_get_size },
+	[OP_NODE_LIST]      = { node_list_read, NULL, node_list_get_size },
+	[OP_CONFIG_PCACHE]  = { config_pcache_read, config_pcache_write,
+				config_pcache_get_size },
+	[OP_CONFIG_OCACHE]  = { config_ocache_read, config_ocache_write,
+				config_ocache_get_size },
+	[OP_CONFIG_SHEEP]   = { config_sheep_info_read,
+				config_sheep_info_write,
+				config_sheep_info_get_size },
+	[OP_VOLUME]         = { volume_read, volume_write, volume_get_size,
+				volume_sync, volume_open },
 };
 
 int sheepfs_set_op(const char *path, unsigned opcode)
@@ -250,6 +258,8 @@ static int create_sheepfs_layout(void)
 		return -1;
 	if (create_node_layout() < 0)
 		return -1;
+	if (create_config_layout() < 0)
+		return -1;
 
 	return 0;
 }
@@ -284,7 +294,7 @@ int main(int argc, char **argv)
 				 &longindex)) >= 0) {
 		switch (ch) {
 		case 'a':
-			sdhost = optarg;
+			memcpy(sdhost, optarg, strlen(optarg));
 			break;
 		case 'd':
 			sheepfs_debug = 1;
diff --git a/sheepfs/sheepfs.h b/sheepfs/sheepfs.h
index e1ed8ae..af64f56 100644
--- a/sheepfs/sheepfs.h
+++ b/sheepfs/sheepfs.h
@@ -11,6 +11,9 @@ enum sheepfs_opcode {
 	OP_VDI_UNMOUNT,
 	OP_NODE_INFO,
 	OP_NODE_LIST,
+	OP_CONFIG_PCACHE,
+	OP_CONFIG_OCACHE,
+	OP_CONFIG_SHEEP,
 	OP_VOLUME,
 };
 
@@ -19,7 +22,7 @@ enum sheepfs_opcode {
 extern char sheepfs_shadow[];
 extern int sheepfs_page_cache;
 extern int sheepfs_object_cache;
-extern const char *sdhost;
+extern char sdhost[];
 extern int sdport;
 
 extern struct strbuf *sheepfs_run_cmd(const char *command);
@@ -46,6 +49,7 @@ extern int volume_create_entry(const char *entry);
 extern int volume_remove_entry(const char *entry);
 extern int volume_sync(const char *path);
 extern int volume_open(const char *path, struct fuse_file_info *);
+extern int reset_socket_pool(void);
 
 /* cluster.c */
 extern int cluster_info_read(const char *path, char *buf, size_t size, off_t);
@@ -67,4 +71,19 @@ extern int node_info_read(const char *path, char *buf, size_t size, off_t);
 extern size_t node_info_get_size(const char *path);
 extern int create_node_layout(void);
 
+/* config.c */
+extern int create_config_layout(void);
+
+extern int config_pcache_read(const char *path, char *buf, size_t size, off_t);
+extern int config_pcache_write(const char *path, const char *, size_t, off_t);
+extern size_t config_pcache_get_size(const char *path);
+
+extern int config_ocache_read(const char *path, char *buf, size_t size, off_t);
+extern int config_ocache_write(const char *path, const char *, size_t, off_t);
+extern size_t config_ocache_get_size(const char *path);
+
+extern int config_sheep_info_read(const char *path, char *, size_t size, off_t);
+extern int config_sheep_info_write(const char *, const char *, size_t, off_t);
+extern size_t config_sheep_info_get_size(const char *path);
+
 #endif
diff --git a/sheepfs/volume.c b/sheepfs/volume.c
index fcd9bb2..f6490bd 100644
--- a/sheepfs/volume.c
+++ b/sheepfs/volume.c
@@ -372,6 +372,27 @@ static int setup_socket_pool(int array[], int len)
 	return 0;
 }
 
+int reset_socket_pool(void)
+{
+	struct rb_node *node;
+	struct vdi_inode *vdi;
+	int ret = 0;
+
+	pthread_rwlock_rdlock(&vdi_inode_tree_lock);
+	for (node = rb_first(&vdi_inode_tree); node; node = rb_next(node)) {
+		vdi = rb_entry(node, struct vdi_inode, rb);
+		destroy_socket_pool(vdi->socket_pool, SOCKET_POOL_SIZE);
+		if (setup_socket_pool(vdi->socket_pool,
+			SOCKET_POOL_SIZE) < 0) {
+			ret = -1;
+			goto out;
+		}
+	}
+out:
+	pthread_rwlock_unlock(&vdi_inode_tree_lock);
+	return ret;
+}
+
 static int init_vdi_info(const char *entry, uint32_t *vid, size_t *size)
 {
 	struct strbuf *buf;
-- 
1.7.10.2




More information about the sheepdog mailing list