diff options
| author | Niels de Vos <ndevos@redhat.com> | 2017-02-27 18:45:16 -0800 | 
|---|---|---|
| committer | Shyamsundar Ranganathan <srangana@redhat.com> | 2017-04-26 01:18:56 +0000 | 
| commit | 1538c98f5e33e0794830d5153f17a96ff28c9914 (patch) | |
| tree | e72011f97e32840903e6d88ea8b3025a375870d2 /libglusterfs/src/graph.c | |
| parent | 0451909e0533d357a45dd427226028e095240dac (diff) | |
libglusterfs: accept random volname in glusterfs_graph_prepare()
When the call to glfs_new("volname") passes a name for the volume and it
does not match the name of the subvolume in the graph, glfs_init() will
fail. This is easily reproducible by a gfapi program that loads the
volume from a .vol file, and not from a GlusterD server.
Change-Id: I33e77fbee7d12eaefe7c384fad6aecfa3582ea5a
BUG: 1425623
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: https://review.gluster.org/16796
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Reviewed-by: Prashanth Pai <ppai@redhat.com>
Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com>
Diffstat (limited to 'libglusterfs/src/graph.c')
| -rw-r--r-- | libglusterfs/src/graph.c | 79 | 
1 files changed, 52 insertions, 27 deletions
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c index 916942c3a2d..1edcf20eda6 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -407,25 +407,27 @@ fill_uuid (char *uuid, int size)  } -int -glusterfs_graph_settop (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx, -                        char *volume_name) +static int +glusterfs_graph_settop (glusterfs_graph_t *graph, char *volume_name, +                        gf_boolean_t exact_match)  { +        int         ret  = -1;          xlator_t   *trav = NULL; -        if (!volume_name) { +        if (!volume_name || !exact_match) {                  graph->top = graph->first; -                return 0; -        } - -        for (trav = graph->first; trav; trav = trav->next) { -                if (strcmp (trav->name, volume_name) == 0) { -                        graph->top = trav; -                        return 0; +                ret = 0; +        } else { +                for (trav = graph->first; trav; trav = trav->next) { +                        if (strcmp (trav->name, volume_name) == 0) { +                                graph->top = trav; +                                ret = 0; +                                break; +                        }                  }          } -        return -1; +        return ret;  } @@ -462,19 +464,32 @@ glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,          /* XXX: CHECKSUM */          /* XXX: attach to -n volname */ -        ret = glusterfs_graph_settop (graph, ctx, volume_name); -        if (ret) { -                char *slash = rindex (volume_name, '/'); -                if (slash) { -                        ret = glusterfs_graph_settop (graph, ctx, slash + 1); -                        if (!ret) { -                                goto ok; -                        } -                } -                gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR, -                        "glusterfs graph settop failed"); -                return -1; +        /* A '/' in the volume name suggests brick multiplexing is used, find +         * the top of the (sub)graph. The volname MUST match the subvol in this +         * case. In other cases (like for gfapi) the default top for the +         * (sub)graph is ok. */ +        if (!volume_name) { +                /* GlusterD does not pass a volume_name */ +                ret = glusterfs_graph_settop (graph, volume_name, _gf_false); +        } else if (strncmp (volume_name, "/snaps/", 7) == 0) { +                /* snap shots have their top xlator named like "/snaps/..."  */ +                ret = glusterfs_graph_settop (graph, volume_name, +                                              _gf_false); +        } else if (volume_name[0] == '/') { +                /* brick multiplexing passes the brick path */ +                ret = glusterfs_graph_settop (graph, volume_name, +                                              _gf_true); +        } else { +                ret = glusterfs_graph_settop (graph, volume_name, +                                              _gf_false);          } +        if (!ret) { +                goto ok; +        } + +        gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR, +                "glusterfs graph settop failed"); +        return -1;  ok:          /* XXX: WORM VOLUME */ @@ -1085,9 +1100,19 @@ glusterfs_graph_attach (glusterfs_graph_t *orig_graph, char *path)          }          /* TBD: memory leaks everywhere */ -        glusterfs_graph_prepare (graph, this->ctx, xl->name); -        glusterfs_graph_init (graph); -        glusterfs_xlator_link (orig_graph->top, graph->top); +        if (glusterfs_graph_prepare (graph, this->ctx, xl->name)) { +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to prepare graph for xlator %s", xl->name); +                return -EIO; +        } else if (glusterfs_graph_init (graph)) { +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to initialize graph for xlator %s", xl->name); +                return -EIO; +        } else if (glusterfs_xlator_link (orig_graph->top, graph->top)) { +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to link the graphs for xlator %s ", xl->name); +                return -EIO; +        }          return 0;  }  | 
