diff options
| -rw-r--r-- | libglusterfs/src/defaults-tmpl.c | 7 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.h | 4 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 220 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 74 | ||||
| -rw-r--r-- | xlators/xlator.sym | 1 | 
5 files changed, 269 insertions, 37 deletions
diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c index 0ef14d5c68e..d311972f0c0 100644 --- a/libglusterfs/src/defaults-tmpl.c +++ b/libglusterfs/src/defaults-tmpl.c @@ -223,3 +223,10 @@ default_mem_acct_init (xlator_t *this)          return ret;  } + +void +default_fini (xlator_t *this) +{ +        if (this && this->private) +                GF_FREE (this->private); +} diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h index 50f1909b90b..9b4f4828e91 100644 --- a/libglusterfs/src/defaults.h +++ b/libglusterfs/src/defaults.h @@ -1297,4 +1297,8 @@ default_setactivelk_failure_cbk (call_frame_t *frame, int32_t op_errno);  int32_t  default_mem_acct_init (xlator_t *this); + +void +default_fini (xlator_t *this); +  #endif /* _DEFAULTS_H */ 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; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 7f9d483ccb3..de353fe702d 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -991,6 +991,18 @@ struct _xlator {          /* Its used as an index to inode_ctx*/          uint32_t            xl_id; + +        /* op_version: initialized in xlator code itself */ +        uint32_t op_version[GF_MAX_RELEASES]; + +        /* flags: initialized in xlator code itself */ +        uint32_t flags; + +        /* id: unique, initialized in xlator code itself */ +        uint32_t id; + +        /* identifier: a full string which can unique identify the xlator */ +        char *identifier;  };  typedef struct { @@ -1001,6 +1013,68 @@ typedef struct {          event_notify_fn_t       notify;  } class_methods_t; +/* This would be the only structure which needs to be exported by +   the translators. For the backward compatibility, in 4.x series +   even the old exported fields will be supported */ +typedef struct { +        /* init(): mandatory method, will be called during the +           graph initialization */ +        int32_t (*init) (xlator_t *this); + +        /* fini(): optional method, will be initialized to default +           method which would just free the 'xlator->private' variable. +           This method is called when the graph is no more in use, and +           is being destroyed. Also when SIGTERM is received */ +        void (*fini) (xlator_t *this); + +        /* reconfigure(): optional method, will be initialized to default +           method in case not provided by xlator. This method is called +           when there are only option changes in xlator, and no graph change. +           eg., a 'gluster volume set' command */ +        int32_t (*reconfigure) (xlator_t *this, dict_t *options); + +        /* mem_acct_init(): used for memory accounting inside of the xlator. +           optional. called during translator initialization */ +	int32_t (*mem_acct_init) (xlator_t *this); + +        /* notify(): used for handling the notification of events from either +           the parent or child in the graph. optional. */ +        event_notify_fn_t notify; + +        /* struct fops: mandatory. provides all the filesystem operations +           methods of the xlator */ +        struct xlator_fops *fops; +        /* struct cbks: optional. provides methods to handle +           inode forgets, and fd releases */ +        struct xlator_cbks *cbks; + +        /* dumpops: a structure again, with methods to dump the details. +           optional. */ +        struct xlator_dumpops  *dumpops; + +        /* struct options: if the translator takes any 'options' from the +           volume file, then that should be defined here. optional. */ +        volume_option_t *options; + +        /* op_version: will be used by volume generation logic to figure +           out whether to insert it in graph or no, based on cluster's +           operating version. +           default value: 0, which means good to insert always */ +        uint32_t op_version[GF_MAX_RELEASES]; + +        /* flags: will be used by volume generation logic to optimize the +           placements etc. +           default value: 0, which means don't treat it specially */ +        uint32_t flags; + +        /* xlator_id: unique per xlator. make sure to have no collission +           in this ID */ +        uint32_t xlator_id; + +        /* identifier: a string constant */ +        char *identifier; +} xlator_api_t; +  #define xlator_has_parent(xl) (xl->parents != NULL)  #define XLATOR_NOTIFY(_xl, params ...)          \ diff --git a/xlators/xlator.sym b/xlators/xlator.sym index f8f1386cf2e..b50eb2848f8 100644 --- a/xlators/xlator.sym +++ b/xlators/xlator.sym @@ -1,3 +1,4 @@ +xlator_api  init  fini  fops  | 
