diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-hooks.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-hooks.c | 971 |
1 files changed, 542 insertions, 429 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c index ab8e0700524..61c0f1c946f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-hooks.c +++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c @@ -1,528 +1,641 @@ /* - Copyright (c) 2007-2012 Gluster, Inc. <http://www.gluster.com> - 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 - <http://www.gnu.org/licenses/>. + Copyright (c) 2007-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#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 <glusterfs/glusterfs.h> +#include <glusterfs/dict.h> +#include <glusterfs/xlator.h> +#include <glusterfs/logging.h> +#include <glusterfs/run.h> +#include <glusterfs/defaults.h> +#include <glusterfs/syscall.h> +#include <glusterfs/compat.h> +#include <glusterfs/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" +#include "glusterd-messages.h" #include <fnmatch.h> #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] = "set", - [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, +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] = "set", + [GD_OP_RESET_VOLUME] = "reset", + [GD_OP_SYNC_VOLUME] = EMPTY, + [GD_OP_LOG_ROTATE] = EMPTY, + [GD_OP_GSYNC_CREATE] = "gsync-create", + [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, + [GD_OP_RESET_BRICK] = EMPTY, }; #undef EMPTY -static inline gf_boolean_t -glusterd_is_hook_enabled (char *script) +static gf_boolean_t +glusterd_is_hook_enabled(char *script) { - return (script[0] == 'S'); + return (script[0] == 'S' && (fnmatch("*.rpmsave", script, 0) != 0) && + (fnmatch("*.rpmnew", script, 0) != 0)); } int -glusterd_hooks_create_hooks_directory (char *basedir) +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_p (path, 0777, _gf_true); - if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due" - "to %s", path, strerror (errno)); - goto out; + 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; + int32_t len = 0; + + xlator_t *this = NULL; + this = THIS; + GF_ASSERT(this); + priv = this->private; + + snprintf(path, sizeof(path), "%s/hooks", basedir); + ret = mkdir_p(path, 0755, _gf_true); + if (ret) { + gf_smsg(this->name, GF_LOG_CRITICAL, errno, GD_MSG_CREATE_DIR_FAILED, + "Path=%s", path, NULL); + goto out; + } + + GLUSTERD_GET_HOOKS_DIR(version_dir, GLUSTERD_HOOK_VER, priv); + ret = mkdir_p(version_dir, 0755, _gf_true); + if (ret) { + gf_smsg(this->name, GF_LOG_CRITICAL, errno, GD_MSG_CREATE_DIR_FAILED, + "Directory=%s", version_dir, NULL); + 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; + + len = snprintf(path, sizeof(path), "%s/%s", version_dir, cmd_subdir); + if ((len < 0) || (len >= sizeof(path))) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, NULL); + ret = -1; + goto out; } - - GLUSTERD_GET_HOOKS_DIR (version_dir, GLUSTERD_HOOK_VER, priv); - ret = mkdir_p (version_dir, 0777, _gf_true); + ret = mkdir_p(path, 0755, _gf_true); if (ret) { - gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due " - "to %s", version_dir, strerror (errno)); - goto out; + gf_smsg(this->name, GF_LOG_CRITICAL, errno, + GD_MSG_CREATE_DIR_FAILED, "Path=%s", path, NULL); + 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_p (path, 0777, _gf_true); - 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_p (path, 0777, _gf_true); - 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++) { + len = snprintf(path, sizeof(path), "%s/%s/%s", version_dir, + cmd_subdir, type_subdir[type]); + if ((len < 0) || (len >= sizeof(path))) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_COPY_FAIL, + NULL); + ret = -1; + goto out; + } + ret = mkdir_p(path, 0755, _gf_true); + if (ret) { + gf_smsg(this->name, GF_LOG_CRITICAL, errno, + GD_MSG_CREATE_DIR_FAILED, "Path=%s", path, NULL); + goto out; + } } + } - ret = 0; + ret = 0; out: - return ret; + return ret; } -char* -glusterd_hooks_get_hooks_cmd_subdir (glusterd_op_t op) +char * +glusterd_hooks_get_hooks_cmd_subdir(glusterd_op_t op) { - GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX)); + GF_ASSERT((op > GD_OP_NONE) && (op < GD_OP_MAX)); - return glusterd_hook_dirnames[op]; + return glusterd_hook_dirnames[op]; } -int -glusterd_hooks_set_volume_args (dict_t *dict, runner_t *runner) +void +glusterd_hooks_add_working_dir(runner_t *runner, glusterd_conf_t *priv) { - int i = 0; - int count = 0; - int ret = -1; - char query[1024] = {0,}; - char *key = NULL; - char *value = NULL; - - ret = dict_get_int32 (dict, "count", &count); - if (ret) - goto out; - - /* This will not happen unless op_ctx - * is corrupted*/ - if (!count) - goto out; - - runner_add_arg (runner, "-o"); - for (i = 1; (ret == 0); i++) { - snprintf (query, sizeof (query), "key%d", i); - ret = dict_get_str (dict, query, &key); - if (ret) - continue; - - snprintf (query, sizeof (query), "value%d", i); - ret = dict_get_str (dict, query, &value); - if (ret) - continue; - - runner_argprintf (runner, "%s=%s", key, value); - } - - ret = 0; -out: - return ret; + runner_argprintf(runner, "--gd-workdir=%s", priv->workdir); } -static int -glusterd_hooks_add_op_args (runner_t *runner, glusterd_op_t op, - dict_t *op_ctx, glusterd_commit_hook_type_t type) +void +glusterd_hooks_add_op(runner_t *runner, char *op) { - int vol_count = 0; - gf_boolean_t truth = _gf_false; - glusterd_volinfo_t *voliter = NULL; - glusterd_conf_t *priv = NULL; - int ret = -1; - - priv = THIS->private; - list_for_each_entry (voliter, &priv->volumes, - vol_list) { - if (glusterd_is_volume_started (voliter)) - vol_count++; - } - - ret = 0; - switch (op) { - case GD_OP_START_VOLUME: - if (type == GD_COMMIT_HOOK_PRE && - vol_count == 0) - truth = _gf_true; - - else if (type == GD_COMMIT_HOOK_POST && - vol_count == 1) - truth = _gf_true; - - else - truth = _gf_false; + runner_argprintf(runner, "--volume-op=%s", op); +} - runner_argprintf (runner, "--first=%s", - truth? "yes":"no"); - break; +void +glusterd_hooks_add_hooks_version(runner_t *runner) +{ + runner_argprintf(runner, "--version=%d", GLUSTERD_HOOK_VER); +} - case GD_OP_STOP_VOLUME: - if (type == GD_COMMIT_HOOK_PRE && - vol_count == 1) - truth = _gf_true; +static void +glusterd_hooks_add_custom_args(dict_t *dict, runner_t *runner) +{ + char *hooks_args = NULL; + int32_t ret = -1; + xlator_t *this = NULL; - else if (type == GD_COMMIT_HOOK_POST && - vol_count == 0) - truth = _gf_true; + this = THIS; + GF_VALIDATE_OR_GOTO("glusterd", this, out); + GF_VALIDATE_OR_GOTO(this->name, dict, out); + GF_VALIDATE_OR_GOTO(this->name, runner, out); - else - truth = _gf_false; + ret = dict_get_str(dict, "hooks_args", &hooks_args); + if (ret) + gf_msg_debug(this->name, 0, "No Hooks Arguments."); + else + gf_msg_debug(this->name, 0, "Hooks Args = %s", hooks_args); - runner_argprintf (runner, "--last=%s", - truth? "yes":"no"); - break; + if (hooks_args) + runner_argprintf(runner, "%s", hooks_args); - case GD_OP_SET_VOLUME: - ret = glusterd_hooks_set_volume_args (op_ctx, runner); - break; +out: + return; +} - default: - break; +int +glusterd_hooks_set_volume_args(dict_t *dict, runner_t *runner) +{ + int i = 0; + int count = 0; + int ret = -1; + int flag = 0; + char query[1024] = { + 0, + }; + char *key = NULL; + char *value = NULL; + char *inet_family = NULL; + xlator_t *this = NULL; + this = THIS; + GF_ASSERT(this); + + ret = dict_get_int32(dict, "count", &count); + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_GET_FAILED, + "Key=count", NULL); + goto out; + } + + /* This will not happen unless op_ctx + * is corrupted*/ + if (!count) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ENTRY, "count", + NULL); + goto out; + } + + runner_add_arg(runner, "-o"); + for (i = 1; ret == 0; i++) { + snprintf(query, sizeof(query), "key%d", i); + ret = dict_get_str(dict, query, &key); + if (ret) + continue; + snprintf(query, sizeof(query), "value%d", i); + ret = dict_get_str(dict, query, &value); + if (ret) + continue; + + runner_argprintf(runner, "%s=%s", key, value); + if ((strncmp(key, "cluster.enable-shared-storage", + SLEN("cluster.enable-shared-storage")) == 0 || + strncmp(key, "enable-shared-storage", + SLEN("enable-shared-storage")) == 0) && + strncmp(value, "enable", SLEN("enable")) == 0) + flag = 1; + } + + glusterd_hooks_add_custom_args(dict, runner); + if (flag == 1) { + ret = dict_get_str_sizen(this->options, "transport.address-family", + &inet_family); + if (!ret) { + runner_argprintf(runner, "transport.address-family=%s", + inet_family); } + } + + ret = 0; +out: + return ret; +} - return ret; +static int +glusterd_hooks_add_op_args(runner_t *runner, glusterd_op_t op, dict_t *op_ctx, + glusterd_commit_hook_type_t type) +{ + int vol_count = 0; + gf_boolean_t truth = _gf_false; + glusterd_volinfo_t *voliter = NULL; + glusterd_conf_t *priv = NULL; + int ret = -1; + + priv = THIS->private; + cds_list_for_each_entry(voliter, &priv->volumes, vol_list) + { + if (glusterd_is_volume_started(voliter)) + vol_count++; + } + + ret = 0; + switch (op) { + case GD_OP_START_VOLUME: + if (type == GD_COMMIT_HOOK_PRE && vol_count == 0) + truth = _gf_true; + + else if (type == GD_COMMIT_HOOK_POST && vol_count == 1) + truth = _gf_true; + + else + truth = _gf_false; + + runner_argprintf(runner, "--first=%s", truth ? "yes" : "no"); + + glusterd_hooks_add_hooks_version(runner); + glusterd_hooks_add_op(runner, "start"); + glusterd_hooks_add_working_dir(runner, priv); + + break; + + case GD_OP_STOP_VOLUME: + if (type == GD_COMMIT_HOOK_PRE && vol_count == 1) + truth = _gf_true; + + else if (type == GD_COMMIT_HOOK_POST && vol_count == 0) + truth = _gf_true; + + else + truth = _gf_false; + + runner_argprintf(runner, "--last=%s", truth ? "yes" : "no"); + break; + + case GD_OP_SET_VOLUME: + ret = glusterd_hooks_set_volume_args(op_ctx, runner); + glusterd_hooks_add_working_dir(runner, priv); + break; + + case GD_OP_GSYNC_CREATE: + glusterd_hooks_add_custom_args(op_ctx, runner); + break; + + case GD_OP_ADD_BRICK: + glusterd_hooks_add_hooks_version(runner); + glusterd_hooks_add_op(runner, "add-brick"); + glusterd_hooks_add_working_dir(runner, priv); + break; + + case GD_OP_RESET_VOLUME: + glusterd_hooks_add_hooks_version(runner); + glusterd_hooks_add_op(runner, "reset"); + glusterd_hooks_add_working_dir(runner, priv); + break; + + default: + break; + } + + return ret; } int -glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx, - glusterd_commit_hook_type_t type) +glusterd_hooks_run_hooks(char *hooks_path, glusterd_op_t op, dict_t *op_ctx, + glusterd_commit_hook_type_t type) { - 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"); + xlator_t *this = NULL; + runner_t runner = { + 0, + }; + DIR *hookdir = NULL; + struct dirent *entry = NULL; + struct dirent scratch[2] = { + { + 0, + }, + }; + char *volname = NULL; + char **lines = NULL; + int N = 8; /*arbitrary*/ + int lineno = 0; + int line_count = 0; + int ret = -1; + + this = THIS; + + ret = dict_get_str(op_ctx, "volname", &volname); + if (ret) { + gf_msg(this->name, GF_LOG_CRITICAL, errno, GD_MSG_DICT_GET_FAILED, + "Failed to get volname " + "from operation context"); + goto out; + } + + hookdir = sys_opendir(hooks_path); + if (!hookdir) { + ret = -1; + gf_msg(this->name, GF_LOG_ERROR, errno, GD_MSG_DIR_OP_FAILED, + "Failed to open dir %s", hooks_path); + goto out; + } + + lines = GF_CALLOC(1, N * sizeof(*lines), gf_gld_mt_charptr); + if (!lines) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); + ret = -1; + goto out; + } + + ret = -1; + line_count = 0; + + while ((entry = sys_readdir(hookdir, scratch))) { + if (gf_irrelevant_entry(entry)) + continue; + if (line_count == N - 1) { + N *= 2; + lines = GF_REALLOC(lines, N * sizeof(char *)); + if (!lines) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, + NULL); 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; + if (glusterd_is_hook_enabled(entry->d_name)) { + lines[line_count] = gf_strdup(entry->d_name); + line_count++; } + } - lines = GF_CALLOC (1, N * sizeof (*lines), gf_gld_mt_charptr); - if (!lines) { - ret = -1; - goto out; - } + lines[line_count] = NULL; + lines = GF_REALLOC(lines, (line_count + 1) * sizeof(char *)); + if (!lines) + 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); - } + qsort(lines, line_count, sizeof(*lines), glusterd_compare_lines); - lines[line_count] = NULL; - lines = GF_REALLOC (lines, (line_count + 1) * sizeof (char *)); - if (!lines) - goto out; + 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 = glusterd_hooks_add_op_args(&runner, op, op_ctx, type); + if (ret) { + gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_ADD_OP_ARGS_FAIL, + "Failed to add " + "command specific arguments"); + 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 = glusterd_hooks_add_op_args (&runner, op, op_ctx, type); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Failed to add " - "command specific arguments"); - goto out; - } - - 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 = 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; + ret = 0; out: - if (lines) { - for (lineno = 0; lineno < line_count+1; lineno++) - if (lines[lineno]) - GF_FREE (lines[lineno]); + if (lines) { + for (lineno = 0; lineno < line_count + 1; lineno++) + GF_FREE(lines[lineno]); - GF_FREE (lines); - } + GF_FREE(lines); + } - if (hookdir) - closedir (hookdir); + if (hookdir) + sys_closedir(hookdir); - return ret; + return ret; } int -glusterd_hooks_post_stub_enqueue (char *scriptdir, glusterd_op_t op, - dict_t *op_ctx) +glusterd_hooks_post_stub_enqueue(char *scriptdir, glusterd_op_t op, + dict_t *op_ctx) { - int ret = -1; - glusterd_hooks_stub_t *stub = NULL; - glusterd_hooks_private_t *hooks_priv = NULL; - glusterd_conf_t *conf = NULL; - - conf = THIS->private; - hooks_priv = conf->hooks_priv; - - ret = glusterd_hooks_stub_init (&stub, scriptdir, op, op_ctx); - if (ret) - goto out; - - pthread_mutex_lock (&hooks_priv->mutex); - { - hooks_priv->waitcount++; - list_add_tail (&stub->all_hooks, &hooks_priv->list); - pthread_cond_signal (&hooks_priv->cond); - } - pthread_mutex_unlock (&hooks_priv->mutex); - - ret = 0; + int ret = -1; + glusterd_hooks_stub_t *stub = NULL; + glusterd_hooks_private_t *hooks_priv = NULL; + glusterd_conf_t *conf = NULL; + + conf = THIS->private; + hooks_priv = conf->hooks_priv; + + ret = glusterd_hooks_stub_init(&stub, scriptdir, op, op_ctx); + if (ret) + goto out; + + pthread_mutex_lock(&hooks_priv->mutex); + { + hooks_priv->waitcount++; + cds_list_add_tail(&stub->all_hooks, &hooks_priv->list); + pthread_cond_signal(&hooks_priv->cond); + } + pthread_mutex_unlock(&hooks_priv->mutex); + + ret = 0; out: - return ret; + return ret; } int -glusterd_hooks_stub_init (glusterd_hooks_stub_t **stub, char *scriptdir, - glusterd_op_t op, dict_t *op_ctx) +glusterd_hooks_stub_init(glusterd_hooks_stub_t **stub, char *scriptdir, + glusterd_op_t op, dict_t *op_ctx) { - int ret = -1; - glusterd_hooks_stub_t *hooks_stub = NULL; - - GF_ASSERT (stub); - if (!stub) - goto out; - - hooks_stub = GF_CALLOC (1, sizeof (*hooks_stub), - gf_gld_mt_hooks_stub_t); - if (!hooks_stub) - goto out; - - INIT_LIST_HEAD (&hooks_stub->all_hooks); - hooks_stub->op = op; - hooks_stub->scriptdir = gf_strdup (scriptdir); - if (!hooks_stub->scriptdir) - goto out; - - hooks_stub->op_ctx = dict_copy_with_ref (op_ctx, hooks_stub->op_ctx); - if (!hooks_stub->op_ctx) - goto out; - - *stub = hooks_stub; - ret = 0; + int ret = -1; + glusterd_hooks_stub_t *hooks_stub = NULL; + + xlator_t *this = NULL; + this = THIS; + GF_ASSERT(this); + GF_ASSERT(stub); + if (!stub) + goto out; + + hooks_stub = GF_CALLOC(1, sizeof(*hooks_stub), gf_gld_mt_hooks_stub_t); + if (!hooks_stub) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); + goto out; + } + + CDS_INIT_LIST_HEAD(&hooks_stub->all_hooks); + hooks_stub->op = op; + hooks_stub->scriptdir = gf_strdup(scriptdir); + if (!hooks_stub->scriptdir) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_STRDUP_FAILED, + "scriptdir=%s", scriptdir, NULL); + goto out; + } + + hooks_stub->op_ctx = dict_copy_with_ref(op_ctx, hooks_stub->op_ctx); + if (!hooks_stub->op_ctx) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_DICT_COPY_FAIL, NULL); + goto out; + } + + *stub = hooks_stub; + ret = 0; out: - if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "Failed to initialize " - "post hooks stub"); - glusterd_hooks_stub_cleanup (hooks_stub); - } + if (ret) { + gf_smsg(this->name, GF_LOG_ERROR, 0, GD_MSG_POST_HOOK_STUB_INIT_FAIL, + NULL); + glusterd_hooks_stub_cleanup(hooks_stub); + } - return ret; + return ret; } void -glusterd_hooks_stub_cleanup (glusterd_hooks_stub_t *stub) +glusterd_hooks_stub_cleanup(glusterd_hooks_stub_t *stub) { - if (!stub) { - gf_log_callingfn (THIS->name, GF_LOG_WARNING, - "hooks_stub is NULL"); - return; - } + if (!stub) { + gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, GD_MSG_HOOK_STUB_NULL, + "hooks_stub is NULL"); + return; + } - if (stub->op_ctx) - dict_unref (stub->op_ctx); + if (stub->op_ctx) + dict_unref(stub->op_ctx); - if (stub->scriptdir) - GF_FREE (stub->scriptdir); + GF_FREE(stub->scriptdir); - if (stub) - GF_FREE (stub); + GF_FREE(stub); } -static void* -hooks_worker (void *args) +static void * +hooks_worker(void *args) { - glusterd_conf_t *conf = NULL; - glusterd_hooks_private_t *hooks_priv = NULL; - glusterd_hooks_stub_t *stub = NULL; - - THIS = args; - conf = THIS->private; - hooks_priv = conf->hooks_priv; - - for (;;) { - pthread_mutex_lock (&hooks_priv->mutex); - { - while (list_empty (&hooks_priv->list)) { - pthread_cond_wait (&hooks_priv->cond, - &hooks_priv->mutex); - } - stub = list_entry (hooks_priv->list.next, - glusterd_hooks_stub_t, - all_hooks); - list_del_init (&stub->all_hooks); - hooks_priv->waitcount--; - - } - pthread_mutex_unlock (&hooks_priv->mutex); - - glusterd_hooks_run_hooks (stub->scriptdir, stub->op, - stub->op_ctx, GD_COMMIT_HOOK_POST); - glusterd_hooks_stub_cleanup (stub); + glusterd_conf_t *conf = NULL; + glusterd_hooks_private_t *hooks_priv = NULL; + glusterd_hooks_stub_t *stub = NULL; + + THIS = args; + conf = THIS->private; + hooks_priv = conf->hooks_priv; + + for (;;) { + pthread_mutex_lock(&hooks_priv->mutex); + { + while (cds_list_empty(&hooks_priv->list)) { + pthread_cond_wait(&hooks_priv->cond, &hooks_priv->mutex); + } + stub = cds_list_entry(hooks_priv->list.next, glusterd_hooks_stub_t, + all_hooks); + cds_list_del_init(&stub->all_hooks); + hooks_priv->waitcount--; } + pthread_mutex_unlock(&hooks_priv->mutex); + + glusterd_hooks_run_hooks(stub->scriptdir, stub->op, stub->op_ctx, + GD_COMMIT_HOOK_POST); + glusterd_hooks_stub_cleanup(stub); + } - return NULL; + return NULL; } int -glusterd_hooks_priv_init (glusterd_hooks_private_t **new) +glusterd_hooks_priv_init(glusterd_hooks_private_t **new) { - int ret = -1; - glusterd_hooks_private_t *hooks_priv = NULL; - - if (!new) - goto out; - - hooks_priv = GF_CALLOC (1, sizeof (*hooks_priv), - gf_gld_mt_hooks_priv_t); - if (!hooks_priv) - goto out; - - pthread_mutex_init (&hooks_priv->mutex, NULL); - pthread_cond_init (&hooks_priv->cond, NULL); - INIT_LIST_HEAD (&hooks_priv->list); - hooks_priv->waitcount = 0; - - *new = hooks_priv; - ret = 0; + int ret = -1; + glusterd_hooks_private_t *hooks_priv = NULL; + + xlator_t *this = NULL; + this = THIS; + GF_ASSERT(this); + + if (!new) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_INVALID_ARGUMENT, NULL); + goto out; + } + + hooks_priv = GF_CALLOC(1, sizeof(*hooks_priv), gf_gld_mt_hooks_priv_t); + if (!hooks_priv) { + gf_smsg(this->name, GF_LOG_ERROR, errno, GD_MSG_NO_MEMORY, NULL); + goto out; + } + + pthread_mutex_init(&hooks_priv->mutex, NULL); + pthread_cond_init(&hooks_priv->cond, NULL); + CDS_INIT_LIST_HEAD(&hooks_priv->list); + hooks_priv->waitcount = 0; + + *new = hooks_priv; + ret = 0; out: - return ret; + return ret; } int -glusterd_hooks_spawn_worker (xlator_t *this) +glusterd_hooks_spawn_worker(xlator_t *this) { - int ret = -1; - glusterd_conf_t *conf = NULL; - glusterd_hooks_private_t *hooks_priv = NULL; - - - ret = glusterd_hooks_priv_init (&hooks_priv); - if (ret) - goto out; - - conf = this->private; - conf->hooks_priv = hooks_priv; - ret = pthread_create (&hooks_priv->worker, NULL, hooks_worker, - (void *)this); - if (ret) - gf_log (this->name, GF_LOG_CRITICAL, "Failed to spawn post " - "hooks worker thread"); + int ret = -1; + glusterd_conf_t *conf = NULL; + glusterd_hooks_private_t *hooks_priv = NULL; + + ret = glusterd_hooks_priv_init(&hooks_priv); + if (ret) + goto out; + + conf = this->private; + conf->hooks_priv = hooks_priv; + ret = gf_thread_create(&hooks_priv->worker, NULL, hooks_worker, + (void *)this, "gdhooks"); + if (ret) + gf_msg(this->name, GF_LOG_CRITICAL, errno, GD_MSG_SPAWN_THREADS_FAIL, + "Failed to spawn post " + "hooks worker thread"); out: - return ret; + return ret; } |
