diff options
| author | Avra Sengupta <asengupt@redhat.com> | 2013-03-13 10:21:57 +0100 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2013-07-15 01:23:53 -0700 | 
| commit | 2af3e8bd6dd0fba429681b6329283afe8c34c70b (patch) | |
| tree | f14c174d3a0d9a2fa47b0865d533f78ce1d3c247 | |
| parent | 51ed78005c676addef0d0a70ca47c794a6396075 (diff) | |
libxlator: implement pluggable aggregation policies
The API is described in libxlator.h.
Behavior remains the same for this commit; this
is a preparatory step for per-translator customization
of aggregation.
Change-Id: I5d42923af59b2fd78e1ff59c12763875b57c5190
BUG: 847839
Original Author: Csaba Henk <csaba@redhat.com>
Signed-off-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-on: http://review.gluster.org/4903
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amarts@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 2 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 4 | ||||
| -rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 4 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.c | 112 | ||||
| -rw-r--r-- | xlators/lib/src/libxlator.h | 83 | 
5 files changed, 158 insertions, 47 deletions
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 1fc8f613e6c..c52cfbfa39a 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -1510,6 +1510,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                                             sub_volumes,                                             priv->child_count,                                             MARKER_UUID_TYPE, +                                           marker_uuid_default_gauge,                                             priv->vol_uuid)) {                          gf_log (this->name, GF_LOG_INFO, @@ -1562,6 +1563,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,                                                     sub_volumes,                                                     priv->child_count,                                                     MARKER_XTIME_TYPE, +                                                   marker_xtime_default_gauge,                                                     priv->vol_uuid)) {                                  gf_log (this->name, GF_LOG_INFO,                                          "%s: failed to get marker attr (%s)", diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index d622e60360c..ab64f6d2364 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2255,7 +2255,8 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,                  if (cluster_getmarkerattr (frame, this, loc, key,                                             local, dht_getxattr_unwind,                                             sub_volumes, cnt, -                                           MARKER_UUID_TYPE, conf->vol_uuid)) { +                                           MARKER_UUID_TYPE, marker_uuid_default_gauge, +                                           conf->vol_uuid)) {                          op_errno = EINVAL;                          goto err;                  } @@ -2279,6 +2280,7 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,                                                     local, dht_getxattr_unwind,                                                     sub_volumes, cnt,                                                     MARKER_XTIME_TYPE, +                                                   marker_xtime_default_gauge,                                                     conf->vol_uuid)) {                                  op_errno = EINVAL;                                  goto err; diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index c1294bdd421..056dea2eb59 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -5302,7 +5302,8 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,                  if (cluster_getmarkerattr (frame, this, loc, name,                                             local, stripe_getxattr_unwind,                                             sub_volumes, priv->child_count, -                                           MARKER_UUID_TYPE, priv->vol_uuid)) { +                                           MARKER_UUID_TYPE, marker_uuid_default_gauge, +                                           priv->vol_uuid)) {                          op_errno = EINVAL;                          goto err;                  } @@ -5381,6 +5382,7 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,                                                     sub_volumes,                                                     local->marker.call_count,                                                     MARKER_XTIME_TYPE, +                                                   marker_xtime_default_gauge,                                                     priv->vol_uuid)) {                                  op_errno = EINVAL;                                  goto err; diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c index 8ae3ff3148a..9e535725544 100644 --- a/xlators/lib/src/libxlator.c +++ b/xlators/lib/src/libxlator.c @@ -11,6 +11,34 @@  #include "libxlator.h" +int marker_xtime_default_gauge[] = { +        [MCNT_FOUND]    =  1, +        [MCNT_NOTFOUND] = -1, +        [MCNT_ENODATA]  = -1, +        [MCNT_ENOTCONN] = -1, +        [MCNT_ENOENT]   = -1, +        [MCNT_EOTHER]   = -1, +}; + +int marker_uuid_default_gauge[] = { +        [MCNT_FOUND]    =  1, +        [MCNT_NOTFOUND] =  0, +        [MCNT_ENODATA]  =  0, +        [MCNT_ENOTCONN] =  0, +        [MCNT_ENOENT]   =  0, +        [MCNT_EOTHER]   =  0, +}; + +static int marker_idx_errno_map[] = { +        [MCNT_FOUND]    = EINVAL, +        [MCNT_NOTFOUND] = EINVAL, +        [MCNT_ENOENT]   = ENOENT, +        [MCNT_ENOTCONN] = ENOTCONN, +        [MCNT_ENODATA]  = ENODATA, +        [MCNT_EOTHER]   = EINVAL, +        [MCNT_MAX]      = 0, +}; +  /*Copy the contents of oldtimebuf to newtimbuf*/  static void  update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf) @@ -47,22 +75,61 @@ match_uuid_local (const char *name, char *uuid)  static void  marker_local_incr_errcount (xl_marker_local_t *local, int op_errno)  { +        marker_result_idx_t i = -1; +          if (!local)                  return;          switch (op_errno) {                  case ENODATA: -                        local->enodata_count++; +                        i = MCNT_ENODATA;                          break;                  case ENOENT: -                        local->enoent_count++; +                        i = MCNT_ENOENT;                          break;                  case ENOTCONN: -                        local->enotconn_count++; +                        i = MCNT_ENOTCONN;                          break;                  default: +                        i = MCNT_EOTHER; +                        break; +        } + +        local->count[i]++; +} + +static int +evaluate_marker_results (int *gauge, int *count) +{ +        int i = 0; +        int op_errno = 0; +        gf_boolean_t sane = _gf_true; + +        /* check if the policy of the gauge is violated; +         * if yes, try to get the best errno, ie. look +         * for the first position where there is a more +         * specific kind of vioilation than the generic EINVAL +         */ +        for (i = 0; i < MCNT_MAX; i++) { +                if (sane) { +                        if ((gauge[i] > 0 && count[i] < gauge[i]) || +                            (gauge[i] < 0 && count[i] >= -gauge[i])) { +                                sane = _gf_false; +                                /* generic action: adopt corresponding errno */ +                                op_errno = marker_idx_errno_map[i]; +                        } +                } else { +                        /* already insane; trying to get a more informative +                         * errno by checking subsequent counters +                         */ +                        if (count[i] > 0) +                                op_errno = marker_idx_errno_map[i]; +                } +                if (op_errno && op_errno != EINVAL)                          break;          } + +        return op_errno;  }  /* Aggregate all the <volid>.xtime attrs of the cluster and send the max*/ @@ -98,14 +165,10 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          {                  callcnt = --local->call_count; -                if (local->esomerr) -                        goto unlock; -                  vol_uuid = local->vol_uuid;                  if (op_ret) {                          marker_local_incr_errcount (local, op_errno); -                        local->esomerr = op_errno;                          goto unlock;                  } @@ -119,11 +182,11 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  if (dict_get_ptr (dict, marker_xattr, (void **)&net_timebuf)) {                          gf_log (this->name, GF_LOG_WARNING,                                  "Unable to get <uuid>.xtime attr"); -                        local->noxtime_count++; +                        local->count[MCNT_NOTFOUND]++;                          goto unlock;                  } -                if (local->has_xtime) { +                if (local->count[MCNT_FOUND]) {                          get_hosttime (net_timebuf, host_timebuf);                          if ( (host_timebuf[0]>local->host_timebuf[0]) ||                                  (host_timebuf[0] == local->host_timebuf[0] && @@ -135,7 +198,7 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  } else {                          get_hosttime (net_timebuf, local->host_timebuf);                          update_timebuf (net_timebuf, local->net_timebuf); -                        local->has_xtime = _gf_true; +                        local->count[MCNT_FOUND]++;                  }          } @@ -147,7 +210,7 @@ unlock:                  op_errno = 0;                  need_unwind = 1; -                if (local->has_xtime) { +                if (local->count[MCNT_FOUND]) {                          if (!dict)                                  dict = dict_new(); @@ -160,17 +223,9 @@ unlock:                          }                  } -                if (local->noxtime_count) -                        goto out; - -                if (local->enodata_count || local->enotconn_count || -                                              local->enoent_count) { +                op_errno = evaluate_marker_results (local->gauge, local->count); +                if (op_errno)                          op_ret = -1; -                        op_errno = local->enodata_count? ENODATA: -                                        local->enotconn_count? ENOTCONN: -                                        local->enoent_count? ENOENT: -                                        local->esomerr; -                }          }  out: @@ -228,7 +283,7 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  if (ret)                          goto unlock; -                if (marker_has_volinfo (local)) { +                if (local->count[MCNT_FOUND]) {                          if ((local->volmark->major != volmark->major) ||                              (local->volmark->minor != volmark->minor)) {                                  op_ret = -1; @@ -257,6 +312,7 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          uuid_unparse (volmark->uuid, vol_uuid);                          if (volmark->retval)                                  local->retval = volmark->retval; +                        local->count[MCNT_FOUND]++;                  }          }  unlock: @@ -267,7 +323,7 @@ unlock:                  op_errno = 0;                  need_unwind = 1; -                if (marker_has_volinfo (local)) { +                if (local->count[MCNT_FOUND]) {                          if (!dict)                                  dict = dict_new(); @@ -277,11 +333,10 @@ unlock:                                  op_ret = -1;                                  op_errno = ENOMEM;                          } -                } else { -                        op_ret = -1; -                        op_errno = local->enotconn_count? ENOTCONN: -                               local->enoent_count? ENOENT:EINVAL;                  } +                op_errno = evaluate_marker_results (local->gauge, local->count); +                if (op_errno) +                        op_ret = -1;          }   out: @@ -303,7 +358,7 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,                         const char *name, void *xl_local,                         xlator_specf_unwind_t xl_specf_getxattr_unwind,                         xlator_t **sub_volumes, int count, int type, -                       char *vol_uuid) +                       int *gauge, char *vol_uuid)  {          int                i     = 0;          xl_marker_local_t  *local = NULL; @@ -326,6 +381,7 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,          local->call_count = count;          local->xl_specf_unwind = xl_specf_getxattr_unwind;          local->vol_uuid = vol_uuid; +        memcpy (local->gauge, gauge, sizeof (local->gauge));          frame->local = local; diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h index c89629e9d9b..1d5e1657f4e 100644 --- a/xlators/lib/src/libxlator.h +++ b/xlators/lib/src/libxlator.h @@ -48,6 +48,69 @@ struct volume_mark {          uint32_t usec;  }__attribute__ ((__packed__)); + +/* + * The enumerated type here + * is used to index two kind + * of integer arrays: + * - gauges + * - counters + + * A counter is used internally, + * in getxattr callbacks, to count + * the results, categorized as + * the enum names suggest. So values + * in the counter are always non-negative. + + * Gauges are part of the API. + * The caller passes one to the + * top-level aggregator function, + * cluster_getmarkerattr(). The gauge + * defines an evaluation policy for the + * counter. That is, at the + * end of the aggregation process + * the gauge is matched against the + * counter, and the policy + * represented by the gauge decides + * whether to return with success or failure, + * and in latter case, what particular failure + * case (errno). + + * The rules are the following: for some index i, + * - if gauge[i] == 0, no requirement is set + *   against counter[i]; + * - if gauge[i] > 0, counter[i] >= gauge[i] + *   is required; + * - if gauge[i] < 0, counter[i] < |gauge[i]| + *   is required. + + * If the requirement is not met, then i is mapped + * to the respective errno (MCNT_ENOENT -> ENOENT), + * or in lack of that, EINVAL. + + * Cf. evaluate_marker_results() and marker_idx_errno_map[] + * in libxlator.c + + * We provide two default gauges, one inteded for xtime + * aggregation, other for volume mark aggregation. The + * policies they represent agree with the hard-coded + * one prior to gauges. Cf. marker_xtime_default_gauge + * and marker_uuid_default_gauge in libxlator.c + */ + +typedef enum { +        MCNT_FOUND, +        MCNT_NOTFOUND, +        MCNT_ENODATA, +        MCNT_ENOTCONN, +        MCNT_ENOENT, +        MCNT_EOTHER, +        MCNT_MAX +} marker_result_idx_t; + +extern int marker_xtime_default_gauge[]; +extern int marker_uuid_default_gauge[]; +  struct marker_str {          struct volume_mark    *volmark;          data_t                *data; @@ -55,13 +118,8 @@ struct marker_str {          uint32_t               host_timebuf[2];          uint32_t               net_timebuf[2];          int32_t                call_count; -        unsigned               has_xtime:1; -        int32_t                enoent_count; -        int32_t                enotconn_count; -        int32_t                enodata_count; -        int32_t                noxtime_count; - -        int                    esomerr; +        int                    gauge[MCNT_MAX]; +        int                    count[MCNT_MAX];          xlator_specf_unwind_t  xl_specf_unwind;          void                  *xl_local; @@ -71,15 +129,6 @@ struct marker_str {  typedef struct marker_str xl_marker_local_t; -static inline gf_boolean_t -marker_has_volinfo (xl_marker_local_t *marker) -{ -       if (marker->volmark) -                return _gf_true; -       else -                return _gf_false; -} -  int32_t  cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                           int op_ret, int op_errno, dict_t *dict, dict_t *xdata); @@ -93,7 +142,7 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,                         const char *name, void *xl_local,                         xlator_specf_unwind_t xl_specf_getxattr_unwind,                         xlator_t **sub_volumes, int count, int type, -                       char *vol_uuid); +                       int *gauge, char *vol_uuid);  int  match_uuid_local (const char *name, char *uuid);  | 
