3 years agolibmultipath: remove FREE_CONST() again
Martin Wilck [Wed, 7 Mar 2018 23:15:51 +0000 (00:15 +0100)]
libmultipath: remove FREE_CONST() again

The FREE_CONST macro is of questionable value, as reviewers have pointed
out. The users of this macro were mostly functions that called
uevent_get_dm_xyz(). But these functions don't need to return const char*,
as they allocate the strings they return. So my change of the prototype
was wrong. This patch reverts it. The few other users of FREE_CONST can
also be reverted to use char* instead of const char* with negligible risk.

Fixes: "libmultipath: fix compiler warnings for -Wcast-qual"
Fixes: "libmultipath: const qualifier for wwid and alias"

(Note: this reverts changes not committed upstream. But as these changes are
deeply in the middle of my large-ish series of patches, it's probably easier
to simply add this patch on top than to rebase the whole series).

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: fix wrong output of "multipath -t"
Martin Wilck [Wed, 7 Mar 2018 23:15:50 +0000 (00:15 +0100)]
libmultipath: fix wrong output of "multipath -t"

The default values printed by "multipath -t" or "multipathd show config"
for "detect_prio", "detect_checker", and "retain_attached_hw_handler"
don't match the actual compiled-in defaults. Moreover, several other
options would also be displayed wrongly if the defaults were changed.

Signed-off-by: Martin Wilck <>
3 years agoIntroduce the ibmultipath/unaligned.h header file
Bart Van Assche [Wed, 7 Mar 2018 23:15:49 +0000 (00:15 +0100)]
Introduce the ibmultipath/unaligned.h header file

This patch avoids that Coverity reports the following for the code
in libmultipath/prioritizers/alua_rtpg.c:

   CID 173256:  Integer handling issues  (SIGN_EXTENSION)
    Suspicious implicit sign extension: "buf[0]" with type "unsigned char" (8 bits, unsigned) is promoted in "((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) + 4" to type "int" (32 bits, signed), then sign-extended to type "unsigned long" (64 bits, unsigned).  If "((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) + 4" is greater than 0x7FFFFFFF, the upper bits of the result will all be 1.

Signed-off-by: Bart Van Assche <>
Signed-off-by: Martin Wilck <>
3 years agolibmultipath: Fix sgio_get_vpd()
Bart Van Assche [Wed, 7 Mar 2018 23:15:48 +0000 (00:15 +0100)]
libmultipath: Fix sgio_get_vpd()

Pass the VPD page number to sgio_get_vpd() such that the page needed
by the caller is queried instead of page 0x83. Fix the statement that
computes the length of the page returned by do_inq(). Fix the return
code check in the caller of sgio_get_vpd().

Signed-off-by: Bart Van Assche <>
Signed-off-by: Martin Wilck <>
3 years agokpartx: Improve reliability of find_loop_by_file()
Bart Van Assche [Wed, 7 Mar 2018 23:15:47 +0000 (00:15 +0100)]
kpartx: Improve reliability of find_loop_by_file()

Avoid that the strchr() call in this function examines uninitialized
data on the stack. This patch avoids that Coverity reports the following:

    CID 173252:  Error handling issues  (CHECKED_RETURN)
    "read(int, void *, size_t)" returns the number of bytes read, but it is ignored.

Signed-off-by: Bart Van Assche <>
Signed-off-by: Martin Wilck <>
3 years agolibmultipath, alloc_path_with_pathinfo(): Ensure that pp->wwid is '\0'-terminated
Bart Van Assche [Wed, 7 Mar 2018 23:15:46 +0000 (00:15 +0100)]
libmultipath, alloc_path_with_pathinfo(): Ensure that pp->wwid is '\0'-terminated

Discovered by Coverity (CID 173257).

Signed-off-by: Bart Van Assche <>
Signed-off-by: Martin Wilck <>
3 years agolibmultipath: enable feature disable changed wwid by default
Chongyun Wu [Wed, 7 Mar 2018 23:15:45 +0000 (00:15 +0100)]
libmultipath: enable feature disable changed wwid by default

enable feature disable changed wwid by default.

Signed-off-by: Chongyun Wu <>
Signed-off-by: Martin Wilck <>
3 years agomultipathd: add lock protection for cli_list_status
Chongyun Wu [Wed, 7 Mar 2018 23:15:44 +0000 (00:15 +0100)]
multipathd: add lock protection for cli_list_status

cli_list_status will access vecs->pathvec which should have lock
protection, otherwise might get inconsistent data or other

Signed-off-by: Chongyun Wu <>
Signed-off-by: Martin Wilck <>
3 years agomultipath-tools: reformat and update comments in hwtable
Xose Vazquez Perez [Wed, 7 Mar 2018 23:10:00 +0000 (00:10 +0100)]
multipath-tools: reformat and update comments in hwtable

Cc: Christophe Varoqui <>
Cc: device-mapper development <>
Signed-off-by: Xose Vazquez Perez <>
3 years agomultipath-tools: move Nimble and SGI to HPE section
Xose Vazquez Perez [Wed, 7 Mar 2018 23:09:59 +0000 (00:09 +0100)]
multipath-tools: move Nimble and SGI to HPE section

They were absorbed by HPE time ago.

Cc: Christophe Varoqui <>
Cc: device-mapper development <>
Signed-off-by: Xose Vazquez Perez <>
3 years agomultipath-tools: build: prevent intermediate file deletion
Martin Wilck [Wed, 7 Mar 2018 23:08:59 +0000 (00:08 +0100)]
multipath-tools: build: prevent intermediate file deletion

By default, "make" removes intermediate files from implicit rules
if they are the only dependency. Prevent that by using .SECONDARY.
Otherwise some files will be re-built upon second invocation of "make".

Fixes: e39283ebd79b "multipath-tools: add dependency tracking to Makefiles"
Reported-by: Xose Vazquez Perez <>
Signed-off-by: Martin Wilck <>
3 years agomultipath: fix clang warning in delegate_to_multipathd
Martin Wilck [Wed, 7 Mar 2018 23:08:58 +0000 (00:08 +0100)]
multipath: fix clang warning in delegate_to_multipathd

Fixes this warning from clang:

main.c:628:11: warning: variable 'reply' is used uninitialized
whenever 'if' condition is true [-Wsometimes-uninitialized]
main.c:609:32: note: initialize the variable 'reply' to silence this warning

Fixes: 506d253b7f89 "multipath: delegate dangerous commands to multipathd"
Reported-by: Xose Vazquez Perez <>
Signed-off-by: Martin Wilck <>
3 years agomultipathd: fix -Wpointer-to-int-cast warning in uxlsnr
Martin Wilck [Wed, 7 Mar 2018 23:08:57 +0000 (00:08 +0100)]
multipathd: fix -Wpointer-to-int-cast warning in uxlsnr

Fixes: "multipathd: release uxsocket and resource when cancel thread"
Signed-off-by: Martin Wilck <>
3 years agolibmultipath: fix crash on shutdown if io_err thread isn't running
Martin Wilck [Wed, 7 Mar 2018 23:08:56 +0000 (00:08 +0100)]
libmultipath: fix crash on shutdown if io_err thread isn't running

If we've never created the io_error checker thread, we shouldn't
cancel it.

Fixes: 160da9fa4339 "multipathd: start marginal path checker thread

Signed-off-by: Martin Wilck <>
3 years agomultipath-tools: add info about how to get a release directly from gitweb
Xose Vazquez Perez [Fri, 12 Jan 2018 16:56:41 +0000 (17:56 +0100)]
multipath-tools: add info about how to get a release directly from gitweb

gitweb is able to extract and serve a release right away.

Cc: Christophe Varoqui <>
Cc: device-mapper development <>
Signed-off-by: Xose Vazquez Perez <>
3 years agoBump version to 0.7.5 0.7.5
Christophe Varoqui [Wed, 7 Mar 2018 09:52:25 +0000 (10:52 +0100)]
Bump version to 0.7.5

3 years agomultipathd: start marginal path checker thread lazily
Martin Wilck [Tue, 6 Mar 2018 21:18:42 +0000 (22:18 +0100)]
multipathd: start marginal path checker thread lazily

I noticed that the io_error checker thread accounts for most of the
activity of multipathd even if the marginal path checking paramters
are not set (which is still the default in most installations I assume).

Therefore, start the io_error checker thread only if there's at least
one map with marginal error path checking configured. Also, make sure
the thread is really up when start_io_err_stat_thread() returns.

This requires adding a "vecs" argument to setup_map, because vecs
needs to be passed to the io_error checking code.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: fix race in stop_io_err_stat_thread
Martin Wilck [Tue, 6 Mar 2018 21:18:41 +0000 (22:18 +0100)]
libmultipath: fix race in stop_io_err_stat_thread

It's wrong, and unnecessary, to call pthread_kill after
pthread_cancel. I have observed cases where the io_err checker
thread hung in libpthread after receiving the USR2 signal, in particular
when multipathd is run under strace. (If multipathd is killed with
SIGINT under strace, and the io_error thread is running, it happens
almost every time). If this happens, the io_err thread
tries to obtain a mutex in the urcu code (presumably rcu_unregister_thread())
and the main thread hangs in pthread_join().

With the change from this patch, the thread is shut down cleanly. I haven't
observed the hang under strace with the patch.

Signed-off-by: Martin Wilck <>
3 years agomultipathd: fix signal blocking logic
Martin Wilck [Mon, 5 Mar 2018 23:15:07 +0000 (00:15 +0100)]
multipathd: fix signal blocking logic

multipathd is supposed to block all signals in all threads, except
the uxlsnr thread which handles termination and reconfiguration
signals (SIGUSR1) in its ppoll() call, SIGUSR2 in the waiter thread
and the marginal path checker thread, and occasional SIGALRM. The current
logic does exactly the oppsite, it blocks termination signals in SIGPOLL and
allows multipathd to be killed e.g. by SIGALRM.

Fix that by inverting the logic. The argument to pthread_sigmask and
ppoll is the set of *blocked* signals, not vice versa.

The marginal paths code needs to unblock SIGUSR2 now explicity, as
the dm-event waiter code already does. Doing this with pselect()
avoids asynchronous cancellation.

Fixes: 810082e "libmultipath, multipathd: Rework SIGPIPE handling"
Fixes: 534ec4c "multipathd: Ensure that SIGINT, SIGTERM, SIGHUP and SIGUSR1
are delivered to the uxsock thread"

Signed-off-by: Martin Wilck <>
3 years agomultipathd: update path group prio in check_path
Martin Wilck [Mon, 5 Mar 2018 23:15:06 +0000 (00:15 +0100)]
multipathd: update path group prio in check_path

The previous patch "libmultipath: don't update path groups when printing"
removed the call to path_group_prio_update() in the printing code path.
To compensate for that, recalculate path group prio also when it's not
strictly necessary (i.e. if failback "manual" is set).

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: foreign/nvme: implement path display
Martin Wilck [Mon, 5 Mar 2018 23:15:05 +0000 (00:15 +0100)]
libmultipath: foreign/nvme: implement path display

implement display of path information for NVMe foreign paths and maps.
With this patch, I get output like this for Linux NVMe soft targets:

nvme-submultipathd show topology
sys0:NQN:subsysname (uuid.96926ba3-b207-437c-902c-4a4df6538c3f) [nvme] nvme0n1 NVMe,Linux,4.15.0-r
size=2097152 features='n/a' hwhandler='n/a' wp=rw
`-+- policy='n/a' prio=n/a status=n/a
  |- 0:1:1 nvme0c1n1 0:0 n/a n/a live
  |- 0:2:1 nvme0c2n1 0:0 n/a n/a live
  |- 0:3:1 nvme0c3n1 0:0 n/a n/a live
  `- 0:4:1 nvme0c4n1 0:0 n/a n/a live

multipathd show paths format '%G %d %i %o %z %m %N'
foreign dev       hcil  dev_st serial           multipath host WWNN
[nvme]  nvme0c1n1 0:1:1 live   1c2c86659503a02f nvme0n1   rdma:traddr=,trsvcid=4420
[nvme]  nvme0c2n1 0:2:1 live   1c2c86659503a02f nvme0n1   rdma:traddr=,trsvcid=4420
[nvme]  nvme0c3n1 0:3:1 live   1c2c86659503a02f nvme0n1   rdma:traddr=,trsvcid=4420
[nvme]  nvme0c4n1 0:4:1 live   1c2c86659503a02f nvme0n1   rdma:traddr=,trsvcid=4420

(admittedly, I abused the 'WWNN' wildcard here a bit to display information
which is helpful for NVMe over RDMA).

Signed-off-by: Martin Wilck <>
3 years agomultipathd: use foreign API
Martin Wilck [Mon, 5 Mar 2018 23:15:04 +0000 (00:15 +0100)]
multipathd: use foreign API

Call into the foreign library code when paths are discovered, uevents
are received, and in the checker loop. Furthermore, use the foreign
code to print information in the "multipathd show paths", "multipathd
show maps", and "multipathd show topology" client commands.

We don't support foreign data in the individual "show map" and "show path"
commands, and neither in the "json" commands. The former is a deliberate
decision, the latter could be added if desired.

Signed-off-by: Martin Wilck <>
3 years agomultipath: use foreign API
Martin Wilck [Mon, 5 Mar 2018 23:15:03 +0000 (00:15 +0100)]
multipath: use foreign API

Use the "foreign" code to print information about multipath maps
owned by foreign libraries in print mode (multipath -ll, -l).

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: pathinfo: call into foreign library
Martin Wilck [Mon, 5 Mar 2018 23:15:02 +0000 (00:15 +0100)]
libmultipath: pathinfo: call into foreign library

This actually enables the use of foreign paths.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath/foreign: nvme foreign library
Martin Wilck [Mon, 5 Mar 2018 23:15:01 +0000 (00:15 +0100)]
libmultipath/foreign: nvme foreign library

This still contains stubs for path handling and checking, but it's functional
for printing already.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath/print: add "%G - foreign" wildcard
Martin Wilck [Mon, 5 Mar 2018 23:15:00 +0000 (00:15 +0100)]
libmultipath/print: add "%G - foreign" wildcard

This adds a format field to identify foreign maps as such, and
uses it in default-formatted topology output (generic_style()).

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: API for foreign multipath handling
Martin Wilck [Mon, 5 Mar 2018 23:14:59 +0000 (00:14 +0100)]
libmultipath: API for foreign multipath handling

Add an API for "foreign" multipaths. Foreign libraries are loaded
from ${multipath_dir}/libforeign-*.so, as we do for checkers.

Refer to "foreign.h" for details about the API itself. Like we do for
checkers, high-level multipath code isn't supposed to call the API directly,
but rather the wrapper functions declared in "foreign.h".

This API is used only for displaying information and for logging. An extension to
other functionality (such as monitoring or administration) might be feasible,
but is not planned.

Foreign libraries communicate with libmultipath through the API defined in
"foreign.h". The foreign library can implement multipath maps, pathgroups,
and paths as it likes, they just need to provide the simple interfaces
defined in "generic.h" to libmultipath. These interfaces are used in libmultipath's
"print" implementation to convey various bits of information to users. By
using the same interfaces for printing that libmultipath uses internally,
foreign library implementations can focus on the technical side without
worrying about output formatting compatibility.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: print: use generic API for get_x_layout()
Martin Wilck [Mon, 5 Mar 2018 23:14:58 +0000 (00:14 +0100)]
libmultipath: print: use generic API for get_x_layout()

Introduce new functions _get_path_layout and _get_multipath_layout
using the new "generic" API to determine field widths, and map the
old API to them.

Furthermore, replace the boolean "header" by an enum with 3 possible
values. The new value LAYOUT_RESET_NOT allows calling the get_x_layout
function several times and determine the overall field width.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: print: convert API to generic data type
Martin Wilck [Mon, 5 Mar 2018 23:14:57 +0000 (00:14 +0100)]
libmultipath: print: convert API to generic data type

Convert higher level API (snprint_multipath_topology() etc) to
using the generic multipath API. This will allow "foreign"
multipath objects that implement the generic API to be printed
exactly like native multipathd objects.

The previous API (using "struct multipath*" and "struct path" remains
in place through macros mapping to the new functions. By doing this
and testing in regular setups, it's easily verified that the new
API works and produces the same results.

Moreover, abstract out the code to determine the output format from multipath
properties into snprint_multipath_style(), to be able to use it as generic
->style() method.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: "generic multipath" interface
Martin Wilck [Mon, 5 Mar 2018 23:14:56 +0000 (00:14 +0100)]
libmultipath: "generic multipath" interface

This patch adds a simplified abstract interface to the multipath data structures.
The idea is to allow "foreign" data structures to be treated by libmultipath
if they implement the same interface. Currently, the intention is to use this
only to provide formatted output about from this interface.

This interface assumes only that the data structure is organized in maps
containing path groups containing paths, and that formatted printing (using
the wildcards defined in libmultipath) is possible on each level of the data

The patch also implements the interface for the internal dm_multipath data

The style() method looks a bit exotic, but it's necessary because
print_multipath_topology() uses different formats depending on the mpp
properties. This needs to be in the generic interface, too, if we want to
produce identical output.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: add vector_convert()
Martin Wilck [Mon, 5 Mar 2018 23:14:55 +0000 (00:14 +0100)]
libmultipath: add vector_convert()

This is a handy helper for creating one vector from another,
mapping each element of the origin vector to an element of
the target vector with a given conversion function. It can
also be used to "concatenate" vectors by passing in a non-NULL first

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: add vector_free_const()
Martin Wilck [Mon, 5 Mar 2018 23:14:54 +0000 (00:14 +0100)]
libmultipath: add vector_free_const()

... to dispose of constant vectors (const struct _vector*).

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agomultipath-tools: use -Werror=cast-qual
Martin Wilck [Mon, 5 Mar 2018 23:14:53 +0000 (00:14 +0100)]
multipath-tools: use -Werror=cast-qual

Casting "const" away is often an indicator for wrong code.
Add a compiler flag to warn about such possible breakage.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: fix compiler warnings for -Wcast-qual
Martin Wilck [Mon, 5 Mar 2018 23:14:52 +0000 (00:14 +0100)]
libmultipath: fix compiler warnings for -Wcast-qual

Fix the warnings that were caused by adding the -Wcast-qual compiler
flag in the previous patch.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: use "const" in devmapper code
Martin Wilck [Mon, 5 Mar 2018 23:14:51 +0000 (00:14 +0100)]
libmultipath: use "const" in devmapper code

Improve use of "const" qualifiers in libmultipath's devmapper code.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath/print: use "const" where appropriate
Martin Wilck [Mon, 5 Mar 2018 23:14:50 +0000 (00:14 +0100)]
libmultipath/print: use "const" where appropriate

Convert the print.h/print.c code to use "const" qualifiers
properly. This is generally considered good programming practice,
and the printing code shouldn't change any objects anyway.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: don't update path groups when printing
Martin Wilck [Mon, 5 Mar 2018 23:14:49 +0000 (00:14 +0100)]
libmultipath: don't update path groups when printing

Updating the prio values for printing makes no sense. The user wants to see
the prio values multipath is actually using for path group selection, and
updating the values here means actually lying to the user if the prio values
have changed, but multipathd hasn't updated them internally.

If we really don't update the pathgroup prios when we need to, this should be
fixed elsewhere. The current wrong output would just hide that if it occured.

Moreover, correctness forbids changing properties so deeply in a code path
that's supposed to print them only. Finally, this piece of code prevents the
print.c code to be converted to proper "const" usage.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: parser: use call-by-value for "snprint" methods
Martin Wilck [Mon, 5 Mar 2018 23:14:48 +0000 (00:14 +0100)]
libmultipath: parser: use call-by-value for "snprint" methods

Convert the snprint methods for all keywords to call-by-value,
and use "const" qualifier for the "data" argument. This makes sure
that "snprint" type functions don't modify the data they're print,
helps compile-time correctness checking, and allows more proper
"const" cleanups in the future.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: get rid of selector "hack" in print.c
Martin Wilck [Mon, 5 Mar 2018 23:14:47 +0000 (00:14 +0100)]
libmultipath: get rid of selector "hack" in print.c

By properly linking the path groups with their parent multipath,
we don't need this "hack" any more.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agolibmultipath: remove unused "stdout helpers"
Martin Wilck [Mon, 5 Mar 2018 23:14:46 +0000 (00:14 +0100)]
libmultipath: remove unused "stdout helpers"

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agomultipath(d)/Makefile: add explicit dependency on libraries
Martin Wilck [Mon, 5 Mar 2018 23:14:45 +0000 (00:14 +0100)]
multipath(d)/Makefile: add explicit dependency on libraries

Otherwise the binaries won't be re-linked if the libraries change.

Signed-off-by: Martin Wilck <>
Reviewed-by: Benjamin Marzinski <>
3 years agomultipath-tools: add INSPUR/MCS to hardware table
Tom Geng(耿芳忠) [Mon, 29 Jan 2018 06:04:29 +0000 (06:04 +0000)]
multipath-tools: add INSPUR/MCS to hardware table

Hi, Xose,
I sent the patch to dm-devel last week, but forgot to CC you. Please help to
review and have chance to submit to the mainline.
Thank you a lot.

From 091bae5fec22c61f0c3e6f9ab848fecae5203122 Mon Sep 17 00:00:00 2001
From: Tom Geng <>
Date: Tue, 23 Jan 2018 15:33:09 +0800
Subject: [PATCH] multipath-tools: add INSPUR/MCS to hardware table

3 years agomultipath: print sysfs state in fast list mode
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:14 +0000 (21:42 -0600)]
multipath: print sysfs state in fast list mode

commit b123e711ea2a4b471a98ff5e26815df3773636b5 "libmultipath: cleanup
orphan device states" stopped multipathd from showing old state for
orphan paths by checking if pp->mpp was set, and only printing the state
if it was.   Unfortunately, when "multipath -l" is run, pp->mpp isn't
set. While the checker state isn't checked and shouldn't be printed with
"-l", the sysfs state can be, and was before b123e711. This patch sets
pp->mpp in fast list mode, so that the sysfs state gets printed. It
also verifies that the path exists in sysfs, and if not, marks it as

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: change spurious uevent msg priority
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:13 +0000 (21:42 -0600)]
multipathd: change spurious uevent msg priority

The "spurious uevent, path already in pathvec" is not anything to worry
about, so it should not have the error priority.

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agoFix set_no_path_retry() regression
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:12 +0000 (21:42 -0600)]
Fix set_no_path_retry() regression

commit 0f850db7fceb6b2bf4968f3831efd250c17c6138 "multipathd: clean up
set_no_path_retry" has a bug in it. It made set_no_path_retry
never reset mpp->retry_ticks, even if the device was in recovery mode,
and there were valid paths. This meant that adding new paths didn't
remove a device from recovery mode, and queueing could get disabled,
even while there were valid paths. This patch fixes that.

This patch also fixes a bug in cli_restore_queueing() and
cli_restore_all_queueing(), where a device that had no_path_retry
set to "queue" would enter recovery mode (although queueing would
never actually get disabled).

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: remove unused configure parameter
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:11 +0000 (21:42 -0600)]
multipathd: remove unused configure parameter

configure() is always called with start_waiters=1, so there is no point
in having the parameter. Remove it.

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: remove coalesce_paths from ev_add_map
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:10 +0000 (21:42 -0600)]
multipathd: remove coalesce_paths from ev_add_map

If ev_add_map is called for a multipath device that doesn't exist in
device-mapper, it will call coalesce_paths to add it.  This doesn't work
and hasn't for years. It doesn't add the map to the mpvec, or start up
waiters, or do any of the necessary things that do get done when you
call ev_add_map for a map that does exist in device mapper.

Fortunately, there are only two things that call ev_add_map. uev_add_map
makes sure that the device does exist in device-mapper before calling
ev_add_map, and cli_add_map creates the device first and then calls
ev_add_map, if the device doesn't exist.

So, there is no reason for coalesce_paths to be in ev_add_map. This
removes it.

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipath: fix DEF_TIMEOUT use
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:09 +0000 (21:42 -0600)]
multipath: fix DEF_TIMEOUT use

DEF_TIMEOUT is specified in seconds. The io_hdr timeout is specified in
milliseconds, so we need to convert it. Multipath should be waiting
longer than 30 milliseconds here. If there are concerns that 30 seconds
may be too long, we could always make this configurable, using
conf->checker_timeout if set.

Reviewed-by: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agolibmultipath: fix tur checker locking
Benjamin Marzinski [Tue, 13 Feb 2018 03:42:08 +0000 (21:42 -0600)]
libmultipath: fix tur checker locking

Commit 6e2423fd fixed a bug where the tur checker could cancel a
detached thread after it had exitted. However in fixing this, the new
code grabbed a mutex (to call condlog) while holding a spin_lock.  To
deal with this, I've done away with the holder spin_lock completely, and
replaced it with two atomic variables, based on a suggestion by Martin

The holder variable works exactly like before.  When the checker is
initialized, it is set to 1. When a thread is created it is incremented.
When either the thread or the checker are done with the context, they
atomically decrement the holder variable and check its value. If it
is 0, they free the context. If it is 1, they never touch the context

The other variable has changed. First, ct->running and ct->thread have
switched uses. ct->thread is now only ever accessed by the checker,
never the thread.  If it is non-NULL, a thread has started up, but
hasn't been dealt with by the checker yet. It is also obviously used
by the checker to cancel the thread.

ct->running is now an atomic variable.  When the thread is started
it is set to 1. When the checker wants to kill a thread, it atomically
sets the value to 0 and reads the previous value.  If it was 1,
the checker cancels the thread. If it was 0, the nothing needs to be
done.  After the checker has dealt with the thread, it sets ct->thread
to NULL.

Right before the thread finishes and pops the cleanup handler, it
atomically sets the value of ct->running to 0 and reads the previous
value. If it was 1, the thread just pops the cleanup handler and exits.
If it was 0, then the checker is trying to cancel the thread, and so the
thread calls pause(), which is a cancellation point.

Cc: Martin Wilck <>
Cc: Bart Van Assche <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipath-tools: handle exit signal immediately
Martin Wilck [Tue, 30 Jan 2018 14:16:24 +0000 (15:16 +0100)]
multipath-tools: handle exit signal immediately

multipathd shouldn't try to service any more client connections
when it receives an exit signal. Moreover, ppoll() can return
success even if signals occured. So check for reconfigure or
log_reset signals after handling pending client requests.

Based on an analysis by Chongyun Wu.

Reported-by: Chongyun Wu <>
Signed-off-by: Martin Wilck <>
3 years agolibmultipath: increase path product_id/rev field size for NVMe
Martin Wilck [Fri, 19 Jan 2018 11:55:35 +0000 (12:55 +0100)]
libmultipath: increase path product_id/rev field size for NVMe

NVMe allows longer strings for the model (product) and firmware rev
than SCSI.

Signed-off-by: Martin Wilck <>
3 years agomultipath-tools: add dependency tracking to Makefiles
Martin Wilck [Fri, 19 Jan 2018 00:19:44 +0000 (01:19 +0100)]
multipath-tools: add dependency tracking to Makefiles

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: ignore natively multipathed NVME devices
Martin Wilck [Fri, 19 Jan 2018 00:19:43 +0000 (01:19 +0100)]
libmultipath: ignore natively multipathed NVME devices

Such devices have a parent with SUBSYSTEM="nvme-subsystem", not "nvme".
Furthermore, avoid a possible segfaults NULL checks.

Signed-off-by: Martin Wilck <>
3 years agomultipath.rules: handle NVME devices
Martin Wilck [Fri, 19 Jan 2018 00:19:42 +0000 (01:19 +0100)]
multipath.rules: handle NVME devices

Note: ID_WWN is set in 60-persistent-storage.rules in current systemd.
That won't work well together with us installing multipath.rules as
56-multipath.rules -  multipath -u won't see ID_WWN.

However, we have strong reasons to run before blkid is invoked.
ID_WWN determination for NVMe should be moved to an earlier udev rule.
See systemd pull request #7594 on github.

Signed-off-by: Martin Wilck <>
3 years agomultipathd: ignore uevents for non-mpath devices
Martin Wilck [Mon, 29 Jan 2018 23:57:50 +0000 (00:57 +0100)]
multipathd: ignore uevents for non-mpath devices

multipathd can't deal with other devices anyway. Proceeding further
with events for other devices just generates log noise.

Based on an idea from Ritika Srivastava <>.
("multipath-tools: Skip CHANGE uevent for non-mpath devices").

Changes in v2: always return immediately for non-mpath case
  (Ritika Srivastava)

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: add uevent_is_mpath
Martin Wilck [Wed, 17 Jan 2018 07:49:38 +0000 (08:49 +0100)]
libmultipath: add uevent_is_mpath

This function can be used to test if an uevent belongs to valid
multipath device. Unit tests are also added.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: move UUID_PREFIX to devmapper.h
Martin Wilck [Wed, 17 Jan 2018 07:49:37 +0000 (08:49 +0100)]
libmultipath: move UUID_PREFIX to devmapper.h

This constant is useful elsewhere, too.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: const qualifier for wwid and alias
Martin Wilck [Wed, 17 Jan 2018 07:49:36 +0000 (08:49 +0100)]
libmultipath: const qualifier for wwid and alias

Add "const" qualifiers to some function arguments and fields,
in order to tidy up const handling of libmultipath.

Signed-off-by: Martin Wilck <>
3 years agolibmultipath: refactor uevent_get_XXX
Martin Wilck [Wed, 17 Jan 2018 07:49:35 +0000 (08:49 +0100)]
libmultipath: refactor uevent_get_XXX

Use common helper functions for uevent_get_XXX.

Signed-off-by: Martin Wilck <>
3 years agotests: cmocka-based unit test for uevent_get_XXX
Martin Wilck [Wed, 17 Jan 2018 07:49:34 +0000 (08:49 +0100)]
tests: cmocka-based unit test for uevent_get_XXX

This patch starts a simple unit test framework for multipath-tools
based on the cmocka framework ( As a start,
it adds unit tests for the uevent_get_XXX set of functions.

Note that some tests currently fail. This will be fixed by the
following patches.

Signed-off-by: Martin Wilck <>
3 years agoassemble_map: no newline at end of params string
Martin Wilck [Wed, 17 Jan 2018 07:49:33 +0000 (08:49 +0100)]
assemble_map: no newline at end of params string

This newline is superfluous for device-mapper, and causes ugly
debug output.

Signed-off-by: Martin Wilck <>
3 years agomultipathd: release uxsocket and resource when cancel thread
Wuchongyun [Wed, 17 Jan 2018 08:15:05 +0000 (08:15 +0000)]
multipathd: release uxsocket and resource when cancel thread

Hi Matin,
I think it's a good idea to move the close(ux_sock) call further up to avoid new clients trying to connect, Below is the new patch for your comment. Please help to review. Thanks.

Issue description: we meet this issue: when multipathd initilaze and
call uxsock_listen to create unix domain socket, but return -1 and
the errno is 98 and then the uxsock_listen return null. After multipathd
startup we can't receive any user's multipathd commands to finish the
new multipath creation or any operations any more!

We found that uxlsnr thread's cleanup function not close the sockets
also not release the clients when cancel thread, the domain socket
will be release by the system. In any special environment like the
machine's load is very heavy or any situations, the system may not close
the old domain socket when we try to create and bind the new domain
socket may return errno:98(Address already in use).

And also we make some experiments:
in uxsock_cleanup if we close the ux_sock first and then immdediately
call ux_socket_listen to create new ux_sock and initialization will be
OK; if we don't close the ux_sock and call ux_socket_listen will return
-1 and errno = 98.

So we believe that close uxsocket and release clients  when cancel
thread can make sure of that new starting multipathd thread can
create new uxsocket successfully, also can receive multipathd commands
properly. And this path can fix clients' memory leak too.

Signed-off-by: Chongyun Wu <>
3 years agolibmultipath: path latency: remove warnings
Martin Wilck [Sat, 13 Jan 2018 21:19:38 +0000 (22:19 +0100)]
libmultipath: path latency: remove warnings

The warnings at here are pointless. We are looking at a single
path only. Firstly, the standdard deviation for this measurement
can't be "too low" - the lower, the more precise the measurement,
the better. Secondly, a high standard deviation indicates an
unstable path with highly variable latency. Not good, but nothing
to warn about here.

What matters for the selection of "base_num" is not how a single
path behaves, but how different paths of the same path group relate
to each other, which we don't know at this point at the code.

What we want to avoid is too fine a differentiation, in particular
in combination with group_by_prio, because we'd loose the ability for
load balancing. But this is rather a topic for the man page or a
"best practices" document.

3 years agolibmultipath: path latency: simplify getprio()
Martin Wilck [Sat, 13 Jan 2018 21:19:37 +0000 (22:19 +0100)]
libmultipath: path latency: simplify getprio()

The log standard deviation can be calculated much more simply
by realizing

   sum_n (x_i - avg(x))^2 == sum_n x_i^2 - n * avg(x)^2

Also, use timespecsub rather than the custom timeval_to_usec,
and avoid taking log(0).

3 years agolibmultipath: path latency: log threshold with p2
Martin Wilck [Sat, 13 Jan 2018 21:19:36 +0000 (22:19 +0100)]
libmultipath: path latency: log threshold with p2

This is not a critical error. It just means that the path in
question will have low priority (rightly so, if it has >100s latency).

3 years agolibmultipath: path latency: fix default base num
Martin Wilck [Sat, 13 Jan 2018 21:19:35 +0000 (22:19 +0100)]
libmultipath: path latency: fix default base num

I don't think anyone can measure latency to 1% accuracy. It's
better to not even pretend to be able to. 10% should be fine
even for the most latency-critical environments.

3 years agomultipathd.service: set TasksMax=infinity
Martin Wilck [Sat, 13 Jan 2018 21:19:34 +0000 (22:19 +0100)]
multipathd.service: set TasksMax=infinity

Systemd 228 introduced a global task limit of 512 for system services.
System 231 changed this to 15% of pid_max, or 4915.
In particular the one of systemd 228 is too low for multipathd with
many LUNs. Use TasksMax=infinity to overcome this limitation.

3 years agotest-kpartx: add test for mapping without UUID
Martin Wilck [Sat, 13 Jan 2018 21:19:33 +0000 (22:19 +0100)]
test-kpartx: add test for mapping without UUID

kpartx shouldn't remove these mappings.

3 years agomultipathd: fix compiler warning for uev_pathfail_check
Martin Wilck [Sat, 13 Jan 2018 21:19:32 +0000 (22:19 +0100)]
multipathd: fix compiler warning for uev_pathfail_check

gcc7 spits out an indentation warning for this function.

Fixes: 8392431 "multipath-tools: check null path before handle path-failed event"

3 years agomultipathd.service: drop Before=lvm2-lvmetad.service
Martin Wilck [Sat, 13 Jan 2018 21:19:31 +0000 (22:19 +0100)]
multipathd.service: drop Before=lvm2-lvmetad.service

lvm2-lvmetad does not depend on multipathd. On the contrary,
when multipathd sets up a map that contains LVM PVs, it's good
if lvm2-lvmetad is already running.

3 years agomultipathd.socket: add
Martin Wilck [Sat, 13 Jan 2018 21:19:30 +0000 (22:19 +0100)]
multipathd.socket: add

Without this, "systemctl enable multipathd.service" spits out
an error message.

3 years agokpartx.rules: fix by-id/scsi-* for user_friendly_names
Martin Wilck [Sat, 13 Jan 2018 21:19:29 +0000 (22:19 +0100)]
kpartx.rules: fix by-id/scsi-* for user_friendly_names

With user_friendly names (or generally, with aliases), the udev
rules create /dev/disk/by-id/scsi-${ALIAS} rather than
/dev/disk/by-id/scsi-${ID_SERIAL}. Fix that.

3 years agomultipath -C: decrease log level
Martin Wilck [Sat, 13 Jan 2018 21:19:28 +0000 (22:19 +0100)]
multipath -C: decrease log level

Avoid that the positive case ("usable paths found") spams the
syslog on systems with many LUNs.

3 years agolibmultipath: hwtable: no_path_retry="queue" for NetApp NVMe
Martin Wilck [Tue, 23 Jan 2018 17:07:04 +0000 (18:07 +0100)]
libmultipath: hwtable: no_path_retry="queue" for NetApp NVMe

Netapp requested this default setting for NetApp E-Series NVMe in addition to "multibus".
Also, finalize the product ID regex after consulting with NetApp (the FW reporting just
"ONTAP Controller" was beta only).

This obsoletes my previous "FIX" patch
'FIX "libmultipath: hwtable: multibus for NetApp NVMe-FC'

Fixes: "libmultipath: hwtable: multibus for NetApp NVMe-FC"
Signed-off-by: Martin Wilck <>
3 years agolibmultipath: hwtable: multibus for NetApp NVMe-FC
Martin Wilck [Sat, 13 Jan 2018 21:19:27 +0000 (22:19 +0100)]
libmultipath: hwtable: multibus for NetApp NVMe-FC

Use multibus policy for NetApp NVMe-FC namespace controllers.
The search logic in find_hwe() looks for vendor/product matches backwards, and
quits if a match is found. Therefore specific sub-entries of a generic entry
have to be listed below the generic ones. Therefore, pull the generic NVME
entry with ".*" product name match on top. The NetApp-specific one is put
into the NetApp section. This way, more vendor-specific exceptions for NVME
may be added later.

3 years agolibmultipath: select ALUA prioritizer for RDAC arrays only
Martin Wilck [Sat, 13 Jan 2018 21:19:26 +0000 (22:19 +0100)]
libmultipath: select ALUA prioritizer for RDAC arrays only

Since commit 7e2f46d3, multipathd with "detect_prio" setting (=default)
chooses ALUA prioritizer rather than sysfs prioritizer for arrays with
implicit TPGS. But the intention of that patch was to choose ALUA for
NetApp E-Series (RDAC) storage arrays *only*, not for every array
with implicit TPGS.

3 years agolibmultipath: get_vpd_sgio: support VPD 0xc9
Martin Wilck [Sat, 13 Jan 2018 21:19:25 +0000 (22:19 +0100)]
libmultipath: get_vpd_sgio: support VPD 0xc9

This VPD is needed to check for NetApp E-Series RDAC support.

3 years agolibmultipath: sgio_get_vpd: add page argument
Martin Wilck [Sat, 13 Jan 2018 21:19:24 +0000 (22:19 +0100)]
libmultipath: sgio_get_vpd: add page argument

get_vpd_sgio() assumes to be able to send different VPD inquires.
This requires passing the pg argument to sgio_get_vpd().

3 years agolibmultipath: fix return code of sgio_get_vpd()
Martin Wilck [Sat, 13 Jan 2018 21:19:23 +0000 (22:19 +0100)]
libmultipath: fix return code of sgio_get_vpd()

This function must return the length of data received in success

3 years agolibmultipath: fix return code of sysfs_get_timeout
Martin Wilck [Sat, 13 Jan 2018 21:19:22 +0000 (22:19 +0100)]
libmultipath: fix return code of sysfs_get_timeout

This function should return 1 on success, as the other sysfs_get_XXX
functions. The callers actually expect this - therefore timeout values
from sysfs are never used.

3 years agolibmultipath: condlog: log to stderr
Martin Wilck [Sat, 13 Jan 2018 21:19:21 +0000 (22:19 +0100)]
libmultipath: condlog: log to stderr

Calling 'multipath' might result in various error messages, all
of which should be directed to stderr.
Having them intermixed with the actual output on stdout makes
parsing really hard.

Signed-off-by: Martin Wilck <>
3 years agomultipath: delegate dangerous commands to multipathd
Martin Wilck [Sat, 13 Jan 2018 21:19:20 +0000 (22:19 +0100)]
multipath: delegate dangerous commands to multipathd

Some multipath commands are dangerous to run while multipathd is running.
For example, "multipath -r" may apply a modified configuration to the kernel,
while multipathd is still using the old configuration, leading to
inconsistent state between multipathd and the kernel.

It is safer to use equivalent multipathd client commands instead.
For now, do this only for "multipath -r", but other invocations
may be added in the future. Perhaps some day, all "multipath"
commands will be mapped to multipathd actions.

Note that with delegation, "multipath -r" will not produce any
terminal output, so this may affect users who capture "multipath -r"
output for parsing it. It would be very hard to produce compatible output
to the normal multipath command for different verbosity levels. I
considered running "show topology" after "reconfigure", but the output
would have slightly different format and would only match -v2, anyway.

I plan to convert more multipath commands, but that needs some more
thought. Some additional multipathd client commands need to be
implemented first.

Changes wrt v2:
 - use libmpathcmd rather than exec'ing multipathd (Ben Marzinski)
 - pass more parameters from main program, preparing for other commands

3 years agolibmultipath: don't try to set hwhandler if it is retained
Martin Wilck [Sat, 13 Jan 2018 21:19:19 +0000 (22:19 +0100)]
libmultipath: don't try to set hwhandler if it is retained

Setting a device handler only works if retain_attached_hw_handler
is 'no', or if the kernel didn't auto-assign a handler. If this
is not the case, don't even attempt to set a different handler.

This requires reading the sysfs "dh_state" path attribute.

3 years agolibmultipath: don't update path queueing on reload
Benjamin Marzinski [Wed, 13 Dec 2017 18:08:07 +0000 (12:08 -0600)]
libmultipath: don't update path queueing on reload

With the fix to the features handling code, the multipath device should
already be reloaded with the correct value for queue_if_no_path, so
there's no need to go reset it immediately afterwards.

Cc: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: marginal path code fixes
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:06 +0000 (12:49 -0600)]
multipathd: marginal path code fixes

There are a couple of issues I noticed with the marginal paths code.

In hit_io_err_recheck_time() there are some problems with the initial
checks. We should always recover the path if there are no other usable
paths to the device, so this check should be first. Also, we just
checked that io_err_disable_reinstate isn't zero before calling this
function, so we don't need to check again here (and it doesn't make any
sense to continue disabling the path if io_err_disable_reinstate is set
to zero).  Finally, the only kind of errors we can get while calling
clock_gettime() are going to happen on every call. So, if we can't get
the time, assume that the timeout has passed.

The multipath.conf.5 description of marginal_path_err_sample_time,
states that sampling is stopped for marginal_path_err_rate_threshold
seconds, when it should be marginal_path_err_recheck_gap_time

Lastly, there is a race that can cause multipathd to access freed memory
on shutdown. io_err_stat_thr is started as a detached thread. This means
that stop_io_err_stat_thread() can't know when it has actually stopped,
after pthread_cancel() and pthread_kill() are called. To be safe, it
should not start the thread in a deteched state, and call join to verify
that it has stopped before freeing the memory it uses.  But more
importantly, stop_io_err_stat_thread() was being called before the
checker and uevent threads were being canceled. Both of these threads
access data that is freed in stop_io_err_stat_thread(). To avoid the
chance of these threads accessing freed memory, child() should wait
until these threads are stopped before calling

Cc: Guan Junxiong <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipath: check failed path dmstate in check_path
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:05 +0000 (12:49 -0600)]
multipath: check failed path dmstate in check_path

If a path's checker state is down before and after a path check, but the
path's dmstate is active, mutipath won't update the dmstate. It only
updates the dmstate when the path first fails.  This can cause the
kernel to try known faulty paths, if the multipath device was reloaded
outside of multipathd.  check_path() already checks for and deals with a
similar case where the path's checker state is up before and after a
path check, but the dmstate is failed.  It should do the same thing for
faulty paths.

Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: clean up set_no_path_retry
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:04 +0000 (12:49 -0600)]
multipathd: clean up set_no_path_retry

set_no_path_retry() was always updating the queue_if_no_path setting,
even if it was unnecessary.  This caused problems when no_path_retry was
set to a number, where any time __setup_multipath() was called with
reset, queuing automatically restarted, even if there were no usable

Instead, set_no_path_retry() should just fix the queueing if it is set
to an incorrect value.  This is simple to detect if no_path_retry is set
to "queue" or "fail".  When it is set to a number, multipathd needs to
see if there are usable paths. If so, queueing should be enabled.  If
not, queueing may be either enabled or disabled, but if it is enabled
and the device isn't already in recovery mode, it should be.

Also, calling dm_map_present() is pointless in __setup_multipath(),
since the existence of the map was just checked in dm_get_info().

Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: move recovery mode code to function
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:03 +0000 (12:49 -0600)]
multipathd: move recovery mode code to function

Instead of having multiple functions all running slightly different
code to move a multipath device to recovery mode, there is now
an enter_recovery_mode() function that all of them call.

Signed-off-by: Benjamin Marzinski <>
3 years agolibmultipath: __setup_multipath param cleanup
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:02 +0000 (12:49 -0600)]
libmultipath: __setup_multipath param cleanup

setup multipath is only called by the daemon, so there is no point in
the is_daemon parameter.

Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: remove select_* from setup_multipath
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:01 +0000 (12:49 -0600)]
multipathd: remove select_* from setup_multipath

select_rr_weight() and select_pgfailback() don't need to be set each
time setup_multipath is called, since nothing ever changes the value
of the multipath variable that they set.

select_flush_on_last_del() and select_no_path retry() are a little more
involved.  In multipathd, it is possible to override no_path_retry by
either setting flush_on_last_del, or by manually running the
"disablequeueing" mutipathd command. Queueing gets restored when a path
gets added back to the multipath device. This was done by moving the
select_* functions into setup_multipath, where they frequently get
called unnecessarily.  select_flush_on_last_del() can get removed by
simply using another variable besides flush_on_last_del to track wether
or not we should be force queueing to be disabled.

Since it's only possible to change whether or not you have queueing
force disabled by reloading the device with path, or by manually
restoring it, there is no reason to call select_no_path_retry() on every
call to setup_multipath

Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: fix device creation issues
Benjamin Marzinski [Thu, 7 Dec 2017 18:49:00 +0000 (12:49 -0600)]
multipathd: fix device creation issues

Right now, devices created by multipath and added to multipthd via
ev_add_map() are setup up incorrectly until the first time they get
reloaded.  setup_map() is not run on these devices, which means that all
of the multipath variables set up there don't get initialized until a
later reload.  Also, adopt_paths is run to pull in any paths that the
device is missing, but the device is never reloaded afterwards, so these
paths aren't used.

Now, add_map_without_path() sets up the basic multipath device variables
and then calls update_map() to finish the setup and reload the device.
This patch also moves the code in __setup_multipath(), that only existed
to handle adding devices via ev_add_map(), to where it belongs.

However, it is possible to create a device with no paths, which means
the device cannot know which hwentry to use for its device
configuration.  __setup_multipath() used to help with this via
extract_hwe_from_path(), which grabbed the hwentry from a path if the
multipath device didn't already have it set. This is now done both when
paths are added or the map is updated, which means that
extract_hwe_from_path() runs before the device is configured in
setup_map() instead of after the table has already been loaded. This is
a good thing. But because of this, it can't check the dmstate or the
pathgroup state.  I don't believe it's necessary to care what state the
path is in, especially now that we use libudev. The vendor and product
information gets cached by libudev when the path device is first added,
and should remain the same regardless of whether or not the device is
currently up.  My version does try to take the hwe information from a
path in the PATH_UP state first, but this is mostly to satisfy the
paranoia of the old version.

Also, map_discovery(), which creates multipath devices during multipathd
startup and reconfiguration, that only exist to see if multipathd needs
to reload the device table, called __setup_multipath() as well. Even
after removing the unnecessary code from __setup_multpiath, that still
does pointless work for these devices, which will be removed before the
end of configure(). Now, map_discovery() just gets the necessary kernel
information to make the correct call in select_action().

Signed-off-by: Benjamin Marzinski <>
3 years agomultipathd: move helper functions to libmultipath
Benjamin Marzinski [Thu, 7 Dec 2017 18:48:59 +0000 (12:48 -0600)]
multipathd: move helper functions to libmultipath

This commit simply moves sync_map_state() and update_map() from
multipathd/main.c to libmultipath/structs_vec.c, to enable future

Signed-off-by: Benjamin Marzinski <>
3 years agolibmultipath: cleanup features handling code
Benjamin Marzinski [Thu, 7 Dec 2017 18:48:58 +0000 (12:48 -0600)]
libmultipath: cleanup features handling code

Right now multipath does some extra work to set the values for
no_path_retry and retain_hwhandler on existing maps it reads in from the
kernel.  This is so that select_action() can use these values to see if
it needs to reload the devices. However, the way it works, the
queue_if_no_path feature isn't always set correctly, and multipath has
to go back afterwards and reset the value anyways.

It's simpler for select_action to just look at the values in the
features line it read in from the kernel and the features line it would
like the new map to have.  By comparing these, it also avoids the
problem where the no_path_retry values match, so it doesn't reload, but
the actual queue_if_no_path feature value is incorrect, so it has to go
back and reset it. It can also skip calling setup_feature() entirely.

To do this, assemble_map() needs to update mp->features. This would
otherwise partially happen when it had to reset the queue_if_no_path
value.  retain_attached_hw_handler was never getting updated before, so
the output when you created a map was incorrect.

Signed-off-by: Benjamin Marzinski <>
3 years agomultipath: fix hwhandler check in select_action
Benjamin Marzinski [Thu, 7 Dec 2017 18:48:57 +0000 (12:48 -0600)]
multipath: fix hwhandler check in select_action

If the existing multipath table does not have a hardware handler set,
then even if retain_hwhandler is enabled on the new table, it may still
be possible to set the hardware handler on reload. So, adding a
hardware handler to the table should trigger a reload in this case.

Signed-off-by: Benjamin Marzinski <>
3 years agokpartx: don't delete partitions from partitions
Benjamin Marzinski [Thu, 7 Dec 2017 18:48:56 +0000 (12:48 -0600)]
kpartx: don't delete partitions from partitions

The current del-part-nodes rules try to run partx on the partitions
themselves, which will ofen fail with an error in the log, because the
partitions will have been deleted before partx can run on them.

Cc: Martin Wilck <>
Signed-off-by: Benjamin Marzinski <>
3 years agomultipath: add "ghost_delay" parameter
Benjamin Marzinski [Thu, 7 Dec 2017 18:48:55 +0000 (12:48 -0600)]
multipath: add "ghost_delay" parameter

If the lower-priority passive paths for a multipath device appear first,
IO can go to them and cause the hardware handler to activate them,
before the higher priority paths appear, causing the devices to
failback. Setting the "ghost_delay" parameter to a value greater than
0 can avoid this ping-ponging by causing udev to not mark the device as
Ready after its initial creation until either an active path appears,
or ghost_delay seconds have passed. Multipathd does this by setting

Signed-off-by: Benjamin Marzinski <>
3 years agomultipath-tools: check null path before handle path-failed event
Guan Junxiong [Mon, 4 Dec 2017 13:15:50 +0000 (21:15 +0800)]
multipath-tools: check null path before handle path-failed event

In the hot-plug storage OS, if we tear down the target storage,
there is a race between the path removing from the path list and
handling the path-failed udev event. Therefore, we need to check
null path before handle path-failed event.

Signed-off-by: Guan Junxiong <>
3 years agomultipath-tools: output more topology info for NVMe discovery
Jie Yang [Mon, 4 Dec 2017 13:13:57 +0000 (21:13 +0800)]
multipath-tools: output more topology info for NVMe discovery

Assign to controller id of the NVMe/NVMf target
and assign sg_id.lun to namespace ID of the target.

Signed-off-by: Jie Yang <>
Reviewed-by: Guan Junxiong <>
3 years agomultipath-tools: libdmmp: Add new error DMMP_ERR_PERMISSION_DENY
Gris Ge [Tue, 21 Nov 2017 14:09:17 +0000 (22:09 +0800)]
multipath-tools: libdmmp: Add new error DMMP_ERR_PERMISSION_DENY

 * Indicate user does not have privilege to flush mpath or invoke
 * Bump API version to 0.2.0 for this API addition.

Signed-off-by: Gris Ge <>
3 years agomultipath-tools: libdmmp: Add new function dmmp_last_error_msg()
Gris Ge [Tue, 21 Nov 2017 14:09:16 +0000 (22:09 +0800)]
multipath-tools: libdmmp: Add new function dmmp_last_error_msg()

 * New function dmmp_last_error_msg() to retrieve the last error

Signed-off-by: Gris Ge <>