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)  | 
