]> granicus.if.org Git - zfs/commitdiff
Fix import finding spare/l2cache when path changes
authorChunwei Chen <david.chen@osnexus.com>
Wed, 24 May 2017 22:11:23 +0000 (15:11 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 1 Jun 2017 13:38:04 +0000 (06:38 -0700)
When spare or l2cache device path changes, zpool import will not fix up
their paths like normal vdev. The issue is that when you supply a pool
name argument to zpool import, it will use it to filter out device which
doesn't have the pool name in the label. Since spare and l2cache device
never have that in the label, they'll always get filtered out.

We fix this by making sure we never filter out a spare or l2cache
device.

Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes #6158

lib/libzfs/libzfs_import.c

index 40798f42b625759407a78470eaefeb95312b4362..02264433e892fb66ffe8aa001c684fe7fbc3af59 100644 (file)
@@ -1915,15 +1915,29 @@ 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;
+                       boolean_t aux = B_FALSE;
                        int fd;
 
-                       if (iarg->poolname != NULL) {
+                       /*
+                        * Check if it's a spare or l2cache device. If it is,
+                        * we need to skip the name and guid check since they
+                        * don't exist on aux device label.
+                        */
+                       if (iarg->poolname != NULL || iarg->guid != 0) {
+                               uint64_t state;
+                               aux = nvlist_lookup_uint64(config,
+                                   ZPOOL_CONFIG_POOL_STATE, &state) == 0 &&
+                                   (state == POOL_STATE_SPARE ||
+                                   state == POOL_STATE_L2CACHE);
+                       }
+
+                       if (iarg->poolname != NULL && !aux) {
                                char *pname;
 
                                matched = nvlist_lookup_string(config,
                                    ZPOOL_CONFIG_POOL_NAME, &pname) == 0 &&
                                    strcmp(iarg->poolname, pname) == 0;
-                       } else if (iarg->guid != 0) {
+                       } else if (iarg->guid != 0 && !aux) {
                                uint64_t this_guid;
 
                                matched = nvlist_lookup_uint64(config,