diff options
-rw-r--r-- | libglusterfs/src/xlator.c | 32 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 5 |
2 files changed, 27 insertions, 10 deletions
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 9bde4fa8f6c..da5501b2cfa 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -183,7 +183,7 @@ xlator_dynload (xlator_t *xl) 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); @@ -218,16 +218,28 @@ xlator_dynload (xlator_t *xl) goto out; } - if (!(*VOID(&xl->init) = dlsym (handle, "init"))) { - gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s", - dlerror ()); - goto out; - } + /* + * If class_methods exists, its contents override any definitions of + * init or fini for that translator. Otherwise, we fall back to the + * older method of looking for init and fini directly. + */ + vtbl = dlsym(handle,"class_methods"); + if (vtbl) { + xl->init = vtbl->init; + xl->fini = vtbl->fini; + } + else { + if (!(*VOID(&xl->init) = dlsym (handle, "init"))) { + gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s", + dlerror ()); + goto out; + } - if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) { - gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s", - dlerror ()); - goto out; + if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) { + gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s", + dlerror ()); + goto out; + } } if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) { diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 607f0dcecee..2567fc70c48 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -827,6 +827,11 @@ struct _xlator { gf_boolean_t is_autoloaded; }; +typedef struct { + int32_t (*init) (xlator_t *this); + void (*fini) (xlator_t *this); +} class_methods_t; + #define xlator_has_parent(xl) (xl->parents != NULL) #define XLATOR_NOTIFY(_xl, params ...) \ |