mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Retire zpool_id infrastructure
In the interest of maintaining only one udev helper to give vdevs user friendly names, the zpool_id and zpool_layout infrastructure is being retired. They are superseded by vdev_id which incorporates all the previous functionality. Documentation for the new vdev_id(8) helper and its configuration file, vdev_id.conf(5), can be found in their respective man pages. Several useful example files are installed under /etc/zfs/. /etc/zfs/vdev_id.conf.alias.example /etc/zfs/vdev_id.conf.multipath.example /etc/zfs/vdev_id.conf.sas_direct.example /etc/zfs/vdev_id.conf.sas_switch.example Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #981
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
SUBDIRS = zfs zpool zdb zhack zinject zstreamdump ztest zpios
|
||||
SUBDIRS += mount_zfs fsck_zfs zpool_layout zvol_id zpool_id vdev_id
|
||||
SUBDIRS += mount_zfs fsck_zfs zvol_id vdev_id
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
dist_udev_SCRIPTS = zpool_id
|
||||
@@ -1,86 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
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: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
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
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts 'c:d:h' OPTION; do
|
||||
case ${OPTION} in
|
||||
c)
|
||||
CONFIG="${OPTARG}"
|
||||
;;
|
||||
d)
|
||||
DEVICE="${OPTARG}"
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check that a device was requested
|
||||
[ -z "${DEVICE}" ] && usage
|
||||
|
||||
# Check for the existence of a configuration file
|
||||
[ ! -f "${CONFIG}" ] && die "Missing config file: ${CONFIG}"
|
||||
|
||||
# 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=''
|
||||
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 [ -n "${ID_ZPOOL}" ]; then
|
||||
echo "ID_PATH=${ID_PATH}"
|
||||
echo "ID_ZPOOL=${ID_ZPOOL}"
|
||||
echo "ID_ZPOOL_PATH=disk/zpool/${ID_ZPOOL}"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1 +0,0 @@
|
||||
dist_bin_SCRIPTS = zpool_layout
|
||||
@@ -1,281 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Direct-Attached Mode
|
||||
# --------------------
|
||||
# Set BUSES and HOST_PORTS to match the topology of your system. As
|
||||
# each port is enumerated it will be assigned the next channel name.
|
||||
# The current script enumerates each port on a bus before moving on
|
||||
# to enumerate the next bus.
|
||||
#
|
||||
# Every distribution, version of udev, and type of attached storage
|
||||
# seems to result in slightly different formatting of the by-path
|
||||
# name. For this reason you may need to adjust the parsing below
|
||||
# to suit your needs. This is one of the reasons to use a custom
|
||||
# /etc/zfs/zdev.conf file, it allows the by-path naming convention
|
||||
# to change and still keep the simple <channel><rank> naming.
|
||||
#
|
||||
# SAS-Switch Mode
|
||||
# -------------------------
|
||||
# When the host accesses disk via SAS switches the combination of
|
||||
# bus and port number does not necessarily uniquely identify a
|
||||
# channel or disk drawer. In this case we must resort to other
|
||||
# means to infer the physical topology. For a single-level network
|
||||
# (i.e. no switch cascading) we can assign alphabetic channel labels
|
||||
# based on the switch port number that the drawer is connected to.
|
||||
# If support for more complex topologies is needed this script will
|
||||
# need to be customized or replaced.
|
||||
#
|
||||
# In SAS-Switch mode (enabled with "-g switch" ) we require that
|
||||
# udev has been configured to create per-disk symbolic links in
|
||||
# /dev/disk/by-id of the form
|
||||
# <label>-<UUID>-switch-port:<X>-slot:<Y>. <label> is a string that
|
||||
# depends on the subsystem that created the link and defaults to
|
||||
# "dm-uuid-mpath" (this prefix is used by multipathd). <UUID> is a
|
||||
# unique identifier for the disk typically obtained from the scsi_id
|
||||
# program. <X> and <Y> denote the switch port and disk slot
|
||||
# numbers, respectively, and are typically obtained from sysfs.
|
||||
|
||||
AWK=${AWK:-/usr/bin/awk}
|
||||
CONFIG=${CONFIG:-/etc/zfs/zdev.conf}
|
||||
BUSES=( 01 02 03 )
|
||||
HOST_PORTS=( 4 0 )
|
||||
SWITCH_PORTS=( 0 1 2 3 4 5 6 7 8 9 )
|
||||
CHANNELS=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z )
|
||||
TOPOLOGY="direct"
|
||||
TRIGGER="no"
|
||||
MAPPING=linux
|
||||
LABEL=${LABEL:-"dm-uuid-mpath"}
|
||||
DEV_DISK_DIR="/dev/disk/by-path"
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: zpool_layout [-th] [-c file] [-b buses] [-o switch_ports]
|
||||
[-p host_ports] [-n channels] [-m map] [-l label]
|
||||
[-g direct|switch]
|
||||
-c Alternate config file [default=${CONFIG}]
|
||||
-b Enumerate buses [default="${BUSES[*]}"]
|
||||
-o Enumerate switch ports [default="${SWITCH_PORTS[*]}"]
|
||||
-p Enumerate host ports [default="${HOST_PORTS[*]}"]
|
||||
-n Channel names [default="A..Z"]
|
||||
-g Storage network topology [default="${TOPOLOGY}"]
|
||||
-t Trigger and wait for udev to settle [default=${TRIGGER}]
|
||||
-l Prefix of SAS-switch-mode device links [default=${LABEL}]
|
||||
-m Slot mapping [default=${MAPPING}]
|
||||
-h Show this message
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
while getopts 'c:b:o:p:n:l:m:g:th' OPTION; do
|
||||
case ${OPTION} in
|
||||
c)
|
||||
CONFIG=${OPTARG}
|
||||
;;
|
||||
b)
|
||||
BUSES=(${OPTARG})
|
||||
;;
|
||||
o)
|
||||
SWITCH_PORTS=(${OPTARG})
|
||||
;;
|
||||
p)
|
||||
HOST_PORTS=(${OPTARG})
|
||||
;;
|
||||
n)
|
||||
CHANNELS=(${OPTARG})
|
||||
;;
|
||||
l)
|
||||
LABEL=${OPTARG}
|
||||
;;
|
||||
m)
|
||||
MAPPING=`readlink -e ${OPTARG}`
|
||||
;;
|
||||
g)
|
||||
TOPOLOGY=${OPTARG}
|
||||
;;
|
||||
t)
|
||||
TRIGGER=yes
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Verify mapping file exists if specified.
|
||||
# Linux-Slot Custom-Slot
|
||||
if [ ${MAPPING} != "linux" ] && [ ! -e ${MAPPING} ]; then
|
||||
echo "Error: Mapping file '${MAPPING}' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save stdout as fd #8, then redirect stdout to the config file.
|
||||
exec 8>&1
|
||||
exec >${CONFIG}
|
||||
|
||||
map_slot() {
|
||||
local LINUX_SLOT=$1
|
||||
local MAPPED_SLOT=
|
||||
|
||||
if [ ${MAPPING} = "linux" ]; then
|
||||
MAPPED_SLOT=${LINUX_SLOT}
|
||||
else
|
||||
MAPPED_SLOT=`${AWK} "\\$1 == ${LINUX_SLOT} && !/^#/ \
|
||||
{ print \\$2; exit }" $MAPPING`
|
||||
fi
|
||||
printf "%d" ${MAPPED_SLOT}
|
||||
}
|
||||
|
||||
# Generate host port layout table for comment header.
|
||||
print_host_port_layout() {
|
||||
echo "# ------------------ Host Port Layout ---------------------"
|
||||
echo -n "# "
|
||||
for (( i=0; i<${#BUSES[*]}; i++ )); do
|
||||
printf "%-8d" ${BUSES[$i]}
|
||||
done
|
||||
echo
|
||||
|
||||
for (( i=0, k=0; i<${#HOST_PORTS[*]}; i++ )); do
|
||||
printf "# Port %-2d " ${HOST_PORTS[$i]}
|
||||
|
||||
for (( j=0; j<${#BUSES[*]}; j++, k++ )); do
|
||||
let k=$j*${#HOST_PORTS[*]}+$i
|
||||
printf "%-8s" ${CHANNELS[$k]}
|
||||
done
|
||||
echo
|
||||
done
|
||||
echo "#"
|
||||
}
|
||||
|
||||
# Generate SAS switch port layout table for comment header.
|
||||
print_switch_port_layout() {
|
||||
echo "# --------------- SAS Switch Port Layout ------------------"
|
||||
echo -n "# Switch Port "
|
||||
for (( i=0; i<${#SWITCH_PORTS[*]}; i++ )); do
|
||||
printf "%3d" ${SWITCH_PORTS[$i]}
|
||||
done
|
||||
echo
|
||||
echo -n "# Channel "
|
||||
for (( i=0; i<${#SWITCH_PORTS[*]}; i++ )); do
|
||||
printf "%3s" ${CHANNELS[$i]}
|
||||
done
|
||||
echo
|
||||
echo "#"
|
||||
}
|
||||
|
||||
# Generate channel/disk layout table for comment header.
|
||||
print_channel_layout() {
|
||||
pushd ${DEV_DISK_DIR} >/dev/null
|
||||
echo "# ----------------- Channel/Disk Layout -------------------"
|
||||
echo "# Channel Disks"
|
||||
if [ ${TOPOLOGY} = "switch" ] ; then
|
||||
for (( i=0; i<${#SWITCH_PORTS[*]}; i++ )); do
|
||||
printf "# %-9s" ${CHANNELS[$i]}
|
||||
p=${SWITCH_PORTS[$i]}
|
||||
ls ${LABEL}-+([0-9a-f])-switch-port:${p}-slot:+([0-9]) \
|
||||
2>/dev/null | cut -f3 -d':' | sort -u -n | \
|
||||
xargs | tr ' ' ','
|
||||
done
|
||||
else
|
||||
for (( i=0, k=0; i<${#BUSES[*]}; i++ )); do
|
||||
for (( j=0; j<${#HOST_PORTS[*]}; j++, k++ )); do
|
||||
printf "# %-9s" ${CHANNELS[$k]}
|
||||
ls *:${BUSES[$i]}:*:${HOST_PORTS[$j]}* \
|
||||
2>/dev/null | cut -f7 -d'-' | \
|
||||
sort -u -n | xargs | tr ' ' ','
|
||||
done
|
||||
done
|
||||
fi
|
||||
echo "#"
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
# Generate mapping from <channel><rank> to by-path name.
|
||||
map_shortname_to_by_path() {
|
||||
pushd ${DEV_DISK_DIR} >/dev/null
|
||||
for (( i=0, k=0; i<${#BUSES[*]}; i++ )); do
|
||||
for (( j=0; j<${#HOST_PORTS[*]}; j++, k++ )); do
|
||||
BYPATH=(`ls *:${BUSES[$i]}:*:${HOST_PORTS[$j]}* \
|
||||
2>/dev/null | grep -v part | \
|
||||
sort -n -k7 -t'-' | cut -f1-6 -d'-'`)
|
||||
SLOTS=(`ls *:${BUSES[$i]}:*:${HOST_PORTS[$j]}* \
|
||||
2>/dev/null | grep -v part | \
|
||||
sort -n -k7 -t'-' | cut -f7 -d'-'`)
|
||||
TMP_FILE=`mktemp`
|
||||
|
||||
for (( l=0; l<${#SLOTS[*]}; l++ )); do
|
||||
MAPPED_SLOT=`map_slot ${SLOTS[$l]}`
|
||||
printf "%s%d\t%s-%d\n" \
|
||||
${CHANNELS[$k]} ${MAPPED_SLOT} \
|
||||
${BYPATH[$l]} ${SLOTS[$l]} >>${TMP_FILE}
|
||||
done
|
||||
|
||||
echo
|
||||
echo -n "# Channel ${CHANNELS[$k]}, "
|
||||
echo "Bus ${BUSES[$i]}, Port ${HOST_PORTS[$j]}"
|
||||
cat ${TMP_FILE} | sort -n -k2 -t${CHANNELS[$k]}
|
||||
rm -f ${TMP_FILE}
|
||||
done
|
||||
done
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
# Generate mapping from <channel><rank> to by-id name.
|
||||
map_shortname_to_by_id() {
|
||||
pushd ${DEV_DISK_DIR} >/dev/null
|
||||
for (( i=0; i<${#SWITCH_PORTS[*]}; i++ )); do
|
||||
p=${SWITCH_PORTS[$i]}
|
||||
BYID=(`ls ${LABEL}-+([0-9a-f])-switch-port:${p}-slot:+([0-9]) \
|
||||
2>/dev/null | grep -v part | sort -k3n -t':' | \
|
||||
cut -f1-2 -d':'`)
|
||||
SLOTS=(`ls ${LABEL}-+([0-9a-f])-switch-port:${p}-slot:+([0-9]) \
|
||||
2>/dev/null | grep -v part | sort -k3n -t':' | \
|
||||
cut -f3 -d':'`)
|
||||
TMP_FILE=`mktemp`
|
||||
|
||||
for (( l=0; l<${#SLOTS[*]}; l++ )); do
|
||||
MAPPED_SLOT=`map_slot ${SLOTS[$l]}`
|
||||
printf "%s%d\t%s:%d\n" \
|
||||
${CHANNELS[$i]} ${MAPPED_SLOT} ${BYID[$l]} \
|
||||
${SLOTS[$l]} >>${TMP_FILE}
|
||||
done
|
||||
|
||||
echo
|
||||
echo -n "# Channel ${CHANNELS[$i]}, "
|
||||
echo "SAS Switch Port ${SWITCH_PORTS[$i]}"
|
||||
cat ${TMP_FILE} | sort -n -k2 -t${CHANNELS[$i]}
|
||||
rm -f ${TMP_FILE}
|
||||
done
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
# Generate comment header.
|
||||
echo "#"
|
||||
echo "# Custom ${DEV_DISK_DIR} to /dev/disk/zpool mapping, "
|
||||
echo "# based of the following physical cable layout."
|
||||
echo "#"
|
||||
|
||||
case ${TOPOLOGY} in
|
||||
direct)
|
||||
print_host_port_layout
|
||||
print_channel_layout
|
||||
map_shortname_to_by_path
|
||||
;;
|
||||
switch)
|
||||
DEV_DISK_DIR="/dev/disk/by-id"
|
||||
print_switch_port_layout
|
||||
print_channel_layout
|
||||
map_shortname_to_by_id
|
||||
;;
|
||||
esac
|
||||
|
||||
# Restore stdout from fd #8 and close fd #8.
|
||||
exec 1>&8 8>&-
|
||||
|
||||
if [ ${TRIGGER} = "yes" ]; then
|
||||
udevadm trigger --action=change --subsystem-match=block
|
||||
udevadm settle
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user