Add zpool_layout command

The zpool_layout command is designed to automatically scan the
udev /dev/disk/by-path directory and generate a /etc/zfs/zdev.conf
file.  It does this by enumerating the disks attached to the
specified buses/ports and sequentially mapping them to short
<channel><rank> names in /dev/disk/zpool/.  This tool should only
be run after all the available disks have been discovered.  And
the resulting config file does not need to be regenerated unless
your backend configuration changes.
This commit is contained in:
Brian Behlendorf 2010-08-16 15:54:06 -07:00
parent 96c653a09b
commit 7f939f28eb
4 changed files with 123 additions and 1 deletions

View File

@ -1 +1 @@
SUBDIRS = zfs zpool zpool_id zdb zinject ztest SUBDIRS = zfs zpool zpool_id zpool_layout zdb zinject ztest

View File

@ -0,0 +1 @@
dist_bin_SCRIPTS = zpool_layout

120
cmd/zpool_layout/zpool_layout Executable file
View File

@ -0,0 +1,120 @@
#!/bin/bash
#
# Set BUSES and 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.
#
CONFIG=${CONFIG:-/etc/zfs/zdev.conf}
BUSES=( 01 02 03 )
PORTS=( 4 0 )
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 )
TRIGGER=
usage() {
cat << EOF
Usage: zpool_layout [-th] [-c file] [-b buses] [-p ports] [-n channels]
-c Alternate config file [default=/etc/zfs/zdev.conf]
-b Enumerate buses [default="01 02 03"]
-p Enumerate ports [default="4 0"]
-n Channel names [default="A..Z"]
-t Trigger and wait for udev to settle [default=no]
-h Show this message
EOF
exit 0
}
while getopts 'c:b:p:n:th' OPTION; do
case ${OPTION} in
c)
CONFIG=${OPTARG}
;;
b)
BUSES=(${OPTARG})
;;
p)
PORTS=(${OPTARG})
;;
n)
CHANNELS=(${OPTARG})
;;
t)
TRIGGER=1
;;
h)
usage
;;
esac
done
# Save stdout as fd #8, then redirect stdout to the config file.
exec 8>&1
exec >${CONFIG}
pushd /dev/disk/by-path >/dev/null
# Generate comment header.
echo "#"
echo "# Custom /dev/disk/by-path to /dev/disk/zpool mapping, "
echo "# based of the following physical cable layout."
echo "#"
# Generate host port layout table for comment header.
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<${#PORTS[*]}; i++ )); do
printf "# Port %-2d " ${PORTS[$i]}
for (( j=0; j<${#BUSES[*]}; j++, k++ )); do
let k=$j*${#PORTS[*]}+$i
printf "%-8s" ${CHANNELS[$k]}
done
echo
done
echo "#"
# Generate channel/disk layout table for comment header.
echo "# ----------------- Channel/Disk Layout -------------------"
echo "# Channel Disks"
for (( i=0, k=0; i<${#BUSES[*]}; i++ )); do
for (( j=0; j<${#PORTS[*]}; j++, k++ )); do
printf "# %-9s" ${CHANNELS[$k]}
ls *:${BUSES[$i]}:*:${PORTS[$j]}* 2>/dev/null | \
cut -f7 -d'-' | sort -n | tr '\n' ','
echo
done
done
echo "#"
# Generate mapping from <channel><rank> to by-path name.
TMP_FILE=`mktemp`
AWK=${AWK:-/bin/awk}
for (( i=0, k=0; i<${#BUSES[*]}; i++ )); do
for (( j=0; j<${#PORTS[*]}; j++, k++ )); do
ls *:${BUSES[$i]}:*:${PORTS[$j]}* 2>/dev/null | \
sort -n -k7 -t'-'>${TMP_FILE}
echo
echo -n "# Channel ${CHANNELS[$k]}, "
echo "Bus ${BUSES[$i]}, Port ${PORTS[$j]}"
${AWK} -F '-' -v ch="${CHANNELS[$k]}" \
'{print ch$7 "\t" $0 }' ${TMP_FILE}
done
done
# Restore stdout from fd #8 and close fd #8.
exec 1>&8 8>&-
rm -f ${TMP_FILE}
popd >/dev/null
if [ ${TRIGGER} ]; then
udevadm trigger
udevadm settle
fi
exit 0

View File

@ -74,6 +74,7 @@ AC_CONFIG_FILES([
cmd/zinject/Makefile cmd/zinject/Makefile
cmd/zpool/Makefile cmd/zpool/Makefile
cmd/zpool_id/Makefile cmd/zpool_id/Makefile
cmd/zpool_layout/Makefile
cmd/ztest/Makefile cmd/ztest/Makefile
module/Makefile module/Makefile
module/avl/Makefile module/avl/Makefile