From c30d8ded0c8c64a9a144cf478502bb4e512ab9fa Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 14 Nov 2016 09:40:18 -0800 Subject: [PATCH] Fix 'zpool import' detection issue Before adding the entry to the configuration verify that the device can be opened exclusively. This ensures that as long as multipathd is running the underlying multipath devices, which otherwise appear identical to their /dev/mapper counterpart, are pruned from the configuration. Failure to do so can result in a result in the vdev appearing as UNAVAIL when the vdev path provided to the kernel can't be opened exclusively. This check would normally be performed in zpool_open_func() but placing it there would result in false positives because it is called concurrently for many devices. Reviewed-by: Olaf Faaland Reviewed-by: Tony Hutter Signed-off-by: Brian Behlendorf Closes #5387 --- lib/libzfs/libzfs_import.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c index e23232792f..fe783a3a39 100644 --- a/lib/libzfs/libzfs_import.c +++ b/lib/libzfs/libzfs_import.c @@ -1912,6 +1912,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) if (slice->rn_config != NULL) { nvlist_t *config = slice->rn_config; boolean_t matched = B_TRUE; + int fd; if (iarg->poolname != NULL) { char *pname; @@ -1929,9 +1930,21 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) if (!matched) { nvlist_free(config); } else { - add_config(hdl, &pools, - slice->rn_name, slice->rn_order, - slice->rn_num_labels, config); + /* + * Verify all remaining entries can be opened + * exclusively. This will prune all underlying + * multipath devices which otherwise could + * result in the vdev appearing as UNAVAIL. + */ + fd = open(slice->rn_name, O_RDONLY | O_EXCL); + if (fd >= 0) { + close(fd); + add_config(hdl, &pools, + slice->rn_name, slice->rn_order, + slice->rn_num_labels, config); + } else { + nvlist_free(config); + } } } free(slice->rn_name);