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 |