From cbb7a20daf7d59681eb21495361236cf68e9cd3b Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Fri, 13 Apr 2012 14:28:05 +0530 Subject: glusterd: Moved 'hooks' interface code to glusterd-hooks.* Change-Id: Ia7c0e37154414bddb05516e11b3cc4e6ae83ff38 BUG: 806996 Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.com/3142 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/mgmt/glusterd/src/Makefile.am | 4 +- xlators/mgmt/glusterd/src/glusterd-hooks.c | 250 +++++++++++++++++++++++++++++ xlators/mgmt/glusterd/src/glusterd-hooks.h | 49 ++++++ xlators/mgmt/glusterd/src/glusterd-op-sm.c | 5 +- xlators/mgmt/glusterd/src/glusterd-store.c | 211 ------------------------ xlators/mgmt/glusterd/src/glusterd-store.h | 21 --- xlators/mgmt/glusterd/src/glusterd.c | 3 +- 7 files changed, 306 insertions(+), 237 deletions(-) create mode 100644 xlators/mgmt/glusterd/src/glusterd-hooks.c create mode 100644 xlators/mgmt/glusterd/src/glusterd-hooks.h (limited to 'xlators/mgmt/glusterd') diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index d11dd2af292..d1dbf584227 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -8,7 +8,7 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \ glusterd-volgen.c glusterd-rebalance.c glusterd-quota.c \ glusterd-geo-rep.c glusterd-replace-brick.c glusterd-log-ops.c \ glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \ - glusterd-syncop.c + glusterd-syncop.c glusterd-hooks.c glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ $(top_builddir)/rpc/xdr/src/libgfxdr.la \ @@ -17,7 +17,7 @@ glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \ noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h \ glusterd-sm.h glusterd-store.h glusterd-mem-types.h \ glusterd-pmap.h glusterd-volgen.h glusterd-mountbroker.h \ - glusterd-syncop.h + glusterd-syncop.h glusterd-hooks.h AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\ diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c new file mode 100644 index 00000000000..ef12e70f2a6 --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c @@ -0,0 +1,250 @@ +/* + Copyright (c) 2007-2012 Gluster, Inc. + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . +*/ +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "globals.h" +#include "glusterfs.h" +#include "dict.h" +#include "xlator.h" +#include "logging.h" +#include "run.h" +#include "defaults.h" +#include "compat.h" +#include "compat-errno.h" +#include "glusterd.h" +#include "glusterd-sm.h" +#include "glusterd-op-sm.h" +#include "glusterd-utils.h" +#include "glusterd-store.h" +#include "glusterd-hooks.h" + +extern int mkdir_if_missing (char *dir); + +#define EMPTY "" +char glusterd_hook_dirnames[GD_OP_MAX][256] = +{ + [GD_OP_NONE] = EMPTY, + [GD_OP_CREATE_VOLUME] = "create", + [GD_OP_START_BRICK] = EMPTY, + [GD_OP_STOP_BRICK] = EMPTY, + [GD_OP_DELETE_VOLUME] = "delete", + [GD_OP_START_VOLUME] = "start", + [GD_OP_STOP_VOLUME] = "stop", + [GD_OP_DEFRAG_VOLUME] = EMPTY, + [GD_OP_ADD_BRICK] = "add-brick", + [GD_OP_REMOVE_BRICK] = "remove-brick", + [GD_OP_REPLACE_BRICK] = EMPTY, + [GD_OP_SET_VOLUME] = EMPTY, + [GD_OP_RESET_VOLUME] = EMPTY, + [GD_OP_SYNC_VOLUME] = EMPTY, + [GD_OP_LOG_ROTATE] = EMPTY, + [GD_OP_GSYNC_SET] = EMPTY, + [GD_OP_PROFILE_VOLUME] = EMPTY, + [GD_OP_QUOTA] = EMPTY, + [GD_OP_STATUS_VOLUME] = EMPTY, + [GD_OP_REBALANCE] = EMPTY, + [GD_OP_HEAL_VOLUME] = EMPTY, + [GD_OP_STATEDUMP_VOLUME] = EMPTY, + [GD_OP_LIST_VOLUME] = EMPTY, + [GD_OP_CLEARLOCKS_VOLUME] = EMPTY, + [GD_OP_DEFRAG_BRICK_VOLUME] = EMPTY, +}; +#undef EMPTY + +static inline gf_boolean_t +glusterd_is_hook_enabled (char *script) +{ + return (script[0] == 'S'); +} + +int +glusterd_hooks_create_hooks_directory (char *basedir) +{ + int ret = -1; + int op = GD_OP_NONE; + int type = GD_COMMIT_HOOK_NONE; + char version_dir[PATH_MAX] = {0, }; + char path[PATH_MAX] = {0, }; + char *cmd_subdir = NULL; + char type_subdir[GD_COMMIT_HOOK_MAX][256] = {{0, }, + "pre", + "post"}; + glusterd_conf_t *priv = NULL; + + priv = THIS->private; + + snprintf (path, sizeof (path), "%s/hooks", basedir); + ret = mkdir_if_missing (path); + if (ret) { + gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due" + "to %s", path, strerror (errno)); + goto out; + } + + GLUSTERD_GET_HOOKS_DIR (version_dir, GLUSTERD_HOOK_VER, priv); + ret = mkdir_if_missing (version_dir); + if (ret) { + gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due " + "to %s", version_dir, strerror (errno)); + goto out; + } + + for (op = GD_OP_NONE+1; op < GD_OP_MAX; op++) { + cmd_subdir = glusterd_hooks_get_hooks_cmd_subdir (op); + if (strlen (cmd_subdir) == 0) + continue; + + snprintf (path, sizeof (path), "%s/%s", version_dir, + cmd_subdir); + ret = mkdir_if_missing (path); + if (ret) { + gf_log (THIS->name, GF_LOG_CRITICAL, + "Unable to create %s due to %s", + path, strerror (errno)); + goto out; + } + + for (type = GD_COMMIT_HOOK_PRE; type < GD_COMMIT_HOOK_MAX; + type++) { + snprintf (path, sizeof (path), "%s/%s/%s", + version_dir, cmd_subdir, type_subdir[type]); + ret = mkdir_if_missing (path); + if (ret) { + gf_log (THIS->name, GF_LOG_CRITICAL, + "Unable to create %s due to %s", + path, strerror (errno)); + goto out; + } + } + } + + ret = 0; +out: + return ret; +} + +char* +glusterd_hooks_get_hooks_cmd_subdir (glusterd_op_t op) +{ + GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX)); + + return glusterd_hook_dirnames[op]; +} + +int +glusterd_hooks_run_hooks (char *hooks_path, dict_t *op_ctx) +{ + xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + runner_t runner = {0, }; + struct dirent *entry = NULL; + DIR *hookdir = NULL; + char *volname = NULL; + char **lines = NULL; + int N = 8; /*arbitrary*/ + int lineno = 0; + int line_count = 0; + int ret = -1; + + this = THIS; + priv = this->private; + + ret = dict_get_str (op_ctx, "volname", &volname); + if (ret) { + gf_log (this->name, GF_LOG_CRITICAL, "Failed to get volname " + "from operation context"); + goto out; + } + + hookdir = opendir (hooks_path); + if (!hookdir) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s, due " + "to %s", hooks_path, strerror (errno)); + goto out; + } + + lines = GF_CALLOC (1, N * sizeof (*lines), gf_gld_mt_charptr); + if (!lines) { + ret = -1; + goto out; + } + + ret = -1; + line_count = 0; + glusterd_for_each_entry (entry, hookdir); + while (entry) { + if (line_count == N-1) { + N *= 2; + lines = GF_REALLOC (lines, N * sizeof (char *)); + if (!lines) + goto out; + } + + if (glusterd_is_hook_enabled (entry->d_name)) { + lines[line_count] = gf_strdup (entry->d_name); + line_count++; + } + + glusterd_for_each_entry (entry, hookdir); + } + + lines[line_count] = NULL; + lines = GF_REALLOC (lines, (line_count + 1) * sizeof (char *)); + if (!lines) + goto out; + + qsort (lines, line_count, sizeof (*lines), glusterd_compare_lines); + + for (lineno = 0; lineno < line_count; lineno++) { + + runinit (&runner); + runner_argprintf (&runner, "%s/%s", hooks_path, lines[lineno]); + /*Add future command line arguments to hook scripts below*/ + runner_argprintf (&runner, "--volname=%s", volname); + ret = runner_run_reuse (&runner); + if (ret) { + runner_log (&runner, this->name, GF_LOG_ERROR, + "Failed to execute script"); + } else { + runner_log (&runner, this->name, GF_LOG_INFO, + "Ran script"); + } + runner_end (&runner); + } + + ret = 0; +out: + if (lines) { + for (lineno = 0; lineno < line_count+1; lineno++) + if (lines[lineno]) + GF_FREE (lines[lineno]); + + GF_FREE (lines); + } + + if (hookdir) + closedir (hookdir); + + return ret; +} + diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.h b/xlators/mgmt/glusterd/src/glusterd-hooks.h new file mode 100644 index 00000000000..a57eab0fa41 --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-hooks.h @@ -0,0 +1,49 @@ +/* + Copyright (c) 2006-2012 Gluster, Inc. + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . +*/ + +#ifndef _GLUSTERD_HOOKS_H_ +#define _GLUSTERD_HOOKS_H_ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#define GLUSTERD_GET_HOOKS_DIR(path, version, priv) \ + snprintf (path, PATH_MAX, "%s/hooks/%d", priv->workdir,\ + version); + +#define GLUSTERD_HOOK_VER 1 + +typedef enum glusterd_commit_hook_type { + GD_COMMIT_HOOK_NONE = 0, + GD_COMMIT_HOOK_PRE, + GD_COMMIT_HOOK_POST, + GD_COMMIT_HOOK_MAX +} glusterd_commit_hook_type_t; + +int +glusterd_hooks_create_hooks_directory (char *basedir); + +char * +glusterd_hooks_get_hooks_cmd_subdir (glusterd_op_t op); + +int +glusterd_hooks_run_hooks (char *hooks_path, dict_t *op_ctx); +#endif diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index b243df4338f..8f70472f50c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -45,6 +45,7 @@ #include "glusterd-op-sm.h" #include "glusterd-utils.h" #include "glusterd-store.h" +#include "glusterd-hooks.h" #include "glusterd-volgen.h" #include "syscall.h" #include "cli1-xdr.h" @@ -2281,7 +2282,7 @@ glusterd_op_commit_hook (glusterd_op_t op, dict_t *op_ctx, glusterd_commit_hook else if (type == GD_COMMIT_HOOK_POST) strcpy (type_subdir, "post"); - cmd_subdir = glusterd_store_get_hooks_cmd_subdir (op); + cmd_subdir = glusterd_hooks_get_hooks_cmd_subdir (op); if (strlen (cmd_subdir) == 0) return -1; @@ -2289,7 +2290,7 @@ glusterd_op_commit_hook (glusterd_op_t op, dict_t *op_ctx, glusterd_commit_hook snprintf (scriptdir, sizeof (scriptdir), "%s/%s/%s", hookdir, cmd_subdir, type_subdir); - return glusterd_store_run_hooks (scriptdir, op_ctx); + return glusterd_hooks_run_hooks (scriptdir, op_ctx); } static int diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 4cfbf5e4c3d..56c1d98754a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -51,39 +51,6 @@ #include #include -extern int mkdir_if_missing (char *dir); - -#define EMPTY "" -char glusterd_hook_dirnames[GD_OP_MAX][256] = -{ - [GD_OP_NONE] = EMPTY, - [GD_OP_CREATE_VOLUME] = "create", - [GD_OP_START_BRICK] = EMPTY, - [GD_OP_STOP_BRICK] = EMPTY, - [GD_OP_DELETE_VOLUME] = "delete", - [GD_OP_START_VOLUME] = "start", - [GD_OP_STOP_VOLUME] = "stop", - [GD_OP_DEFRAG_VOLUME] = EMPTY, - [GD_OP_ADD_BRICK] = "add-brick", - [GD_OP_REMOVE_BRICK] = "remove-brick", - [GD_OP_REPLACE_BRICK] = EMPTY, - [GD_OP_SET_VOLUME] = EMPTY, - [GD_OP_RESET_VOLUME] = EMPTY, - [GD_OP_SYNC_VOLUME] = EMPTY, - [GD_OP_LOG_ROTATE] = EMPTY, - [GD_OP_GSYNC_SET] = EMPTY, - [GD_OP_PROFILE_VOLUME] = EMPTY, - [GD_OP_QUOTA] = EMPTY, - [GD_OP_STATUS_VOLUME] = EMPTY, - [GD_OP_REBALANCE] = EMPTY, - [GD_OP_HEAL_VOLUME] = EMPTY, - [GD_OP_STATEDUMP_VOLUME] = EMPTY, - [GD_OP_LIST_VOLUME] = EMPTY, - [GD_OP_CLEARLOCKS_VOLUME] = EMPTY, - [GD_OP_DEFRAG_BRICK_VOLUME] = EMPTY, -}; -#undef EMPTY - static int32_t glusterd_store_mkdir (char *path) { @@ -2497,181 +2464,3 @@ out: gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); return ret; } - -static inline gf_boolean_t -glusterd_is_hook_enabled (char *script) -{ - return (script[0] == 'S'); -} - -int -glusterd_store_create_hooks_directory (char *basedir) -{ - int ret = -1; - int op = GD_OP_NONE; - int type = GD_COMMIT_HOOK_NONE; - char version_dir[PATH_MAX] = {0, }; - char path[PATH_MAX] = {0, }; - char *cmd_subdir = NULL; - char type_subdir[GD_COMMIT_HOOK_MAX][256] = {{0, }, - "pre", - "post"}; - glusterd_conf_t *priv = NULL; - - priv = THIS->private; - - snprintf (path, sizeof (path), "%s/hooks", basedir); - ret = mkdir_if_missing (path); - if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due" - "to %s", path, strerror (errno)); - goto out; - } - - GLUSTERD_GET_HOOKS_DIR (version_dir, GLUSTERD_HOOK_VER, priv); - ret = mkdir_if_missing (version_dir); - if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due " - "to %s", version_dir, strerror (errno)); - goto out; - } - - for (op = GD_OP_NONE+1; op < GD_OP_MAX; op++) { - cmd_subdir = glusterd_store_get_hooks_cmd_subdir (op); - if (strlen (cmd_subdir) == 0) - continue; - - snprintf (path, sizeof (path), "%s/%s", version_dir, - cmd_subdir); - ret = mkdir_if_missing (path); - if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, - "Unable to create %s due to %s", - path, strerror (errno)); - goto out; - } - - for (type = GD_COMMIT_HOOK_PRE; type < GD_COMMIT_HOOK_MAX; - type++) { - snprintf (path, sizeof (path), "%s/%s/%s", - version_dir, cmd_subdir, type_subdir[type]); - ret = mkdir_if_missing (path); - if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, - "Unable to create %s due to %s", - path, strerror (errno)); - goto out; - } - } - } - - ret = 0; -out: - return ret; -} - -char* -glusterd_store_get_hooks_cmd_subdir (glusterd_op_t op) -{ - GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX)); - - return glusterd_hook_dirnames[op]; -} - -int -glusterd_store_run_hooks (char *hooks_path, dict_t *op_ctx) -{ - xlator_t *this = NULL; - glusterd_conf_t *priv = NULL; - runner_t runner = {0, }; - struct dirent *entry = NULL; - DIR *hookdir = NULL; - char *volname = NULL; - char **lines = NULL; - int N = 8; /*arbitrary*/ - int lineno = 0; - int line_count = 0; - int ret = -1; - - this = THIS; - priv = this->private; - - ret = dict_get_str (op_ctx, "volname", &volname); - if (ret) { - gf_log (this->name, GF_LOG_CRITICAL, "Failed to get volname " - "from operation context"); - goto out; - } - - hookdir = opendir (hooks_path); - if (!hookdir) { - ret = -1; - gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s, due " - "to %s", hooks_path, strerror (errno)); - goto out; - } - - lines = GF_CALLOC (1, N * sizeof (*lines), gf_gld_mt_charptr); - if (!lines) { - ret = -1; - goto out; - } - - ret = -1; - line_count = 0; - glusterd_for_each_entry (entry, hookdir); - while (entry) { - if (line_count == N-1) { - N *= 2; - lines = GF_REALLOC (lines, N * sizeof (char *)); - if (!lines) - goto out; - } - - if (glusterd_is_hook_enabled (entry->d_name)) { - lines[line_count] = gf_strdup (entry->d_name); - line_count++; - } - - glusterd_for_each_entry (entry, hookdir); - } - - lines[line_count] = NULL; - lines = GF_REALLOC (lines, (line_count + 1) * sizeof (char *)); - if (!lines) - goto out; - - qsort (lines, line_count, sizeof (*lines), glusterd_compare_lines); - - for (lineno = 0; lineno < line_count; lineno++) { - - runinit (&runner); - runner_argprintf (&runner, "%s/%s", hooks_path, lines[lineno]); - /*Add future command line arguments to hook scripts below*/ - runner_argprintf (&runner, "--volname=%s", volname); - ret = runner_run_reuse (&runner); - if (ret) { - runner_log (&runner, this->name, GF_LOG_ERROR, - "Failed to execute script"); - } else { - runner_log (&runner, this->name, GF_LOG_INFO, - "Ran script"); - } - runner_end (&runner); - } - - ret = 0; -out: - if (lines) { - for (lineno = 0; lineno < line_count+1; lineno++) - if (lines[lineno]) - GF_FREE (lines[lineno]); - - GF_FREE (lines); - } - - if (hookdir) - closedir (hookdir); - - return ret; -} diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index 788949d55fc..f54ffffcef1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -74,10 +74,6 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_PEER_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_PEER_STATE "state" -#define GLUSTERD_GET_HOOKS_DIR(path, version, priv) \ - snprintf (path, PATH_MAX, "%s/hooks/%d", priv->workdir,\ - version); - #define glusterd_for_each_entry(entry, dir) \ do {\ entry = NULL;\ @@ -101,14 +97,6 @@ typedef enum { GD_STORE_STAT_FAILED } glusterd_store_op_errno_t; -#define GLUSTERD_HOOK_VER 1 -typedef enum glusterd_commit_hook_type { - GD_COMMIT_HOOK_NONE = 0, - GD_COMMIT_HOOK_PRE, - GD_COMMIT_HOOK_POST, - GD_COMMIT_HOOK_MAX -} glusterd_commit_hook_type_t; - int32_t glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac); @@ -152,13 +140,4 @@ glusterd_perform_volinfo_version_action (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac); gf_boolean_t glusterd_store_is_valid_brickpath (char *volname, char *brick); - -int -glusterd_store_create_hooks_directory (char *basedir); - -char * -glusterd_store_get_hooks_cmd_subdir (glusterd_op_t op); - -int -glusterd_store_run_hooks (char *hooks_path, dict_t *op_ctx); #endif diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index b1856d81d98..7f41721c0a2 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -44,6 +44,7 @@ #include "glusterd-sm.h" #include "glusterd-op-sm.h" #include "glusterd-store.h" +#include "glusterd-hooks.h" #include "glusterd-utils.h" #include "common-utils.h" #include "run.h" @@ -981,7 +982,7 @@ init (xlator_t *this) GLUSTERD_GET_HOOKS_DIR (hooks_dir, GLUSTERD_HOOK_VER, conf); if (stat (hooks_dir, &buf)) { - ret = glusterd_store_create_hooks_directory (dirname); + ret = glusterd_hooks_create_hooks_directory (dirname); if (-1 == ret) { gf_log (this->name, GF_LOG_CRITICAL, "Unable to create hooks directory "); -- cgit