diff -Nru zfs-linux-0.6.5.6/debian/changelog zfs-linux-0.6.5.6/debian/changelog --- zfs-linux-0.6.5.6/debian/changelog 2016-04-13 06:53:27.000000000 -0500 +++ zfs-linux-0.6.5.6/debian/changelog 2016-04-20 19:39:15.000000000 -0500 @@ -1,3 +1,9 @@ +zfs-linux (0.6.5.6-0ubuntu9~rlaager1) xenial; urgency=medium + + * Backport Brian Behlendorf's "Fix 'zpool import' blkid device names" + + -- Richard Laager Wed, 20 Apr 2016 19:35:34 -0500 + zfs-linux (0.6.5.6-0ubuntu8) xenial; urgency=medium [ Richard Laager ] diff -Nru zfs-linux-0.6.5.6/debian/patches/1003-Fix-zpool-import-blkid-device-names.patch zfs-linux-0.6.5.6/debian/patches/1003-Fix-zpool-import-blkid-device-names.patch --- zfs-linux-0.6.5.6/debian/patches/1003-Fix-zpool-import-blkid-device-names.patch 1969-12-31 18:00:00.000000000 -0600 +++ zfs-linux-0.6.5.6/debian/patches/1003-Fix-zpool-import-blkid-device-names.patch 2016-04-20 19:38:24.000000000 -0500 @@ -0,0 +1,206 @@ +From 764a2aa54e4834757466ecfad2b23745d4cb6962 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Wed, 20 Apr 2016 10:17:01 -0700 +Subject: [PATCH] Fix 'zpool import' blkid device names + +When importing a pool using the blkid cache only the device +node path was added to the list of known paths for a device. +This results in 'zpool import' always using the sdX names +in preference to the 'path' name stored in the label. + +To fix the issue the blkid import path has been updated to +add both the 'path', 'devid', and 'devname' names from the +label to known paths. Sanity check is done to ensure these +paths do refer to the same device identified by blkid. + +Signed-off-by: Brian Behlendorf +Issue #3043 +--- + lib/libzfs/libzfs_import.c | 142 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 123 insertions(+), 19 deletions(-) + +Index: zfs-linux-0.6.5.6/lib/libzfs/libzfs_import.c +=================================================================== +--- zfs-linux-0.6.5.6.orig/lib/libzfs/libzfs_import.c 2016-04-20 19:37:13.211240071 -0500 ++++ zfs-linux-0.6.5.6/lib/libzfs/libzfs_import.c 2016-04-20 19:37:13.207240025 -0500 +@@ -122,6 +122,8 @@ get_devid(const char *path) + } + + ++#define DEV_BYID_PATH "/dev/disk/by-id/" ++ + /* + * Go through and fix up any path and/or devid information for the given vdev + * configuration. +@@ -162,7 +164,6 @@ fix_paths(nvlist_t *nv, name_entry_t *na + best = NULL; + for (ne = names; ne != NULL; ne = ne->ne_next) { + if (ne->ne_guid == guid) { +- + if (path == NULL) { + best = ne; + break; +@@ -352,6 +353,116 @@ add_config(libzfs_handle_t *hdl, pool_li + return (0); + } + ++static int ++add_path(libzfs_handle_t *hdl, pool_list_t *pools, uint64_t pool_guid, ++ uint64_t vdev_guid, const char *path, int order) ++{ ++ nvlist_t *label; ++ uint64_t guid; ++ int error, fd, num_labels; ++ ++ fd = open64(path, O_RDONLY); ++ if (fd < 0) ++ return (errno); ++ ++ error = zpool_read_label(fd, &label, &num_labels); ++ close(fd); ++ ++ if (error || label == NULL) ++ return (ENOENT); ++ ++ error = nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, &guid); ++ if (error || guid != pool_guid) { ++ nvlist_free(label); ++ return (EINVAL); ++ } ++ ++ error = nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid); ++ if (error || guid != vdev_guid) { ++ nvlist_free(label); ++ return (EINVAL); ++ } ++ ++ error = add_config(hdl, pools, path, order, num_labels, label); ++ ++ return (error); ++} ++ ++static int ++add_configs_from_label_impl(libzfs_handle_t *hdl, pool_list_t *pools, ++ nvlist_t *nvroot, uint64_t pool_guid, uint64_t vdev_guid) ++{ ++ char udevpath[MAXPATHLEN]; ++ char *path; ++ nvlist_t **child; ++ uint_t c, children; ++ uint64_t guid; ++ int error; ++ ++ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, ++ &child, &children) == 0) { ++ for (c = 0; c < children; c++) { ++ error = add_configs_from_label_impl(hdl, pools, ++ child[c], pool_guid, vdev_guid); ++ if (error) ++ return (error); ++ } ++ return (0); ++ } ++ ++ if (nvroot == NULL) ++ return (0); ++ ++ error = nvlist_lookup_uint64(nvroot, ZPOOL_CONFIG_GUID, &guid); ++ if ((error != 0) || (guid != vdev_guid)) ++ return (0); ++ ++ error = nvlist_lookup_string(nvroot, ZPOOL_CONFIG_PATH, &path); ++ if (error == 0) ++ (void) add_path(hdl, pools, pool_guid, vdev_guid, path, 0); ++ ++ error = nvlist_lookup_string(nvroot, ZPOOL_CONFIG_DEVID, &path); ++ if (error == 0) { ++ sprintf(udevpath, "%s%s", DEV_BYID_PATH, path); ++ (void) add_path(hdl, pools, pool_guid, vdev_guid, udevpath, 1); ++ } ++ ++ return (0); ++} ++ ++/* ++ * Given a disk label call add_config() for all known paths to the device ++ * as described by the label itself. The paths are added in the following ++ * priority order: 'path', 'devid', 'devnode'. As these alternate paths are ++ * added the labels are verified to make sure they refer to the same device. ++ */ ++static int ++add_configs_from_label(libzfs_handle_t *hdl, pool_list_t *pools, ++ char *devname, int num_labels, nvlist_t *label) ++{ ++ nvlist_t *nvroot; ++ uint64_t pool_guid; ++ uint64_t vdev_guid; ++ int error; ++ ++ if (nvlist_lookup_nvlist(label, ZPOOL_CONFIG_VDEV_TREE, &nvroot) || ++ nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, &pool_guid) || ++ nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &vdev_guid)) ++ return (ENOENT); ++ ++ /* Allow devlinks to stabilize so all paths are available. */ ++ zpool_label_disk_wait(devname, DISK_LABEL_WAIT); ++ ++ /* Add alternate paths as described by the label vdev_tree. */ ++ (void) add_configs_from_label_impl(hdl, pools, nvroot, ++ pool_guid, vdev_guid); ++ ++ /* Add the device node /dev/sdX path as a last resort. */ ++ error = add_config(hdl, pools, devname, 100, num_labels, label); ++ ++ return (error); ++} ++ + /* + * Returns true if the named pool matches the given GUID. + */ +@@ -975,9 +1086,7 @@ zpool_find_import_blkid(libzfs_handle_t + blkid_cache cache; + blkid_dev_iterate iter; + blkid_dev dev; +- const char *devname; +- nvlist_t *config; +- int fd, err, num_labels; ++ int err; + + err = blkid_get_cache(&cache, NULL); + if (err != 0) { +@@ -1008,25 +1117,23 @@ zpool_find_import_blkid(libzfs_handle_t + } + + while (blkid_dev_next(iter, &dev) == 0) { +- devname = blkid_dev_devname(dev); ++ nvlist_t *label; ++ char *devname; ++ int fd, num_labels; ++ ++ devname = (char *) blkid_dev_devname(dev); + if ((fd = open64(devname, O_RDONLY)) < 0) + continue; + +- err = zpool_read_label(fd, &config, &num_labels); ++ err = zpool_read_label(fd, &label, &num_labels); + (void) close(fd); + +- if (err != 0) { +- (void) no_memory(hdl); +- goto err_blkid3; +- } ++ if (err || label == NULL) ++ continue; + +- if (config != NULL) { +- err = add_config(hdl, pools, devname, 0, +- num_labels, config); +- if (err != 0) +- goto err_blkid3; +- } ++ add_configs_from_label(hdl, pools, devname, num_labels, label); + } ++ err = 0; + + err_blkid3: + blkid_dev_iterate_end(iter); diff -Nru zfs-linux-0.6.5.6/debian/patches/series zfs-linux-0.6.5.6/debian/patches/series --- zfs-linux-0.6.5.6/debian/patches/series 2016-03-30 17:07:32.000000000 -0500 +++ zfs-linux-0.6.5.6/debian/patches/series 2016-04-20 19:35:29.000000000 -0500 @@ -6,3 +6,4 @@ 1001-Fix-aarch64-compilation.patch 1002-Add-support-32-bit-FS_IOC32_-GET-SET-FLAGS-compat-io.patch enable-zed.patch +1003-Fix-zpool-import-blkid-device-names.patch