<div dir="ltr">Applied,<div>Thanks.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jun 30, 2014 at 7:13 AM, Benjamin Marzinski <span dir="ltr"><<a href="mailto:bmarzins@redhat.com" target="_blank">bmarzins@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Multipathd was only orphaning paths that it removed, not ones that were<br>
removed by the multipath command.  This could cause problems if a path<br>
was failed but not removed, and "multipath -r" was run.  multipath would<br>
remove the path, and when multipathd updated itself, it would remove<br>
that path from the multipath device's path list, but not orphan it.<br>
When the path became active again, multipathd crashed trying to adjust<br>
the pathgroups of the multipath device it had previously belonged to.<br>
<br>
This patch makes sure that whenever multipathd updates the multipath device<br>
table, it first makes sure the mpp->paths is uptodate.  Once it has<br>
finished updating the device table, it orphans any paths in mpp->paths<br>
that are no longer part of the multipath device.<br>
<br>
Signed-off-by: Benjamin Marzinski <<a href="mailto:bmarzins@redhat.com">bmarzins@redhat.com</a>><br>
---<br>
 libmultipath/structs_vec.c | 31 +++++++++++++++++++++++++++----<br>
 multipathd/main.c          |  4 ++++<br>
 2 files changed, 31 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c<br>
index 8cdbe3d..23f5bbb 100644<br>
--- a/libmultipath/structs_vec.c<br>
+++ b/libmultipath/structs_vec.c<br>
@@ -281,12 +281,38 @@ update_multipath_status (struct multipath *mpp)<br>
        return 0;<br>
 }<br>
<br>
+void sync_paths(struct multipath *mpp, vector pathvec)<br>
+{<br>
+       struct path *pp;<br>
+       struct pathgroup  *pgp;<br>
+       int found, i, j;<br>
+<br>
+       vector_foreach_slot (mpp->paths, pp, i) {<br>
+               found = 0;<br>
+               vector_foreach_slot(mpp->pg, pgp, j) {<br>
+                       if (find_slot(pgp->paths, (void *)pp) != -1) {<br>
+                               found = 1;<br>
+                               break;<br>
+                       }<br>
+               }<br>
+               if (!found) {<br>
+                       condlog(3, "%s dropped path %s", mpp->alias, pp->dev);<br>
+                       vector_del_slot(mpp->paths, i--);<br>
+                       orphan_path(pp, "path removed externally");<br>
+               }<br>
+       }<br>
+       update_mpp_paths(mpp, pathvec);<br>
+       vector_foreach_slot (mpp->paths, pp, i)<br>
+               pp->mpp = mpp;<br>
+}<br>
+<br>
 extern int<br>
 update_multipath_strings (struct multipath *mpp, vector pathvec)<br>
 {<br>
        if (!mpp)<br>
                return 1;<br>
<br>
+       update_mpp_paths(mpp, pathvec);<br>
        condlog(4, "%s: %s", mpp->alias, __FUNCTION__);<br>
<br>
        free_multipath_attributes(mpp);<br>
@@ -295,6 +321,7 @@ update_multipath_strings (struct multipath *mpp, vector pathvec)<br>
<br>
        if (update_multipath_table(mpp, pathvec))<br>
                return 1;<br>
+       sync_paths(mpp, pathvec);<br>
<br>
        if (update_multipath_status(mpp))<br>
                return 1;<br>
@@ -508,13 +535,9 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)<br>
                return 2;<br>
        }<br>
<br>
-       free_pgvec(mpp->pg, KEEP_PATHS);<br>
-       mpp->pg = NULL;<br>
-<br>
        if (__setup_multipath(vecs, mpp, reset))<br>
                return 1; /* mpp freed in setup_multipath */<br>
<br>
-       adopt_paths(vecs->pathvec, mpp, 0);<br>
        /*<br>
         * compare checkers states with DM states<br>
         */<br>
diff --git a/multipathd/main.c b/multipathd/main.c<br>
index 56d00d3..337bfe9 100644<br>
--- a/multipathd/main.c<br>
+++ b/multipathd/main.c<br>
@@ -1170,6 +1170,10 @@ check_path (struct vectors * vecs, struct path * pp)<br>
                        pp->dev);<br>
                pp->dmstate = PSTATE_UNDEF;<br>
        }<br>
+       /* if update_multipath_strings orphaned the path, quit early */<br>
+       if (!pp->mpp)<br>
+               return 0;<br>
+<br>
        pp->chkrstate = newstate;<br>
        if (newstate != pp->state) {<br>
                int oldstate = pp->state;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.1<br>
<br>
</font></span></blockquote></div><br></div>