[dm-devel] [PATCH v2 6/6] multipathd: use symbolic returns for ev_remove_path()
Benjamin Marzinski
bmarzins at redhat.com
Fri May 14 15:51:41 UTC 2021
On Thu, May 13, 2021 at 08:11:13PM +0000, Martin Wilck wrote:
> On Thu, 2021-05-13 at 12:23 -0500, Benjamin Marzinski wrote:
> > There are many possible outcomes of calling ev_remove_path(), and not
> > all callers agree on which outcomes are a success and which are a
> > failure. So ev_remove_path() should simply return a different value
> > for
> > each outcome, and the callers can decide how to deal with them.
> >
> > Signed-off-by: Benjamin Marzinski <bmarzins at redhat.com>
> > ---
> > multipathd/cli_handlers.c | 14 ++++++++++++--
> > multipathd/main.c | 35 +++++++++++++++++++----------------
> > multipathd/main.h | 9 +++++++++
> > 3 files changed, 40 insertions(+), 18 deletions(-)
> >
> > diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
> > index 1de6ad8e..1462ea84 100644
> > --- a/multipathd/cli_handlers.c
> > +++ b/multipathd/cli_handlers.c
> > @@ -752,7 +752,8 @@ cli_add_path (void * v, char ** reply, int * len,
> > void * data)
> > /* Have the checker reinstate this
> > path asap */
> > pp->tick = 1;
> > return 0;
> > - } else if (!ev_remove_path(pp, vecs, true))
> > + } else if (ev_remove_path(pp, vecs, true) &
> > + REMOVE_PATH_SUCCESS)
> > /* Path removed in ev_remove_path()
> > */
> > pp = NULL;
> > else {
> > @@ -813,6 +814,7 @@ cli_del_path (void * v, char ** reply, int * len,
> > void * data)
> > struct vectors * vecs = (struct vectors *)data;
> > char * param = get_keyparam(v, PATH);
> > struct path *pp;
> > + int ret;
> >
> > param = convert_dev(param, 1);
> > condlog(2, "%s: remove path (operator)", param);
> > @@ -821,7 +823,15 @@ cli_del_path (void * v, char ** reply, int *
> > len, void * data)
> > condlog(0, "%s: path already removed", param);
> > return 1;
> > }
> > - return ev_remove_path(pp, vecs, 1);
> > + ret = ev_remove_path(pp, vecs, 1);
> > + if (ret == REMOVE_PATH_DELAY) {
> > + *reply = strdup("delayed\n");
> > + *len = strlen(*reply) + 1;
> > + } else if (ret == REMOVE_PATH_MAP_ERROR) {
> > + *reply = strdup("map reload error. removed\n");
> > + *len = strlen(*reply) + 1;
> > + }
> > + return (ret == REMOVE_PATH_FAILURE);
> > }
> >
> > int
> > diff --git a/multipathd/main.c b/multipathd/main.c
> > index 4bdf14bd..72fb7e38 100644
> > --- a/multipathd/main.c
> > +++ b/multipathd/main.c
> > @@ -838,7 +838,7 @@ handle_path_wwid_change(struct path *pp, struct
> > vectors *vecs)
> > return;
> >
> > udd = udev_device_ref(pp->udev);
> > - if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) {
> > + if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) &&
> > pp->mpp) {
> > pp->dmstate = PSTATE_FAILED;
> > dm_fail_path(pp->mpp->alias, pp->dev_t);
> > }
> > @@ -948,8 +948,8 @@ uev_add_path (struct uevent *uev, struct vectors
> > * vecs, int need_do_map)
> > * Make another attempt to remove the
> > path
> > */
> > pp->mpp = prev_mpp;
> > - ret = ev_remove_path(pp, vecs, true);
> > - if (ret != 0) {
> > + if (!(ev_remove_path(pp, vecs, true)
> > &
> > + REMOVE_PATH_SUCCESS)) {
> > /*
> > * Failure in ev_remove_path
> > will keep
> > * path in pathvec in
> > INIT_REMOVED state
> > @@ -960,6 +960,7 @@ uev_add_path (struct uevent *uev, struct vectors
> > * vecs, int need_do_map)
> > dm_fail_path(pp->mpp->alias,
> > pp->dev_t);
> > condlog(1, "%s: failed to re-
> > add path still mapped in %s",
> > pp->dev, pp->mpp-
> > >alias);
> > + ret = 1;
> > } else if (r == PATHINFO_OK)
> > /*
> > * Path successfully freed,
> > move on to
> > @@ -1167,7 +1168,7 @@ static int
> > uev_remove_path (struct uevent *uev, struct vectors * vecs, int
> > need_do_map)
> > {
> > struct path *pp;
> > - int ret;
> > + int ret = 0;
> >
> > condlog(3, "%s: remove path (uevent)", uev->kernel);
> > delete_foreign(uev->udev);
> > @@ -1176,8 +1177,8 @@ uev_remove_path (struct uevent *uev, struct
> > vectors * vecs, int need_do_map)
> > lock(&vecs->lock);
> > pthread_testcancel();
> > pp = find_path_by_dev(vecs->pathvec, uev->kernel);
> > - if (pp)
> > - ret = ev_remove_path(pp, vecs, need_do_map);
> > + if (pp && ev_remove_path(pp, vecs, need_do_map) ==
> > REMOVE_PATH_FAILURE)
> > + ret = 1;
> > lock_cleanup_pop(vecs->lock);
> > if (!pp) {
> > /* Not an error; path might have been purged earlier
> > */
> > @@ -1191,7 +1192,7 @@ int
> > ev_remove_path (struct path *pp, struct vectors * vecs, int
> > need_do_map)
> > {
> > struct multipath * mpp;
> > - int i, retval = 0;
> > + int i, retval = REMOVE_PATH_SUCCESS;
> > char params[PARAMS_SIZE] = {0};
> >
> > /*
> > @@ -1245,7 +1246,6 @@ ev_remove_path (struct path *pp, struct vectors
> > * vecs, int need_do_map)
> > condlog(2, "%s: removed map after"
> > " removing all paths",
> > alias);
> > - retval = 0;
> > /* flush_map() has freed the path */
> > goto out;
> > }
> > @@ -1262,11 +1262,14 @@ ev_remove_path (struct path *pp, struct
> > vectors * vecs, int need_do_map)
> >
> > if (mpp->wait_for_udev) {
> > mpp->wait_for_udev = 2;
> > + retval = REMOVE_PATH_DELAY;
> > goto out;
> > }
> >
> > - if (!need_do_map)
> > + if (!need_do_map) {
> > + retval = REMOVE_PATH_DELAY;
> > goto out;
> > + }
> > /*
> > * reload the map
> > */
> > @@ -1275,7 +1278,7 @@ ev_remove_path (struct path *pp, struct vectors
> > * vecs, int need_do_map)
> > condlog(0, "%s: failed in domap for "
> > "removal of path %s",
> > mpp->alias, pp->dev);
> > - retval = 1;
> > + retval = REMOVE_PATH_FAILURE;
>
> Hm. With the introduction of INIT_REMOVED, this failure isn't fatal any
> more. As far as multipathd is concerned, the path is removed and will
> be deleted from the map as soon as the reason for the domap() failure
> (likely a problem with some other device in the map) is resolved.
> There's no difference from the REMOVE_PATH_DELAY case wrt how the path
> will be treated in the future.
>
> So while I agree it's reasonable to distinguish this case from the
> "delay without failure" cases above, I'm unsure if we should treat it
> as an error in uev_remove_path() (or uev_trigger(), for that matter).
Sure. All that a failure does is print an error message anyway, and a
message already gets printed if domap fails, so another message won't
help with debugging problems.
>
> > } else {
> > /*
> > * update our state from kernel
> > @@ -1283,12 +1286,12 @@ ev_remove_path (struct path *pp, struct
> > vectors * vecs, int need_do_map)
> > char devt[BLK_DEV_SIZE];
> >
> > strlcpy(devt, pp->dev_t, sizeof(devt));
> > +
> > + /* setup_multipath will free the path
> > + * regardless of whether it succeeds or
> > + * fails */
> > if (setup_multipath(vecs, mpp))
> > - return 0;
> > - /*
> > - * Successful map reload without this path:
> > - * sync_map_state() will free it.
> > - */
> > + return REMOVE_PATH_MAP_ERROR;
> > sync_map_state(mpp);
> >
> > condlog(2, "%s: path removed from map %s",
> > @@ -1307,7 +1310,7 @@ fail:
> > condlog(0, "%s: error removing path. removing map %s", pp-
> > >dev,
> > mpp->alias);
> > remove_map_and_stop_waiter(mpp, vecs);
> > - return 0;
> > + return REMOVE_PATH_MAP_ERROR;
> > }
> >
> > static int
> > diff --git a/multipathd/main.h b/multipathd/main.h
> > index ddd953f9..24d050c8 100644
> > --- a/multipathd/main.h
> > +++ b/multipathd/main.h
> > @@ -13,6 +13,15 @@ enum daemon_status {
> > DAEMON_STATUS_SIZE,
> > };
> >
> > +#define REMOVE_PATH_FAILURE 0x0 /* path was not removed */
>
> We should add a remark that this is normally non-fatal, it's init state
> is set to INIT_REMOVED, and that it will be removed at the next
> possible occasion. The only thing that should be avoided is to try and
> add another path with the same major/minor number.
Sure.
> Use an enum, maybe?
I can do that.
-Ben
> Regards,
> Martin
>
>
> > +#define REMOVE_PATH_SUCCESS 0x1 /* path was removed */
> > +#define REMOVE_PATH_DELAY 0x2 /* path is set to be removed later. it
> > + * currently still exists and is part
> > of the
> > + * kernel map */
> > +#define REMOVE_PATH_MAP_ERROR 0x5 /* map was removed because of
> > error. value
> > + * includes REMOVE_PATH_SUCCESS bit
> > + * because the path was also
> > removed */
>
>
>
> > +
> > struct prout_param_descriptor;
> > struct prin_resp;
> >
More information about the dm-devel
mailing list