-#!/bin/bash
+#!/bin/sh
-CONFIG=${CONFIG:-/etc/zfs/zdev.conf}
-PATH_ID=${PATH_ID:-/lib/udev/path_id}
-AWK=${AWK:-/bin/awk}
+CONFIG="${CONFIG:-/etc/zfs/zdev.conf}"
+
+if [ -z "${PATH_ID}" ]; then
+ # The path_id helper became a builtin command in udev 174.
+ if [ -x '/lib/udev/path_id' ]; then
+ PATH_ID='/lib/udev/path_id'
+ else
+ PATH_ID='udevadm test-builtin path_id'
+ fi
+fi
die() {
echo "Error: $*"
usage() {
cat << EOF
-Usage: zpool_id [h] [-c configfile] <devpath>
+Usage: zpool_id [-h] [-c configfile] <devpath>
-c Alternate config file [default /etc/zfs/zdev.conf]
-d Use path_id from device as the mapping key
-h Show this message
while getopts 'c:d:h' OPTION; do
case ${OPTION} in
c)
- CONFIG=${OPTARG}
+ CONFIG="${OPTARG}"
;;
d)
- DEVICE=${OPTARG}
+ DEVICE="${OPTARG}"
;;
h)
usage
done
# Check that a device was requested
-[ -z ${DEVICE} ] && usage
+[ -z "${DEVICE}" ] && usage
# Check for the existence of a configuration file
-[ ! -f ${CONFIG} ] && die "Missing config file: ${CONFIG}"
+[ ! -f "${CONFIG}" ] && die "Missing config file: ${CONFIG}"
-# Use udev's path_id to generate a unique persistent key
-eval `${PATH_ID} ${DEVICE}`
-[ -z ${ID_PATH} ] && die "Missing ID_PATH for ${DEVICE}"
+# If we are handling a multipath device then $DM_UUID will be
+# exported and we'll use its value (prefixed with dm-uuid per
+# multipathd's naming convention) as our unique persistent key.
+# For traditional devices we'll obtain the key from udev's
+# path_id.
+if [ -n "${DM_UUID}" ] && echo "${DM_UUID}" | grep -q -e '^mpath' ; then
+ ID_PATH="dm-uuid-${DM_UUID}"
+else
+ eval `${PATH_ID} ${DEVICE}`
+ [ -z "${ID_PATH}" ] && die "Missing ID_PATH for ${DEVICE}"
+fi
# Use the persistent key to lookup the zpool device id in the
# configuration file which is of the format <device id> <key>.
# Lines starting with #'s are treated as comments and ignored.
# Exact matches are required, wild cards are not supported,
# and only the first match is returned.
-ID_ZPOOL=`${AWK} "/${ID_PATH}\>/ && !/^#/ { print \\$1; exit }" ${CONFIG}`
-[ -z ${ID_ZPOOL} ] && die "Missing ID_ZPOOL for ID_PATH: ${ID_PATH}"
+ID_ZPOOL=''
+while read CONFIG_ZPOOL CONFIG_PATH REPLY; do
+ if [ "${CONFIG_ZPOOL}" != "${CONFIG_ZPOOL#\#}" ]; then
+ # Skip comment lines.
+ continue
+ fi
+ if [ "${CONFIG_PATH}" = "${ID_PATH}" ]; then
+ ID_ZPOOL="${CONFIG_ZPOOL}"
+ break
+ fi
+done <"${CONFIG}"
+
+[ -z "${ID_ZPOOL}" ] && die "Missing ID_ZPOOL for ID_PATH: ${ID_PATH}"
-if [ ${ID_ZPOOL} ]; then
+if [ -n "${ID_ZPOOL}" ]; then
echo "ID_PATH=${ID_PATH}"
echo "ID_ZPOOL=${ID_ZPOOL}"
echo "ID_ZPOOL_PATH=disk/zpool/${ID_ZPOOL}"