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>
This commit is contained in:
parent
51ed78005c
commit
2af3e8bd6d
@ -1510,6 +1510,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
sub_volumes,
|
sub_volumes,
|
||||||
priv->child_count,
|
priv->child_count,
|
||||||
MARKER_UUID_TYPE,
|
MARKER_UUID_TYPE,
|
||||||
|
marker_uuid_default_gauge,
|
||||||
priv->vol_uuid)) {
|
priv->vol_uuid)) {
|
||||||
|
|
||||||
gf_log (this->name, GF_LOG_INFO,
|
gf_log (this->name, GF_LOG_INFO,
|
||||||
@ -1562,6 +1563,7 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
sub_volumes,
|
sub_volumes,
|
||||||
priv->child_count,
|
priv->child_count,
|
||||||
MARKER_XTIME_TYPE,
|
MARKER_XTIME_TYPE,
|
||||||
|
marker_xtime_default_gauge,
|
||||||
priv->vol_uuid)) {
|
priv->vol_uuid)) {
|
||||||
gf_log (this->name, GF_LOG_INFO,
|
gf_log (this->name, GF_LOG_INFO,
|
||||||
"%s: failed to get marker attr (%s)",
|
"%s: failed to get marker attr (%s)",
|
||||||
|
@ -2255,7 +2255,8 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
if (cluster_getmarkerattr (frame, this, loc, key,
|
if (cluster_getmarkerattr (frame, this, loc, key,
|
||||||
local, dht_getxattr_unwind,
|
local, dht_getxattr_unwind,
|
||||||
sub_volumes, cnt,
|
sub_volumes, cnt,
|
||||||
MARKER_UUID_TYPE, conf->vol_uuid)) {
|
MARKER_UUID_TYPE, marker_uuid_default_gauge,
|
||||||
|
conf->vol_uuid)) {
|
||||||
op_errno = EINVAL;
|
op_errno = EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -2279,6 +2280,7 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
local, dht_getxattr_unwind,
|
local, dht_getxattr_unwind,
|
||||||
sub_volumes, cnt,
|
sub_volumes, cnt,
|
||||||
MARKER_XTIME_TYPE,
|
MARKER_XTIME_TYPE,
|
||||||
|
marker_xtime_default_gauge,
|
||||||
conf->vol_uuid)) {
|
conf->vol_uuid)) {
|
||||||
op_errno = EINVAL;
|
op_errno = EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -5302,7 +5302,8 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
if (cluster_getmarkerattr (frame, this, loc, name,
|
if (cluster_getmarkerattr (frame, this, loc, name,
|
||||||
local, stripe_getxattr_unwind,
|
local, stripe_getxattr_unwind,
|
||||||
sub_volumes, priv->child_count,
|
sub_volumes, priv->child_count,
|
||||||
MARKER_UUID_TYPE, priv->vol_uuid)) {
|
MARKER_UUID_TYPE, marker_uuid_default_gauge,
|
||||||
|
priv->vol_uuid)) {
|
||||||
op_errno = EINVAL;
|
op_errno = EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -5381,6 +5382,7 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
|
|||||||
sub_volumes,
|
sub_volumes,
|
||||||
local->marker.call_count,
|
local->marker.call_count,
|
||||||
MARKER_XTIME_TYPE,
|
MARKER_XTIME_TYPE,
|
||||||
|
marker_xtime_default_gauge,
|
||||||
priv->vol_uuid)) {
|
priv->vol_uuid)) {
|
||||||
op_errno = EINVAL;
|
op_errno = EINVAL;
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -11,6 +11,34 @@
|
|||||||
#include "libxlator.h"
|
#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*/
|
/*Copy the contents of oldtimebuf to newtimbuf*/
|
||||||
static void
|
static void
|
||||||
update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf)
|
update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf)
|
||||||
@ -47,22 +75,61 @@ match_uuid_local (const char *name, char *uuid)
|
|||||||
static void
|
static void
|
||||||
marker_local_incr_errcount (xl_marker_local_t *local, int op_errno)
|
marker_local_incr_errcount (xl_marker_local_t *local, int op_errno)
|
||||||
{
|
{
|
||||||
|
marker_result_idx_t i = -1;
|
||||||
|
|
||||||
if (!local)
|
if (!local)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (op_errno) {
|
switch (op_errno) {
|
||||||
case ENODATA:
|
case ENODATA:
|
||||||
local->enodata_count++;
|
i = MCNT_ENODATA;
|
||||||
break;
|
break;
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
local->enoent_count++;
|
i = MCNT_ENOENT;
|
||||||
break;
|
break;
|
||||||
case ENOTCONN:
|
case ENOTCONN:
|
||||||
local->enotconn_count++;
|
i = MCNT_ENOTCONN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
i = MCNT_EOTHER;
|
||||||
break;
|
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*/
|
/* 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;
|
callcnt = --local->call_count;
|
||||||
|
|
||||||
if (local->esomerr)
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
vol_uuid = local->vol_uuid;
|
vol_uuid = local->vol_uuid;
|
||||||
|
|
||||||
if (op_ret) {
|
if (op_ret) {
|
||||||
marker_local_incr_errcount (local, op_errno);
|
marker_local_incr_errcount (local, op_errno);
|
||||||
local->esomerr = op_errno;
|
|
||||||
goto unlock;
|
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)) {
|
if (dict_get_ptr (dict, marker_xattr, (void **)&net_timebuf)) {
|
||||||
gf_log (this->name, GF_LOG_WARNING,
|
gf_log (this->name, GF_LOG_WARNING,
|
||||||
"Unable to get <uuid>.xtime attr");
|
"Unable to get <uuid>.xtime attr");
|
||||||
local->noxtime_count++;
|
local->count[MCNT_NOTFOUND]++;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local->has_xtime) {
|
if (local->count[MCNT_FOUND]) {
|
||||||
get_hosttime (net_timebuf, host_timebuf);
|
get_hosttime (net_timebuf, host_timebuf);
|
||||||
if ( (host_timebuf[0]>local->host_timebuf[0]) ||
|
if ( (host_timebuf[0]>local->host_timebuf[0]) ||
|
||||||
(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 {
|
} else {
|
||||||
get_hosttime (net_timebuf, local->host_timebuf);
|
get_hosttime (net_timebuf, local->host_timebuf);
|
||||||
update_timebuf (net_timebuf, local->net_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;
|
op_errno = 0;
|
||||||
need_unwind = 1;
|
need_unwind = 1;
|
||||||
|
|
||||||
if (local->has_xtime) {
|
if (local->count[MCNT_FOUND]) {
|
||||||
if (!dict)
|
if (!dict)
|
||||||
dict = dict_new();
|
dict = dict_new();
|
||||||
|
|
||||||
@ -160,17 +223,9 @@ unlock:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local->noxtime_count)
|
op_errno = evaluate_marker_results (local->gauge, local->count);
|
||||||
goto out;
|
if (op_errno)
|
||||||
|
|
||||||
if (local->enodata_count || local->enotconn_count ||
|
|
||||||
local->enoent_count) {
|
|
||||||
op_ret = -1;
|
op_ret = -1;
|
||||||
op_errno = local->enodata_count? ENODATA:
|
|
||||||
local->enotconn_count? ENOTCONN:
|
|
||||||
local->enoent_count? ENOENT:
|
|
||||||
local->esomerr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -228,7 +283,7 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
if (marker_has_volinfo (local)) {
|
if (local->count[MCNT_FOUND]) {
|
||||||
if ((local->volmark->major != volmark->major) ||
|
if ((local->volmark->major != volmark->major) ||
|
||||||
(local->volmark->minor != volmark->minor)) {
|
(local->volmark->minor != volmark->minor)) {
|
||||||
op_ret = -1;
|
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);
|
uuid_unparse (volmark->uuid, vol_uuid);
|
||||||
if (volmark->retval)
|
if (volmark->retval)
|
||||||
local->retval = volmark->retval;
|
local->retval = volmark->retval;
|
||||||
|
local->count[MCNT_FOUND]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
@ -267,7 +323,7 @@ unlock:
|
|||||||
op_errno = 0;
|
op_errno = 0;
|
||||||
need_unwind = 1;
|
need_unwind = 1;
|
||||||
|
|
||||||
if (marker_has_volinfo (local)) {
|
if (local->count[MCNT_FOUND]) {
|
||||||
if (!dict)
|
if (!dict)
|
||||||
dict = dict_new();
|
dict = dict_new();
|
||||||
|
|
||||||
@ -277,11 +333,10 @@ unlock:
|
|||||||
op_ret = -1;
|
op_ret = -1;
|
||||||
op_errno = ENOMEM;
|
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:
|
out:
|
||||||
@ -303,7 +358,7 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
|
|||||||
const char *name, void *xl_local,
|
const char *name, void *xl_local,
|
||||||
xlator_specf_unwind_t xl_specf_getxattr_unwind,
|
xlator_specf_unwind_t xl_specf_getxattr_unwind,
|
||||||
xlator_t **sub_volumes, int count, int type,
|
xlator_t **sub_volumes, int count, int type,
|
||||||
char *vol_uuid)
|
int *gauge, char *vol_uuid)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
xl_marker_local_t *local = NULL;
|
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->call_count = count;
|
||||||
local->xl_specf_unwind = xl_specf_getxattr_unwind;
|
local->xl_specf_unwind = xl_specf_getxattr_unwind;
|
||||||
local->vol_uuid = vol_uuid;
|
local->vol_uuid = vol_uuid;
|
||||||
|
memcpy (local->gauge, gauge, sizeof (local->gauge));
|
||||||
|
|
||||||
frame->local = local;
|
frame->local = local;
|
||||||
|
|
||||||
|
@ -48,6 +48,69 @@ struct volume_mark {
|
|||||||
uint32_t usec;
|
uint32_t usec;
|
||||||
}__attribute__ ((__packed__));
|
}__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 marker_str {
|
||||||
struct volume_mark *volmark;
|
struct volume_mark *volmark;
|
||||||
data_t *data;
|
data_t *data;
|
||||||
@ -55,13 +118,8 @@ struct marker_str {
|
|||||||
uint32_t host_timebuf[2];
|
uint32_t host_timebuf[2];
|
||||||
uint32_t net_timebuf[2];
|
uint32_t net_timebuf[2];
|
||||||
int32_t call_count;
|
int32_t call_count;
|
||||||
unsigned has_xtime:1;
|
int gauge[MCNT_MAX];
|
||||||
int32_t enoent_count;
|
int count[MCNT_MAX];
|
||||||
int32_t enotconn_count;
|
|
||||||
int32_t enodata_count;
|
|
||||||
int32_t noxtime_count;
|
|
||||||
|
|
||||||
int esomerr;
|
|
||||||
|
|
||||||
xlator_specf_unwind_t xl_specf_unwind;
|
xlator_specf_unwind_t xl_specf_unwind;
|
||||||
void *xl_local;
|
void *xl_local;
|
||||||
@ -71,15 +129,6 @@ struct marker_str {
|
|||||||
|
|
||||||
typedef struct marker_str xl_marker_local_t;
|
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
|
int32_t
|
||||||
cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||||
int op_ret, int op_errno, dict_t *dict, dict_t *xdata);
|
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,
|
const char *name, void *xl_local,
|
||||||
xlator_specf_unwind_t xl_specf_getxattr_unwind,
|
xlator_specf_unwind_t xl_specf_getxattr_unwind,
|
||||||
xlator_t **sub_volumes, int count, int type,
|
xlator_t **sub_volumes, int count, int type,
|
||||||
char *vol_uuid);
|
int *gauge, char *vol_uuid);
|
||||||
|
|
||||||
int
|
int
|
||||||
match_uuid_local (const char *name, char *uuid);
|
match_uuid_local (const char *name, char *uuid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user