[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