diff mbox series

[1/5] multipathd: don't fail to remove path once the map is removed

Message ID 1620775324-23984-2-git-send-email-bmarzins@redhat.com (mailing list archive)
State Not Applicable, archived
Delegated to: christophe varoqui
Headers show
Series Memory issues found by coverity | expand

Commit Message

Benjamin Marzinski May 11, 2021, 11:22 p.m. UTC
In ev_remove_path(), if update_mpp_paths() fails, we delete the entire
map. However, since update_mpp_paths() happens before we call
set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so
remove_map_and_stop_waiter() doesn't remove the path when in removes the
map.  But with the map removed, there's nothing to keep us from removing
the path.

Call set_path_removed() before update_mpp_paths() to avoid the odd case
of ev_remove_path() removing the map but not the path.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 libmultipath/structs_vec.c |  3 +--
 multipathd/main.c          | 13 ++++++++-----
 2 files changed, 9 insertions(+), 7 deletions(-)

Comments

Martin Wilck May 12, 2021, 9:11 a.m. UTC | #1
On Tue, 2021-05-11 at 18:22 -0500, Benjamin Marzinski wrote:
> In ev_remove_path(), if update_mpp_paths() fails, we delete the
> entire
> map. However, since update_mpp_paths() happens before we call
> set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so
> remove_map_and_stop_waiter() doesn't remove the path when in removes
> the
> map.  But with the map removed, there's nothing to keep us from
> removing
> the path.
> 
> Call set_path_removed() before update_mpp_paths() to avoid the odd
> case
> of ev_remove_path() removing the map but not the path.
> 
> Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
> ---
>  libmultipath/structs_vec.c |  3 +--
>  multipathd/main.c          | 13 ++++++++-----
>  2 files changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
> index d242c06b..432c0c63 100644
> --- a/libmultipath/structs_vec.c
> +++ b/libmultipath/structs_vec.c
> @@ -45,8 +45,7 @@ int update_mpp_paths(struct multipath *mpp, vector
> pathvec)
>  
>                                 /*
>                                  * Avoid adding removed paths to the
> map again
> -                                * when we reload it. Such paths may
> exist if
> -                                * domap fails in ev_remove_path().
> +                                * when we reload it.

I'd like to keep the remark about domap(). It's meant as a reminder for
us and future developers how this situation is most likely to come to
pass.

Other than that, ACK.

Regards,
Martin


--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Benjamin Marzinski May 12, 2021, 2:17 p.m. UTC | #2
On Wed, May 12, 2021 at 09:11:01AM +0000, Martin Wilck wrote:
> On Tue, 2021-05-11 at 18:22 -0500, Benjamin Marzinski wrote:
> > In ev_remove_path(), if update_mpp_paths() fails, we delete the
> > entire
> > map. However, since update_mpp_paths() happens before we call
> > set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so
> > remove_map_and_stop_waiter() doesn't remove the path when in removes
> > the
> > map.  But with the map removed, there's nothing to keep us from
> > removing
> > the path.
> > 
> > Call set_path_removed() before update_mpp_paths() to avoid the odd
> > case
> > of ev_remove_path() removing the map but not the path.
> > 
> > Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
> > ---
> >  libmultipath/structs_vec.c |  3 +--
> >  multipathd/main.c          | 13 ++++++++-----
> >  2 files changed, 9 insertions(+), 7 deletions(-)
> > 
> > diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
> > index d242c06b..432c0c63 100644
> > --- a/libmultipath/structs_vec.c
> > +++ b/libmultipath/structs_vec.c
> > @@ -45,8 +45,7 @@ int update_mpp_paths(struct multipath *mpp, vector
> > pathvec)
> >  
> >                                 /*
> >                                  * Avoid adding removed paths to the
> > map again
> > -                                * when we reload it. Such paths may
> > exist if
> > -                                * domap fails in ev_remove_path().
> > +                                * when we reload it.
> 
> I'd like to keep the remark about domap(). It's meant as a reminder for
> us and future developers how this situation is most likely to come to
> pass.

Sure. I just removed it, since we now call update_mpp_paths immediately
after calling set_path_removed(), so it seemed more obvious that we will
run into this situation than it did before, when it only happened if we
first failed in ev_remove_path(). I'm fine with putting it back.

> 
> Other than that, ACK.
> 
> Regards,
> Martin

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
diff mbox series

Patch

diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
index d242c06b..432c0c63 100644
--- a/libmultipath/structs_vec.c
+++ b/libmultipath/structs_vec.c
@@ -45,8 +45,7 @@  int update_mpp_paths(struct multipath *mpp, vector pathvec)
 
 				/*
 				 * Avoid adding removed paths to the map again
-				 * when we reload it. Such paths may exist if
-				 * domap fails in ev_remove_path().
+				 * when we reload it.
 				 */
 				pp1 = find_path_by_devt(pathvec, pp->dev_t);
 				if (pp1 && pp->initialized != INIT_REMOVED &&
diff --git a/multipathd/main.c b/multipathd/main.c
index 102946bf..449ce384 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1199,6 +1199,13 @@  ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
 	 * avoid referring to the map of an orphaned path
 	 */
 	if ((mpp = pp->mpp)) {
+		/*
+		 * Mark the path as removed. In case of success, we
+		 * will delete it for good. Otherwise, it will be deleted
+		 * later, unless all attempts to reload this map fail.
+		 */
+		set_path_removed(pp);
+
 		/*
 		 * transform the mp->pg vector of vectors of paths
 		 * into a mp->params string to feed the device-mapper
@@ -1210,13 +1217,9 @@  ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
 		}
 
 		/*
-		 * Mark the path as removed. In case of success, we
-		 * will delete it for good. Otherwise, it will be deleted
-		 * later, unless all attempts to reload this map fail.
-		 * Note: we have to explicitly remove pp from mpp->paths,
+		 * we have to explicitly remove pp from mpp->paths,
 		 * update_mpp_paths() doesn't do that.
 		 */
-		set_path_removed(pp);
 		i = find_slot(mpp->paths, pp);
 		if (i != -1)
 			vector_del_slot(mpp->paths, i);