diff options
author | Venky Shankar <vshankar@redhat.com> | 2012-02-21 14:23:13 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2012-02-22 23:19:44 -0800 |
commit | 5842656feba99a239b922f8099fb336c66b61929 (patch) | |
tree | 449394308a3db029e73ab4e907ca10b57278b02f | |
parent | 7820f7563aff8e1a5e73eb75adc387635a301b6e (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.h | 7 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-read.c | 139 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 2 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 121 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 5 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 166 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe.h | 5 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 7 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 121 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.h | 3 |
10 files changed, 395 insertions, 181 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index 75476cef801..0ab5767980f 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 499804e6a36..c4619270207 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 8abc4358352..f0cb32c12b1 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 377f44b955a..0d0df320d72 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 798d5b6d949..3d215ab2546 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 62a28d71f52..c44bac57525 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 e78583996d2..580920a1b30 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 f122acbf6ce..e925c75a26a 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 deaf2e772ef..1b4d1a335c0 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 c72adac9e45..c551ffc1abd 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) |