diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-utils.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 152 | 
1 files changed, 87 insertions, 65 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index feb81d8de80..987615a573d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -735,8 +735,8 @@ glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo)  }  int32_t -glusterd_brickinfo_from_brick (char *brick, -                               glusterd_brickinfo_t **brickinfo) +glusterd_brickinfo_new_from_brick (char *brick, +                                   glusterd_brickinfo_t **brickinfo)  {          int32_t                 ret = -1;          glusterd_brickinfo_t    *new_brickinfo = NULL; @@ -780,11 +780,69 @@ out:          return ret;  } +static gf_boolean_t +_is_prefix (char *str1, char *str2) +{ +        GF_ASSERT (str1); +        GF_ASSERT (str2); + +        int             i = 0; +        int             small_len = 0; +        gf_boolean_t    prefix = _gf_true; + +        small_len = min (strlen (str1), strlen (str2)); +        for (i = 0; i < small_len; i++) { +                if (str1[i] != str2[i]) { +                        prefix = _gf_false; +                        break; +                } + +        } + +        return prefix; +} + +/* Checks if @path is available in the peer identified by @uuid + * 'availability' is determined by querying current state of volumes + * in the cluster. */ +gf_boolean_t +glusterd_is_brickpath_available (uuid_t uuid, char *path) +{ +        glusterd_brickinfo_t    *brickinfo = NULL; +        glusterd_volinfo_t      *volinfo   = NULL; +        glusterd_conf_t         *priv      = NULL; +        gf_boolean_t            available  = _gf_false; +        char                    tmp_path[PATH_MAX+1] = {0}; +        char                    tmp_brickpath[PATH_MAX+1] = {0}; + +        priv = THIS->private; + +        strncpy (tmp_path, path, PATH_MAX); +        /* path may not yet exist */ +        if (!realpath (path, tmp_path) && (errno != ENOENT)) +                goto out; + +        list_for_each_entry (volinfo, &priv->volumes, vol_list) { +                list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                        if (uuid_compare (uuid, brickinfo->uuid)) +                                continue; + +                        if (!realpath (brickinfo->path, tmp_brickpath)) +                                goto out; + +                        if (_is_prefix (tmp_brickpath, tmp_path)) +                                goto out; +                } +        } +        available = _gf_true; +out: +        return available; +} +  int32_t  glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,                                 glusterd_volinfo_t *volinfo, -                               glusterd_brickinfo_t **brickinfo, -                               gf_path_match_t path_match) +                               glusterd_brickinfo_t **brickinfo)  {          glusterd_brickinfo_t    *brickiter = NULL;          uuid_t                  peer_uuid = {0}; @@ -800,34 +858,19 @@ glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,          ret = -1;          list_for_each_entry (brickiter, &volinfo->bricks, brick_list) { -                if (uuid_is_null (brickiter->uuid) && -                    glusterd_resolve_brick (brickiter)) +                if ((uuid_is_null (brickiter->uuid)) && +                    (glusterd_resolve_brick (brickiter) != 0))                          goto out;                  if (uuid_compare (peer_uuid, brickiter->uuid))                          continue; -                if (!strcmp (brickiter->path, path)) { +                if (strcmp (brickiter->path, path) == 0) {                          gf_log (THIS->name, GF_LOG_INFO, "Found brick");                          ret = 0;                          if (brickinfo)                                  *brickinfo = brickiter;                          break;                  } - -                if (path_match != GF_PATH_PARTIAL) -                        continue; - -#ifdef GF_LINUX_HOST_OS -                if (!fnmatch (path, brickiter->path, FNM_LEADING_DIR) || -                    !fnmatch (brickiter->path, path, FNM_LEADING_DIR)) { -                        gf_log (THIS->name, GF_LOG_ERROR, -                                "paths %s and %s are recursive", -                                path, brickiter->path); -                        *brickinfo = brickiter; -                        ret = 0; -                        break; -                } -#endif          }  out: @@ -838,40 +881,23 @@ out:  int32_t  glusterd_volume_brickinfo_get_by_brick (char *brick,                                          glusterd_volinfo_t *volinfo, -                                        glusterd_brickinfo_t **brickinfo, -                                        gf_path_match_t path_match) +                                        glusterd_brickinfo_t **brickinfo)  {          int32_t                 ret = -1; -        char                    *hostname = NULL; -        char                    *path = NULL; -        char                    *tmp_host = NULL; -        char                    *tmp_path = NULL; +        glusterd_brickinfo_t    *tmp_brickinfo = NULL;          GF_ASSERT (brick);          GF_ASSERT (volinfo); -        gf_log ("", GF_LOG_INFO, "brick: %s", brick); - -        tmp_host = gf_strdup (brick); -        if (tmp_host) -                get_host_name (tmp_host, &hostname); -        tmp_path = gf_strdup (brick); -        if (tmp_path) -                get_path_name (tmp_path, &path); - -        if (!hostname || !path) { -                gf_log ("", GF_LOG_ERROR, -                        "brick %s is not of form <HOSTNAME>:<export-dir>", -                        brick); -                ret = -1; +        ret = glusterd_brickinfo_new_from_brick (brick, &tmp_brickinfo); +        if (ret)                  goto out; -        } -        ret = glusterd_volume_brickinfo_get (NULL, hostname, path, volinfo, -                                             brickinfo, path_match); +        ret = glusterd_volume_brickinfo_get (NULL, tmp_brickinfo->hostname, +                                             tmp_brickinfo->path, volinfo, +                                             brickinfo); +        (void) glusterd_brickinfo_delete (tmp_brickinfo);  out: -        GF_FREE (tmp_host); -        GF_FREE (tmp_path);          gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);          return ret;  } @@ -885,7 +911,7 @@ glusterd_is_brick_decommissioned (glusterd_volinfo_t *volinfo, char *hostname,          int                     ret = -1;          ret = glusterd_volume_brickinfo_get (NULL, hostname, path, volinfo, -                                             &brickinfo, GF_PATH_COMPLETE); +                                             &brickinfo);          if (ret)                  goto out;          decommissioned = brickinfo->decommissioned; @@ -2289,7 +2315,7 @@ glusterd_import_volinfo (dict_t *vols, int count,                  if (ret)                          goto out; -                ret = glusterd_brickinfo_from_brick (src_brick, +                ret = glusterd_brickinfo_new_from_brick (src_brick,                                                       &new_volinfo->src_brick);                  if (ret) {                          gf_log ("", GF_LOG_ERROR, "Unable to create" @@ -2304,7 +2330,7 @@ glusterd_import_volinfo (dict_t *vols, int count,                  if (ret)                          goto out; -                ret = glusterd_brickinfo_from_brick (dst_brick, +                ret = glusterd_brickinfo_new_from_brick (dst_brick,                                                       &new_volinfo->dst_brick);                  if (ret) {                          gf_log ("", GF_LOG_ERROR, "Unable to create" @@ -2366,8 +2392,7 @@ glusterd_volinfo_copy_brick_portinfo (glusterd_volinfo_t *new_volinfo,                  ret = glusterd_volume_brickinfo_get (new_brickinfo->uuid,                                                       new_brickinfo->hostname,                                                       new_brickinfo->path, -                                                     old_volinfo, &old_brickinfo, -                                                     GF_PATH_COMPLETE); +                                                     old_volinfo, &old_brickinfo);                  if ((0 == ret) && glusterd_is_brick_started (old_brickinfo)) {                          new_brickinfo->port = old_brickinfo->port;                  } @@ -2393,8 +2418,7 @@ glusterd_volinfo_stop_stale_bricks (glusterd_volinfo_t *new_volinfo,                  ret = glusterd_volume_brickinfo_get (old_brickinfo->uuid,                                                       old_brickinfo->hostname,                                                       old_brickinfo->path, -                                                     new_volinfo, &new_brickinfo, -                                                     GF_PATH_COMPLETE); +                                                     new_volinfo, &new_brickinfo);                  if (ret) {                          ret = glusterd_brick_stop (old_volinfo, old_brickinfo);                          if (ret) @@ -3373,9 +3397,9 @@ glusterd_brickinfo_get (uuid_t uuid, char *hostname, char *path,          list_for_each_entry (volinfo, &priv->volumes, vol_list) {                  ret = glusterd_volume_brickinfo_get (uuid, hostname, path, -                                                     volinfo, brickinfo, -                                                     GF_PATH_COMPLETE); -                if (!ret) +                                                     volinfo, brickinfo); +                if (ret == 0) +                        /*Found*/                          goto out;          }  out: @@ -4250,7 +4274,6 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,                               char *op_errstr, size_t len)  {          glusterd_brickinfo_t    *newbrickinfo = NULL; -        glusterd_brickinfo_t    *tmpbrkinfo = NULL;          int                     ret = -1;          gf_boolean_t            is_allocated = _gf_false;          glusterd_peerinfo_t     *peerinfo = NULL; @@ -4267,7 +4290,7 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,          GF_ASSERT (op_errstr);          if (!brickinfo) { -                ret = glusterd_brickinfo_from_brick (brick, &newbrickinfo); +                ret = glusterd_brickinfo_new_from_brick (brick, &newbrickinfo);                  if (ret)                          goto out;                  is_allocated = _gf_true; @@ -4297,11 +4320,10 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,                  goto out;          }  brick_validation: -        ret = glusterd_brickinfo_get (newbrickinfo->uuid, -                                      newbrickinfo->hostname, -                                      newbrickinfo->path, &tmpbrkinfo); -        if (!ret) { -                snprintf(op_errstr, len, "Brick: %s already in use", +        if (!glusterd_is_brickpath_available (newbrickinfo->uuid, +                                              newbrickinfo->path)) { +                snprintf(op_errstr, len, "Brick: %s not available. Brick may " +                         "be containing or be contained by an existing brick",                           brick);                  gf_log (THIS->name, GF_LOG_ERROR, "%s", op_errstr);                  ret = -1; @@ -4836,7 +4858,7 @@ glusterd_delete_brick (glusterd_volinfo_t* volinfo,          ret = glusterd_volume_brickinfo_get (brickinfo->uuid,                                               brickinfo->hostname,                                               brickinfo->path, volinfo, -                                             NULL, GF_PATH_COMPLETE); +                                             NULL);          GF_ASSERT (0 == ret);  #endif          glusterd_delete_volfile (volinfo, brickinfo);  | 
