]>
Commit | Line | Data |
---|---|---|
a6ef9522 | 1 | #!/bin/sh |
821b6834 NB |
2 | # |
3 | # vdev_id: udev helper to generate user-friendly names for JBOD disks | |
4 | # | |
5 | # This script parses the file /etc/zfs/vdev_id.conf to map a | |
6 | # physical path in a storage topology to a channel name. The | |
7 | # channel name is combined with a disk enclosure slot number to | |
8 | # create an alias that reflects the physical location of the drive. | |
9 | # This is particularly helpful when it comes to tasks like replacing | |
10 | # failed drives. Slot numbers may also be re-mapped in case the | |
11 | # default numbering is unsatisfactory. The drive aliases will be | |
12 | # created as symbolic links in /dev/disk/by-vdev. | |
13 | # | |
2957f38d NB |
14 | # The currently supported topologies are sas_direct and sas_switch. |
15 | # A multipath mode is supported in which dm-mpath devices are | |
16 | # handled by examining the first-listed running component disk. In | |
17 | # multipath mode the configuration file should contain a channel | |
18 | # definition with the same name for each path to a given enclosure. | |
19 | # | |
20 | # The alias keyword provides a simple way to map already-existing | |
21 | # device symlinks to more convenient names. It is suitable for | |
22 | # small, static configurations or for sites that have some automated | |
23 | # way to generate the mapping file. | |
24 | # | |
821b6834 NB |
25 | # |
26 | # Some example configuration files are given below. | |
27 | ||
28 | # # | |
29 | # # Example vdev_id.conf - sas_direct. | |
30 | # # | |
31 | # | |
32 | # multipath no | |
33 | # topology sas_direct | |
34 | # phys_per_port 4 | |
bba365cf | 35 | # slot bay |
821b6834 NB |
36 | # |
37 | # # PCI_ID HBA PORT CHANNEL NAME | |
38 | # channel 85:00.0 1 A | |
39 | # channel 85:00.0 0 B | |
40 | # channel 86:00.0 1 C | |
41 | # channel 86:00.0 0 D | |
42 | # | |
09d0b30f NB |
43 | # # Custom mapping for Channel A |
44 | # | |
45 | # # Linux Mapped | |
46 | # # Slot Slot Channel | |
47 | # slot 1 7 A | |
48 | # slot 2 10 A | |
49 | # slot 3 3 A | |
50 | # slot 4 6 A | |
51 | # | |
52 | # # Default mapping for B, C, and D | |
53 | # slot 1 4 | |
54 | # slot 2 2 | |
55 | # slot 3 1 | |
56 | # slot 4 3 | |
821b6834 NB |
57 | |
58 | # # | |
59 | # # Example vdev_id.conf - sas_switch | |
60 | # # | |
61 | # | |
62 | # topology sas_switch | |
63 | # | |
64 | # # SWITCH PORT CHANNEL NAME | |
65 | # channel 1 A | |
66 | # channel 2 B | |
67 | # channel 3 C | |
68 | # channel 4 D | |
69 | ||
70 | # # | |
71 | # # Example vdev_id.conf - multipath | |
72 | # # | |
73 | # | |
74 | # multipath yes | |
75 | # | |
76 | # # PCI_ID HBA PORT CHANNEL NAME | |
77 | # channel 85:00.0 1 A | |
78 | # channel 85:00.0 0 B | |
79 | # channel 86:00.0 1 A | |
80 | # channel 86:00.0 0 B | |
81 | ||
2957f38d NB |
82 | # # |
83 | # # Example vdev_id.conf - alias | |
84 | # # | |
85 | # | |
86 | # # by-vdev | |
87 | # # name fully qualified or base name of device link | |
88 | # alias d1 /dev/disk/by-id/wwn-0x5000c5002de3b9ca | |
89 | # alias d2 wwn-0x5000c5002def789e | |
90 | ||
821b6834 NB |
91 | PATH=/bin:/sbin:/usr/bin:/usr/sbin |
92 | CONFIG=/etc/zfs/vdev_id.conf | |
93 | PHYS_PER_PORT= | |
94 | DEV= | |
821b6834 NB |
95 | MULTIPATH= |
96 | TOPOLOGY= | |
bba365cf | 97 | BAY= |
821b6834 NB |
98 | |
99 | usage() { | |
100 | cat << EOF | |
101 | Usage: vdev_id [-h] | |
102 | vdev_id <-d device> [-c config_file] [-p phys_per_port] | |
269db7a4 | 103 | [-g sas_direct|sas_switch|scsi] [-m] |
821b6834 | 104 | |
ad0b23b1 | 105 | -c specify name of an alternative config file [default=$CONFIG] |
821b6834 | 106 | -d specify basename of device (i.e. sda) |
c66401fa | 107 | -e Create enclose device symlinks only (/dev/by-enclosure) |
821b6834 NB |
108 | -g Storage network topology [default="$TOPOLOGY"] |
109 | -m Run in multipath mode | |
110 | -p number of phy's per switch port [default=$PHYS_PER_PORT] | |
111 | -h show this summary | |
112 | EOF | |
113 | exit 0 | |
114 | } | |
115 | ||
116 | map_slot() { | |
64025fa3 BB |
117 | LINUX_SLOT=$1 |
118 | CHANNEL=$2 | |
821b6834 | 119 | |
09d0b30f | 120 | MAPPED_SLOT=`awk "\\$1 == \"slot\" && \\$2 == ${LINUX_SLOT} && \ |
2d9d57b0 | 121 | \\$4 ~ /^${CHANNEL}$|^$/ { print \\$3; exit }" $CONFIG` |
821b6834 NB |
122 | if [ -z "$MAPPED_SLOT" ] ; then |
123 | MAPPED_SLOT=$LINUX_SLOT | |
124 | fi | |
125 | printf "%d" ${MAPPED_SLOT} | |
126 | } | |
127 | ||
128 | map_channel() { | |
64025fa3 BB |
129 | MAPPED_CHAN= |
130 | PCI_ID=$1 | |
131 | PORT=$2 | |
821b6834 NB |
132 | |
133 | case $TOPOLOGY in | |
134 | "sas_switch") | |
ba43f456 | 135 | MAPPED_CHAN=`awk "\\$1 == \"channel\" && \\$2 == ${PORT} \ |
821b6834 NB |
136 | { print \\$3; exit }" $CONFIG` |
137 | ;; | |
269db7a4 | 138 | "sas_direct"|"scsi") |
ba43f456 NB |
139 | MAPPED_CHAN=`awk "\\$1 == \"channel\" && \ |
140 | \\$2 == \"${PCI_ID}\" && \\$3 == ${PORT} \ | |
141 | { print \\$4; exit }" $CONFIG` | |
821b6834 NB |
142 | ;; |
143 | esac | |
144 | printf "%s" ${MAPPED_CHAN} | |
145 | } | |
146 | ||
2957f38d NB |
147 | sas_handler() { |
148 | if [ -z "$PHYS_PER_PORT" ] ; then | |
ba43f456 NB |
149 | PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \ |
150 | {print \\$2; exit}" $CONFIG` | |
2957f38d NB |
151 | fi |
152 | PHYS_PER_PORT=${PHYS_PER_PORT:-4} | |
153 | if ! echo $PHYS_PER_PORT | grep -q -E '^[0-9]+$' ; then | |
154 | echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric" | |
155 | exit 1 | |
156 | fi | |
157 | ||
158 | if [ -z "$MULTIPATH_MODE" ] ; then | |
ba43f456 NB |
159 | MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \ |
160 | {print \\$2; exit}" $CONFIG` | |
2957f38d NB |
161 | fi |
162 | ||
163 | # Use first running component device if we're handling a dm-mpath device | |
164 | if [ "$MULTIPATH_MODE" = "yes" ] ; then | |
165 | # If udev didn't tell us the UUID via DM_NAME, check /dev/mapper | |
166 | if [ -z "$DM_NAME" ] ; then | |
167 | DM_NAME=`ls -l --full-time /dev/mapper | | |
168 | awk "/\/$DEV$/{print \\$9}"` | |
169 | fi | |
170 | ||
171 | # For raw disks udev exports DEVTYPE=partition when | |
172 | # handling partitions, and the rules can be written to | |
173 | # take advantage of this to append a -part suffix. For | |
174 | # dm devices we get DEVTYPE=disk even for partitions so | |
175 | # we have to append the -part suffix directly in the | |
176 | # helper. | |
177 | if [ "$DEVTYPE" != "partition" ] ; then | |
178 | PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'` | |
179 | fi | |
180 | ||
181 | # Strip off partition information. | |
182 | DM_NAME=`echo $DM_NAME | sed 's/p[0-9][0-9]*$//'` | |
183 | if [ -z "$DM_NAME" ] ; then | |
184 | return | |
185 | fi | |
186 | ||
2a152383 | 187 | # Get the raw scsi device name from multipath -ll. Strip off |
383efa57 | 188 | # leading pipe symbols to make field numbering consistent. |
2a152383 | 189 | DEV=`multipath -ll $DM_NAME | |
383efa57 | 190 | awk '/running/{gsub("^[|]"," "); print $3 ; exit}'` |
2957f38d NB |
191 | if [ -z "$DEV" ] ; then |
192 | return | |
193 | fi | |
194 | fi | |
195 | ||
196 | if echo $DEV | grep -q ^/devices/ ; then | |
197 | sys_path=$DEV | |
198 | else | |
199 | sys_path=`udevadm info -q path -p /sys/block/$DEV 2>/dev/null` | |
200 | fi | |
201 | ||
202 | # Use positional parameters as an ad-hoc array | |
203 | set -- $(echo "$sys_path" | tr / ' ') | |
204 | num_dirs=$# | |
205 | scsi_host_dir="/sys" | |
206 | ||
207 | # Get path up to /sys/.../hostX | |
208 | i=1 | |
209 | while [ $i -le $num_dirs ] ; do | |
210 | d=$(eval echo \${$i}) | |
211 | scsi_host_dir="$scsi_host_dir/$d" | |
212 | echo $d | grep -q -E '^host[0-9]+$' && break | |
213 | i=$(($i + 1)) | |
214 | done | |
215 | ||
216 | if [ $i = $num_dirs ] ; then | |
217 | return | |
218 | fi | |
219 | ||
220 | PCI_ID=$(eval echo \${$(($i -1))} | awk -F: '{print $2":"$3}') | |
221 | ||
222 | # In sas_switch mode, the directory four levels beneath | |
223 | # /sys/.../hostX contains symlinks to phy devices that reveal | |
224 | # the switch port number. In sas_direct mode, the phy links one | |
225 | # directory down reveal the HBA port. | |
226 | port_dir=$scsi_host_dir | |
227 | case $TOPOLOGY in | |
228 | "sas_switch") j=$(($i + 4)) ;; | |
229 | "sas_direct") j=$(($i + 1)) ;; | |
230 | esac | |
231 | ||
232 | i=$(($i + 1)) | |
233 | while [ $i -le $j ] ; do | |
234 | port_dir="$port_dir/$(eval echo \${$i})" | |
235 | i=$(($i + 1)) | |
236 | done | |
237 | ||
238 | PHY=`ls -d $port_dir/phy* 2>/dev/null | head -1 | awk -F: '{print $NF}'` | |
239 | if [ -z "$PHY" ] ; then | |
d49d9c2b | 240 | PHY=0 |
2957f38d NB |
241 | fi |
242 | PORT=$(( $PHY / $PHYS_PER_PORT )) | |
243 | ||
244 | # Look in /sys/.../sas_device/end_device-X for the bay_identifier | |
245 | # attribute. | |
246 | end_device_dir=$port_dir | |
247 | while [ $i -lt $num_dirs ] ; do | |
248 | d=$(eval echo \${$i}) | |
249 | end_device_dir="$end_device_dir/$d" | |
250 | if echo $d | grep -q '^end_device' ; then | |
251 | end_device_dir="$end_device_dir/sas_device/$d" | |
252 | break | |
253 | fi | |
254 | i=$(($i + 1)) | |
255 | done | |
256 | ||
bba365cf AB |
257 | SLOT= |
258 | case $BAY in | |
259 | "bay") | |
260 | SLOT=`cat $end_device_dir/bay_identifier 2>/dev/null` | |
261 | ;; | |
262 | "phy") | |
263 | SLOT=`cat $end_device_dir/phy_identifier 2>/dev/null` | |
264 | ;; | |
d49d9c2b DK |
265 | "port") |
266 | d=$(eval echo \${$i}) | |
267 | SLOT=`echo $d | sed -e 's/^.*://'` | |
268 | ;; | |
bba365cf AB |
269 | "id") |
270 | i=$(($i + 1)) | |
271 | d=$(eval echo \${$i}) | |
272 | SLOT=`echo $d | sed -e 's/^.*://'` | |
273 | ;; | |
274 | "lun") | |
275 | i=$(($i + 2)) | |
276 | d=$(eval echo \${$i}) | |
277 | SLOT=`echo $d | sed -e 's/^.*://'` | |
278 | ;; | |
993669a7 SG |
279 | "ses") |
280 | # look for this SAS path in all SCSI Enclosure Services | |
281 | # (SES) enclosures | |
282 | sas_address=`cat $end_device_dir/sas_address 2>/dev/null` | |
283 | enclosures=`lsscsi -g | \ | |
284 | sed -n -e '/enclosu/s/^.* \([^ ][^ ]*\) *$/\1/p'` | |
285 | for enclosure in $enclosures; do | |
286 | set -- $(sg_ses -p aes $enclosure | \ | |
287 | awk "/device slot number:/{slot=\$12} \ | |
288 | /SAS address: $sas_address/\ | |
289 | {print slot}") | |
290 | SLOT=$1 | |
291 | if [ -n "$SLOT" ] ; then | |
292 | break | |
293 | fi | |
294 | done | |
295 | ;; | |
bba365cf | 296 | esac |
2957f38d NB |
297 | if [ -z "$SLOT" ] ; then |
298 | return | |
299 | fi | |
300 | ||
2957f38d | 301 | CHAN=`map_channel $PCI_ID $PORT` |
09d0b30f | 302 | SLOT=`map_slot $SLOT $CHAN` |
2957f38d NB |
303 | if [ -z "$CHAN" ] ; then |
304 | return | |
305 | fi | |
306 | echo ${CHAN}${SLOT}${PART} | |
307 | } | |
308 | ||
269db7a4 SG |
309 | scsi_handler() { |
310 | if [ -z "$FIRST_BAY_NUMBER" ] ; then | |
311 | FIRST_BAY_NUMBER=`awk "\\$1 == \"first_bay_number\" \ | |
312 | {print \\$2; exit}" $CONFIG` | |
313 | fi | |
314 | FIRST_BAY_NUMBER=${FIRST_BAY_NUMBER:-0} | |
315 | ||
316 | if [ -z "$PHYS_PER_PORT" ] ; then | |
317 | PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \ | |
318 | {print \\$2; exit}" $CONFIG` | |
319 | fi | |
320 | PHYS_PER_PORT=${PHYS_PER_PORT:-4} | |
321 | if ! echo $PHYS_PER_PORT | grep -q -E '^[0-9]+$' ; then | |
322 | echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric" | |
323 | exit 1 | |
324 | fi | |
325 | ||
326 | if [ -z "$MULTIPATH_MODE" ] ; then | |
327 | MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \ | |
328 | {print \\$2; exit}" $CONFIG` | |
329 | fi | |
330 | ||
331 | # Use first running component device if we're handling a dm-mpath device | |
332 | if [ "$MULTIPATH_MODE" = "yes" ] ; then | |
333 | # If udev didn't tell us the UUID via DM_NAME, check /dev/mapper | |
334 | if [ -z "$DM_NAME" ] ; then | |
335 | DM_NAME=`ls -l --full-time /dev/mapper | | |
336 | awk "/\/$DEV$/{print \\$9}"` | |
337 | fi | |
338 | ||
339 | # For raw disks udev exports DEVTYPE=partition when | |
340 | # handling partitions, and the rules can be written to | |
341 | # take advantage of this to append a -part suffix. For | |
342 | # dm devices we get DEVTYPE=disk even for partitions so | |
343 | # we have to append the -part suffix directly in the | |
344 | # helper. | |
345 | if [ "$DEVTYPE" != "partition" ] ; then | |
346 | PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'` | |
347 | fi | |
348 | ||
349 | # Strip off partition information. | |
350 | DM_NAME=`echo $DM_NAME | sed 's/p[0-9][0-9]*$//'` | |
351 | if [ -z "$DM_NAME" ] ; then | |
352 | return | |
353 | fi | |
354 | ||
355 | # Get the raw scsi device name from multipath -ll. Strip off | |
356 | # leading pipe symbols to make field numbering consistent. | |
357 | DEV=`multipath -ll $DM_NAME | | |
358 | awk '/running/{gsub("^[|]"," "); print $3 ; exit}'` | |
359 | if [ -z "$DEV" ] ; then | |
360 | return | |
361 | fi | |
362 | fi | |
363 | ||
364 | if echo $DEV | grep -q ^/devices/ ; then | |
365 | sys_path=$DEV | |
366 | else | |
367 | sys_path=`udevadm info -q path -p /sys/block/$DEV 2>/dev/null` | |
368 | fi | |
369 | ||
370 | # expect sys_path like this, for example: | |
371 | # /devices/pci0000:00/0000:00:0b.0/0000:09:00.0/0000:0a:05.0/0000:0c:00.0/host3/target3:1:0/3:1:0:21/block/sdv | |
372 | ||
373 | # Use positional parameters as an ad-hoc array | |
374 | set -- $(echo "$sys_path" | tr / ' ') | |
375 | num_dirs=$# | |
376 | scsi_host_dir="/sys" | |
377 | ||
378 | # Get path up to /sys/.../hostX | |
379 | i=1 | |
380 | while [ $i -le $num_dirs ] ; do | |
381 | d=$(eval echo \${$i}) | |
382 | scsi_host_dir="$scsi_host_dir/$d" | |
383 | echo $d | grep -q -E '^host[0-9]+$' && break | |
384 | i=$(($i + 1)) | |
385 | done | |
386 | ||
387 | if [ $i = $num_dirs ] ; then | |
388 | return | |
389 | fi | |
390 | ||
391 | PCI_ID=$(eval echo \${$(($i -1))} | awk -F: '{print $2":"$3}') | |
392 | ||
393 | # In scsi mode, the directory two levels beneath | |
394 | # /sys/.../hostX reveals the port and slot. | |
395 | port_dir=$scsi_host_dir | |
396 | j=$(($i + 2)) | |
397 | ||
398 | i=$(($i + 1)) | |
399 | while [ $i -le $j ] ; do | |
400 | port_dir="$port_dir/$(eval echo \${$i})" | |
401 | i=$(($i + 1)) | |
402 | done | |
403 | ||
404 | set -- $(echo $port_dir | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/') | |
405 | PORT=$1 | |
406 | SLOT=$(($2 + $FIRST_BAY_NUMBER)) | |
407 | ||
408 | if [ -z "$SLOT" ] ; then | |
409 | return | |
410 | fi | |
411 | ||
412 | CHAN=`map_channel $PCI_ID $PORT` | |
413 | SLOT=`map_slot $SLOT $CHAN` | |
414 | if [ -z "$CHAN" ] ; then | |
415 | return | |
416 | fi | |
417 | echo ${CHAN}${SLOT}${PART} | |
418 | } | |
419 | ||
c66401fa TH |
420 | # Figure out the name for the enclosure symlink |
421 | enclosure_handler () { | |
422 | # We get all the info we need from udev's DEVPATH variable: | |
423 | # | |
424 | # DEVPATH=/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/subsystem/devices/0:0:0:0/scsi_generic/sg0 | |
425 | ||
426 | # Get the enclosure ID ("0:0:0:0") | |
427 | ENC=$(basename $(readlink -m "/sys/$DEVPATH/../..")) | |
428 | if [ ! -d /sys/class/enclosure/$ENC ] ; then | |
429 | # Not an enclosure, bail out | |
430 | return | |
431 | fi | |
432 | ||
433 | # Get the long sysfs device path to our enclosure. Looks like: | |
434 | # /devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/port-0:0/ ... /enclosure/0:0:0:0 | |
435 | ||
436 | ENC_DEVICE=$(readlink /sys/class/enclosure/$ENC) | |
437 | ||
438 | # Grab the full path to the hosts port dir: | |
439 | # /devices/pci0000:00/0000:00:03.0/0000:05:00.0/host0/port-0:0 | |
440 | PORT_DIR=$(echo $ENC_DEVICE | grep -Eo '.+host[0-9]+/port-[0-9]+:[0-9]+') | |
441 | ||
442 | # Get the port number | |
443 | PORT_ID=$(echo $PORT_DIR | grep -Eo "[0-9]+$") | |
444 | ||
445 | # The PCI directory is two directories up from the port directory | |
446 | # /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0 | |
447 | PCI_ID_LONG=$(basename $(readlink -m "/sys/$PORT_DIR/../..")) | |
448 | ||
449 | # Strip down the PCI address from 0000:05:00.0 to 05:00.0 | |
450 | PCI_ID=$(echo "$PCI_ID_LONG" | sed -r 's/^[0-9]+://g') | |
451 | ||
452 | # Name our device according to vdev_id.conf (like "L0" or "U1"). | |
453 | NAME=$(awk "/channel/{if (\$1 == \"channel\" && \$2 == \"$PCI_ID\" && \ | |
454 | \$3 == \"$PORT_ID\") {print \$4int(count[\$4])}; count[\$4]++}" $CONFIG) | |
455 | ||
456 | echo "${NAME}" | |
457 | } | |
458 | ||
2957f38d NB |
459 | alias_handler () { |
460 | # Special handling is needed to correctly append a -part suffix | |
461 | # to partitions of device mapper devices. The DEVTYPE attribute | |
462 | # is normally set to "disk" instead of "partition" in this case, | |
463 | # so the udev rules won't handle that for us as they do for | |
464 | # "plain" block devices. | |
465 | # | |
466 | # For example, we may have the following links for a device and its | |
467 | # partitions, | |
468 | # | |
469 | # /dev/disk/by-id/dm-name-isw_dibgbfcije_ARRAY0 -> ../../dm-0 | |
470 | # /dev/disk/by-id/dm-name-isw_dibgbfcije_ARRAY0p1 -> ../../dm-1 | |
471 | # /dev/disk/by-id/dm-name-isw_dibgbfcije_ARRAY0p2 -> ../../dm-3 | |
472 | # | |
473 | # and the following alias in vdev_id.conf. | |
474 | # | |
475 | # alias A0 dm-name-isw_dibgbfcije_ARRAY0 | |
476 | # | |
477 | # The desired outcome is for the following links to be created | |
478 | # without having explicitly defined aliases for the partitions. | |
479 | # | |
480 | # /dev/disk/by-vdev/A0 -> ../../dm-0 | |
481 | # /dev/disk/by-vdev/A0-part1 -> ../../dm-1 | |
482 | # /dev/disk/by-vdev/A0-part2 -> ../../dm-3 | |
483 | # | |
484 | # Warning: The following grep pattern will misidentify whole-disk | |
485 | # devices whose names end with 'p' followed by a string of | |
486 | # digits as partitions, causing alias creation to fail. This | |
487 | # ambiguity seems unavoidable, so devices using this facility | |
488 | # must not use such names. | |
64025fa3 | 489 | DM_PART= |
2957f38d NB |
490 | if echo $DM_NAME | grep -q -E 'p[0-9][0-9]*$' ; then |
491 | if [ "$DEVTYPE" != "partition" ] ; then | |
492 | DM_PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'` | |
493 | fi | |
494 | fi | |
495 | ||
496 | # DEVLINKS attribute must have been populated by already-run udev rules. | |
497 | for link in $DEVLINKS ; do | |
498 | # Remove partition information to match key of top-level device. | |
499 | if [ -n "$DM_PART" ] ; then | |
500 | link=`echo $link | sed 's/p[0-9][0-9]*$//'` | |
501 | fi | |
502 | # Check both the fully qualified and the base name of link. | |
503 | for l in $link `basename $link` ; do | |
ba43f456 | 504 | alias=`awk "\\$1 == \"alias\" && \\$3 == \"${l}\" \ |
2957f38d NB |
505 | { print \\$2; exit }" $CONFIG` |
506 | if [ -n "$alias" ] ; then | |
507 | echo ${alias}${DM_PART} | |
508 | return | |
509 | fi | |
510 | done | |
511 | done | |
512 | } | |
513 | ||
c66401fa | 514 | while getopts 'c:d:eg:mp:h' OPTION; do |
821b6834 NB |
515 | case ${OPTION} in |
516 | c) | |
2957f38d NB |
517 | CONFIG=${OPTARG} |
518 | ;; | |
821b6834 | 519 | d) |
2957f38d NB |
520 | DEV=${OPTARG} |
521 | ;; | |
c66401fa TH |
522 | e) |
523 | # When udev sees a scsi_generic device, it calls this script with -e to | |
524 | # create the enclosure device symlinks only. We also need | |
525 | # "enclosure_symlinks yes" set in vdev_id.config to actually create the | |
526 | # symlink. | |
527 | ENCLOSURE_MODE=$(awk '{if ($1 == "enclosure_symlinks") print $2}' $CONFIG) | |
528 | if [ "$ENCLOSURE_MODE" != "yes" ] ; then | |
529 | exit 0 | |
530 | fi | |
531 | ;; | |
821b6834 NB |
532 | g) |
533 | TOPOLOGY=$OPTARG | |
534 | ;; | |
535 | p) | |
536 | PHYS_PER_PORT=${OPTARG} | |
537 | ;; | |
538 | m) | |
539 | MULTIPATH_MODE=yes | |
540 | ;; | |
821b6834 NB |
541 | h) |
542 | usage | |
543 | ;; | |
544 | esac | |
545 | done | |
546 | ||
547 | if [ ! -r $CONFIG ] ; then | |
548 | exit 0 | |
549 | fi | |
550 | ||
64025fa3 | 551 | if [ -z "$DEV" ] && [ -z "$ENCLOSURE_MODE" ] ; then |
821b6834 NB |
552 | echo "Error: missing required option -d" |
553 | exit 1 | |
554 | fi | |
555 | ||
556 | if [ -z "$TOPOLOGY" ] ; then | |
ba43f456 | 557 | TOPOLOGY=`awk "\\$1 == \"topology\" {print \\$2; exit}" $CONFIG` |
821b6834 | 558 | fi |
a6ef9522 | 559 | |
bba365cf AB |
560 | if [ -z "$BAY" ] ; then |
561 | BAY=`awk "\\$1 == \"slot\" {print \\$2; exit}" $CONFIG` | |
562 | fi | |
563 | ||
c66401fa TH |
564 | TOPOLOGY=${TOPOLOGY:-sas_direct} |
565 | ||
566 | # Should we create /dev/by-enclosure symlinks? | |
64025fa3 | 567 | if [ "$ENCLOSURE_MODE" = "yes" ] && [ "$TOPOLOGY" = "sas_direct" ] ; then |
c66401fa TH |
568 | ID_ENCLOSURE=$(enclosure_handler) |
569 | if [ -z "$ID_ENCLOSURE" ] ; then | |
570 | exit 0 | |
571 | fi | |
572 | ||
573 | # Just create the symlinks to the enclosure devices and then exit. | |
574 | ENCLOSURE_PREFIX=$(awk '/enclosure_symlinks_prefix/{print $2}' $CONFIG) | |
575 | if [ -z "$ENCLOSURE_PREFIX" ] ; then | |
576 | ENCLOSURE_PREFIX="enc" | |
577 | fi | |
578 | echo "ID_ENCLOSURE=$ID_ENCLOSURE" | |
579 | echo "ID_ENCLOSURE_PATH=by-enclosure/$ENCLOSURE_PREFIX-$ID_ENCLOSURE" | |
580 | exit 0 | |
581 | fi | |
582 | ||
2957f38d NB |
583 | # First check if an alias was defined for this device. |
584 | ID_VDEV=`alias_handler` | |
821b6834 | 585 | |
2957f38d | 586 | if [ -z "$ID_VDEV" ] ; then |
bba365cf | 587 | BAY=${BAY:-bay} |
2957f38d NB |
588 | case $TOPOLOGY in |
589 | sas_direct|sas_switch) | |
590 | ID_VDEV=`sas_handler` | |
591 | ;; | |
269db7a4 SG |
592 | scsi) |
593 | ID_VDEV=`scsi_handler` | |
594 | ;; | |
2957f38d NB |
595 | *) |
596 | echo "Error: unknown topology $TOPOLOGY" | |
597 | exit 1 | |
598 | ;; | |
599 | esac | |
821b6834 NB |
600 | fi |
601 | ||
2957f38d NB |
602 | if [ -n "$ID_VDEV" ] ; then |
603 | echo "ID_VDEV=${ID_VDEV}" | |
604 | echo "ID_VDEV_PATH=disk/by-vdev/${ID_VDEV}" | |
821b6834 | 605 | fi |