diff options
| -rw-r--r-- | api/src/glfs-handleops.c | 12 | ||||
| -rw-r--r-- | api/src/glfs-handles.h | 1 | ||||
| -rw-r--r-- | api/src/glfs-internal.h | 1 | ||||
| -rw-r--r-- | api/src/glfs.c | 59 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/upcall-utils.h | 15 | ||||
| -rw-r--r-- | xlators/features/upcall/src/upcall.c | 49 | 
7 files changed, 135 insertions, 3 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index c010f0c9a0f..f458cb4bd58 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -1881,6 +1881,18 @@ pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)          __GLFS_ENTRY_VALIDATE_FS (fs, err); +        /* check if upcalls are enabled */ +        if (!fs->upcall_features) { +                errno = ENOTSUP; +                goto restore; +        } + +        /* check if GF_UPCALL_CACHE_INVALIDATION is supported */ +        if (!(fs->upcall_features & (1 << GF_UPCALL_CACHE_INVALIDATION))) { +                errno = ENOTSUP; +                goto restore; +        } +          /* get the active volume */          subvol = glfs_active_subvol (fs); diff --git a/api/src/glfs-handles.h b/api/src/glfs-handles.h index 19c4e8f7a62..ddb11bf0bd5 100644 --- a/api/src/glfs-handles.h +++ b/api/src/glfs-handles.h @@ -293,6 +293,7 @@ glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask) __THROW    0   : Success.    -1  : Error condition, mostly due to out of memory. +        'errno' is set to ENOTSUP if upcall feature is not enabled.  */ diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 71c83755ec3..5eb57d4b8e4 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -199,6 +199,7 @@ struct glfs {  	gf_boolean_t        migration_in_progress; +        uint32_t            upcall_features; /* supported upcall events */          struct list_head    upcall_list;          pthread_mutex_t     upcall_list_mutex; /* mutex for upcall entry list */ diff --git a/api/src/glfs.c b/api/src/glfs.c index fc392947e1e..7b9f1ed6d01 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -253,6 +253,58 @@ get_volfp (struct glfs *fs)  } +static int +detect_upcall_features (struct glfs *fs) +{ +        xlator_t        *subvol   = NULL; +        int              ret      = -1; +        dict_t          *dict     = NULL; +        uint32_t         features = 0; + +        DECLARE_OLD_THIS; +        __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs); + +        subvol = glfs_active_subvol (fs); +        if (!subvol) { +                ret = -1; +                errno = EIO; +                goto out; +        } + +        ret = syncop_ipc (subvol, GF_IPC_UPCALL_FEATURES, NULL, &dict); +        DECODE_SYNCOP_ERR (ret); + +        if (ret) +                /* some real error occured */ +                goto out; + +        if (!dict) { +                /* unavailable upcalls should not be an error */ +                ret = 0; +                goto out; +        } + +        ret = dict_get_uint32 (dict, GF_UPCALL_FEATURES, &features); +        if (ret) { +                /* unavailable upcalls should not be an error */ +                ret = 0; +                goto out; +        } + +        fs->upcall_features = features; + +out: +        if (dict) +                dict_unref (dict); + +        glfs_subvol_done (fs, subvol); +        __GLFS_EXIT_FS; + +invalid_fs: +        return ret; +} + +  int  glfs_volumes_init (struct glfs *fs)  { @@ -267,7 +319,7 @@ glfs_volumes_init (struct glfs *fs)  	if (cmd_args->volfile_server) {  		ret = glfs_mgmt_init (fs); -		goto out; +		goto finish;  	}  	fp = get_volfp (fs); @@ -284,6 +336,11 @@ glfs_volumes_init (struct glfs *fs)  	if (ret)  		goto out; +finish: +        ret = detect_upcall_features (fs); +        if (ret) +                goto out; +  out:  	return ret;  } diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 86ea42ee849..9b07e8c7565 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -125,6 +125,7 @@ enum _gf_client_pid  enum _gf_xlator_ipc_targets {          GF_IPC_TARGET_CHANGELOG = 0, +        GF_IPC_UPCALL_FEATURES = 1,  };  typedef enum _gf_boolean gf_boolean_t; diff --git a/libglusterfs/src/upcall-utils.h b/libglusterfs/src/upcall-utils.h index 001566fd85e..5f6970fe7e1 100644 --- a/libglusterfs/src/upcall-utils.h +++ b/libglusterfs/src/upcall-utils.h @@ -15,9 +15,20 @@  #include "compat-uuid.h"  #include "compat.h" +/* Used by GF_IPC_UPCALL_FEATURES in the ipc() FOP. + * + * Each feature is a bit in the uint32_t, this likely will match all the events + * from the gf_upcall_event_t enum. + * + * When the bit for GF_UPCALL_EVENT_NULL is not set, upcall is loaded, but + * disabled. + */ +#define GF_UPCALL_FEATURES "gluster.upcall.features" +  typedef enum { -        GF_UPCALL_EVENT_NULL, -        GF_UPCALL_CACHE_INVALIDATION, +        GF_UPCALL_EVENT_NULL = 0, +        GF_UPCALL_CACHE_INVALIDATION = 1, +        /* add new events to the feature mask in up_ipc() */  } gf_upcall_event_t;  struct gf_upcall { diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c index 4954d43db07..bb29866543b 100644 --- a/xlators/features/upcall/src/upcall.c +++ b/xlators/features/upcall/src/upcall.c @@ -1552,6 +1552,52 @@ err:  }  int32_t +up_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ +        int        ret        = 0; +        uint32_t   features   = 0; + +        /* upcall only has one IPC operation */ +        if (op != GF_IPC_UPCALL_FEATURES) +                goto wind; + +        if (!xdata) { +                xdata = dict_new(); +                if (!xdata) { +                        ret = -1; +                        goto unwind; +                } +        } else { +                /* take an extra reference so that we can unconditionally unref +                 * it later */ +                dict_ref (xdata); +        } + +        /* build the feature bitmask */ +        if (is_upcall_enabled(this)) +                features |= (1 << GF_UPCALL_EVENT_NULL); + +        /* check if 'GF_UPCALL_CACHE_INVALIDATION' is available */ +        if (is_cache_invalidation_enabled(this)) +                features |= (1 << GF_UPCALL_CACHE_INVALIDATION); + +        ret = dict_set_uint32 (xdata, GF_UPCALL_FEATURES, features); + +unwind: +        UPCALL_STACK_UNWIND (ipc, frame, ret, errno, xdata); + +        dict_unref (xdata); + +        return 0; + +wind: +        STACK_WIND (frame, default_ipc_cbk, FIRST_CHILD(this), +                    FIRST_CHILD(this)->fops->ipc, op, xdata); + +        return 0; +} + +int32_t  mem_acct_init (xlator_t *this)  {          int     ret = -1; @@ -1813,6 +1859,9 @@ struct xlator_fops fops = {          .rmdir       = up_rmdir,          .rename      = up_rename, +        /* xlator internal communication */ +        .ipc         = up_ipc, +  #ifdef NOT_SUPPORTED          /* internal lk fops */          .inodelk     = up_inodelk,  | 
