summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/xlator.c32
-rw-r--r--libglusterfs/src/xlator.h5
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 ...) \