[dm-devel] [PATCH 04/11] multipathd: add need_do_map to indicate whether need calling domap() in ev_add_path()

Benjamin Marzinski bmarzins at redhat.com
Tue Jan 17 16:14:01 UTC 2017


On Tue, Jan 17, 2017 at 03:28:06PM +0800, tang.junhui at zte.com.cn wrote:
>    Hello Ben
> 
>    Thank you for your patience again.
> 
>    I'll modify code according to your suggestion as this:
>    1) add configuration in the defaults section
>       uid_attrs "sd:ID_SERIAL dasd:ID_UID"
>       it would override any other configurations if this
>       filed is configured and matched;
> 
>    2) In uevent processing thread, we will assign merge_id
>       according the label in uevents by this configuration;
> 
>    3) this patch will take back:
>       [PATCH 12/12] libmultipath: use existing wwid when
>       wwid has already been existed in uevent
> 
>    4) if this field is not configured, only do filtering and
>       no merging works.
> 
>    Please confirm whether this modification is feasible.

Yes. This is perfectly reasonable solution.  Thanks for doing all the
work on this.

-Ben

> 
>    Regards,
>    Tang Junhui
> 
>    ������:         "Benjamin Marzinski" <bmarzins at redhat.com>
>    �ռ���:         tang.junhui at zte.com.cn,
>    ����:        christophe.varoqui at opensvc.com, hare at suse.de,
>    mwilck at suse.com, bart.vanassche at sandisk.com, dm-devel at redhat.com,
>    zhang.kai16 at zte.com.cn, tang.wenjun3 at zte.com.cn
>    ����:         2017/01/17 05:38
>    ����:        Re: [PATCH 04/11] multipathd: add need_do_map to indicate
>    whether need calling domap() in ev_add_path()
> 
>    --------------------------------------------------------------------------
> 
>    On Thu, Jan 12, 2017 at 01:52:20PM +0800, tang.junhui at zte.com.cn wrote:
>    > From: tang.junhui <tang.junhui at zte.com.cn>
>    >
>    > Usually calling domap() in ev_add_path() is needed, but only last path
>    > need to call domap() in processing for merged uevents to reduce the
>    > count of calling domap() and promote efficiency. So add input parameter
>    > need_do_map to indicate whether need calling domap() in ev_add_path().
> 
>    With the addition of checking if the merge_id equals the wwid, you are
>    protected against accidentially merging paths that shouldn't be merged,
>    which is great.  But setting need_do_map for these paths doesn't
>    completely make sure that if the wwid and merge_id differ, you will
>    always call domap.
> 
>    A contrived situation where this fails would look like:
> 
>    add path1, path2, path3
> 
>    where merge_id equals the wwid for path1 and path2, but there is a
>    different wwid for path3.  In this case, you would call domap on just
>    the multipath device for path3, but since path1 and path2 matched the
>    merge_id, they wouldn't force a call to domap.
> 
>    A less contrived example would be
> 
>    add path1, path2, path3, path4
> 
>    Where these were devices that were actually pointing at two different
>    LUNs, but all set ID_SERIAL the same. path1 and path2 pointed to one
>    LUN, while path3 and path4 pointed to another LUN.  In this case the
>    wwid of path1 and path2 matched the merge_id, while the wwid of path3
>    and path4 was different. In this case you would call domap twice, on
>    both path3 and path4, but nothing would call domap to create a multipath
>    device for path1 and path2.
> 
>    In general, the code to set need_do_map if the wwid and merge_id don't
>    match only works if either none of the device in a merged set have wwids
>    that match the merge_id, or if the last device has a wwid that matches
>    the merge_id. If there are devices with wwids that match the merge_id,
>    but the last device in the set isn't one of them, then some devices will
>    not get a multipath device created for them.
> 
>    Now, I don't know of any device that works like my above example, so
>    your code will likely work fine for all real-world devices.  Also,
>    fixing this is a pain, as you don't find out until processing the last
>    path in a set that things went wrong, and then you would have to go back
>    and run the skipped functions on one of the paths you have already
>    processed.
> 
>    The easy way to fix it is to use the other possibility that I mentioned
>    before, which is to not have the merge_id, and just use the udev
>    provided wwid, instead of fetching it from pathinfo.  Like I mentioned,
>    if you do this, you want to make sure that you only try to grab the wwid
>    from the udev events for devices with the correct kernel name: ID_SERIAL
>    only for "sd.*" devices, and ID_UID only for "dasd.*" devices. I also
>    think that this should be configurable.
> 
>    Otherwise, you can either go through the messy work of calling domap
>    correctly when the last device of a set has a wwid that doesn't match
>    the merge_id, or we can decide that this won't acutally cause problems
>    with any known device, and punt fixing it for now. And if it causes
>    problems with some future devices, we can deal with it then.
> 
>    -Ben
> 
>    >
>    > Change-Id: I7f33de49a1d89d91180dcb95cd94e4944ae7ff36
>    > Signed-off-by: tang.wenjun <tang.wenjun3 at zte.com.cn>
>    > ---
>    >  multipathd/cli_handlers.c |  3 ++-
>    >  multipathd/main.c         | 47
>    ++++++++++++++++++++++++++++++++++++-----------
>    >  multipathd/main.h         |  2 +-
>    >  3 files changed, 39 insertions(+), 13 deletions(-)
>    >
>    > diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
>    > index b0eeca6..3a46c09 100644
>    > --- a/multipathd/cli_handlers.c
>    > +++ b/multipathd/cli_handlers.c
>    > @@ -670,7 +670,8 @@ cli_add_path (void * v, char ** reply, int * len,
>    void * data)
>    >                                    pp->checkint = conf->checkint;
>    >                   }
>    >                   put_multipath_config(conf);
>    > -                 return ev_add_path(pp, vecs);
>    > +                 return ev_add_path(pp, vecs, 1);
>    > +
>    >  blacklisted:
>    >                   *reply = strdup("blacklisted\n");
>    >                   *len = strlen(*reply) + 1;
>    > diff --git a/multipathd/main.c b/multipathd/main.c
>    > index adc3258..ebd7de1 100644
>    > --- a/multipathd/main.c
>    > +++ b/multipathd/main.c
>    > @@ -608,7 +608,7 @@ ev_remove_map (char * devname, char * alias, int
>    minor, struct vectors * vecs)
>    >  }
>    >  
>    >  static int
>    > -uev_add_path (struct uevent *uev, struct vectors * vecs)
>    > +uev_add_path (struct uevent *uev, struct vectors * vecs, int
>    need_do_map)
>    >  {
>    >                   struct path *pp;
>    >                   int ret = 0, i;
>    > @@ -640,9 +640,18 @@ uev_add_path (struct uevent *uev, struct vectors *
>    vecs)
>    >                                                     r = pathinfo(pp,
>    conf,
>    >                                                                        
>      DI_ALL | DI_BLACKLIST);
>    >                                                    
>    put_multipath_config(conf);
>    > -                                                   if (r ==
>    PATHINFO_OK)
>    > -                                                                    ret
>    = ev_add_path(pp, vecs);
>    > -                                                   else if (r ==
>    PATHINFO_SKIPPED) {
>    > +                                                   if (r ==
>    PATHINFO_OK) {
>    > +                                                                    /*
>    > +                                                                     *
>    Make sure merging use the correct wwid
>    > +                                                                     *
>    Othterwise calling domap()
>    > +                                                                     */
>    > +                                                                    if
>    (!need_do_map &&
>    > +                                                                      
>     uev->merge_id &&
>    > +                                                                      
>     strcmp(uev->merge_id, pp->wwid))
>    > +                                                                      
>                  need_do_map = 1;
>    > +
>    > +                                                                    ret
>    = ev_add_path(pp, vecs, need_do_map);
>    > +                                                   } else if (r ==
>    PATHINFO_SKIPPED) {
>    >                                                                    
>     condlog(3, "%s: remove blacklisted path",
>    >                                                                        
>                  uev->kernel);
>    >                                                                      i =
>    find_slot(vecs->pathvec, (void *)pp);
>    > @@ -681,7 +690,16 @@ uev_add_path (struct uevent *uev, struct vectors *
>    vecs)
>    >                                    conf = get_multipath_config();
>    >                                    pp->checkint = conf->checkint;
>    >                                    put_multipath_config(conf);
>    > -                                  ret = ev_add_path(pp, vecs);
>    > +                                  /*
>    > +                                   * Make sure merging use the correct
>    wwid
>    > +                                   * Othterwise calling domap()
>    > +                                   */
>    > +                                  if (!need_do_map &&
>    > +                                      uev->merge_id &&
>    > +                                      strcmp(uev->merge_id, pp->wwid))
>    > +                                                   need_do_map = 1;
>    > +
>    > +                                  ret = ev_add_path(pp, vecs,
>    need_do_map);
>    >                   } else {
>    >                                    condlog(0, "%s: failed to store path
>    info, "
>    >                                                     "dropping event",
>    > @@ -699,7 +717,7 @@ uev_add_path (struct uevent *uev, struct vectors *
>    vecs)
>    >   * 1: error
>    >   */
>    >  int
>    > -ev_add_path (struct path * pp, struct vectors * vecs)
>    > +ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map)
>    >  {
>    >                   struct multipath * mpp;
>    >                   char params[PARAMS_SIZE] = {0};
>    > @@ -767,6 +785,13 @@ rescan:
>    >                   /* persistent reservation check*/
>    >                   mpath_pr_event_handle(pp);
>    >  
>    > +                 if (!need_do_map)
>    > +                                  return 0;
>    > +
>    > +                 if (!dm_map_present(mpp->alias)) {
>    > +                                  mpp->action = ACT_CREATE;
>    > +                                  start_waiter = 1;
>    > +                 }
>    >                   /*
>    >                    * push the map to the device-mapper
>    >                    */
>    > @@ -995,7 +1020,7 @@ uev_update_path (struct uevent *uev, struct vectors
>    * vecs)
>    >                                    }
>    >  
>    >                                    if (pp->initialized ==
>    INIT_REQUESTED_UDEV)
>    > -                                                   retval =
>    uev_add_path(uev, vecs);
>    > +                                                   retval =
>    uev_add_path(uev, vecs, 1);
>    >                                    else if (mpp && ro >= 0) {
>    >                                                     condlog(2, "%s:
>    update path write_protect to '%d' (uevent)", uev->kernel, ro);
>    >  
>    > @@ -1150,7 +1175,7 @@ uev_trigger (struct uevent * uev, void *
>    trigger_data)
>    >                   put_multipath_config(conf);
>    >  
>    >                   if (!strncmp(uev->action, "add", 3)) {
>    > -                                  r = uev_add_path(uev, vecs);
>    > +                                  r = uev_add_path(uev, vecs, 1);
>    >                                    goto out;
>    >                   }
>    >                   if (!strncmp(uev->action, "remove", 6)) {
>    > @@ -1570,7 +1595,7 @@ check_path (struct vectors * vecs, struct path *
>    pp, int ticks)
>    >                                                     conf =
>    get_multipath_config();
>    >                                                     ret = pathinfo(pp,
>    conf, DI_ALL | DI_BLACKLIST);
>    >                                                     if (ret ==
>    PATHINFO_OK) {
>    > -                                                                  
>     ev_add_path(pp, vecs);
>    > +                                                                  
>     ev_add_path(pp, vecs, 1);
>    >                                                                    
>     pp->tick = 1;
>    >                                                     } else if (ret ==
>    PATHINFO_SKIPPED) {
>    >                                                                    
>     put_multipath_config(conf);
>    > @@ -1686,7 +1711,7 @@ check_path (struct vectors * vecs, struct path *
>    pp, int ticks)
>    >                                    }
>    >                                    if (!disable_reinstate &&
>    reinstate_path(pp, add_active)) {
>    >                                                     condlog(3, "%s:
>    reload map", pp->dev);
>    > -                                                   ev_add_path(pp,
>    vecs);
>    > +                                                   ev_add_path(pp,
>    vecs, 1);
>    >                                                     pp->tick = 1;
>    >                                                     return 0;
>    >                                    }
>    > @@ -1709,7 +1734,7 @@ check_path (struct vectors * vecs, struct path *
>    pp, int ticks)
>    >                                                     /* Clear IO errors
>    */
>    >                                                     if
>    (reinstate_path(pp, 0)) {
>    >                                                                    
>     condlog(3, "%s: reload map", pp->dev);
>    > -                                                                  
>     ev_add_path(pp, vecs);
>    > +                                                                  
>     ev_add_path(pp, vecs, 1);
>    >                                                                    
>     pp->tick = 1;
>    >                                                                    
>     return 0;
>    >                                                     }
>    > diff --git a/multipathd/main.h b/multipathd/main.h
>    > index f72580d..f810d41 100644
>    > --- a/multipathd/main.h
>    > +++ b/multipathd/main.h
>    > @@ -22,7 +22,7 @@ void exit_daemon(void);
>    >  const char * daemon_status(void);
>    >  int need_to_delay_reconfig (struct vectors *);
>    >  int reconfigure (struct vectors *);
>    > -int ev_add_path (struct path *, struct vectors *);
>    > +int ev_add_path (struct path *, struct vectors *, int);
>    >  int ev_remove_path (struct path *, struct vectors *);
>    >  int ev_add_map (char *, char *, struct vectors *);
>    >  int ev_remove_map (char *, char *, int, struct vectors *);
>    > --
>    > 2.8.1.windows.1
>    >




More information about the dm-devel mailing list