summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenky Shankar <vshankar@redhat.com>2012-02-21 14:23:13 +0530
committerVijay Bellur <vijay@gluster.com>2012-02-22 23:19:44 -0800
commit5842656feba99a239b922f8099fb336c66b61929 (patch)
tree449394308a3db029e73ab4e907ca10b57278b02f
parent7820f7563aff8e1a5e73eb75adc387635a301b6e (diff)
Introduce new extended attribute: node-uuid
Request for trusted.glusterfs.node-uuid returns pathinfo like string but containing the UUID of glusterd instead of the backend path for the requested file. This info is benificial for tasks like parallel rebalance that will make use of the UUID for data locality. Change-Id: I766a09cc4a5f63aebd11c73107924a1b29242dcf BUG: 772610 Signed-off-by: Venky Shankar <vshankar@redhat.com> Reviewed-on: http://review.gluster.com/2614 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Shishir Gowda <shishirng@gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--libglusterfs/src/glusterfs.h7
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c139
-rw-r--r--xlators/cluster/afr/src/afr.h2
-rw-r--r--xlators/cluster/dht/src/dht-common.c121
-rw-r--r--xlators/cluster/dht/src/dht-common.h5
-rw-r--r--xlators/cluster/stripe/src/stripe.c166
-rw-r--r--xlators/cluster/stripe/src/stripe.h5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c7
-rw-r--r--xlators/storage/posix/src/posix.c121
-rw-r--r--xlators/storage/posix/src/posix.h3
10 files changed, 395 insertions, 181 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 75476cef8..0ab576798 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -81,6 +81,13 @@
#define GF_XATTR_CLRLK_CMD "glusterfs.clrlk"
#define GF_XATTR_PATHINFO_KEY "trusted.glusterfs.pathinfo"
+#define GF_XATTR_NODE_UUID_KEY "trusted.glusterfs.node-uuid"
+
+#define XATTR_IS_PATHINFO(x) (strncmp (x, GF_XATTR_PATHINFO_KEY, \
+ strlen (GF_XATTR_PATHINFO_KEY)) == 0)
+#define XATTR_IS_NODE_UUID(x) (strncmp (x, GF_XATTR_NODE_UUID_KEY, \
+ strlen (GF_XATTR_NODE_UUID_KEY)) == 0)
+
#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
#define GFID_XATTR_KEY "trusted.gfid"
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index 499804e6a..c46192702 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -726,24 +726,73 @@ unlock:
return ret;
}
+/**
+ * node-uuid cbk uses next child querying mechanism
+ */
+int32_t
+afr_getxattr_node_uuid_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ xlator_t **children = NULL;
+ int unwind = 1;
+ int curr_call_child = 0;
+
+ priv = this->private;
+ children = priv->children;
+
+ local = frame->local;
+
+ if (op_ret == -1) { /** query the _next_ child */
+
+ /**
+ * _current_ becomes _next_
+ * If done with all childs and yet no success; give up !
+ */
+ curr_call_child = (int) ((long)cookie);
+ if (++curr_call_child == priv->child_count)
+ goto unwind;
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "op_ret (-1): Re-querying afr-child (%d/%d)",
+ curr_call_child, priv->child_count);
+
+ unwind = 0;
+ STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
+ (void *) (long) curr_call_child,
+ children[curr_call_child],
+ children[curr_call_child]->fops->getxattr,
+ &local->loc,
+ local->cont.getxattr.name);
+ }
+
+ unwind:
+ if (unwind)
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+
+ return 0;
+}
+
int32_t
afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
dict_t *dict)
{
- afr_local_t *local = NULL;
- int32_t callcnt = 0;
- int ret = 0;
- char *pathinfo = NULL;
- char *pathinfo_serz = NULL;
- char pathinfo_cky[1024] = {0,};
- dict_t *xattr = NULL;
- long cky = 0;
- int32_t padding = 0;
- int32_t tlen = 0;
+ afr_local_t *local = NULL;
+ int32_t callcnt = 0;
+ int ret = 0;
+ char *xattr = NULL;
+ char *xattr_serz = NULL;
+ char xattr_cky[1024] = {0,};
+ dict_t *nxattr = NULL;
+ long cky = 0;
+ int32_t padding = 0;
+ int32_t tlen = 0;
if (!frame || !frame->local || !this) {
- gf_log (this->name, GF_LOG_ERROR, "possible NULL deref");
+ gf_log ("", GF_LOG_ERROR, "possible NULL deref");
goto out;
}
@@ -761,70 +810,80 @@ afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
local->dict = dict_new ();
if (local->dict) {
- ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo);
+ ret = dict_get_str (dict,
+ local->cont.getxattr.name,
+ &xattr);
if (ret)
goto out;
- pathinfo = gf_strdup (pathinfo);
+ xattr = gf_strdup (xattr);
- snprintf (pathinfo_cky, 1024, "%s-%ld", GF_XATTR_PATHINFO_KEY, cky);
- ret = dict_set_dynstr (local->dict, pathinfo_cky, pathinfo);
+ (void)snprintf (xattr_cky, 1024, "%s-%ld",
+ local->cont.getxattr.name, cky);
+ ret = dict_set_dynstr (local->dict,
+ xattr_cky, xattr);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo cookie key");
+ gf_log (this->name, GF_LOG_ERROR,
+ "Cannot set xattr cookie key");
goto out;
}
- local->cont.getxattr.pathinfo_len += strlen (pathinfo) + 1;
+ local->cont.getxattr.xattr_len += strlen (xattr) + 1;
}
}
out:
UNLOCK (&frame->lock);
if (!callcnt) {
- if (!local->cont.getxattr.pathinfo_len)
+ if (!local->cont.getxattr.xattr_len)
goto unwind;
- xattr = dict_new ();
- if (!xattr)
+ nxattr = dict_new ();
+ if (!nxattr)
goto unwind;
/* extra bytes for decorations (brackets and <>'s) */
- padding = strlen (this->name) + strlen (AFR_PATHINFO_HEADER) + 4;
- local->cont.getxattr.pathinfo_len += (padding + 2);
+ padding += strlen (this->name) + strlen (AFR_PATHINFO_HEADER) + 4;
+ local->cont.getxattr.xattr_len += (padding + 2);
- pathinfo_serz = GF_CALLOC (local->cont.getxattr.pathinfo_len, sizeof (char),
- gf_common_mt_char);
+ xattr_serz = GF_CALLOC (local->cont.getxattr.xattr_len,
+ sizeof (char), gf_common_mt_char);
- if (!pathinfo_serz)
+ if (!xattr_serz)
goto unwind;
/* the xlator info */
- sprintf (pathinfo_serz, "(<"AFR_PATHINFO_HEADER"%s> ", this->name);
+ (void) sprintf (xattr_serz, "(<"AFR_PATHINFO_HEADER"%s> ",
+ this->name);
/* actual series of pathinfo */
- ret = dict_serialize_value_with_delim (local->dict, pathinfo_serz + strlen (pathinfo_serz),
+ ret = dict_serialize_value_with_delim (local->dict,
+ xattr_serz + strlen (xattr_serz),
&tlen, ' ');
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Error serializing dictionary");
+ gf_log (this->name, GF_LOG_ERROR, "Error serializing"
+ " dictionary");
goto unwind;
}
/* closing part */
- *(pathinfo_serz + padding + tlen) = ')';
- *(pathinfo_serz + padding + tlen + 1) = '\0';
+ *(xattr_serz + padding + tlen) = ')';
+ *(xattr_serz + padding + tlen + 1) = '\0';
- ret = dict_set_dynstr (xattr, GF_XATTR_PATHINFO_KEY, pathinfo_serz);
+ ret = dict_set_dynstr (nxattr, local->cont.getxattr.name,
+ xattr_serz);
if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo key in dict");
+ gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo"
+ " key in dict");
unwind:
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, nxattr);
if (local->dict)
dict_unref (local->dict);
- if (xattr)
- dict_unref (xattr);
+ if (nxattr)
+ dict_unref (nxattr);
}
return ret;
@@ -964,6 +1023,16 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
return 0;
}
+ if (XATTR_IS_NODE_UUID (name)) {
+ i = 0;
+ STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
+ (void *) (long) i,
+ children[i],
+ children[i]->fops->getxattr,
+ loc, name);
+ return 0;
+ }
+
if (*priv->vol_uuid) {
if ((match_uuid_local (name, priv->vol_uuid) == 0)
&& (-1 == frame->root->pid)) {
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 8abc43583..f0cb32c12 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -480,7 +480,7 @@ typedef struct _afr_local {
struct {
char *name;
int last_index;
- long pathinfo_len;
+ long xattr_len;
} getxattr;
struct {
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 377f44b95..0d0df320d 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -1629,8 +1629,27 @@ fill_layout_info (dht_layout_t *layout, char *buf)
}
}
+void
+dht_fill_pathinfo_xattr (xlator_t *this, dht_local_t *local,
+ char *xattr_buf, int32_t alloc_len,
+ int flag, char *layout_buf)
+{
+ if (flag && local->xattr_val)
+ snprintf (xattr_buf, alloc_len,
+ "((<"DHT_PATHINFO_HEADER"%s> %s) (%s-layout %s))",
+ this->name, local->xattr_val, this->name,
+ layout_buf);
+ else if (local->xattr_val)
+ snprintf (xattr_buf, alloc_len,
+ "(<"DHT_PATHINFO_HEADER"%s> %s)",
+ this->name, local->xattr_val);
+ else if (flag)
+ snprintf (xattr_buf, alloc_len, "(%s-layout %s)",
+ this->name, layout_buf);
+}
+
int
-dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+dht_vgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, dict_t *xattr)
{
dht_local_t *local = NULL;
@@ -1647,31 +1666,36 @@ dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
if (op_ret != -1) {
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value_got);
+ ret = dict_get_str (xattr, local->xsel, &value_got);
if (!ret) {
alloc_len = strlen (value_got);
/**
- * allocate the buffer:- we allocate 10 bytes extra in case we need to
- * append ' Link: ' in the buffer for another STACK_WIND
+ * allocate the buffer:- we allocate 10 bytes extra in
+ * case we need to append ' Link: ' in the buffer for
+ * another STACK_WIND
*/
- if (!local->pathinfo) {
+ if (!local->xattr_val) {
alloc_len += (strlen (DHT_PATHINFO_HEADER) + 10);
- local->pathinfo = GF_CALLOC (alloc_len, sizeof (char), gf_common_mt_char);
+ local->xattr_val =
+ GF_CALLOC (alloc_len,
+ sizeof (char),
+ gf_common_mt_char);
}
- if (local->pathinfo) {
- plen = strlen (local->pathinfo);
+ if (local->xattr_val) {
+ plen = strlen (local->xattr_val);
if (plen) {
/* extra byte(s) for \0 to be safe */
alloc_len += (plen + 2);
- local->pathinfo = GF_REALLOC (local->pathinfo,
- alloc_len);
- if (!local->pathinfo)
+ local->xattr_val =
+ GF_REALLOC (local->xattr_val,
+ alloc_len);
+ if (!local->xattr_val)
goto out;
}
- strcat (local->pathinfo, value_got);
+ strcat (local->xattr_val, value_got);
}
}
}
@@ -1687,26 +1711,28 @@ dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dict = dict_new ();
- /* we would need max-to-max this many bytes to create pathinfo string */
- alloc_len += (2 * strlen (this->name)) + strlen (layout_buf) + 40;
- xattr_buf = GF_CALLOC (alloc_len, sizeof (char), gf_common_mt_char);
-
- if (flag && local->pathinfo)
- snprintf (xattr_buf, alloc_len, "((<"DHT_PATHINFO_HEADER"%s> %s) (%s-layout %s))",
- this->name, local->pathinfo, this->name,
- layout_buf);
- else if (local->pathinfo)
- snprintf (xattr_buf, alloc_len, "(<"DHT_PATHINFO_HEADER"%s> %s)",
- this->name, local->pathinfo);
- else if (flag)
- snprintf (xattr_buf, alloc_len, "(%s-layout %s)",
- this->name, layout_buf);
+ /* we would need max this many bytes to create xattr string */
+ alloc_len += (2 * strlen (this->name))
+ + strlen (layout_buf)
+ + 40;
+ xattr_buf = GF_CALLOC (alloc_len,
+ sizeof (char), gf_common_mt_char);
+
+ if (XATTR_IS_PATHINFO (local->xsel)) {
+ (void) dht_fill_pathinfo_xattr (this, local, xattr_buf,
+ alloc_len, flag,
+ layout_buf);
+ } else if (XATTR_IS_NODE_UUID (local->xsel)) {
+ (void) snprintf (xattr_buf, alloc_len, "%s",
+ local->xattr_val);
+ } else
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown local->xsel (%s)", local->xsel);
- ret = dict_set_dynstr (dict, GF_XATTR_PATHINFO_KEY,
- xattr_buf);
+ ret = dict_set_dynstr (dict, local->xsel, xattr_buf);
- if (local->pathinfo)
- GF_FREE (local->pathinfo);
+ if (local->xattr_val)
+ GF_FREE (local->xattr_val);
DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
@@ -1716,19 +1742,24 @@ dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
- if (local->pathinfo)
- strcat (local->pathinfo, " Link: ");
+ /**
+ * XXX: We will never reach here as call_cnt will always be 1.
+ * But code is kept untouched as we may need it when hashed_subvol
+ * bug is fixed.
+ */
+ if (local->xattr_val)
+ strcat (local->xattr_val, " Link: ");
if (local->hashed_subvol) {
/* This will happen if there pending */
- STACK_WIND (frame, dht_pathinfo_getxattr_cbk, local->hashed_subvol,
+ STACK_WIND (frame, dht_vgetxattr_cbk, local->hashed_subvol,
local->hashed_subvol->fops->getxattr,
&local->loc, local->key);
return 0;
}
- gf_log ("this->name", GF_LOG_ERROR, "Unable to find hashed_subvol for path"
- " %s", local->pathinfo);
+ gf_log ("this->name", GF_LOG_ERROR, "Unable to find hashed_subvol"
+ " for path %s", local->xattr_val);
DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, dict);
return 0;
@@ -1852,25 +1883,13 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
}
}
- if (key && (strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)) {
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get hashed_subvol for %s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
+ if (key && ((strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)
+ || strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0)) {
cached_subvol = local->cached_subvol;
+ (void) strncpy (local->xsel, key, 256);
local->call_cnt = 1;
- if (hashed_subvol != cached_subvol) {
- local->call_cnt = 2;
- local->hashed_subvol = hashed_subvol;
- }
-
- STACK_WIND (frame, dht_pathinfo_getxattr_cbk, cached_subvol,
+ STACK_WIND (frame, dht_vgetxattr_cbk, cached_subvol,
cached_subvol->fops->getxattr, loc, key);
return 0;
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index 798d5b6d9..3d215ab25 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -144,9 +144,12 @@ struct dht_local {
dev_t rdev;
/* need for file-info */
- char *pathinfo;
+ char *xattr_val;
char *key;
+ /* which xattr request? */
+ char xsel[256];
+
char *newpath;
/* gfid related */
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c
index 62a28d71f..c44bac575 100644
--- a/xlators/cluster/stripe/src/stripe.c
+++ b/xlators/cluster/stripe/src/stripe.c
@@ -4567,7 +4567,7 @@ out:
}
int32_t
-stripe_pathinfo_aggregate (char *buffer, stripe_local_t *local, int32_t *total)
+stripe_xattr_aggregate (char *buffer, stripe_local_t *local, int32_t *total)
{
int32_t i = 0;
int32_t ret = -1;
@@ -4582,10 +4582,10 @@ stripe_pathinfo_aggregate (char *buffer, stripe_local_t *local, int32_t *total)
for (i = 0; i < local->nallocs; i++) {
xattr = local->xattr_list + i;
- len = xattr->pathinfo_len;
+ len = xattr->xattr_len;
- if (len && xattr && xattr->pathinfo) {
- memcpy (buffer, xattr->pathinfo, len);
+ if (len && xattr && xattr->xattr_value) {
+ memcpy (buffer, xattr->xattr_value, len);
buffer += len;
*buffer++ = ' ';
}
@@ -4601,7 +4601,7 @@ stripe_pathinfo_aggregate (char *buffer, stripe_local_t *local, int32_t *total)
}
int32_t
-stripe_free_pathinfo_str (stripe_local_t *local)
+stripe_free_xattr_str (stripe_local_t *local)
{
int32_t i = 0;
int32_t ret = -1;
@@ -4613,8 +4613,8 @@ stripe_free_pathinfo_str (stripe_local_t *local)
for (i = 0; i < local->nallocs; i++) {
xattr = local->xattr_list + i;
- if (xattr && xattr->pathinfo)
- GF_FREE (xattr->pathinfo);
+ if (xattr && xattr->xattr_value)
+ GF_FREE (xattr->xattr_value);
}
ret = 0;
@@ -4623,18 +4623,64 @@ stripe_free_pathinfo_str (stripe_local_t *local)
}
int32_t
-stripe_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
+stripe_fill_pathinfo_xattr (xlator_t *this, stripe_local_t *local,
+ char **xattr_serz)
+{
+ int ret = -1;
+ int32_t padding = 0;
+ int32_t tlen = 0;
+ char stripe_size_str[20] = {0,};
+ char *pathinfo_serz = NULL;
+
+ if (!local) {
+ gf_log (this->name, GF_LOG_ERROR, "Possible NULL deref");
+ goto out;
+ }
+
+ (void) snprintf (stripe_size_str, 20, "%ld",
+ (local->fctx) ? local->fctx->stripe_size : 0);
+
+ /* extra bytes for decorations (brackets and <>'s) */
+ padding = strlen (this->name) + strlen (STRIPE_PATHINFO_HEADER)
+ + strlen (stripe_size_str) + 7;
+ local->xattr_total_len += (padding + 2);
+
+ pathinfo_serz = GF_CALLOC (local->xattr_total_len, sizeof (char),
+ gf_common_mt_char);
+ if (!pathinfo_serz)
+ goto out;
+
+ /* xlator info */
+ (void) sprintf (pathinfo_serz, "(<"STRIPE_PATHINFO_HEADER"%s:[%s]> ",
+ this->name, stripe_size_str);
+
+ ret = stripe_xattr_aggregate (pathinfo_serz + padding, local, &tlen);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Cannot aggregate pathinfo list");
+ goto out;
+ }
+
+ *(pathinfo_serz + padding + tlen) = ')';
+ *(pathinfo_serz + padding + tlen + 1) = '\0';
+
+ *xattr_serz = pathinfo_serz;
+
+ ret = 0;
+ out:
+ return ret;
+}
+
+int32_t
+stripe_vgetxattr_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
dict_t *dict) {
stripe_local_t *local = NULL;
int32_t callcnt = 0;
int32_t ret = -1;
long cky = 0;
- char *pathinfo = NULL;
- char *pathinfo_serz = NULL;
- int32_t padding = 0;
- int32_t tlen = 0;
- char stripe_size_str[20] = {0,};
+ char *xattr_val = NULL;
+ char *xattr_serz = NULL;
stripe_xattr_sort_t *xattr = NULL;
dict_t *stripe_xattr = NULL;
@@ -4646,6 +4692,11 @@ stripe_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
local = frame->local;
cky = (long) cookie;
+ if (!local->xsel) {
+ gf_log (this->name, GF_LOG_ERROR, "Empty xattr in cbk");
+ return ret;
+ }
+
LOCK (&frame->lock);
{
callcnt = --local->wind_count;
@@ -4654,23 +4705,24 @@ stripe_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
goto out;
if (!local->xattr_list)
- local->xattr_list = (stripe_xattr_sort_t *) GF_CALLOC (local->nallocs,
- sizeof (stripe_xattr_sort_t),
- gf_stripe_mt_xattr_sort_t);
+ local->xattr_list = (stripe_xattr_sort_t *)
+ GF_CALLOC (local->nallocs,
+ sizeof (stripe_xattr_sort_t),
+ gf_stripe_mt_xattr_sort_t);
if (local->xattr_list) {
- ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo);
+ ret = dict_get_str (dict, local->xsel, &xattr_val);
if (ret)
goto out;
xattr = local->xattr_list + (int32_t) cky;
- pathinfo = gf_strdup (pathinfo);
+ xattr_val = gf_strdup (xattr_val);
xattr->pos = cky;
- xattr->pathinfo = pathinfo;
- xattr->pathinfo_len = strlen (pathinfo);
+ xattr->xattr_value = xattr_val;
+ xattr->xattr_len = strlen (xattr_val);
- local->xattr_total_len += strlen (pathinfo) + 1;
+ local->xattr_total_len += xattr->xattr_len + 1;
}
}
out:
@@ -4684,38 +4736,29 @@ stripe_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
if (!stripe_xattr)
goto unwind;
- snprintf (stripe_size_str, 20, "%ld", local->stripe_size);
-
- /* extra bytes for decorations (brackets and <>'s) */
- padding = strlen (this->name) + strlen (STRIPE_PATHINFO_HEADER)
- + strlen (stripe_size_str) + 7;
- local->xattr_total_len += (padding + 2);
-
- pathinfo_serz = GF_CALLOC (local->xattr_total_len, sizeof (char),
- gf_common_mt_char);
- if (!pathinfo_serz)
- goto unwind;
-
- /* xlator info */
- sprintf (pathinfo_serz, "(<"STRIPE_PATHINFO_HEADER"%s:[%s]> ", this->name, stripe_size_str);
-
- ret = stripe_pathinfo_aggregate (pathinfo_serz + padding, local, &tlen);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Cannot aggregate pathinfo list");
+ /* select filler based on ->xsel */
+ if (XATTR_IS_PATHINFO (local->xsel))
+ ret = stripe_fill_pathinfo_xattr (this, local,
+ &xattr_serz);
+ else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown xattr in xattr request");
goto unwind;
}
- *(pathinfo_serz + padding + tlen) = ')';
- *(pathinfo_serz + padding + tlen + 1) = '\0';
-
- ret = dict_set_dynstr (stripe_xattr, GF_XATTR_PATHINFO_KEY, pathinfo_serz);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo key in dict");
+ if (!ret) {
+ ret = dict_set_dynstr (stripe_xattr, local->xsel,
+ xattr_serz);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "Can't set %s key in dict", local->xsel);
+ }
unwind:
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, stripe_xattr);
+ STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno,
+ stripe_xattr);
- ret = stripe_free_pathinfo_str (local);
+ ret = stripe_free_xattr_str (local);
if (local->xattr_list)
GF_FREE (local->xattr_list);
@@ -4797,19 +4840,30 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
return 0;
}
- if (name && (strncmp (name, GF_XATTR_PATHINFO_KEY,
- strlen (GF_XATTR_PATHINFO_KEY)) == 0)) {
- ret = inode_ctx_get (loc->inode, this,
- (uint64_t *) &local->stripe_size);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "stripe size unavailable from inode ctx - relying"
- " on pathinfo could lead to wrong results");
+ if (name &&
+ ((strncmp (name, GF_XATTR_PATHINFO_KEY,
+ strlen (GF_XATTR_PATHINFO_KEY)) == 0))) {
+ if (IA_ISREG (loc->inode->ia_type)) {
+ ret = inode_ctx_get (loc->inode, this,
+ (uint64_t *) &local->fctx);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "stripe size unavailable from fctx"
+ " relying on pathinfo could lead to"
+ " wrong results");
+ }
+
local->nallocs = local->wind_count = priv->child_count;
+ (void) strncpy (local->xsel, name, strlen (name));
+ /**
+ * for xattrs that need info from all childs, fill ->xsel
+ * as above and call the filler function in cbk based on
+ * it
+ */
for (i = 0, trav = this->children; i < priv->child_count; i++,
trav = trav->next) {
- STACK_WIND_COOKIE (frame, stripe_getxattr_pathinfo_cbk,
+ STACK_WIND_COOKIE (frame, stripe_vgetxattr_cbk,
(void *) (long) i, trav->xlator,
trav->xlator->fops->getxattr,
loc, name);
diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h
index e78583996..580920a1b 100644
--- a/xlators/cluster/stripe/src/stripe.h
+++ b/xlators/cluster/stripe/src/stripe.h
@@ -66,8 +66,8 @@
typedef struct stripe_xattr_sort {
int32_t pos;
- int32_t pathinfo_len;
- char *pathinfo;
+ int32_t xattr_len;
+ char *xattr_value;
} stripe_xattr_sort_t;
/**
@@ -178,6 +178,7 @@ struct stripe_local {
stripe_xattr_sort_t *xattr_list;
int32_t xattr_total_len;
int32_t nallocs;
+ char xsel[256];
struct marker_str marker;
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index f122acbf6..e925c75a2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1106,6 +1106,7 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
FILE *file = NULL;
gf_boolean_t is_locked = _gf_false;
char socketpath[PATH_MAX] = {0};
+ char glusterd_uuid[1024] = {0,};
#ifdef DEBUG
char valgrind_logfile[PATH_MAX] = {0};
#endif
@@ -1208,11 +1209,15 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
}
#endif
+ (void) snprintf (glusterd_uuid, 1024, "*-posix.glusterd-uuid=%s",
+ uuid_utoa (priv->uuid));
runner_add_args (&runner, SBIN_DIR"/glusterfsd",
"-s", "localhost", "--volfile-id", volfile,
"-p", pidfile, "-S", socketpath,
"--brick-name", brickinfo->path,
- "-l", brickinfo->logfile, NULL);
+ "-l", brickinfo->logfile,
+ "--xlator-option", glusterd_uuid,
+ NULL);
runner_add_arg (&runner, "--brick-port");
if (volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) {
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index deaf2e772..1b4d1a335 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -2379,21 +2379,23 @@ int32_t
posix_getxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, const char *name)
{
- struct posix_private *priv = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t list_offset = 0;
- size_t size = 0;
- size_t remaining_size = 0;
- char key[4096] = {0,};
- char host_buf[1024] = {0,};
- char * value = NULL;
- char * list = NULL;
- char * real_path = NULL;
- dict_t * dict = NULL;
- char * file_contents = NULL;
- int ret = -1;
- char * path = NULL;
+ struct posix_private *priv = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int32_t list_offset = 0;
+ size_t size = 0;
+ size_t remaining_size = 0;
+ char key[4096] = {0,};
+ char host_buf[1024] = {0,};
+ char *value = NULL;
+ char *list = NULL;
+ char *real_path = NULL;
+ dict_t *dict = NULL;
+ char *file_contents = NULL;
+ int ret = -1;
+ char *path = NULL;
+ char *rpath = NULL;
+ char *dyn_rpath = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -2444,15 +2446,50 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,
}
if (loc->inode && name &&
(strcmp (name, GF_XATTR_PATHINFO_KEY) == 0)) {
- snprintf (host_buf, 1024, "<POSIX:%s:%s>", priv->hostname,
- real_path);
- size = strlen (host_buf) + 1;
- ret = dict_set_str (dict, GF_XATTR_PATHINFO_KEY,
- host_buf);
+ if (LOC_HAS_ABSPATH (loc))
+ MAKE_REAL_PATH (rpath, this, loc->path);
+ else
+ rpath = real_path;
+
+ (void) snprintf (host_buf, 1024, "<POSIX(%s):%s:%s>",
+ priv->base_path, priv->hostname, rpath);
+
+ dyn_rpath = gf_strdup (host_buf);
+ if (!dyn_rpath) {
+ ret = -1;
+ goto done;
+ }
+ size = strlen (dyn_rpath) + 1;
+ ret = dict_set_dynstr (dict, GF_XATTR_PATHINFO_KEY,
+ dyn_rpath);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"could not set value (%s) in dictionary",
- host_buf);
+ dyn_rpath);
+ }
+
+ goto done;
+ }
+
+ if (loc->inode && name &&
+ (strcmp (name, GF_XATTR_NODE_UUID_KEY) == 0)
+ && !uuid_is_null (priv->glusterd_uuid)) {
+ (void) snprintf (host_buf, 1024, "<%s>",
+ uuid_utoa (priv->glusterd_uuid));
+
+ dyn_rpath = gf_strdup (host_buf);
+ if (!dyn_rpath) {
+ ret = -1;
+ goto done;
+ }
+
+ size = strlen (dyn_rpath) + 1;
+ ret = dict_set_dynstr (dict, GF_XATTR_NODE_UUID_KEY,
+ dyn_rpath);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "could not set value (%s) in dictionary",
+ dyn_rpath);
}
goto done;
}
@@ -3762,19 +3799,20 @@ mem_acct_init (xlator_t *this)
int
init (xlator_t *this)
{
- struct posix_private *_private = NULL;
- data_t *dir_data = NULL;
- data_t *tmp_data = NULL;
- struct stat buf = {0,};
- gf_boolean_t tmp_bool = 0;
- int dict_ret = 0;
- int ret = 0;
- int op_ret = -1;
- int32_t janitor_sleep = 0;
- uuid_t old_uuid = {0,};
- uuid_t dict_uuid = {0,};
- uuid_t gfid = {0,};
- uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+ struct posix_private *_private = NULL;
+ data_t *dir_data = NULL;
+ data_t *tmp_data = NULL;
+ struct stat buf = {0,};
+ gf_boolean_t tmp_bool = 0;
+ int dict_ret = 0;
+ int ret = 0;
+ int op_ret = -1;
+ int32_t janitor_sleep = 0;
+ uuid_t old_uuid = {0,};
+ uuid_t dict_uuid = {0,};
+ uuid_t gfid = {0,};
+ uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+ char *guuid = NULL;
dir_data = dict_get (this->options, "directory");
@@ -4022,6 +4060,19 @@ init (xlator_t *this)
"for every open)");
}
+ ret = dict_get_str (this->options, "glusterd-uuid", &guuid);
+ if (!ret) {
+ if (uuid_parse (guuid, _private->glusterd_uuid))
+ gf_log (this->name, GF_LOG_WARNING, "Cannot parse "
+ "glusterd (node) UUID, node-uuid xattr "
+ "request would return - \"No such attribute\"");
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG, "No glusterd (node) UUID "
+ "passed - node-uuid xattr request will return "
+ "\"No such attribute\"");
+ }
+ ret = 0;
+
_private->janitor_sleep_duration = 600;
dict_ret = dict_get_int32 (this->options, "janitor-sleep-duration",
@@ -4175,5 +4226,7 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_INT },
{ .key = {"volume-id"},
.type = GF_OPTION_TYPE_ANY },
+ { .key = {"glusterd-uuid"},
+ .type = GF_OPTION_TYPE_STR },
{ .key = {NULL} }
};
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index c72adac9e..c551ffc1a 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -122,6 +122,9 @@ struct posix_private {
struct stat handledir;
+/* uuid of glusterd that swapned the brick process */
+ uuid_t glusterd_uuid;
+
};
#define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)