diff options
author | Amar Tumballi <amarts@redhat.com> | 2017-11-28 14:44:46 +0530 |
---|---|---|
committer | Kaushal M <kaushal@redhat.com> | 2017-11-30 09:16:13 +0000 |
commit | 5b4b25c697f93d3dfe352013a442f2ec73fd3b8b (patch) | |
tree | f9bf3452741e702cf5774924fc70eb82d7831d2e /libglusterfs/src/xlator.c | |
parent | 3460b8cfc550f272bdae588e8929b75b105ab06b (diff) |
xlator: provide a xlator_api_t structure to include all exported options
each translator from now on can have just 1 symbol exported called
'xlator_api', which has all the required fields in it.
Updates: #164
Change-Id: I48d54f5ec59fee842b1d55877e3ac5e9ec9b6bdd
Signed-off-by: Amar Tumballi <amarts@redhat.com>
Diffstat (limited to 'libglusterfs/src/xlator.c')
-rw-r--r-- | libglusterfs/src/xlator.c | 220 |
1 files changed, 183 insertions, 37 deletions
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index e371038f2c7..ed1d95d01e1 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -40,6 +40,10 @@ xlator_init_unlock (void) (void) pthread_mutex_unlock (&xlator_init_mutex); } +static struct xlator_cbks default_cbks = { }; +struct volume_options default_options[] = { + { .key = {NULL} }, +}; static void fill_defaults (xlator_t *xl) @@ -102,10 +106,16 @@ fill_defaults (xlator_t *xl) SET_DEFAULT_FOP (getspec); + if (!xl->cbks) + xl->cbks = &default_cbks; + SET_DEFAULT_CBK (release); SET_DEFAULT_CBK (releasedir); SET_DEFAULT_CBK (forget); + if (!xl->fini) + xl->fini = default_fini; + if (!xl->notify) xl->notify = default_notify; @@ -136,9 +146,10 @@ int xlator_volopt_dynload (char *xlator_type, void **dl_handle, volume_opt_list_t *opt_list) { - int ret = -1; - char *name = NULL; - void *handle = NULL; + int ret = -1; + char *name = NULL; + void *handle = NULL; + xlator_api_t *xlapi = NULL; GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out); @@ -163,11 +174,28 @@ xlator_volopt_dynload (char *xlator_type, void **dl_handle, goto out; } - if (!(opt_list->given_opt = dlsym (handle, "options"))) { - dlerror (); - gf_msg ("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, - "Failed to load xlator opt table"); - goto out; + /* check new struct first, and then check this */ + xlapi = dlsym (handle, "xlator_api"); + if (!xlapi) { + gf_msg ("xlator", GF_LOG_DEBUG, 0, LG_MSG_DLSYM_ERROR, + "dlsym(xlator_api) on %s. " + "Fall back to old symbols", dlerror ()); + /* This case is not an error for now, so allow it + to fall back to old methods. */ + opt_list->given_opt = dlsym (handle, "options"); + if (!opt_list->given_opt) { + dlerror (); + gf_msg ("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, + "Failed to load xlator opt table"); + goto out; + } + } else { + opt_list->given_opt = xlapi->options; + if (!opt_list->given_opt) { + gf_msg ("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, + "Failed to load xlator options table"); + goto out; + } } *dl_handle = handle; @@ -184,44 +212,24 @@ xlator_volopt_dynload (char *xlator_type, void **dl_handle, } - -int -xlator_dynload (xlator_t *xl) +int xlator_dynload_oldway (xlator_t *xl) { int ret = -1; - char *name = NULL; void *handle = NULL; volume_opt_list_t *vol_opt = NULL; class_methods_t *vtbl = NULL; - GF_VALIDATE_OR_GOTO ("xlator", xl, out); - - INIT_LIST_HEAD (&xl->volume_options); - - ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type); - if (-1 == ret) { - goto out; - } - - ret = -1; - - gf_msg_trace ("xlator", 0, "attempt to load file %s", name); - - handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); - if (!handle) { - gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, - "%s", dlerror ()); - goto out; - } - xl->dlhandle = handle; + handle = xl->dlhandle; - if (!(xl->fops = dlsym (handle, "fops"))) { + xl->fops = dlsym (handle, "fops"); + if (!xl->fops) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "dlsym(fops) on %s", dlerror ()); goto out; } - if (!(xl->cbks = dlsym (handle, "cbks"))) { + xl->cbks = dlsym (handle, "cbks"); + if (!xl->cbks) { gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, "dlsym(cbks) on %s", dlerror ()); goto out; @@ -276,20 +284,158 @@ xlator_dynload (xlator_t *xl) } vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), - gf_common_mt_volume_opt_list_t); + gf_common_mt_volume_opt_list_t); if (!vol_opt) { goto out; } if (!(vol_opt->given_opt = dlsym (handle, "options"))) { - dlerror (); gf_msg_trace (xl->name, 0, "Strict option validation not " - "enforced -- neglecting"); + "enforced -- neglecting (%s)", dlerror ()); + } + INIT_LIST_HEAD (&vol_opt->list); + list_add_tail (&vol_opt->list, &xl->volume_options); + + ret = 0; + +out: + return ret; +} + +int xlator_dynload_newway (xlator_t *xl) +{ + int ret = -1; + void *handle = NULL; + volume_opt_list_t *vol_opt = NULL; + xlator_api_t *xlapi = NULL; + + handle = xl->dlhandle; + + xlapi = dlsym (handle, "xlator_api"); + if (!xlapi) { + gf_msg ("xlator", GF_LOG_INFO, 0, LG_MSG_DLSYM_ERROR, + "dlsym(xlator_api) on %s. " + "Fall back to old symbols", dlerror ()); + /* This case is not an error for now, so allow it + to fall back to old methods. */ + ret = 1; + goto out; + } + + xl->fops = xlapi->fops; + if (!xl->fops) { + gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, + "%s: struct missing (fops)", xl->name); + goto out; + } + + xl->cbks = xlapi->cbks; + if (!xl->cbks) { + gf_msg_trace ("xlator", 0, "%s: struct missing (cbks)", + xl->name); + } + + xl->init = xlapi->init; + if (!xl->init) { + gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, + "%s: method missing (init)", xl->name); + goto out; + } + + xl->fini = xlapi->fini; + if (!xl->fini) { + gf_msg_trace ("xlator", 0, "%s: method missing (fini)", + xl->name); + } + + xl->reconfigure = xlapi->reconfigure; + if (!xl->reconfigure) { + gf_msg_trace ("xlator", 0, "%s: method missing (reconfigure)", + xl->name); + } + xl->notify = xlapi->notify; + if (!xl->notify) { + gf_msg_trace ("xlator", 0, "%s: method missing (notify)", + xl->name); + } + xl->dumpops = xlapi->dumpops; + if (!xl->dumpops) { + gf_msg_trace ("xlator", 0, "%s: method missing (dumpops)", + xl->name); + } + xl->mem_acct_init = xlapi->mem_acct_init; + if (!xl->mem_acct_init) { + gf_msg_trace ("xlator", 0, "%s: method missing (mem_acct_init)", + xl->name); + } + + vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), + gf_common_mt_volume_opt_list_t); + if (!vol_opt) { + goto out; } + + vol_opt->given_opt = xlapi->options; + if (!vol_opt->given_opt) { + gf_msg ("xlator", GF_LOG_INFO, 0, LG_MSG_DLSYM_ERROR, + "%s: options not provided, using default", xl->name); + vol_opt->given_opt = default_options; + } + INIT_LIST_HEAD (&vol_opt->list); list_add_tail (&vol_opt->list, &xl->volume_options); + xl->id = xlapi->xlator_id; + xl->flags = xlapi->flags; + xl->identifier = xlapi->identifier; + memcpy (xl->op_version, xlapi->op_version, + sizeof (uint32_t) * GF_MAX_RELEASES); + + ret = 0; +out: + return ret; +} + + +int +xlator_dynload (xlator_t *xl) +{ + int ret = -1; + char *name = NULL; + void *handle = NULL; + + GF_VALIDATE_OR_GOTO ("xlator", xl, out); + + INIT_LIST_HEAD (&xl->volume_options); + + ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type); + if (-1 == ret) { + goto out; + } + + ret = -1; + + gf_msg_trace ("xlator", 0, "attempt to load file %s", name); + + handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); + if (!handle) { + gf_msg ("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, + "%s", dlerror ()); + goto out; + } + xl->dlhandle = handle; + + ret = xlator_dynload_newway (xl); + if (-1 == ret) + goto out; + if (1 == ret) { + /* it means we don't find the new symbol in xlator code */ + ret = xlator_dynload_oldway (xl); + if (-1 == ret) + goto out; + } + fill_defaults (xl); ret = 0; |