summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorRyo Furuhashi <76208814+bonfffire@users.noreply.github.com>2021-02-05 12:56:03 +0900
committerGitHub <noreply@github.com>2021-02-05 09:26:03 +0530
commitea86b664f3b1f54901ce1b7d7fba7d80456f2089 (patch)
tree919548836635cf8862afc5182091aab8489bd24c /xlators
parent73ad20e5863a63625cd4e0a94b4393d98dc7393f (diff)
downloadglusterfs-ea86b664f3b1f54901ce1b7d7fba7d80456f2089.tar.gz
glusterfs-ea86b664f3b1f54901ce1b7d7fba7d80456f2089.tar.xz
glusterfs-ea86b664f3b1f54901ce1b7d7fba7d80456f2089.zip
glusterd-volgen: Add functionality to accept any custom xlator (#1974)
* glusterd-volgen: Add functionality to accept any custom xlator Add new function which allow users to insert any custom xlators. It makes to provide a way to add any processing into file operations. Users can deploy the plugin(xlator shared object) and integrate it to glusterfsd. If users want to enable a custom xlator, do the follows: 1. put xlator object(.so file) into "XLATOR_DIR/user/" 2. set the option user.xlator.<xlator> to the existing xlator-name to specify of the position in graph 3. restart gluster volume Options for custom xlator are able to set in "user.xlator.<xlator>.<optkey>". Fixes: #1943 Signed-off-by:Ryo Furuhashi <ryo.furuhashi.nh@hitachi.com> Co-authored-by: Yaniv Kaul <ykaul@redhat.com> Co-authored-by: Xavi Hernandez <xhernandez@users.noreply.github.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 347559f96d..06e5e1f332 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -46,6 +46,11 @@ struct gd_validate_reconf_opts {
extern struct volopt_map_entry glusterd_volopt_map[];
+struct check_and_add_user_xlator_t {
+ volgen_graph_t *graph;
+ char *volname;
+};
+
#define RPC_SET_OPT(XL, CLI_OPT, XLATOR_OPT, ERROR_CMD) \
do { \
char *_value = NULL; \
@@ -2706,6 +2711,145 @@ out:
return ret;
}
+static gf_boolean_t
+check_user_xlator_position(dict_t *dict, char *key, data_t *value,
+ void *prev_xlname)
+{
+ if (strncmp(key, "user.xlator.", SLEN("user.xlator.")) != 0) {
+ return false;
+ }
+
+ if (fnmatch("user.xlator.*.*", key, 0) == 0) {
+ return false;
+ }
+
+ char *value_str = data_to_str(value);
+ if (!value_str) {
+ return false;
+ }
+
+ if (strcmp(value_str, prev_xlname) == 0) {
+ gf_log("glusterd", GF_LOG_INFO,
+ "found insert position of user-xlator(%s)", key);
+ return true;
+ }
+
+ return false;
+}
+
+static int
+set_user_xlator_option(dict_t *set_dict, char *key, data_t *value, void *data)
+{
+ xlator_t *xl = data;
+ char *optname = strrchr(key, '.') + 1;
+
+ gf_log("glusterd", GF_LOG_DEBUG, "set user xlator option %s = %s", key,
+ value->data);
+
+ return xlator_set_option(xl, optname, strlen(optname), data_to_str(value));
+}
+
+static int
+insert_user_xlator_to_graph(dict_t *set_dict, char *key, data_t *value,
+ void *action_data)
+{
+ int ret = -1;
+
+ struct check_and_add_user_xlator_t *data = action_data;
+
+ char *xlator_name = strrchr(key, '.') + 1; // user.xlator.<xlator_name>
+ char *xlator_option_matcher = NULL;
+ char *type = NULL;
+ xlator_t *xl = NULL;
+
+ // convert optkey to xlator type
+ if (gf_asprintf(&type, "user/%s", xlator_name) < 0) {
+ gf_log("glusterd", GF_LOG_ERROR, "failed to generate user-xlator type");
+ goto out;
+ }
+
+ gf_log("glusterd", GF_LOG_INFO, "add user xlator=%s to graph", type);
+
+ xl = volgen_graph_add(data->graph, type, data->volname);
+ if (!xl) {
+ goto out;
+ }
+
+ ret = gf_asprintf(&xlator_option_matcher, "user.xlator.%s.*", xlator_name);
+ if (ret < 0) {
+ gf_log("glusterd", GF_LOG_ERROR,
+ "failed to generate user-xlator option matcher");
+ goto out;
+ }
+
+ dict_foreach_fnmatch(set_dict, xlator_option_matcher,
+ set_user_xlator_option, xl);
+
+out:
+ if (type)
+ GF_FREE(type);
+ if (xlator_option_matcher)
+ GF_FREE(xlator_option_matcher);
+
+ return ret;
+}
+
+static int
+validate_user_xlator_position(dict_t *this, char *key, data_t *value,
+ void *unused)
+{
+ int ret = -1;
+ int i = 0;
+
+ if (!value)
+ goto out;
+
+ if (fnmatch("user.xlator.*.*", key, 0) == 0) {
+ ret = 0;
+ goto out;
+ }
+
+ char *value_str = data_to_str(value);
+ if (!value_str)
+ goto out;
+
+ int num_xlators = sizeof(server_graph_table) /
+ sizeof(server_graph_table[0]);
+ for (i = 0; i < num_xlators; i++) {
+ if (server_graph_table[i].dbg_key &&
+ strcmp(value_str, server_graph_table[i].dbg_key) == 0) {
+ ret = 0;
+ goto out;
+ }
+ }
+
+out:
+ if (ret == -1)
+ gf_log("glusterd", GF_LOG_ERROR, "invalid user xlator position %s = %s",
+ key, value->data);
+
+ return ret;
+}
+
+static int
+check_and_add_user_xl(volgen_graph_t *graph, dict_t *set_dict, char *volname,
+ char *prev_xlname)
+{
+ if (!prev_xlname)
+ goto out;
+
+ struct check_and_add_user_xlator_t data = {.graph = graph,
+ .volname = volname};
+
+ if (dict_foreach_match(set_dict, check_user_xlator_position, prev_xlname,
+ insert_user_xlator_to_graph, &data) < 0) {
+ return -1;
+ }
+
+out:
+ return 0;
+}
+
static int
server_graph_builder(volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
dict_t *set_dict, void *param)
@@ -2715,6 +2859,12 @@ server_graph_builder(volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
char *loglevel = NULL;
int i = 0;
+ if (dict_foreach_fnmatch(set_dict, "user.xlator.*",
+ validate_user_xlator_position, NULL) < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+
i = sizeof(server_graph_table) / sizeof(server_graph_table[0]) - 1;
while (i >= 0) {
@@ -2732,6 +2882,11 @@ server_graph_builder(volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (ret)
goto out;
+ ret = check_and_add_user_xl(graph, set_dict, volinfo->volname,
+ server_graph_table[i].dbg_key);
+ if (ret)
+ goto out;
+
i--;
}