adding libxlator, to ensure proper client side aggregation of marks by clustering translators
Signed-off-by: Kaushik BV <kaushikbv@gluster.com> Signed-off-by: Csaba Henk <csaba@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 2310 (georeplication) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2310
This commit is contained in:
parent
11dd59b788
commit
73bce15b61
@ -97,6 +97,7 @@ enum gf_common_mem_types_ {
|
||||
gf_common_mt_rdma_context_t = 72,
|
||||
gf_common_mt_sge = 73,
|
||||
gf_common_mt_rpcclnt_cb_program_t = 74,
|
||||
gf_common_mt_end = 75
|
||||
gf_common_mt_libxl_marker_local = 75,
|
||||
gf_common_mt_end = 76
|
||||
};
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
xlator_LTLIBRARIES = afr.la pump.la
|
||||
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
|
||||
|
||||
afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c
|
||||
afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c $(top_builddir)/xlators/lib/src/libxlator.c
|
||||
|
||||
afr_la_LDFLAGS = -module -avoidversion
|
||||
afr_la_SOURCES = $(afr_common_source) afr.c
|
||||
@ -11,10 +11,11 @@ pump_la_LDFLAGS = -module -avoidversion
|
||||
pump_la_SOURCES = $(afr_common_source) pump.c
|
||||
pump_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
|
||||
noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c
|
||||
noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c $(top_builddir)/xlators/lib/src/libxlator.h
|
||||
|
||||
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
|
||||
-I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS)
|
||||
-I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS) \
|
||||
-I$(top_srcdir)/xlators/lib/src
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
|
@ -656,6 +656,15 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
afr_getxattr_unwind (void *arg, call_frame_t *frame,
|
||||
int op_ret, int op_errno, dict_t *dict)
|
||||
|
||||
{
|
||||
AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
afr_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
loc_t *loc, const char *name)
|
||||
@ -664,8 +673,11 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
xlator_t ** children = NULL;
|
||||
int call_child = 0;
|
||||
afr_local_t * local = NULL;
|
||||
xlator_list_t * trav = NULL;
|
||||
xlator_t ** sub_volumes= NULL;
|
||||
|
||||
int read_child = -1;
|
||||
int i = 0;
|
||||
|
||||
int32_t op_ret = -1;
|
||||
int32_t op_errno = 0;
|
||||
@ -683,6 +695,11 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
ALLOC_OR_GOTO (local, afr_local_t, out);
|
||||
frame->local = local;
|
||||
|
||||
loc_copy (&local->loc, loc);
|
||||
if (name)
|
||||
local->cont.getxattr.name = gf_strdup (name);
|
||||
|
||||
|
||||
if (name) {
|
||||
if (!strncmp (name, AFR_XATTR_PREFIX,
|
||||
strlen (AFR_XATTR_PREFIX))) {
|
||||
@ -690,6 +707,60 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
op_errno = ENODATA;
|
||||
goto out;
|
||||
}
|
||||
if ((strcmp (GF_XATTR_MARKER_KEY, name) == 0)
|
||||
&& (-1 == 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,
|
||||
priv->vol_uuid)) {
|
||||
|
||||
op_errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*priv->vol_uuid) {
|
||||
if ((match_uuid_local (name, priv->vol_uuid) == 0)
|
||||
&& (-1 == 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_XTIME_TYPE,
|
||||
priv->vol_uuid)) {
|
||||
op_errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -712,9 +783,6 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
local->cont.getxattr.last_tried = call_child;
|
||||
}
|
||||
|
||||
loc_copy (&local->loc, loc);
|
||||
if (name)
|
||||
local->cont.getxattr.name = gf_strdup (name);
|
||||
|
||||
STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
|
||||
(void *) (long) call_child,
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "compat-errno.h"
|
||||
#include "afr-mem-types.h"
|
||||
|
||||
#include "libxlator.h"
|
||||
|
||||
#define AFR_XATTR_PREFIX "trusted.afr"
|
||||
|
||||
struct _pump_private;
|
||||
@ -89,6 +91,8 @@ typedef struct _afr_private {
|
||||
pthread_mutex_t mutex;
|
||||
struct list_head saved_fds; /* list of fds on which locks have succeeded */
|
||||
gf_boolean_t optimistic_change_log;
|
||||
|
||||
char vol_uuid[UUID_SIZE + 1];
|
||||
} afr_private_t;
|
||||
|
||||
typedef struct {
|
||||
@ -616,6 +620,8 @@ typedef struct _afr_local {
|
||||
} transaction;
|
||||
|
||||
afr_self_heal_t self_heal;
|
||||
|
||||
struct marker_str marker;
|
||||
} afr_local_t;
|
||||
|
||||
|
||||
@ -927,4 +933,8 @@ afr_transaction_local_init (afr_local_t *local, afr_private_t *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
afr_marker_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
loc_t *loc, const char *name,afr_local_t *local, afr_private_t *priv );
|
||||
|
||||
#endif /* __AFR_H__ */
|
||||
|
@ -4,7 +4,8 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
|
||||
|
||||
|
||||
dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c \
|
||||
dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c
|
||||
dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \
|
||||
$(top_builddir)/xlators/lib/src/libxlator.c
|
||||
|
||||
dht_la_SOURCES = $(dht_common_source) dht.c
|
||||
|
||||
@ -20,10 +21,11 @@ nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
switch_la_LDFLAGS = -module -avoidversion
|
||||
switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
|
||||
noinst_HEADERS = dht-common.h dht-common.c dht-mem-types.h
|
||||
noinst_HEADERS = dht-common.h dht-common.c dht-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h
|
||||
|
||||
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
|
||||
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
|
||||
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
|
||||
-I$(top_srcdir)/xlators/lib/src
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
|
@ -27,12 +27,14 @@
|
||||
|
||||
#include "glusterfs.h"
|
||||
#include "xlator.h"
|
||||
#include "libxlator.h"
|
||||
#include "dht-common.h"
|
||||
#include "defaults.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <libgen.h>
|
||||
|
||||
|
||||
/* TODO:
|
||||
- use volumename in xattr instead of "dht"
|
||||
- use NS locks
|
||||
@ -1834,6 +1836,14 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
dht_getxattr_unwind (void *getxattr, call_frame_t *frame,
|
||||
int op_ret, int op_errno, dict_t *dict)
|
||||
{
|
||||
DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dht_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
@ -1845,6 +1855,7 @@ 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 ret = 0;
|
||||
int flag = 0;
|
||||
@ -1867,6 +1878,14 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
goto err;
|
||||
}
|
||||
|
||||
local = dht_local_init (frame);
|
||||
if (!local) {
|
||||
op_errno = ENOMEM;
|
||||
gf_log (this->name, GF_LOG_ERROR,
|
||||
"Out of memory");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (key && (strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)) {
|
||||
hashed_subvol = dht_subvol_get_hashed (this, loc);
|
||||
cached_subvol = dht_subvol_get_cached (this, loc->inode);
|
||||
@ -1959,14 +1978,54 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
goto err;
|
||||
}
|
||||
|
||||
local = dht_local_init (frame);
|
||||
if (!local) {
|
||||
op_errno = ENOMEM;
|
||||
gf_log (this->name, GF_LOG_ERROR,
|
||||
"Out of memory");
|
||||
if (key && (!strcmp (GF_XATTR_MARKER_KEY, key))
|
||||
&& (-1 == frame->root->pid)) {
|
||||
|
||||
if (loc->inode-> ia_type == IA_IFDIR) {
|
||||
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, conf->vol_uuid)) {
|
||||
op_errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key && *conf->vol_uuid) {
|
||||
if ((match_uuid_local (key, conf->vol_uuid) == 0) &&
|
||||
(-1 == frame->root->pid)) {
|
||||
if (loc->inode-> ia_type == IA_IFDIR) {
|
||||
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,
|
||||
conf->vol_uuid)) {
|
||||
op_errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = loc_dup (loc, &local->loc);
|
||||
if (ret == -1) {
|
||||
op_errno = ENOMEM;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "dht-mem-types.h"
|
||||
#include "libxlator.h"
|
||||
|
||||
#ifndef _DHT_H
|
||||
#define _DHT_H
|
||||
@ -128,6 +129,9 @@ struct dht_local {
|
||||
|
||||
/* gfid related */
|
||||
uuid_t gfid;
|
||||
|
||||
/*Marker Related*/
|
||||
struct marker_str marker;
|
||||
};
|
||||
typedef struct dht_local dht_local_t;
|
||||
|
||||
@ -160,6 +164,7 @@ struct dht_conf {
|
||||
void *private; /* Can be used by wrapper xlators over
|
||||
dht */
|
||||
gf_boolean_t use_readdirp;
|
||||
char vol_uuid[UUID_SIZE + 1];
|
||||
};
|
||||
typedef struct dht_conf dht_conf_t;
|
||||
|
||||
|
@ -4,13 +4,14 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
|
||||
|
||||
stripe_la_LDFLAGS = -module -avoidversion
|
||||
|
||||
stripe_la_SOURCES = stripe.c
|
||||
stripe_la_SOURCES = stripe.c $(top_builddir)/xlators/lib/src/libxlator.c
|
||||
stripe_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
|
||||
|
||||
noinst_HEADERS = stripe.h stripe-mem-types.h
|
||||
noinst_HEADERS = stripe.h stripe-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h
|
||||
|
||||
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
|
||||
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
|
||||
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
|
||||
-I$(top_srcdir)/xlators/lib/src
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
#include "stripe.h"
|
||||
#include "libxlator.h"
|
||||
|
||||
void
|
||||
stripe_local_wipe (stripe_local_t *local)
|
||||
@ -3896,6 +3897,7 @@ init (xlator_t *this)
|
||||
priv->nodes_down = priv->child_count;
|
||||
this->private = priv;
|
||||
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (ret) {
|
||||
@ -3942,6 +3944,110 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t
|
||||
stripe_getxattr_unwind (void *getxattr, call_frame_t *frame,
|
||||
int op_ret, int op_errno, dict_t *dict)
|
||||
|
||||
{
|
||||
STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
stripe_getxattr (call_frame_t *frame, xlator_t *this,
|
||||
loc_t *loc, const char *name)
|
||||
{
|
||||
stripe_local_t *local = NULL;
|
||||
xlator_list_t *trav = NULL;
|
||||
stripe_private_t *priv = NULL;
|
||||
int32_t op_errno = EINVAL;
|
||||
int i = 0;
|
||||
xlator_t **sub_volumes;
|
||||
|
||||
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);
|
||||
|
||||
priv = this->private;
|
||||
trav = this->children;
|
||||
|
||||
/* Initialization */
|
||||
local = GF_CALLOC (1, sizeof (stripe_local_t),
|
||||
gf_stripe_mt_stripe_local_t);
|
||||
if (!local) {
|
||||
op_errno = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
local->op_ret = -1;
|
||||
frame->local = local;
|
||||
loc_copy (&local->loc, loc);
|
||||
|
||||
|
||||
if (name && (strcmp (GF_XATTR_MARKER_KEY, name) == 0)
|
||||
&& (-1 == 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, priv->vol_uuid)) {
|
||||
op_errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*priv->vol_uuid) {
|
||||
if ((match_uuid_local (name, priv->vol_uuid) == 0)
|
||||
&& (-1 == 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_XTIME_TYPE,
|
||||
priv->vol_uuid)) {
|
||||
op_errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
|
||||
FIRST_CHILD(this)->fops->getxattr, loc, name);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct xlator_fops fops = {
|
||||
.stat = stripe_stat,
|
||||
@ -3967,6 +4073,8 @@ struct xlator_fops fops = {
|
||||
.fsetattr = stripe_fsetattr,
|
||||
.lookup = stripe_lookup,
|
||||
.mknod = stripe_mknod,
|
||||
|
||||
.getxattr = stripe_getxattr,
|
||||
};
|
||||
|
||||
struct xlator_cbks cbks = {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "compat.h"
|
||||
#include "compat-errno.h"
|
||||
#include "stripe-mem-types.h"
|
||||
#include "libxlator.h"
|
||||
#include <fnmatch.h>
|
||||
#include <signal.h>
|
||||
|
||||
@ -84,6 +85,7 @@ struct stripe_private {
|
||||
int8_t child_count;
|
||||
int8_t *state; /* Current state of child node */
|
||||
gf_boolean_t xattr_supported; /* default yes */
|
||||
char vol_uuid[UUID_SIZE + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -163,6 +165,8 @@ struct stripe_local {
|
||||
/* For File I/O fops */
|
||||
dict_t *dict;
|
||||
|
||||
struct marker_str marker;
|
||||
|
||||
/* General usage */
|
||||
off_t offset;
|
||||
off_t stripe_size;
|
||||
@ -180,4 +184,5 @@ struct stripe_local {
|
||||
typedef struct stripe_local stripe_local_t;
|
||||
typedef struct stripe_private stripe_private_t;
|
||||
|
||||
|
||||
#endif /* _STRIPE_H_ */
|
||||
|
371
xlators/lib/src/libxlator.c
Normal file
371
xlators/lib/src/libxlator.c
Normal file
@ -0,0 +1,371 @@
|
||||
#include "mem-types.h"
|
||||
#include "libxlator.h"
|
||||
|
||||
|
||||
/*Copy the contents of oldtimebuf to newtimbuf*/
|
||||
static void
|
||||
update_timebuf (uint32_t *oldtimbuf, uint32_t *newtimebuf)
|
||||
{
|
||||
newtimebuf[0] = (oldtimbuf[0]);
|
||||
newtimebuf[1] = (oldtimbuf[1]);
|
||||
}
|
||||
|
||||
/* Convert Timebuf in network order to host order */
|
||||
static void
|
||||
get_hosttime (uint32_t *oldtimbuf, uint32_t *newtimebuf)
|
||||
{
|
||||
newtimebuf[0] = ntohl (oldtimbuf[0]);
|
||||
newtimebuf[1] = ntohl (oldtimbuf[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Match the Incoming trusted.glusterfs.<uuid>.xtime against volume uuid */
|
||||
int
|
||||
match_uuid_local (const char *name, char *uuid)
|
||||
{
|
||||
name = strtail ((char *)name, MARKER_XATTR_PREFIX);
|
||||
if (!name || name++[0] != '.')
|
||||
return -1;
|
||||
|
||||
name = strtail ((char *)name, uuid);
|
||||
if (!name || strcmp (name, ".xtime") != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Aggregate all the <volid>.xtime attrs of the cluster and send the max*/
|
||||
int32_t
|
||||
cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int op_ret, int op_errno, dict_t *dict)
|
||||
|
||||
{
|
||||
|
||||
int32_t callcnt = 0;
|
||||
int ret = -1;
|
||||
uint32_t *net_timebuf;
|
||||
uint32_t host_timebuf[2];
|
||||
char *marker_xattr;
|
||||
struct marker_str *local;
|
||||
char *vol_uuid;
|
||||
|
||||
if (!this || !frame || !frame->local || !cookie) {
|
||||
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
|
||||
goto out;
|
||||
}
|
||||
|
||||
local = frame->local;
|
||||
if (!local || !local->vol_uuid) {
|
||||
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
|
||||
goto out;
|
||||
}
|
||||
|
||||
vol_uuid = local->vol_uuid;
|
||||
|
||||
if (op_ret && op_errno == ENOENT) {
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --local->call_count;
|
||||
local->enoent_count++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (op_ret && op_errno == ENOTCONN) {
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --local->call_count;
|
||||
local->enotconn_count++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --local->call_count;
|
||||
if (!gf_asprintf (& marker_xattr, "%s.%s.%s",
|
||||
MARKER_XATTR_PREFIX, vol_uuid, XTIME)) {
|
||||
op_errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (dict_get_ptr (dict, marker_xattr, (void **)&net_timebuf)) {
|
||||
gf_log (this->name, GF_LOG_WARNING,
|
||||
"Unable to get <uuid>.xtime attr");
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (local->has_xtime) {
|
||||
|
||||
get_hosttime (net_timebuf, host_timebuf);
|
||||
if ( (host_timebuf[0]>local->host_timebuf[0]) ||
|
||||
(host_timebuf[0] == local->host_timebuf[0] &&
|
||||
host_timebuf[1] >= local->host_timebuf[1])) {
|
||||
|
||||
update_timebuf (net_timebuf, local->net_timebuf);
|
||||
update_timebuf (host_timebuf, local->host_timebuf);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
get_hosttime (net_timebuf, local->host_timebuf);
|
||||
update_timebuf (net_timebuf, local->net_timebuf);
|
||||
local->has_xtime = _gf_true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
done:
|
||||
UNLOCK (&frame->lock);
|
||||
|
||||
if (!callcnt) {
|
||||
|
||||
op_ret = 0;
|
||||
op_errno = 0;
|
||||
if (local->has_xtime) {
|
||||
if (!dict) {
|
||||
dict = dict_new();
|
||||
if (ret) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
op_ret = -1;
|
||||
if (local->enotconn_count) {
|
||||
op_errno = ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
if (local->enoent_count) {
|
||||
op_errno = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
op_errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (local->xl_specf_unwind) {
|
||||
frame->local = local->xl_local;
|
||||
local->xl_specf_unwind (getxattr, frame, op_ret,
|
||||
op_errno, dict);
|
||||
return 0;
|
||||
}
|
||||
STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int32_t
|
||||
cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int op_ret, int op_errno, dict_t *dict)
|
||||
{
|
||||
int32_t callcnt = 0;
|
||||
data_t *data = NULL;
|
||||
struct volume_mark *volmark = NULL;
|
||||
struct marker_str *marker = NULL;
|
||||
char *vol_uuid;
|
||||
|
||||
|
||||
if (!this || !frame || !cookie) {
|
||||
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
|
||||
goto out;
|
||||
}
|
||||
|
||||
marker = frame->local;
|
||||
|
||||
if (!marker) {
|
||||
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
|
||||
goto out;
|
||||
}
|
||||
|
||||
vol_uuid = marker->vol_uuid;
|
||||
|
||||
if (op_ret && (ENOENT == op_errno)) {
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --marker->call_count;
|
||||
marker->enoent_count++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (op_ret && (ENOTCONN == op_errno)) {
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --marker->call_count;
|
||||
marker->enotconn_count++;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(data = dict_get (dict, GF_XATTR_MARKER_KEY))) {
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --marker->call_count;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
volmark = (struct volume_mark *)data->data;
|
||||
|
||||
LOCK (&frame->lock);
|
||||
{
|
||||
callcnt = --marker->call_count;
|
||||
|
||||
if (marker_has_volinfo (marker)) {
|
||||
|
||||
if ((marker->volmark->major != volmark->major) ||
|
||||
(marker->volmark->minor != volmark->minor)) {
|
||||
op_ret = -1;
|
||||
op_errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
else if (volmark->retval) {
|
||||
data_unref ((data_t *) marker->volmark);
|
||||
marker->volmark = volmark;
|
||||
callcnt = 0;
|
||||
}
|
||||
else if ( (volmark->sec > marker->volmark->sec) ||
|
||||
((volmark->sec == marker->volmark->sec)
|
||||
&& (volmark->usec >= marker->volmark->usec))) {
|
||||
|
||||
marker->volmark = volmark;
|
||||
}
|
||||
|
||||
} else {
|
||||
marker->volmark = volmark;
|
||||
uuid_unparse (volmark->uuid, vol_uuid);
|
||||
if (volmark->retval)
|
||||
callcnt = 0;
|
||||
}
|
||||
}
|
||||
done:
|
||||
UNLOCK (&frame->lock);
|
||||
|
||||
if (!callcnt) {
|
||||
op_ret = 0;
|
||||
op_errno = 0;
|
||||
if (marker_has_volinfo (marker)) {
|
||||
if (!dict) {
|
||||
dict = dict_new();
|
||||
if (!dict) {
|
||||
op_ret = -1;
|
||||
op_errno = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (dict_set_static_bin (dict, GF_XATTR_MARKER_KEY,
|
||||
marker->volmark,
|
||||
sizeof (struct volume_mark))) {
|
||||
op_ret = -1;
|
||||
op_errno = ENOMEM;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (marker->enotconn_count) {
|
||||
op_ret = -1;
|
||||
op_errno = ENOTCONN;
|
||||
goto out;
|
||||
}
|
||||
if (marker->enoent_count) {
|
||||
op_ret = -1;
|
||||
op_errno = ENOENT;
|
||||
}
|
||||
else {
|
||||
op_ret = -1;
|
||||
op_errno = EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
if (marker->xl_specf_unwind) {
|
||||
frame->local = marker->xl_local;
|
||||
marker->xl_specf_unwind (getxattr, frame, op_ret,
|
||||
op_errno, dict);
|
||||
return 0;
|
||||
}
|
||||
STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
|
||||
}
|
||||
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,
|
||||
char *vol_uuid)
|
||||
{
|
||||
int i;
|
||||
struct marker_str *local;
|
||||
|
||||
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);
|
||||
|
||||
local->xl_local = xl_local;
|
||||
frame->local = local;
|
||||
|
||||
local->call_count = count;
|
||||
|
||||
local->xl_specf_unwind = xl_specf_getxattr_unwind;
|
||||
|
||||
local->vol_uuid = vol_uuid;
|
||||
|
||||
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);
|
||||
else if (MARKER_XTIME_TYPE == type)
|
||||
STACK_WIND (frame, cluster_markerxtime_cbk,
|
||||
*(sub_volumes + i),
|
||||
(*(sub_volumes + i))->fops->getxattr,
|
||||
loc, name);
|
||||
else {
|
||||
gf_log (this->name, GF_LOG_WARNING,
|
||||
"Unrecognized type of marker attr recived");
|
||||
STACK_WIND (frame, default_getxattr_cbk,
|
||||
*(sub_volumes + i),
|
||||
(*(sub_volumes + i))->fops->getxattr,
|
||||
loc, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return -1;
|
||||
|
||||
}
|
86
xlators/lib/src/libxlator.h
Normal file
86
xlators/lib/src/libxlator.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _LIBXLATOR_H
|
||||
#define _LIBXLATOR_H
|
||||
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "xlator.h"
|
||||
#include "logging.h"
|
||||
#include "defaults.h"
|
||||
#include "common-utils.h"
|
||||
#include "compat.h"
|
||||
#include "compat-errno.h"
|
||||
|
||||
|
||||
#define MARKER_XATTR_PREFIX "trusted.glusterfs"
|
||||
#define XTIME "xtime"
|
||||
#define VOLUME_MARK "volume-mark"
|
||||
#define GF_XATTR_MARKER_KEY MARKER_XATTR_PREFIX "." VOLUME_MARK
|
||||
#define UUID_SIZE 36
|
||||
#define MARKER_UUID_TYPE 1
|
||||
#define MARKER_XTIME_TYPE 2
|
||||
|
||||
|
||||
typedef int32_t (*xlator_specf_unwind_t) (void *getxattr, call_frame_t *frame,
|
||||
int op_ret, int op_errno, dict_t *dict);
|
||||
|
||||
|
||||
struct volume_mark {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t uuid[16];
|
||||
uint8_t retval;
|
||||
uint32_t sec;
|
||||
uint32_t usec;
|
||||
}__attribute__ ((__packed__));
|
||||
|
||||
struct marker_str {
|
||||
struct volume_mark *volmark;
|
||||
data_t *data;
|
||||
|
||||
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;
|
||||
|
||||
xlator_specf_unwind_t xl_specf_unwind;
|
||||
void *xl_local;
|
||||
char *vol_uuid;
|
||||
};
|
||||
|
||||
static inline gf_boolean_t
|
||||
marker_has_volinfo (struct marker_str *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);
|
||||
|
||||
int32_t
|
||||
cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
||||
int op_ret, int op_errno, dict_t *dict);
|
||||
|
||||
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,
|
||||
char *vol_uuid);
|
||||
|
||||
int
|
||||
match_uuid_local (const char *name, char *uuid);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !_LIBXLATOR_H */
|
Loading…
x
Reference in New Issue
Block a user