From 21cd43cfd62f69cd011fced7ebec93b9347f9fce Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Wed, 11 Mar 2015 17:43:12 +0530 Subject: libxlator: Change marker xattr handling interface - Changed the implementation of marker xattr handling to take just a function which populates important data that is different from default 'gauge' values and subvolumes where the call needs to be wound. - Removed duplicate code I found while reading the code and moved it to cluster_marker_unwind. Removed unused structure members. - Changed dht/afr/stripe implementations to follow the new implementation - Implemented marker xattr handling for ec. Change-Id: Ib0c3626fe31eb7c8aae841eabb694945bf23abd4 BUG: 1200372 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/9892 Tested-by: Gluster Build System Reviewed-by: Xavier Hernandez Reviewed-by: Shyamsundar Ranganathan Reviewed-by: Ravishankar N Reviewed-by: Vijay Bellur --- tests/basic/geo-replication/marker-xattrs.t | 108 ++++++++++ tests/volume.rc | 6 +- xlators/cluster/afr/src/afr-inode-read.c | 90 ++------ xlators/cluster/afr/src/afr.h | 2 - xlators/cluster/dht/src/dht-common.c | 70 ++----- xlators/cluster/dht/src/dht-common.h | 3 - xlators/cluster/ec/src/ec.c | 23 +++ xlators/cluster/ec/src/ec.h | 2 + xlators/cluster/stripe/src/stripe.c | 84 +++----- xlators/cluster/stripe/src/stripe.h | 2 - xlators/lib/src/libxlator.c | 310 +++++++++++++--------------- xlators/lib/src/libxlator.h | 14 +- 12 files changed, 352 insertions(+), 362 deletions(-) create mode 100755 tests/basic/geo-replication/marker-xattrs.t diff --git a/tests/basic/geo-replication/marker-xattrs.t b/tests/basic/geo-replication/marker-xattrs.t new file mode 100755 index 00000000000..a7dcb50aa78 --- /dev/null +++ b/tests/basic/geo-replication/marker-xattrs.t @@ -0,0 +1,108 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +TEST glusterd +TEST pidof glusterd + +## Start and create a replicated volume +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}-{0,1,2,3} + +TEST $CLI volume set $V0 indexing on + +TEST $CLI volume start $V0; + +## Mount native +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0 + +## Mount client-pid=-1 +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 --client-pid=-1 $M1 + +TEST touch $M0 + +vol_uuid=$(get_volume_mark $M1) +xtime=trusted.glusterfs.$vol_uuid.xtime + +TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +TEST kill_brick $V0 $H0 $B0/${V0}-0 + +TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 + +TEST $CLI volume stop $V0; +TEST $CLI volume delete $V0; + +cleanup +TEST glusterd +TEST pidof glusterd +## Start and create a disperse volume +TEST $CLI volume create $V0 disperse 3 redundancy 1 $H0:$B0/${V0}-{0,1,2} + +TEST $CLI volume set $V0 indexing on + +TEST $CLI volume start $V0; + +## Mount native +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" mount_get_option_value $M0 $V0-disperse-0 childs_up + +## Mount client-pid=-1 +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 --client-pid=-1 $M1 +EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" mount_get_option_value $M1 $V0-disperse-0 childs_up + +TEST touch $M0 + +vol_uuid=$(get_volume_mark $M1) +xtime=trusted.glusterfs.$vol_uuid.xtime + +TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +TEST kill_brick $V0 $H0 $B0/${V0}-0 + +TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 + +TEST $CLI volume stop $V0; +TEST $CLI volume delete $V0; + +cleanup +TEST glusterd +TEST pidof glusterd +## Start and create a stripe volume +TEST $CLI volume create $V0 stripe 2 $H0:$B0/${V0}-{0,1} + +TEST $CLI volume set $V0 indexing on + +TEST $CLI volume start $V0; + +## Mount native +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0 + +## Mount client-pid=-1 +TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 --client-pid=-1 $M1 + +TEST touch $M0 + +vol_uuid=$(get_volume_mark $M1) +xtime=trusted.glusterfs.$vol_uuid.xtime + +TEST "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +TEST kill_brick $V0 $H0 $B0/${V0}-0 + +#Stripe doesn't tolerate ENOTCONN +TEST ! "getfattr -n $xtime $M1 | grep -q ${xtime}=" + +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0 +EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M1 + +TEST $CLI volume stop $V0; +TEST $CLI volume delete $V0; + +cleanup diff --git a/tests/volume.rc b/tests/volume.rc index 1276dccdbae..ac078e2bcce 100644 --- a/tests/volume.rc +++ b/tests/volume.rc @@ -469,5 +469,9 @@ function mount_get_option_value { local subvol=$2 local key=$3 - grep "$3" $m/.meta/graphs/active/$subvol/private | awk '{print $3}' + grep -w "$3" $m/.meta/graphs/active/$subvol/private | awk '{print $3}' +} + +function get_volume_mark { + getfattr -n trusted.glusterfs.volume-mark -ehex $1 | sed -n 's/^trusted.glusterfs.volume-mark=0x//p' | cut -b5-36 | sed 's/\([a-f0-9]\{8\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)\([a-f0-9]\{4\}\)/\1-\2-\3-\4-/' } diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c index 77acf0b25b9..afa40fbad2a 100644 --- a/xlators/cluster/afr/src/afr-inode-read.c +++ b/xlators/cluster/afr/src/afr-inode-read.c @@ -1408,6 +1408,23 @@ afr_getxattr_all_subvols (xlator_t *this, call_frame_t *frame, return; } +int +afr_marker_populate_args (call_frame_t *frame, int type, int *gauge, + xlator_t **subvols) +{ + xlator_t *this = frame->this; + afr_private_t *priv = this->private; + + memcpy (subvols, priv->children, sizeof (*subvols) * priv->child_count); + + if (type == MARKER_XTIME_TYPE) { + /*Don't error out on ENOENT/ENOTCONN */ + gauge[MCNT_NOTFOUND] = 0; + gauge[MCNT_ENOTCONN] = 0; + } + return priv->child_count; +} + int32_t afr_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) @@ -1415,13 +1432,10 @@ afr_getxattr (call_frame_t *frame, xlator_t *this, afr_private_t *priv = NULL; xlator_t **children = NULL; afr_local_t *local = NULL; - xlator_list_t *trav = NULL; - xlator_t **sub_volumes = NULL; int i = 0; int32_t op_errno = 0; int ret = -1; fop_getxattr_cbk_t cbk = NULL; - int afr_xtime_gauge[MCNT_MAX] = {0,}; local = AFR_FRAME_INIT (frame, op_errno); @@ -1457,35 +1471,11 @@ afr_getxattr (call_frame_t *frame, xlator_t *this, op_errno = ENODATA; goto out; } - if ((strcmp (GF_XATTR_MARKER_KEY, name) == 0) - && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - - local->marker.call_count = priv->child_count; - - sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *)); - for (i = 0, trav = this->children; trav ; - trav = trav->next, i++) { - - *(sub_volumes + i) = trav->xlator; - } - - if (cluster_getmarkerattr (frame, this, loc, name, - local, afr_getxattr_unwind, - sub_volumes, - priv->child_count, - MARKER_UUID_TYPE, - marker_uuid_default_gauge, - priv->vol_uuid)) { - - gf_log (this->name, GF_LOG_INFO, - "%s: failed to get marker attr (%s)", - loc->path, name); - op_errno = EINVAL; - goto out; - } + if (cluster_handle_marker_getxattr (frame, loc, name, priv->vol_uuid, + afr_getxattr_unwind, + afr_marker_populate_args) == 0) return 0; - } if (!strcmp (name, GF_AFR_HEAL_INFO)) { afr_get_heal_info (frame, this, loc, xdata); @@ -1519,46 +1509,6 @@ afr_getxattr (call_frame_t *frame, xlator_t *this, return 0; } - if (*priv->vol_uuid) { - if ((match_uuid_local (name, priv->vol_uuid) == 0) - && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - local->marker.call_count = priv->child_count; - - sub_volumes = alloca ( priv->child_count - * sizeof (xlator_t *)); - for (i = 0, trav = this->children; trav ; - trav = trav->next, i++) { - - *(sub_volumes + i) = trav->xlator; - - } - - /* don't err out on getting ENOTCONN (brick down) - * from a subset of the bricks - */ - memcpy (afr_xtime_gauge, marker_xtime_default_gauge, - sizeof (afr_xtime_gauge)); - afr_xtime_gauge[MCNT_NOTFOUND] = 0; - afr_xtime_gauge[MCNT_ENOTCONN] = 0; - if (cluster_getmarkerattr (frame, this, loc, - name, local, - afr_getxattr_unwind, - sub_volumes, - priv->child_count, - MARKER_XTIME_TYPE, - afr_xtime_gauge, - priv->vol_uuid)) { - gf_log (this->name, GF_LOG_INFO, - "%s: failed to get marker attr (%s)", - loc->path, name); - op_errno = EINVAL; - goto out; - } - - return 0; - } - } - no_name: afr_read_txn (frame, this, local->loc.inode, afr_getxattr_wind, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 0885b582d77..de000e765ea 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -720,8 +720,6 @@ typedef struct _afr_local { syncbarrier_t barrier; - struct marker_str marker; - /* extra data for fops */ dict_t *xdata_req; dict_t *xdata_rsp; diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 3a196e07be9..b7df1f4da4b 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -2791,6 +2791,22 @@ dht_getxattr_get_real_filename (call_frame_t *frame, xlator_t *this, return 0; } +int +dht_marker_populate_args (call_frame_t *frame, int type, int *gauge, + xlator_t **subvols) +{ + dht_local_t *local = NULL; + int i = 0; + dht_layout_t *layout = NULL; + + local = frame->local; + layout = local->layout; + + for (i = 0; i < layout->cnt; i++) + subvols[i] = layout->list[i].xlator; + + return layout->cnt; +} int dht_getxattr (call_frame_t *frame, xlator_t *this, @@ -2804,7 +2820,6 @@ dht_getxattr (call_frame_t *frame, xlator_t *this, dht_conf_t *conf = NULL; dht_local_t *local = NULL; dht_layout_t *layout = NULL; - xlator_t **sub_volumes = NULL; int op_errno = -1; int i = 0; int cnt = 0; @@ -2918,30 +2933,6 @@ dht_getxattr (call_frame_t *frame, xlator_t *this, return 0; } - if (key && (!strcmp (GF_XATTR_MARKER_KEY, key)) - && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - if (DHT_IS_DIR(layout)) { - cnt = layout->cnt; - } else { - cnt = 1; - } - - sub_volumes = alloca ( cnt * sizeof (xlator_t *)); - for (i = 0; i < cnt; i++) - *(sub_volumes + i) = layout->list[i].xlator; - - if (cluster_getmarkerattr (frame, this, loc, key, - local, dht_getxattr_unwind, - sub_volumes, cnt, - MARKER_UUID_TYPE, marker_uuid_default_gauge, - conf->vol_uuid)) { - op_errno = EINVAL; - goto err; - } - - return 0; - } - if (key && (!strcmp (GF_XATTR_QUOTA_LIMIT_LIST, key) || !strcmp (GF_XATTR_QUOTA_LIMIT_LIST_OBJECT, key))) { /* quota hardlimit and aggregated size of a directory is stored @@ -2955,31 +2946,10 @@ dht_getxattr (call_frame_t *frame, xlator_t *this, return 0; } - if (key && *conf->vol_uuid) { - if ((match_uuid_local (key, conf->vol_uuid) == 0) && - (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - if (DHT_IS_DIR(layout)) { - cnt = layout->cnt; - } else { - cnt = 1; - } - sub_volumes = alloca ( cnt * sizeof (xlator_t *)); - for (i = 0; i < cnt; i++) - sub_volumes[i] = layout->list[i].xlator; - - if (cluster_getmarkerattr (frame, this, loc, key, - local, dht_getxattr_unwind, - sub_volumes, cnt, - MARKER_XTIME_TYPE, - marker_xtime_default_gauge, - conf->vol_uuid)) { - op_errno = EINVAL; - goto err; - } - - return 0; - } - } + if (cluster_handle_marker_getxattr (frame, loc, key, conf->vol_uuid, + dht_getxattr_unwind, + dht_marker_populate_args) == 0) + return 0; if (DHT_IS_DIR(layout)) { cnt = local->call_cnt = layout->cnt; diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 9145f336d7c..9d505c1e601 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -216,9 +216,6 @@ struct dht_local { /* gfid related */ uuid_t gfid; - /*Marker Related*/ - struct marker_str marker; - /* flag used to make sure we need to return estale in {lookup,revalidate}_cbk */ char return_estale; diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index 9fecde4c495..9b8251a5403 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -576,16 +576,39 @@ int32_t ec_gf_fsyncdir(call_frame_t * frame, xlator_t * this, fd_t * fd, return 0; } +int +ec_marker_populate_args (call_frame_t *frame, int type, int *gauge, + xlator_t **subvols) +{ + xlator_t *this = frame->this; + ec_t *ec = this->private; + + memcpy (subvols, ec->xl_list, sizeof (*subvols) * ec->nodes); + + if (type == MARKER_XTIME_TYPE) { + /*Don't error out on ENOENT/ENOTCONN */ + gauge[MCNT_NOTFOUND] = 0; + gauge[MCNT_ENOTCONN] = 0; + } + + return ec->nodes; +} + int32_t ec_gf_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { int error = 0; + ec_t *ec = this->private; if (name && strcmp (name, EC_XATTR_HEAL) != 0) { EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out); } + if (cluster_handle_marker_getxattr (frame, loc, name, ec->vol_uuid, + NULL, ec_marker_populate_args) == 0) + return 0; + ec_getxattr (frame, this, -1, EC_MINIMUM_MIN, default_getxattr_cbk, NULL, loc, name, xdata); diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h index 1c740187757..d565bf8fcb4 100644 --- a/xlators/cluster/ec/src/ec.h +++ b/xlators/cluster/ec/src/ec.h @@ -14,6 +14,7 @@ #include "xlator.h" #include "timer.h" #include "ec-heald.h" +#include "libxlator.h" #define EC_XATTR_PREFIX "trusted.ec." #define EC_XATTR_CONFIG EC_XATTR_PREFIX"config" @@ -45,5 +46,6 @@ struct _ec struct mem_pool * cbk_pool; struct mem_pool * lock_pool; ec_self_heald_t shd; + char vol_uuid[UUID_SIZE + 1]; }; #endif /* __EC_H__ */ diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 7af9442a7ff..8896d7a2ad2 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -5454,6 +5454,25 @@ stripe_vgetxattr_cbk (call_frame_t *frame, void *cookie, return ret; } +int +stripe_marker_populate_args (call_frame_t *frame, int type, int *gauge, + xlator_t **subvols) +{ + xlator_t *this = frame->this; + stripe_private_t *priv = this->private; + stripe_local_t *local = frame->local; + int count = 0; + + count = priv->child_count; + if (MARKER_XTIME_TYPE == type) { + if (!IA_FILE_OR_DIR (local->loc.inode->ia_type)) + count = 1; + } + memcpy (subvols, priv->xl_array, sizeof (*subvols) * count); + + return count; +} + int32_t stripe_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) @@ -5463,7 +5482,6 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this, stripe_private_t *priv = NULL; int32_t op_errno = EINVAL; int i = 0; - xlator_t **sub_volumes; int ret = 0; VALIDATE_OR_GOTO (frame, err); @@ -5486,31 +5504,6 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this, loc_copy (&local->loc, loc); - if (name && (strcmp (GF_XATTR_MARKER_KEY, name) == 0) - && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - local->marker.call_count = priv->child_count; - - sub_volumes = alloca ( priv->child_count * - sizeof (xlator_t *)); - for (i = 0, trav = this->children; trav ; - trav = trav->next, i++) { - - *(sub_volumes + i) = trav->xlator; - - } - - if (cluster_getmarkerattr (frame, this, loc, name, - local, stripe_getxattr_unwind, - sub_volumes, priv->child_count, - MARKER_UUID_TYPE, marker_uuid_default_gauge, - priv->vol_uuid)) { - op_errno = EINVAL; - goto err; - } - - return 0; - } - if (name && strncmp (name, GF_XATTR_QUOTA_SIZE_KEY, strlen (GF_XATTR_QUOTA_SIZE_KEY)) == 0) { local->wind_count = priv->child_count; @@ -5555,41 +5548,10 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this, return 0; } - if (name &&(*priv->vol_uuid)) { - if ((match_uuid_local (name, priv->vol_uuid) == 0) - && (GF_CLIENT_PID_GSYNCD == frame->root->pid)) { - - if (!IA_FILE_OR_DIR (loc->inode->ia_type)) - local->marker.call_count = 1; - else - local->marker.call_count = priv->child_count; - - sub_volumes = alloca (local->marker.call_count * - sizeof (xlator_t *)); - - for (i = 0, trav = this->children; - i < local->marker.call_count; - i++, trav = trav->next) { - *(sub_volumes + i) = trav->xlator; - - } - - if (cluster_getmarkerattr (frame, this, loc, name, - local, - stripe_getxattr_unwind, - sub_volumes, - local->marker.call_count, - MARKER_XTIME_TYPE, - marker_xtime_default_gauge, - priv->vol_uuid)) { - op_errno = EINVAL; - goto err; - } - - return 0; - } - } - + if (cluster_handle_marker_getxattr (frame, loc, name, priv->vol_uuid, + stripe_getxattr_unwind, + stripe_marker_populate_args) == 0) + return 0; STACK_WIND (frame, stripe_internal_getxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h index 5673d18f390..150d9e49f93 100644 --- a/xlators/cluster/stripe/src/stripe.h +++ b/xlators/cluster/stripe/src/stripe.h @@ -190,8 +190,6 @@ struct stripe_local { int32_t nallocs; char xsel[256]; - struct marker_str marker; - /* General usage */ off_t offset; off_t stripe_size; diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c index 0b5036c8ba8..30436131b6b 100644 --- a/xlators/lib/src/libxlator.c +++ b/xlators/lib/src/libxlator.c @@ -61,6 +61,9 @@ get_hosttime (uint32_t *oldtimbuf, uint32_t *newtimebuf) int match_uuid_local (const char *name, char *uuid) { + if (!uuid || !*uuid) + return -1; + name = strtail ((char *)name, MARKER_XATTR_PREFIX); if (!name || name++[0] != '.') return -1; @@ -132,6 +135,57 @@ evaluate_marker_results (int *gauge, int *count) return op_errno; } +static void +cluster_marker_unwind (call_frame_t *frame, char *key, void *value, size_t size, + dict_t *dict) +{ + xl_marker_local_t *local = frame->local; + int ret = 0; + int32_t op_ret = 0; + int32_t op_errno = 0; + gf_boolean_t unref = _gf_false; + + frame->local = local->xl_local; + + if (local->count[MCNT_FOUND]) { + if (!dict) { + dict = dict_new(); + if (dict) { + unref = _gf_true; + } else { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + } + + ret = dict_set_static_bin (dict, key, value, size); + if (ret) { + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + } + + op_errno = evaluate_marker_results (local->gauge, local->count); + if (op_errno) + op_ret = -1; + +out: + if (local->xl_specf_unwind) { + local->xl_specf_unwind (frame, op_ret, + op_errno, dict, NULL); + } else { + STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, + dict, NULL); + } + + GF_FREE (local); + if (unref) + dict_unref (dict); + +} + /* Aggregate all the .xtime attrs of the cluster and send the max*/ int32_t cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -140,26 +194,12 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { int32_t callcnt = 0; - int ret = -1; uint32_t *net_timebuf = NULL; uint32_t host_timebuf[2] = {0,}; char marker_xattr[128] = {0}; xl_marker_local_t *local = NULL; - char need_unwind = 0; - gf_boolean_t unref = _gf_false; - - if (!this || !frame || !frame->local || !cookie) { - gf_log ("", GF_LOG_DEBUG, "possible NULL deref"); - need_unwind = 1; - goto out; - } local = frame->local; - if (!local || !local->vol_uuid) { - gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); - need_unwind = 1; - goto out; - } snprintf (marker_xattr, sizeof (marker_xattr), "%s.%s.%s", MARKER_XATTR_PREFIX, local->vol_uuid, XTIME); @@ -199,50 +239,9 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&frame->lock); - if (!callcnt) { - op_ret = 0; - op_errno = 0; - need_unwind = 1; - - if (local->count[MCNT_FOUND]) { - if (!dict) { - dict = dict_new(); - if (dict) { - unref = _gf_true; - } else { - op_ret = -1; - op_errno = ENOMEM; - goto out; - } - } - - ret = dict_set_static_bin (dict, marker_xattr, - (void *)local->net_timebuf, 8); - if (ret) { - op_ret = -1; - op_errno = ENOMEM; - goto out; - } - } - - op_errno = evaluate_marker_results (local->gauge, local->count); - if (op_errno) - op_ret = -1; - } - -out: - if (need_unwind && local && local->xl_specf_unwind) { - frame->local = local->xl_local; - local->xl_specf_unwind (frame, op_ret, - op_errno, dict, xdata); - GF_FREE (local); - } else if (need_unwind) { - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, - dict, xdata); - } - - if (unref) - dict_unref (dict); + if (callcnt == 0) + cluster_marker_unwind (frame, marker_xattr, local->net_timebuf, + 8, dict); return 0; @@ -256,23 +255,10 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct volume_mark *volmark = NULL; xl_marker_local_t *local = NULL; int32_t ret = -1; - char need_unwind = 0; char *vol_uuid = NULL; - if (!this || !frame || !cookie) { - gf_log ("", GF_LOG_DEBUG, "possible NULL deref"); - need_unwind = 1; - goto out; - } - local = frame->local; - if (!local) { - gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref"); - need_unwind = 1; - goto out; - } - LOCK (&frame->lock); { callcnt = --local->call_count; @@ -296,9 +282,9 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto unlock; } - if (local->retval) + if (local->retval) { goto unlock; - else if (volmark->retval) { + } else if (volmark->retval) { GF_FREE (local->volmark); local->volmark = memdup (volmark, sizeof (*volmark)); @@ -323,103 +309,14 @@ cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, unlock: UNLOCK (&frame->lock); - if (!callcnt) { - op_ret = 0; - op_errno = 0; - need_unwind = 1; + if (callcnt == 0) + cluster_marker_unwind (frame, GF_XATTR_MARKER_KEY, + local->volmark, sizeof (*local->volmark), + dict); - if (local->count[MCNT_FOUND]) { - if (!dict) - dict = dict_new(); - - if (dict_set_bin (dict, GF_XATTR_MARKER_KEY, - local->volmark, - sizeof (struct volume_mark))) { - op_ret = -1; - op_errno = ENOMEM; - } - } - op_errno = evaluate_marker_results (local->gauge, local->count); - if (op_errno) - op_ret = -1; - } - - out: - if (need_unwind && local && local->xl_specf_unwind) { - frame->local = local->xl_local; - local->xl_specf_unwind (frame, op_ret, - op_errno, dict, xdata); - GF_FREE (local); - return 0; - } else if (need_unwind){ - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, - dict, xdata); - } return 0; } - -int32_t -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, - int *gauge, char *vol_uuid) -{ - int i = 0; - xl_marker_local_t *local = NULL; - - VALIDATE_OR_GOTO (frame, err); - VALIDATE_OR_GOTO (this, err); - VALIDATE_OR_GOTO (loc, err); - VALIDATE_OR_GOTO (loc->path, err); - VALIDATE_OR_GOTO (loc->inode, err); - VALIDATE_OR_GOTO (name, err); - VALIDATE_OR_GOTO (xl_specf_getxattr_unwind, err); - - local = GF_CALLOC (sizeof (struct marker_str), 1, - gf_common_mt_libxl_marker_local); - - if (!local) - goto err; - - local->xl_local = xl_local; - 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; - - for (i=0; i < count; i++) { - if (MARKER_UUID_TYPE == type) - STACK_WIND (frame, cluster_markeruuid_cbk, - *(sub_volumes + i), - (*(sub_volumes + i))->fops->getxattr, - loc, name, NULL); - else if (MARKER_XTIME_TYPE == type) - STACK_WIND (frame, cluster_markerxtime_cbk, - *(sub_volumes + i), - (*(sub_volumes + i))->fops->getxattr, - loc, name, NULL); - else { - gf_log (this->name, GF_LOG_WARNING, - "Unrecognized type (%d) of marker attr " - "received", type); - STACK_WIND (frame, default_getxattr_cbk, - *(sub_volumes + i), - (*(sub_volumes + i))->fops->getxattr, - loc, name, NULL); - break; - } - } - - return 0; -err: - return -1; - -} - int gf_get_min_stime (xlator_t *this, dict_t *dst, char *key, data_t *value) { @@ -529,3 +426,84 @@ error: return ret; } + +static int +_get_children_count (xlator_t *xl) +{ + int i = 0; + xlator_list_t *trav = NULL; + for (i = 0, trav = xl->children; trav ; trav = trav->next, i++) { + /*'i' will have the value */ + } + + return i; +} + +int +cluster_handle_marker_getxattr (call_frame_t *frame, loc_t *loc, + const char *name, char *vol_uuid, + xlator_specf_unwind_t unwind, + int (*populate_args) (call_frame_t *frame, + int type, int *gauge, + xlator_t **subvols)) +{ + xlator_t *this = frame->this; + xlator_t **subvols = NULL; + int num_subvols = 0; + int type = 0; + int i = 0; + int gauge[MCNT_MAX] = {0}; + xl_marker_local_t *local = NULL; + + if (GF_CLIENT_PID_GSYNCD != frame->root->pid) + return -EINVAL; + + if (strcmp (GF_XATTR_MARKER_KEY, name) == 0) { + type = MARKER_UUID_TYPE; + memcpy (gauge, marker_uuid_default_gauge, sizeof (gauge)); + } else if (match_uuid_local (name, vol_uuid) == 0) { + type = MARKER_XTIME_TYPE; + memcpy (gauge, marker_xtime_default_gauge, sizeof (gauge)); + } else { + return -EINVAL; + } + + num_subvols = _get_children_count (this); + subvols = alloca (num_subvols * sizeof (*subvols)); + num_subvols = populate_args (frame, type, gauge, subvols); + + local = GF_CALLOC (sizeof (struct marker_str), 1, + gf_common_mt_libxl_marker_local); + + if (!local) + goto fail; + + local->xl_local = frame->local; + local->call_count = num_subvols; + local->xl_specf_unwind = unwind; + local->vol_uuid = vol_uuid; + memcpy (local->gauge, gauge, sizeof (local->gauge)); + + frame->local = local; + + for (i = 0; i < num_subvols; i++) { + if (MARKER_UUID_TYPE == type) + STACK_WIND (frame, cluster_markeruuid_cbk, + subvols[i], + subvols[i]->fops->getxattr, + loc, name, NULL); + else if (MARKER_XTIME_TYPE == type) + STACK_WIND (frame, cluster_markerxtime_cbk, + subvols[i], + subvols[i]->fops->getxattr, + loc, name, NULL); + } + + return 0; +fail: + if (unwind) + unwind (frame, -1, ENOMEM, NULL, NULL); + else + default_getxattr_failure_cbk (frame, ENOMEM); + return 0; +} diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h index 404124ca7d3..20d5a32f248 100644 --- a/xlators/lib/src/libxlator.h +++ b/xlators/lib/src/libxlator.h @@ -139,13 +139,13 @@ int32_t cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, dict_t *dict, dict_t *xdata); -int32_t -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, - int *gauge, char *vol_uuid); - +int +cluster_handle_marker_getxattr (call_frame_t *frame, loc_t *loc, + const char *name, char *vol_uuid, + xlator_specf_unwind_t unwind, + int (*populate_args) (call_frame_t *frame, + int type, int *gauge, + xlator_t **subvols)); int match_uuid_local (const char *name, char *uuid); -- cgit