Hello community,

here is the log from the commit of package multipath-tools for openSUSE:Factory 
checked in at 2019-06-27 15:23:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/multipath-tools (Old)
 and      /work/SRC/openSUSE:Factory/.multipath-tools.new.4615 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "multipath-tools"

Thu Jun 27 15:23:14 2019 rev:114 rq:711933 version:0.8.1+28+suse.fea562a

Changes:
--------
--- /work/SRC/openSUSE:Factory/multipath-tools/multipath-tools.changes  
2019-05-06 13:17:25.135967185 +0200
+++ 
/work/SRC/openSUSE:Factory/.multipath-tools.new.4615/multipath-tools.changes    
    2019-06-27 15:23:15.721180915 +0200
@@ -1,0 +2,15 @@
+Tue Jun 25 15:42:56 UTC 2019 - [email protected]
+
+- Update to version 0.8.1+28+suse.fea562a:
+  * mpathpersist: optimize for setups with many LUNs (bsc#1134648)
+  * mpathpersist: add option -f/--batch-file (bsc#1134648)
+  * libmultipath: get_prio(): really don't reset prio for
+    inaccessible paths (bsc#1118495)
+- Upstream bug fixes from dm-devel (bsc#1139369):
+  * multipath: call store_pathinfo with DI_BLACKLIST
+  * multipathd: fix REALLOC_REPLY with max length reply
+  * libmultipath: make vector_foreach_slot_backwards work as expected
+  * multipathd: fix client response for socket activation
+  * various minor fixes (coverity)
+
+-------------------------------------------------------------------
@@ -20,0 +36 @@
+  * libmultipath: hwtable: add Lenovo DE series (bsc#1125507)

Old:
----
  multipath-tools-0.8.1+8+suse.8c11498.tar.xz

New:
----
  multipath-tools-0.8.1+28+suse.fea562a.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ multipath-tools.spec ++++++
--- /var/tmp/diff_new_pack.o3441i/_old  2019-06-27 15:23:16.297181894 +0200
+++ /var/tmp/diff_new_pack.o3441i/_new  2019-06-27 15:23:16.305181907 +0200
@@ -49,7 +49,7 @@
 %define _sysdir usr/lib
 
 Name:           multipath-tools
-Version:        0.8.1+8+suse.8c11498
+Version:        0.8.1+28+suse.fea562a
 Release:        0
 Summary:        Tools to Manage Multipathed Devices with the device-mapper
 License:        GPL-2.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.o3441i/_old  2019-06-27 15:23:16.337181961 +0200
+++ /var/tmp/diff_new_pack.o3441i/_new  2019-06-27 15:23:16.341181968 +0200
@@ -8,7 +8,7 @@
        are have been added to factory before upstream will be
        counted. Determine patch offset manually! It should be the number
        of patches which are _really_ not upstream (yet). -->
-    <param name="versionformat">@PARENT_TAG@+8+suse.%h</param>
+    <param name="versionformat">@PARENT_TAG@+28+suse.%h</param>
     <param name="revision">factory</param>
     <param name="match-tag">0.[0-9].[0-9]</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.o3441i/_old  2019-06-27 15:23:16.361182002 +0200
+++ /var/tmp/diff_new_pack.o3441i/_new  2019-06-27 15:23:16.361182002 +0200
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/openSUSE/multipath-tools.git</param>
-              <param 
name="changesrevision">8c114985f9fd7eb142ddec9737870f99ff28d5ba</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">fea562ab158a5d87a9011d5decf682c2199c98fa</param></service></servicedata>
\ No newline at end of file

++++++ multipath-tools-0.8.1+8+suse.8c11498.tar.xz -> 
multipath-tools-0.8.1+28+suse.fea562a.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/multipath-tools-0.8.1+8+suse.8c11498/kpartx/dasd.c 
new/multipath-tools-0.8.1+28+suse.fea562a/kpartx/dasd.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/kpartx/dasd.c      2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/kpartx/dasd.c     2019-06-25 
17:30:27.000000000 +0200
@@ -138,6 +138,8 @@
                        return -1;
        } else {
                fd_dasd = dup(fd);
+               if (fd_dasd < 0)
+                       return -1;
        }
 
        if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmpathpersist/mpath_persist.c 
new/multipath-tools-0.8.1+28+suse.fea562a/libmpathpersist/mpath_persist.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmpathpersist/mpath_persist.c    
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmpathpersist/mpath_persist.c   
2019-06-25 17:30:27.000000000 +0200
@@ -16,6 +16,7 @@
 #include "config.h"
 #include "switchgroup.h"
 #include "discovery.h"
+#include "configure.h"
 #include "dmparser.h"
 #include <ctype.h>
 #include "propsel.h"
@@ -96,16 +97,21 @@
                                continue;
                        }
                        pp->mpp = mpp;
-                       if (pp->state == PATH_UNCHECKED ||
-                                       pp->state == PATH_WILD) {
+                       if (pp->udev == NULL) {
+                               pp->udev = get_udev_device(pp->dev_t, DEV_DEVT);
+                               if (pp->udev == NULL) {
+                                       pp->state = PATH_DOWN;
+                                       continue;
+                               }
                                conf = get_multipath_config();
-                               pathinfo(pp, conf, DI_CHECKER);
+                               pathinfo(pp, conf, DI_SYSFS|DI_CHECKER);
                                put_multipath_config(conf);
+                               continue;
                        }
-
-                       if (pp->priority == PRIO_UNDEF) {
+                       if (pp->state == PATH_UNCHECKED ||
+                                       pp->state == PATH_WILD) {
                                conf = get_multipath_config();
-                               pathinfo(pp, conf, DI_PRIO);
+                               pathinfo(pp, conf, DI_CHECKER);
                                put_multipath_config(conf);
                        }
                }
@@ -152,48 +158,47 @@
 int mpath_persistent_reserve_in (int fd, int rq_servact,
        struct prin_resp *resp, int noisy, int verbose)
 {
-       struct stat info;
-       vector curmp = NULL;
-       vector pathvec = NULL;
-       char * alias;
-       struct multipath * mpp;
-       int map_present;
-       int major, minor;
-       int ret;
-       struct config *conf;
+       int ret = mpath_persistent_reserve_init_vecs(verbose);
 
-       conf = get_multipath_config();
-       conf->verbosity = verbose;
-       put_multipath_config(conf);
+       if (ret != MPATH_PR_SUCCESS)
+               return ret;
+       ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy);
+       mpath_persistent_reserve_free_vecs();
+       return ret;
+}
 
-       if (fstat( fd, &info) != 0){
-               condlog(0, "stat error %d", fd);
-               return MPATH_PR_FILE_ERROR;
-       }
-       if(!S_ISBLK(info.st_mode)){
-               condlog(0, "Failed to get major:minor. fd = %d", fd);
-               return MPATH_PR_FILE_ERROR;
-       }
+int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
+       unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, 
int verbose)
+{
+       int ret = mpath_persistent_reserve_init_vecs(verbose);
 
-       major = major(info.st_rdev);
-       minor = minor(info.st_rdev);
-       condlog(4, "Device %d:%d:  ", major, minor);
+       if (ret != MPATH_PR_SUCCESS)
+               return ret;
+       ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type,
+                                            paramp, noisy);
+       mpath_persistent_reserve_free_vecs();
+       return ret;
+}
 
-       /* get alias from major:minor*/
-       alias = dm_mapname(major, minor);
-       if (!alias){
-               condlog(0, "%d:%d failed to get device alias.", major, minor);
-               return MPATH_PR_DMMP_ERROR;
-       }
+static vector curmp;
+static vector pathvec;
 
-       condlog(3, "alias = %s", alias);
-       map_present = dm_map_present(alias);
-       if (map_present && dm_is_mpath(alias) != 1){
-               condlog( 0, "%s: not a multipath device.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out;
-       }
+void mpath_persistent_reserve_free_vecs(void)
+{
+       free_multipathvec(curmp, KEEP_PATHS);
+       free_pathvec(pathvec, FREE_PATHS);
+       curmp = pathvec = NULL;
+}
+
+int mpath_persistent_reserve_init_vecs(int verbose)
+{
+       struct config *conf = get_multipath_config();
 
+       conf->verbosity = verbose;
+       put_multipath_config(conf);
+
+       if (curmp)
+               return MPATH_PR_SUCCESS;
        /*
         * allocate core vectors to store paths and multipaths
         */
@@ -201,70 +206,32 @@
        pathvec = vector_alloc ();
 
        if (!curmp || !pathvec){
-               condlog (0, "%s: vector allocation failed.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               if (curmp)
-                       vector_free(curmp);
-               if (pathvec)
-                       vector_free(pathvec);
-               goto out;
+               condlog (0, "vector allocation failed.");
+               goto err;
        }
 
-       if (path_discovery(pathvec, DI_SYSFS | DI_CHECKER) < 0) {
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
-       }
+       if (dm_get_maps(curmp))
+               goto err;
 
-       /* get info of all paths from the dm device     */
-       if (get_mpvec (curmp, pathvec, alias)){
-               condlog(0, "%s: failed to get device info.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
-       }
+       return MPATH_PR_SUCCESS;
 
-       mpp = find_mp_by_alias(curmp, alias);
-       if (!mpp){
-               condlog(0, "%s: devmap not registered.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
-       }
-
-       ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy);
-
-out1:
-       free_multipathvec(curmp, KEEP_PATHS);
-       free_pathvec(pathvec, FREE_PATHS);
-out:
-       FREE(alias);
-       return ret;
+err:
+       mpath_persistent_reserve_free_vecs();
+       return MPATH_PR_DMMP_ERROR;
 }
 
-int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
-       unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, 
int verbose)
+static int mpath_get_map(int fd, char **palias, struct multipath **pmpp)
 {
-
+       int ret = MPATH_PR_DMMP_ERROR;
        struct stat info;
-
-       vector curmp = NULL;
-       vector pathvec = NULL;
-
-       char * alias;
-       struct multipath * mpp;
-       int map_present;
        int major, minor;
-       int ret;
-       uint64_t prkey;
-       struct config *conf;
-
-       conf = get_multipath_config();
-       conf->verbosity = verbose;
-       put_multipath_config(conf);
+       char *alias;
+       struct multipath *mpp;
 
-       if (fstat( fd, &info) != 0){
+       if (fstat(fd, &info) != 0){
                condlog(0, "stat error fd=%d", fd);
                return MPATH_PR_FILE_ERROR;
        }
-
        if(!S_ISBLK(info.st_mode)){
                condlog(3, "Failed to get major:minor. fd=%d", fd);
                return MPATH_PR_FILE_ERROR;
@@ -274,57 +241,73 @@
        minor = minor(info.st_rdev);
        condlog(4, "Device  %d:%d", major, minor);
 
-       /* get WWN of the device from major:minor*/
+       /* get alias from major:minor*/
        alias = dm_mapname(major, minor);
        if (!alias){
+               condlog(0, "%d:%d failed to get device alias.", major, minor);
                return MPATH_PR_DMMP_ERROR;
        }
 
        condlog(3, "alias = %s", alias);
-       map_present = dm_map_present(alias);
 
-       if (map_present && dm_is_mpath(alias) != 1){
+       if (dm_map_present(alias) && dm_is_mpath(alias) != 1){
                condlog(3, "%s: not a multipath device.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
                goto out;
        }
 
-       /*
-        * allocate core vectors to store paths and multipaths
-        */
-       curmp = vector_alloc ();
-       pathvec = vector_alloc ();
-
-       if (!curmp || !pathvec){
-               condlog (0, "%s: vector allocation failed.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               if (curmp)
-                       vector_free(curmp);
-               if (pathvec)
-                       vector_free(pathvec);
-               goto out;
-       }
-
-       if (path_discovery(pathvec, DI_SYSFS | DI_CHECKER) < 0) {
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
-       }
-
        /* get info of all paths from the dm device     */
        if (get_mpvec(curmp, pathvec, alias)){
                condlog(0, "%s: failed to get device info.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
+               goto out;
        }
 
        mpp = find_mp_by_alias(curmp, alias);
 
        if (!mpp) {
                condlog(0, "%s: devmap not registered.", alias);
-               ret = MPATH_PR_DMMP_ERROR;
-               goto out1;
+               goto out;
        }
 
+       ret = MPATH_PR_SUCCESS;
+       if (pmpp)
+               *pmpp = mpp;
+       if (palias) {
+               *palias = alias;
+               alias = NULL;
+       }
+out:
+       FREE(alias);
+       return ret;
+}
+
+int __mpath_persistent_reserve_in (int fd, int rq_servact,
+       struct prin_resp *resp, int noisy)
+{
+       struct multipath *mpp;
+       int ret;
+
+       ret = mpath_get_map(fd, NULL, &mpp);
+       if (ret != MPATH_PR_SUCCESS)
+               return ret;
+
+       ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy);
+
+       return ret;
+}
+
+int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
+       unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy)
+{
+       struct multipath *mpp;
+       char *alias;
+       int ret;
+       uint64_t prkey;
+       struct config *conf;
+
+       ret = mpath_get_map(fd, &alias, &mpp);
+       if (ret != MPATH_PR_SUCCESS)
+               return ret;
+
        conf = get_multipath_config();
        select_reservation_key(conf, mpp);
        select_all_tg_pt(conf, mpp);
@@ -385,10 +368,6 @@
                update_prkey(alias, 0);
        }
 out1:
-       free_multipathvec(curmp, KEEP_PATHS);
-       free_pathvec(pathvec, FREE_PATHS);
-
-out:
        FREE(alias);
        return ret;
 }
@@ -400,22 +379,22 @@
        struct multipath *mpp;
        char params[PARAMS_SIZE], status[PARAMS_SIZE];
 
-       if (dm_get_maps (curmp)){
-               return 1;
-       }
-
        vector_foreach_slot (curmp, mpp, i){
                /*
                 * discard out of scope maps
                 */
-               if (mpp->alias && refwwid &&
-                   strncmp (mpp->alias, refwwid, WWID_SIZE - 1)){
-                       free_multipath (mpp, KEEP_PATHS);
-                       vector_del_slot (curmp, i);
-                       i--;
+               if (!mpp->alias) {
+                       condlog(0, "%s: map with empty alias!", __func__);
                        continue;
                }
 
+               if (mpp->pg != NULL)
+                       /* Already seen this one */
+                       continue;
+
+               if (refwwid && strncmp (mpp->alias, refwwid, WWID_SIZE - 1))
+                       continue;
+
                dm_get_map(mpp->alias, &mpp->size, params);
                condlog(3, "params = %s", params);
                dm_get_status(mpp->alias, status);
@@ -428,7 +407,6 @@
                 * about them
                 */
                updatepaths(mpp);
-               mpp->bestpg = select_path_group (mpp);
                disassemble_status (status, mpp);
 
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmpathpersist/mpath_persist.h 
new/multipath-tools-0.8.1+28+suse.fea562a/libmpathpersist/mpath_persist.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmpathpersist/mpath_persist.h    
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmpathpersist/mpath_persist.h   
2019-06-25 17:30:27.000000000 +0200
@@ -215,6 +215,15 @@
 
 /*
  * DESCRIPTION :
+ * This function is like mpath_persistent_reserve_in(), except that it doesn't 
call
+ * mpath_persistent_reserve_init_vecs() and 
mpath_persistent_reserve_free_vecs()
+ * before and after the actual PR call.
+ */
+extern int __mpath_persistent_reserve_in(int fd, int rq_servact,
+               struct prin_resp *resp, int noisy);
+
+/*
+ * DESCRIPTION :
  * This function sends PROUT command to the DM device and get the response.
  *
  * @fd: The file descriptor of a multipath device. Input argument.
@@ -238,6 +247,37 @@
 extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
                unsigned int rq_type, struct prout_param_descriptor *paramp, 
int noisy,
                int verbose);
+/*
+ * DESCRIPTION :
+ * This function is like mpath_persistent_reserve_out(), except that it 
doesn't call
+ * mpath_persistent_reserve_init_vecs() and 
mpath_persistent_reserve_free_vecs()
+ * before and after the actual PR call.
+ */
+extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int 
rq_scope,
+               unsigned int rq_type, struct prout_param_descriptor *paramp,
+               int noisy);
+
+/*
+ * DESCRIPTION :
+ * This function allocates data structures and performs basic initialization 
and
+ * device discovery for later calls of __mpath_persistent_reserve_in() or
+ * __mpath_persistent_reserve_out().
+ * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 
3->Max verbose
+ *
+ * RESTRICTIONS:
+ *
+ * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status 
specified
+ *       above in RETURN_STATUS.
+ */
+int mpath_persistent_reserve_init_vecs(int verbose);
+
+/*
+ * DESCRIPTION :
+ * This function frees data structures allocated by
+ * mpath_persistent_reserve_init_vecs().
+ */
+void mpath_persistent_reserve_free_vecs(void);
+
 
 #ifdef __cplusplus
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/checkers/tur.c 
new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/checkers/tur.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/checkers/tur.c        
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/checkers/tur.c       
2019-06-25 17:30:27.000000000 +0200
@@ -290,7 +290,7 @@
 
 static void tur_timeout(struct timespec *tsp)
 {
-       clock_gettime(CLOCK_MONOTONIC, tsp);
+       get_monotonic_time(tsp);
        tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
        normalize_timespec(tsp);
 }
@@ -300,7 +300,7 @@
        struct tur_checker_context *ct = c->context;
        struct timespec now;
 
-       clock_gettime(CLOCK_MONOTONIC, &now);
+       get_monotonic_time(&now);
        ct->time = now.tv_sec + c->timeout;
 }
 
@@ -309,7 +309,7 @@
        struct tur_checker_context *ct = c->context;
        struct timespec now;
 
-       clock_gettime(CLOCK_MONOTONIC, &now);
+       get_monotonic_time(&now);
        return (now.tv_sec > ct->time);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.c 
new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/discovery.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.c   
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/discovery.c  
2019-06-25 17:30:27.000000000 +0200
@@ -134,7 +134,8 @@
                pp = find_path_by_devt(pathvec, devt);
                if (!pp)
                        return store_pathinfo(pathvec, conf,
-                                             udevice, flag, NULL);
+                                             udevice, flag | DI_BLACKLIST,
+                                             NULL);
        }
        return pathinfo(pp, conf, flag);
 }
@@ -1648,10 +1649,11 @@
                /* this changes pp->offline, but why not */
                int state = path_offline(pp);
 
-               if (state == PATH_DOWN || state == PATH_PENDING)
+               if (state == PATH_DOWN || state == PATH_PENDING) {
+                       pp->priority = old_prio;
                        condlog(3, "%s: %s prio error in state %d, keeping prio 
= %d",
                                pp->dev, prio_name(p), state, pp->priority);
-               else {
+               } else {
                        condlog(3, "%s: %s prio error in state %d",
                                pp->dev, prio_name(p), state);
                        pp->priority = PRIO_UNDEF;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/time-util.c 
new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/time-util.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/time-util.c   
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/time-util.c  
2019-06-25 17:30:27.000000000 +0200
@@ -3,6 +3,15 @@
 #include <time.h>
 #include "time-util.h"
 
+void get_monotonic_time(struct timespec *res)
+{
+       struct timespec ts;
+       int rv = clock_gettime(CLOCK_MONOTONIC, &ts);
+
+       assert(rv == 0);
+       *res = ts;
+}
+
 /* Initialize @cond as a condition variable that uses the monotonic clock */
 void pthread_cond_init_mono(pthread_cond_t *cond)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/time-util.h 
new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/time-util.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/time-util.h   
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/time-util.h  
2019-06-25 17:30:27.000000000 +0200
@@ -5,6 +5,7 @@
 
 struct timespec;
 
+void get_monotonic_time(struct timespec *res);
 void pthread_cond_init_mono(pthread_cond_t *cond);
 void normalize_timespec(struct timespec *ts);
 void timespecsub(const struct timespec *a, const struct timespec *b,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/vector.h 
new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/vector.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/vector.h      
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/libmultipath/vector.h     
2019-06-25 17:30:27.000000000 +0200
@@ -40,7 +40,7 @@
 #define vector_foreach_slot_after(v,p,i) \
        for (; (v) && i < VECTOR_SIZE(v) && ((p) = (v)->slot[i]); i++)
 #define vector_foreach_slot_backwards(v,p,i) \
-       for (i = VECTOR_SIZE(v); i > 0 && ((p) = (v)->slot[i-1]); i--)
+       for (i = VECTOR_SIZE(v) - 1; (int)i >= 0 && ((p) = (v)->slot[i]); i--)
 
 #define identity(x) (x)
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/main.c 
new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/main.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/main.c        
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/main.c       
2019-06-25 17:30:27.000000000 +0200
@@ -15,6 +15,8 @@
 #include <pthread.h>
 #include <ctype.h>
 #include <string.h>
+#include "version.h"
+#include <errno.h>
 
 static const char * pr_type_strs[] = {
        "obsolete [0]",
@@ -59,9 +61,101 @@
 
 struct udev *udev;
 
-int main (int argc, char * argv[])
+static int verbose, loglevel, noisy;
+
+static int handle_args(int argc, char * argv[], int line);
+
+static int do_batch_file(const char *batch_fn)
+{
+       char command[] = "mpathpersist";
+       const int ARGV_CHUNK = 2;
+       const char delims[] = " \t\n";
+       size_t len = 0;
+       char *line = NULL;
+       ssize_t n;
+       int nline = 0;
+       int argl = ARGV_CHUNK;
+       FILE *fl;
+       char **argv = calloc(argl, sizeof(*argv));
+       int ret = MPATH_PR_SUCCESS;
+
+       if (argv == NULL)
+               return MPATH_PR_OTHER;
+
+       fl = fopen(batch_fn, "r");
+       if (fl == NULL) {
+               fprintf(stderr, "unable to open %s: %s\n",
+                       batch_fn, strerror(errno));
+               free(argv);
+               return MPATH_PR_SYNTAX_ERROR;
+       } else {
+               if (verbose >= 2)
+                       fprintf(stderr, "running batch file %s\n",
+                               batch_fn);
+       }
+
+       while ((n = getline(&line, &len, fl)) != -1) {
+               char *_token, *token;
+               int argc = 0;
+               int rv;
+
+               nline++;
+               argv[argc++] = command;
+
+               if (line[n-1] == '\n')
+                       line[n-1] = '\0';
+               if (verbose >= 3)
+                       fprintf(stderr, "processing line %d: %s\n",
+                               nline, line);
+
+               for (token = strtok_r(line, delims, &_token);
+                    token != NULL && *token != '#';
+                    token = strtok_r(NULL, delims, &_token)) {
+
+                       if (argc >= argl) {
+                               int argn = argl + ARGV_CHUNK;
+                               char **tmp;
+
+                               tmp = realloc(argv, argn * sizeof(*argv));
+                               if (tmp == NULL)
+                                       break;
+                               argv = tmp;
+                               argl = argn;
+                       }
+
+                       if (argc == 1 && !strcmp(token, command))
+                               continue;
+
+                       argv[argc++] = token;
+               }
+
+               if (argc <= 1)
+                       continue;
+
+               if (verbose >= 2) {
+                       int i;
+
+                       fprintf(stderr, "## file %s line %d:", batch_fn, nline);
+                       for (i = 0; i < argc; i++)
+                               fprintf(stderr, " %s", argv[i]);
+                       fprintf(stderr, "\n");
+               }
+
+               optind = 0;
+               rv = handle_args(argc, argv, nline);
+               if (rv != MPATH_PR_SUCCESS)
+                       ret = rv;
+       }
+
+       fclose(fl);
+       free(argv);
+       free(line);
+       return ret;
+}
+
+static int handle_args(int argc, char * argv[], int nline)
 {
-       int fd, c, res;
+       int fd, c;
        const char *device_name = NULL;
        int num_prin_sa = 0;
        int num_prout_sa = 0;
@@ -82,51 +176,41 @@
        int prin = 1;
        int prin_sa = -1;
        int prout_sa = -1;
-       int verbose = 0;
-       int loglevel = 0;
-       int noisy = 0;
        int num_transport =0;
+       char *batch_fn = NULL;
        void *resp = NULL;
        struct transportid * tmp;
-       struct config *conf;
-
-       if (optind == argc)
-       {
-
-               fprintf (stderr, "No parameter used\n");
-               usage ();
-               exit (1);
-       }
-
-       if (getuid () != 0)
-       {
-               fprintf (stderr, "need to be root\n");
-               exit (1);
-       }
-
-       udev = udev_new();
-       conf = mpath_lib_init();
-       if(!conf) {
-               udev_unref(udev);
-               exit(1);
-       }
 
        memset(transportids, 0, MPATH_MX_TIDS * sizeof(struct transportid));
-       multipath_conf = conf;
 
        while (1)
        {
                int option_index = 0;
 
-               c = getopt_long (argc, argv, "v:Cd:hHioYZK:S:PAT:skrGILcRX:l:",
+               c = getopt_long (argc, argv, 
"v:Cd:hHioYZK:S:PAT:skrGILcRX:l:f:",
                                long_options, &option_index);
                if (c == -1)
                        break;
 
                switch (c)
                {
+                       case 'f':
+                               if (nline != 0) {
+                                       fprintf(stderr,
+                                               "ERROR: -f option not allowed 
in batch file\n");
+                                       ret = MPATH_PR_SYNTAX_ERROR;
+                                       goto out;
+                               }
+                               if (batch_fn != NULL) {
+                                       fprintf(stderr,
+                                               "ERROR: -f option can be used 
at most once\n");
+                                       ret = MPATH_PR_SYNTAX_ERROR;
+                                       goto out;
+                               }
+                               batch_fn = strdup(optarg);
+                               break;
                        case 'v':
-                               if (1 != sscanf (optarg, "%d", &loglevel))
+                               if (nline == 0 && 1 != sscanf (optarg, "%d", 
&loglevel))
                                {
                                        fprintf (stderr, "bad argument to 
'--verbose'\n");
                                        return MPATH_PR_SYNTAX_ERROR;
@@ -265,7 +349,6 @@
 
                        default:
                                fprintf(stderr, "unrecognised switch " "code 
0x%x ??\n", c);
-                               usage ();
                                ret = MPATH_PR_SYNTAX_ERROR;
                                goto out;
                }
@@ -283,27 +366,29 @@
                {
                        for (; optind < argc; ++optind)
                                fprintf (stderr, "Unexpected extra argument: 
%s\n", argv[optind]);
-                       usage ();
                        ret = MPATH_PR_SYNTAX_ERROR;
                        goto out;
                }
        }
 
-       /* set verbosity */
-       noisy = (loglevel >= 3) ? 1 : hex;
-       verbose = (loglevel >= 3)? 3: loglevel;
+       if (nline == 0) {
+               /* set verbosity */
+               noisy = (loglevel >= 3) ? 1 : hex;
+               verbose = (loglevel >= 3)? 3: loglevel;
+               ret = mpath_persistent_reserve_init_vecs(verbose);
+               if (ret != MPATH_PR_SUCCESS)
+                       goto out;
+       }
 
-       if ((prout_flag + prin_flag) == 0)
+       if ((prout_flag + prin_flag) == 0 && batch_fn == NULL)
        {
                fprintf (stderr, "choose either '--in' or '--out' \n");
-               usage ();
                ret = MPATH_PR_SYNTAX_ERROR;
                goto out;
        }
        if ((prout_flag + prin_flag) > 1)
        {
                fprintf (stderr, "choose either '--in' or '--out' \n");
-               usage ();
                ret = MPATH_PR_SYNTAX_ERROR;
                goto out;
        }
@@ -334,21 +419,19 @@
                {
                        fprintf (stderr,
                                        " No service action given for 
Persistent Reserve IN\n");
-                       usage();
                        ret = MPATH_PR_SYNTAX_ERROR;
                }
                else if (num_prin_sa > 1)
                {
                        fprintf (stderr, " Too many service actions given; 
choose "
                                        "one only\n");
-                       usage();
                        ret = MPATH_PR_SYNTAX_ERROR;
                }
        }
        else
        {
-               usage ();
-               ret = MPATH_PR_SYNTAX_ERROR;
+               if (batch_fn == NULL)
+                       ret = MPATH_PR_SYNTAX_ERROR;
                goto out;
        }
 
@@ -356,7 +439,6 @@
        {
                fprintf (stderr, " --relative-target-port"
                                " only useful with --register-move\n");
-               usage ();
                ret = MPATH_PR_SYNTAX_ERROR;
                goto out;
        }
@@ -378,7 +460,6 @@
        if (device_name == NULL)
        {
                fprintf (stderr, "No device name given \n");
-               usage ();
                ret = MPATH_PR_SYNTAX_ERROR;
                goto out;
        }
@@ -403,7 +484,7 @@
                        goto out;
                }
 
-               ret = mpath_persistent_reserve_in (fd, prin_sa, resp, noisy, 
verbose);
+               ret = __mpath_persistent_reserve_in (fd, prin_sa, resp, noisy);
                if (ret != MPATH_PR_SUCCESS )
                {
                        fprintf (stderr, "Persistent Reserve IN command 
failed\n");
@@ -463,8 +544,8 @@
                }
 
                /* PROUT commands other than 'register and move' */
-               ret = mpath_persistent_reserve_out (fd, prout_sa, 0, prout_type,
-                               paramp, noisy, verbose);
+               ret = __mpath_persistent_reserve_out (fd, prout_sa, 0, 
prout_type,
+                               paramp, noisy);
                for (j = 0 ; j < num_transport; j++)
                {
                        tmp = paramp->trnptid_list[j];
@@ -487,17 +568,57 @@
                printf("PR out: command failed\n");
        }
 
-       res = close (fd);
-       if (res < 0)
+       close (fd);
+
+out :
+       if (ret == MPATH_PR_SYNTAX_ERROR) {
+               free(batch_fn);
+               if (nline == 0)
+                       usage();
+               else
+                       fprintf(stderr, "syntax error on line %d in batch 
file\n",
+                               nline);
+       } else if (batch_fn != NULL) {
+               int rv = do_batch_file(batch_fn);
+
+               free(batch_fn);
+               ret = ret == 0 ? rv : ret;
+       }
+       if (nline == 0)
+               mpath_persistent_reserve_free_vecs();
+       return (ret >= 0) ? ret : MPATH_PR_OTHER;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+
+       if (optind == argc)
+       {
+
+               fprintf (stderr, "No parameter used\n");
+               usage ();
+               exit (1);
+       }
+
+       if (getuid () != 0)
        {
-               mpath_lib_exit(conf);
+               fprintf (stderr, "need to be root\n");
+               exit (1);
+       }
+
+       udev = udev_new();
+       multipath_conf = mpath_lib_init();
+       if(!multipath_conf) {
                udev_unref(udev);
-               return MPATH_PR_FILE_ERROR;
+               exit(1);
        }
 
-out :
-       mpath_lib_exit(conf);
+       ret = handle_args(argc, argv, 0);
+
+       mpath_lib_exit(multipath_conf);
        udev_unref(udev);
+
        return (ret >= 0) ? ret : MPATH_PR_OTHER;
 }
 
@@ -687,6 +808,7 @@
 
 static void usage(void)
 {
+       fprintf(stderr, VERSION_STRING);
        fprintf(stderr,
                        "Usage: mpathpersist [OPTIONS] [DEVICE]\n"
                        " Options:\n"
@@ -698,6 +820,7 @@
                        "                   4           Informational messages 
with trace enabled\n"
                        "    --clear|-C                 PR Out: Clear\n"
                        "    --device=DEVICE|-d DEVICE  query or change 
DEVICE\n"
+                       "    --batch-file|-f FILE       run commands from 
FILE\n"
                        "    --help|-h                  output this usage 
message\n"
                        "    --hex|-H                   output response in 
hex\n"
                        "    --in|-i                    request PR In command 
\n"
@@ -706,10 +829,8 @@
                        "    --param-aptpl|-Z           PR Out parameter 
'APTPL'\n"
                        "    --read-keys|-k             PR In: Read Keys\n"
                        "    --param-rk=RK|-K RK        PR Out parameter 
reservation key\n"
-                       "    --param-sark=SARK|-S SARK  PR Out parameter 
service "
-                       "action\n"
-                       "                               reservation key (SARK 
is in "
-                       "hex)\n"
+                       "    --param-sark=SARK|-S SARK  PR Out parameter 
service action\n"
+                       "                               reservation key (SARK 
is in hex)\n"
                        "    --preempt|-P               PR Out: Preempt\n"
                        "    --preempt-abort|-A         PR Out: Preempt and 
Abort\n"
                        "    --prout-type=TYPE|-T TYPE  PR Out command type\n"
@@ -721,11 +842,14 @@
                        "    --release|-L               PR Out: Release\n"
                        "    --report-capabilities|-c   PR In: Report 
Capabilities\n"
                        "    --reserve|-R               PR Out: Reserve\n"
-                       "    --transport-id=TIDS|-X TIDS  TransportIDs can be 
mentioned \n"
-                       "                               in several forms\n"
+                       "    --transport-id=TIDS|-X TIDS  TransportIDs can be 
mentioned\n"
+                       "                                 in several forms\n"
+                       "    --alloc-length=LEN|-l LEN  PR In: maximum 
allocation length\n"
                        " Examples:\n"
                        "     mpathpersist --out --register --param-sark=123abc 
--prout-type=5 /dev/mapper/mpath9\n"
-                       "     mpathpersist -i -k /dev/mapper/mpath9\n"  );
+                       "     mpathpersist -i -k /dev/mapper/mpath9\n"
+                       "     mpathpersist --out --reserve --param-sark=123abc 
--prout-type=8 -d /dev/mapper/mpath9\n"
+                       "     mpathpersist -i -s -d /dev/mapper/mpath9\n");
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/main.h 
new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/main.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/main.h        
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/main.h       
2019-06-25 17:30:27.000000000 +0200
@@ -2,6 +2,7 @@
        {"verbose", 1, NULL, 'v'},
        {"clear", 0, NULL, 'C'},
        {"device", 1, NULL, 'd'},
+       {"batch-file", 1, NULL, 'f' },
        {"help", 0, NULL, 'h'},
        {"hex", 0, NULL, 'H'},
        {"in", 0, NULL, 'i'},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/mpathpersist.8 
new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/mpathpersist.8
--- old/multipath-tools-0.8.1+8+suse.8c11498/mpathpersist/mpathpersist.8        
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/mpathpersist/mpathpersist.8       
2019-06-25 17:30:27.000000000 +0200
@@ -5,7 +5,7 @@
 .\"
 .\" 
----------------------------------------------------------------------------
 .
-.TH MPATHPERSIST 8 2016-10-30 "Linux"
+.TH MPATHPERSIST 8 2019-05-27 "Linux"
 .
 .
 .\" 
----------------------------------------------------------------------------
@@ -71,6 +71,11 @@
 Query or change DEVICE.
 .
 .TP
+.BI \--batch-file=\fIDEVICE\fB|\-f " FILE"
+Read commands from \fIFILE\fR. See section \(dqBATCH FILES\(dq below. This
+option can be given at most once.
+.
+.TP
 .B \--help|\-h
 Output this usage message.
 .
@@ -167,18 +172,114 @@
 .SH EXAMPLE
 .\" 
----------------------------------------------------------------------------
 .
-.TP
-Register the Service Action Reservation Key for the /dev/mapper/mpath9 device:
-\fBmpathpersist --out --register --param-sark=\fI123abc \fB--prout-type=\fI5 
/dev/mapper/mpath9\fR
-.TP
-Read the Service Action Reservation Key for the /dev/mapper/mpath9 device:
+.PP
+Register the key \(dq123abc\(dq for the /dev/mapper/mpath9 device:
+.RS
+\fBmpathpersist --out --register --param-sark=\fI123abc /dev/mapper/mpath9\fR
+.RE
+.PP
+Read registered reservation keys for the /dev/mapper/mpath9 device:
+.RS
 \fBmpathpersist -i -k \fI/dev/mapper/mpath9\fR
-.TP
-Reserve the Service Action Reservation Key for the /dev/mapper/mpath9 device:
-\fBmpathpersist --out --reserve --param-sark=\fI123abc \fB--prout-type=\fI8 
\fB-d \fI/dev/mapper/mpath9\fR
-.TP
+.RE
+.PP
+Create a reservation for the /dev/mapper/mpath9 device with the given
+reservation key:
+.RS
+\fBmpathpersist --out --reserve --param-rk=\fI123abc \fB--prout-type=\fI8 
\fB-d \fI/dev/mapper/mpath9\fR
+.RE
+.PP
 Read the reservation status of the /dev/mapper/mpath9 device:
+.RS
 \fBmpathpersist -i -s -d \fI/dev/mapper/mpath9\fR
+.RE
+.PP
+Release the previously created reservation (note that the prout-type needs to
+be the same as above):
+.RS
+\fBmpathpersist --out --release --param-rk=\fI123abc \fB--prout-type=\fI8 
\fB-d \fI/dev/mapper/mpath9\fR
+.RE
+.PP
+Remove the current key registered for this host (i.e. reset it to 0):
+.RS
+\fBmpathpersist --out --register-ignore -K \fI123abc\fB -S \fI0\fB 
\fI/dev/mapper/mpath9\fR
+.RE
+.PP
+Remove current reservation, and unregister all registered keys from all I_T 
nexuses:
+.RS
+\fBmpathpersist -oCK \fI123abc \fI/dev/mapper/mpath9\fR
+.RE
+.
+.
+.\" 
----------------------------------------------------------------------------
+.SH BATCH FILES
+.\" 
----------------------------------------------------------------------------
+.
+.PP
+The option \fI--batch-file\fR (\fI-f\fR) sets an input file to be processed
+by \fBmpathpersist\fR. Grouping commands in batch files can provide a speed
+improvement in particular on large installments, because \fBmpathpersist\fR
+needs to scan existing paths and maps only once during startup.
+.
+.PP
+The input file is a text file that is parsed
+line by line. Every line of the file is interpreted as a command line
+(i.e. list of options and parameters) for \fBmpathpersist\fR. Options
+and parameters are separated by one or more whitespace characters (space or 
TAB).
+Lines can, but do not have to, begin with the word \(dqmpathpersist\(dq.
+The \(dq#\(dq character, either at the beginning of the line or following
+some whitespace, denotes the start of a comment that lasts until the end of the
+line. Empty lines are allowed. Continuation of mpathpersist commands over
+multiple lines is not supported.
+.
+.PP
+All options listed in this man page, except \fI-f\fR and
+\fI-v\fR, are allowed in batch files. Both short and long option formats may 
be used.
+Using the  \fI-f\fR option inside the batch file is an error. The \fI-v\fR
+option is ignored in batch files.
+.
+.PP
+The multipath map on which to act must be specified on every input line, e.g. 
using the \fI-d\fR option.
+Commands acting on different multipath maps may be combined in a
+batch file, and multiple commands may act on the same multipath
+map. Commands are executed one by one, so
+that commands further down in the file see status changes caused by previous
+commands.
+If \fBmpathpersist\fR encounters an error while processing a line in the
+batch file, batch file processing is \fBnot\fR aborted; subsequent commands
+are executed nonetheless. The exit status of \fBmpathpersist\fR is the status
+of the first failed command, or 0 if all commands succeeded.
+.
+.PP
+If other options and parameters are used along with
+\fI-f\fR on the \fBmpathpersist\fR command line, the command line will be 
executed first, followed
+by the commands from the the batch file.
+.
+.PP
+Below is an example of a valid batch input file.
+.
+.PP
+.RS
+.EX
+# This is an mpathpersist input file.
+# Short and long forms of the same command
+-i -k /dev/dm-1 # short form, this comment is ignored
+mpathpersist --in --read-keys --device=/dev/dm-1
+
+# Mixing of long and short options, variable white space
+  --out  --register    -S  abcde     /dev/dm-1
+
+# Mixing of commands for different maps
+-ir /dev/dm-0
+-ir /dev/dm-1
+
+mpathpersist --out --param-rk abcde --reserve --prout-type 5 /dev/dm-1
+# This should now show a reservation
+-ir /dev/dm-1
+-oCK abcde /dev/dm-1
+--in --read-reservation /dev/dm-1
+.EE
+.RE
 .
 .
 .\" 
----------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipath/main.c 
new/multipath-tools-0.8.1+28+suse.fea562a/multipath/main.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipath/main.c   2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipath/main.c  2019-06-25 
17:30:27.000000000 +0200
@@ -133,11 +133,15 @@
 {
        fprintf (stderr, VERSION_STRING);
        fprintf (stderr, "Usage:\n");
-       fprintf (stderr, "  %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] 
[-b fil] [-q] [dev]\n", progname);
-       fprintf (stderr, "  %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", 
progname);
-       fprintf (stderr, "  %s -F [-v lvl] [-R num]\n", progname);
-       fprintf (stderr, "  %s [-t|-T]\n", progname);
-       fprintf (stderr, "  %s -h\n", progname);
+       fprintf (stderr, "  %s [-v level] [-B|-d|-i|-q|-r] [-b file] [-p 
policy] [device]\n", progname);
+       fprintf (stderr, "  %s [-v level] [-R retries] -f device\n", progname);
+       fprintf (stderr, "  %s [-v level] [-R retries] -F\n", progname);
+       fprintf (stderr, "  %s [-v level] [-l|-ll] [device]\n", progname);
+       fprintf (stderr, "  %s [-v level] [-a|-w] device\n", progname);
+       fprintf (stderr, "  %s [-v level] -W\n", progname);
+       fprintf (stderr, "  %s [-v level] [-i] [-c|-C] device\n", progname);
+       fprintf (stderr, "  %s [-v level] [-i] [-u|-U]\n", progname);
+       fprintf (stderr, "  %s [-h|-t|-T]\n", progname);
        fprintf (stderr,
                "\n"
                "Where:\n"
@@ -159,23 +163,28 @@
                "  -b fil  bindings file location\n"
                "  -w      remove a device from the wwids file\n"
                "  -W      reset the wwids file include only the current 
devices\n"
-               "  -p pol  force all maps to specified path grouping policy :\n"
+               "  -R num  number of times to retry removes of in-use devices\n"
+               "  -u      check if the device specified in the program 
environment should be a\n"
+               "          path in a multipath device\n"
+               "  -U      check if the device specified in the program 
environment is a\n"
+               "          multipath device with usable paths, see -C flag\n"
+               "  -p pol  force all maps to specified path grouping policy:\n"
                "          . failover            one path per priority group\n"
                "          . multibus            all paths in one priority 
group\n"
                "          . group_by_serial     one priority group per 
serial\n"
                "          . group_by_prio       one priority group per 
priority lvl\n"
                "          . group_by_node_name  one priority group per target 
node\n"
-               "  -v lvl  verbosity level\n"
+               "  -v lvl  verbosity level:\n"
                "          . 0 no output\n"
                "          . 1 print created devmap names only\n"
                "          . 2 default verbosity\n"
                "          . 3 print debug information\n"
-               "  -R num  number of times to retry removes of in-use devices\n"
-               "  dev     action limited to:\n"
-               "          . multipath named 'dev' (ex: mpath0) or\n"
-               "          . multipath whose wwid is 'dev' (ex: 60051..)\n"
-               "          . multipath including the path named 'dev' (ex: 
/dev/sda)\n"
-               "          . multipath including the path with maj:min 'dev' 
(ex: 8:0)\n"
+               "  device  action limited to:\n"
+               "          . multipath named 'device' (ex: mpath0)\n"
+               "          . multipath whose wwid is 'device' (ex: 60051...)\n"
+               "          . multipath including the path named 'device' (ex: 
/dev/sda or\n"
+               "            /dev/dm-0)\n"
+               "          . multipath including the path with maj:min 'device' 
(ex: 8:0)\n"
                );
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli.c 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli.c   2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli.c  2019-06-25 
17:30:27.000000000 +0200
@@ -467,6 +467,8 @@
 
        if (r) {
                *reply = genhelp_handler(cmd, r);
+               if (*reply == NULL)
+                       return EINVAL;
                *len = strlen(*reply) + 1;
                return 0;
        }
@@ -474,9 +476,11 @@
        h = find_handler(fingerprint(cmdvec));
 
        if (!h || !h->fn) {
+               free_keys(cmdvec);
                *reply = genhelp_handler(cmd, EINVAL);
+               if (*reply == NULL)
+                       return EINVAL;
                *len = strlen(*reply) + 1;
-               free_keys(cmdvec);
                return 0;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli.h 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli.h   2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli.h  2019-06-25 
17:30:27.000000000 +0200
@@ -100,15 +100,16 @@
                        if (m >= MAX_REPLY_LEN) {               \
                                condlog(1, "Warning: max reply length 
exceeded"); \
                                free(tmp);                      \
-                               r = NULL;                       \
+                               (r) = NULL;                     \
+                       } else {                                \
+                               (r) = REALLOC((r), (m) * 2);    \
+                               if ((r)) {                      \
+                                       memset((r) + (m), 0, (m)); \
+                                       (m) *= 2;               \
+                               }                               \
+                               else                            \
+                                       free(tmp);              \
                        }                                       \
-                       (r) = REALLOC((r), (m) * 2);            \
-                       if ((r)) {                              \
-                               memset((r) + (m), 0, (m));      \
-                               (m) *= 2;                       \
-                       }                                       \
-                       else                                    \
-                               free(tmp);                      \
                }                                               \
        } while (0)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli_handlers.c 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli_handlers.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/cli_handlers.c  
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/cli_handlers.c 
2019-06-25 17:30:27.000000000 +0200
@@ -730,7 +730,7 @@
                conf = get_multipath_config();
                pthread_cleanup_push(put_multipath_config, conf);
                r = store_pathinfo(vecs->pathvec, conf,
-                                  udevice, DI_ALL, &pp);
+                                  udevice, DI_ALL | DI_BLACKLIST, &pp);
                pthread_cleanup_pop(1);
                udev_device_unref(udevice);
                if (!pp) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.c 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/main.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.c  2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/main.c 2019-06-25 
17:30:27.000000000 +0200
@@ -220,6 +220,33 @@
        pthread_mutex_unlock(&config_lock);
 }
 
+/*
+ * If the current status is @oldstate, wait for at most @ms milliseconds
+ * for the state to change, and return the new state, which may still be
+ * @oldstate.
+ */
+enum daemon_status wait_for_state_change_if(enum daemon_status oldstate,
+                                           unsigned long ms)
+{
+       enum daemon_status st;
+       struct timespec tmo;
+
+       if (oldstate == DAEMON_SHUTDOWN)
+               return DAEMON_SHUTDOWN;
+
+       pthread_mutex_lock(&config_lock);
+       pthread_cleanup_push(config_cleanup, NULL);
+       st = running_state;
+       if (st == oldstate && clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) {
+               tmo.tv_nsec += ms * 1000 * 1000;
+               normalize_timespec(&tmo);
+               (void)pthread_cond_timedwait(&config_cond, &config_lock, &tmo);
+               st = running_state;
+       }
+       pthread_cleanup_pop(1);
+       return st;
+}
+
 /* must be called with config_lock held */
 static void __post_config_state(enum daemon_status state)
 {
@@ -256,11 +283,10 @@
                else if (running_state != DAEMON_IDLE) {
                        struct timespec ts;
 
-                       if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
-                               ts.tv_sec += 1;
-                               rc = pthread_cond_timedwait(&config_cond,
-                                                           &config_lock, &ts);
-                       }
+                       get_monotonic_time(&ts);
+                       ts.tv_sec += 1;
+                       rc = pthread_cond_timedwait(&config_cond,
+                                                   &config_lock, &ts);
                }
                if (!rc && (running_state != DAEMON_SHUTDOWN)) {
                        running_state = state;
@@ -1861,15 +1887,12 @@
        }
 
        if (pp->disable_reinstate) {
-               /* If we don't know how much time has passed, automatically
-                * reinstate the path, just to be safe. Also, if there are
-                * no other usable paths, reinstate the path
-                */
-               if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 ||
-                               pp->mpp->nr_active == 0) {
+               /* If there are no other usable paths, reinstate the path */
+               if (pp->mpp->nr_active == 0) {
                        condlog(2, "%s : reinstating path early", pp->dev);
                        goto reinstate_path;
                }
+               get_monotonic_time(&curr_time);
                if ((curr_time.tv_sec - pp->dis_reinstate_time ) > 
pp->mpp->san_path_err_recovery_time) {
                        condlog(2,"%s : reinstate the path after err recovery 
time", pp->dev);
                        goto reinstate_path;
@@ -1905,8 +1928,7 @@
         * delay the path, so there's no point in checking if we should
         */
 
-       if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0)
-               return 0;
+       get_monotonic_time(&curr_time);
        /* when path failures has exceeded the san_path_err_threshold
         * place the path in delayed state till san_path_err_recovery_time
         * so that the cutomer can rectify the issue within this time. After
@@ -2288,17 +2310,14 @@
        condlog(2, "path checkers start up");
 
        /* Tweak start time for initial path check */
-       if (clock_gettime(CLOCK_MONOTONIC, &last_time) != 0)
-               last_time.tv_sec = 0;
-       else
-               last_time.tv_sec -= 1;
+       get_monotonic_time(&last_time);
+       last_time.tv_sec -= 1;
 
        while (1) {
                struct timespec diff_time, start_time, end_time;
                int num_paths = 0, ticks = 0, strict_timing, rc = 0;
 
-               if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0)
-                       start_time.tv_sec = 0;
+               get_monotonic_time(&start_time);
                if (start_time.tv_sec && last_time.tv_sec) {
                        timespecsub(&start_time, &last_time, &diff_time);
                        condlog(4, "tick (%lu.%06lu secs)",
@@ -2357,8 +2376,8 @@
                }
 
                diff_time.tv_nsec = 0;
-               if (start_time.tv_sec &&
-                   clock_gettime(CLOCK_MONOTONIC, &end_time) == 0) {
+               if (start_time.tv_sec) {
+                       get_monotonic_time(&end_time);
                        timespecsub(&end_time, &start_time, &diff_time);
                        if (num_paths) {
                                unsigned int max_checkint;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.h 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/main.h
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.h  2019-04-24 
11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/main.h 2019-06-25 
17:30:27.000000000 +0200
@@ -20,6 +20,8 @@
 
 void exit_daemon(void);
 const char * daemon_status(void);
+enum daemon_status wait_for_state_change_if(enum daemon_status oldstate,
+                                           unsigned long ms);
 int need_to_delay_reconfig (struct vectors *);
 int reconfigure (struct vectors *);
 int ev_add_path (struct path *, struct vectors *, int);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/multipathd.8 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/multipathd.8
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/multipathd.8    
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/multipathd.8   
2019-06-25 17:30:27.000000000 +0200
@@ -25,6 +25,7 @@
 .RB [\| \-v\ \c
 .IR verbosity \|]
 .RB [\| \-B \|]
+.RB [\| \-w \|]
 .
 .
 .\" 
----------------------------------------------------------------------------
@@ -77,6 +78,12 @@
 multipathd. See
 .BR multipath.conf(5).
 .
+.TP
+.B \-w
+Since kernel 4.14 a new device-mapper event polling interface is used for 
updating
+multipath devices on dmevents. Use this flag to force it to use the old event
+waiting method, based on creating a seperate thread for each device.
+.
 .
 .
 .\" 
----------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/uxlsnr.c 
new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/uxlsnr.c
--- old/multipath-tools-0.8.1+8+suse.8c11498/multipathd/uxlsnr.c        
2019-04-24 11:43:52.000000000 +0200
+++ new/multipath-tools-0.8.1+28+suse.fea562a/multipathd/uxlsnr.c       
2019-06-25 17:30:27.000000000 +0200
@@ -130,10 +130,10 @@
 {
        struct timespec diff_time, end_time;
 
-       if (start_time.tv_sec &&
-           clock_gettime(CLOCK_MONOTONIC, &end_time) == 0) {
+       if (start_time.tv_sec) {
                unsigned long msecs;
 
+               get_monotonic_time(&end_time);
                timespecsub(&end_time, &start_time, &diff_time);
                msecs = diff_time.tv_sec * 1000 +
                        diff_time.tv_nsec / (1000 * 1000);
@@ -249,6 +249,18 @@
                        continue;
                }
 
+               /*
+                * Client connection. We shouldn't answer while we're
+                * configuring - nothing may be configured yet.
+                * But we can't wait forever either, because this thread
+                * must handle signals. So wait a short while only.
+                */
+               if (wait_for_state_change_if(DAEMON_CONFIGURE, 10)
+                   == DAEMON_CONFIGURE) {
+                       handle_signals(false);
+                       continue;
+               }
+
                /* see if a client wants to speak to us */
                for (i = 1; i < num_clients + 1; i++) {
                        if (polls[i].revents & POLLIN) {
@@ -268,9 +280,7 @@
                                                i, polls[i].fd);
                                        continue;
                                }
-                               if (clock_gettime(CLOCK_MONOTONIC, &start_time)
-                                   != 0)
-                                       start_time.tv_sec = 0;
+                               get_monotonic_time(&start_time);
                                if (recv_packet_from_client(c->fd, &inbuf,
                                                            uxsock_timeout)
                                    != 0) {


Reply via email to