]>
Commit | Line | Data |
---|---|---|
95d2dabc | 1 | #!/bin/bash |
95d2dabc | 2 | |
8bcfd683 | 3 | # called by dracut |
95d2dabc | 4 | check() { |
29b10e65 | 5 | local _rootdev |
95d2dabc | 6 | # If our prerequisites are not met, fail anyways. |
b31f3fe0 | 7 | require_binaries hostname iscsi-iname iscsiadm iscsid || return 1 |
95d2dabc HH |
8 | |
9 | # If hostonly was requested, fail the check if we are not actually | |
10 | # booting from root. | |
11 | ||
b093aa2d | 12 | is_iscsi() { |
83e0dc7a | 13 | local _dev=$1 |
cb08b013 | 14 | |
b093aa2d HH |
15 | [[ -L "/sys/dev/block/$_dev" ]] || return |
16 | cd "$(readlink -f "/sys/dev/block/$_dev")" | |
95d2dabc HH |
17 | until [[ -d sys || -d iscsi_session ]]; do |
18 | cd .. | |
19 | done | |
20 | [[ -d iscsi_session ]] | |
b093aa2d | 21 | } |
95d2dabc | 22 | |
7f347723 | 23 | [[ $hostonly ]] || [[ $mount_needs ]] && { |
b093aa2d | 24 | pushd . >/dev/null |
c2ab9909 | 25 | for_each_host_dev_and_slaves is_iscsi || return 255 |
b093aa2d | 26 | popd >/dev/null |
95d2dabc HH |
27 | } |
28 | return 0 | |
29 | } | |
30 | ||
2e34f380 HR |
31 | get_ibft_mod() { |
32 | local ibft_mac=$1 | |
cd728308 | 33 | local iface_mac iface_mod |
2e34f380 | 34 | # Return the iSCSI offload module for a given MAC address |
cd728308 HR |
35 | for iface_desc in $(iscsiadm -m iface | cut -f 2 -d ' '); do |
36 | iface_mod=${iface_desc%%,*} | |
37 | iface_mac=${iface_desc#*,} | |
38 | iface_mac=${iface_mac%%,*} | |
39 | if [ "$ibft_mac" = "$iface_mac" ] ; then | |
40 | echo $iface_mod | |
2e34f380 HR |
41 | return 0 |
42 | fi | |
2e34f380 HR |
43 | done |
44 | } | |
45 | ||
442abd16 HR |
46 | install_ibft() { |
47 | # When iBFT / iscsi_boot is detected: | |
48 | # - Use 'ip=ibft' to set up iBFT network interface | |
2e34f380 HR |
49 | # Note: bnx2i is using a different MAC address of iSCSI offloading |
50 | # so the 'ip=ibft' parameter must not be set | |
442abd16 HR |
51 | # - specify firmware booting cmdline parameter |
52 | ||
53 | for d in /sys/firmware/* ; do | |
2e34f380 HR |
54 | if [ -d ${d}/ethernet0 ] ; then |
55 | read ibft_mac < ${d}/ethernet0/mac | |
56 | ibft_mod=$(get_ibft_mod $ibft_mac) | |
57 | fi | |
58 | if [ -z "$ibft_mod" ] && [ -d ${d}/ethernet1 ] ; then | |
59 | read ibft_mac < ${d}/ethernet1/mac | |
60 | ibft_mod=$(get_ibft_mod $ibft_mac) | |
61 | fi | |
442abd16 | 62 | if [ -d ${d}/initiator ] ; then |
2e34f380 | 63 | if [ ${d##*/} = "ibft" ] && [ "$ibft_mod" != "bnx2i" ] ; then |
b31f3fe0 | 64 | echo -n "rd.iscsi.ibft=1 " |
442abd16 HR |
65 | fi |
66 | echo -n "rd.iscsi.firmware=1" | |
67 | fi | |
68 | done | |
69 | } | |
70 | ||
c4d8793c HR |
71 | install_iscsiroot() { |
72 | local devpath=$1 | |
b31f3fe0 | 73 | local scsi_path iscsi_lun session c d conn host flash |
c4d8793c HR |
74 | local iscsi_session iscsi_address iscsi_port iscsi_targetname iscsi_tpgt |
75 | ||
76 | scsi_path=${devpath%%/block*} | |
77 | [ "$scsi_path" = "$devpath" ] && return 1 | |
78 | iscsi_lun=${scsi_path##*:} | |
79 | [ "$iscsi_lun" = "$scsi_path" ] && return 1 | |
80 | session=${devpath%%/target*} | |
81 | [ "$session" = "$devpath" ] && return 1 | |
82 | iscsi_session=${session##*/} | |
83 | [ "$iscsi_session" = "$session" ] && return 1 | |
b31f3fe0 DM |
84 | host=${session%%/session*} |
85 | [ "$host" = "$session" ] && return 1 | |
86 | iscsi_host=${host##*/} | |
87 | ||
88 | for flash in ${host}/flashnode_sess-* ; do | |
89 | is_boot=$(cat $flash/is_boot_target) | |
90 | if [ $is_boot -eq 1 ] ; then | |
91 | # qla4xxx flashnode session; skip iBFT discovery | |
92 | iscsi_initiator=$(cat /sys/class/iscsi_host/${iscsi_host}/initiatorname) | |
93 | echo "rd.iscsi.initiator=${iscsi_initiator}" | |
94 | return; | |
95 | fi | |
96 | done | |
c4d8793c HR |
97 | |
98 | for d in ${session}/* ; do | |
99 | case $d in | |
100 | *connection*) | |
101 | c=${d##*/} | |
102 | conn=${d}/iscsi_connection/${c} | |
103 | if [ -d ${conn} ] ; then | |
104 | iscsi_address=$(cat ${conn}/persistent_address) | |
105 | iscsi_port=$(cat ${conn}/persistent_port) | |
106 | fi | |
107 | ;; | |
108 | *session) | |
109 | if [ -d ${d}/${iscsi_session} ] ; then | |
110 | iscsi_initiator=$(cat ${d}/${iscsi_session}/initiatorname) | |
111 | iscsi_targetname=$(cat ${d}/${iscsi_session}/targetname) | |
112 | fi | |
113 | ;; | |
114 | esac | |
115 | done | |
116 | ||
117 | [ -z "$iscsi_address" ] && return | |
118 | local_address=$(ip -o route get to $iscsi_address | sed -n 's/.*src \([0-9a-f.:]*\).*/\1/p') | |
119 | ifname=$(ip -o route get to $iscsi_address | sed -n 's/.*dev \([^ ]*\).*/\1/p') | |
b31f3fe0 DM |
120 | |
121 | #follow ifcfg settings for boot protocol | |
122 | bootproto=$(sed -n "/BOOTPROTO/s/BOOTPROTO='\([[:alpha:]]*6\?\)4\?'/\1/p" /etc/sysconfig/network/ifcfg-$ifname) | |
123 | if [ $bootproto ]; then | |
124 | printf 'ip=%s:%s ' ${ifname} ${bootproto} | |
125 | else | |
126 | printf 'ip=%s:static ' ${ifname} | |
127 | fi | |
c4d8793c HR |
128 | |
129 | if [ -e /sys/class/net/$ifname/address ] ; then | |
130 | ifmac=$(cat /sys/class/net/$ifname/address) | |
131 | printf 'ifname=%s:%s ' ${ifname} ${ifmac} | |
132 | fi | |
133 | ||
134 | if [ -n "$iscsi_address" -a -n "$iscsi_targetname" ] ; then | |
135 | if [ -n "$iscsi_port" -a "$iscsi_port" -eq 3260 ] ; then | |
136 | iscsi_port= | |
137 | fi | |
138 | if [ -n "$iscsi_lun" -a "$iscsi_lun" -eq 0 ] ; then | |
139 | iscsi_lun= | |
140 | fi | |
141 | # In IPv6 case rd.iscsi.initatior= must pass address in [] brackets | |
142 | case "$iscsi_address" in | |
143 | *:*) | |
144 | iscsi_address="[$iscsi_address]" | |
145 | ;; | |
146 | esac | |
f34a2ef1 TR |
147 | # Must be two separate lines, so that "sort | uniq" commands later |
148 | # can sort out rd.iscsi.initiator= duplicates | |
149 | echo "rd.iscsi.initiator=${iscsi_initiator}" | |
150 | echo "netroot=iscsi:${iscsi_address}::${iscsi_port}:${iscsi_lun}:${iscsi_targetname}" | |
b31f3fe0 | 151 | echo "rd.neednet=1" |
c4d8793c HR |
152 | fi |
153 | return 0 | |
154 | } | |
155 | ||
156 | ||
157 | install_softiscsi() { | |
158 | [ -d /sys/firmware/ibft ] && return 0 | |
159 | ||
160 | is_softiscsi() { | |
161 | local _dev=$1 | |
162 | local iscsi_dev | |
163 | ||
164 | [[ -L "/sys/dev/block/$_dev" ]] || return | |
165 | iscsi_dev=$(cd -P /sys/dev/block/$_dev; echo $PWD) | |
166 | install_iscsiroot $iscsi_dev | |
167 | } | |
168 | ||
169 | for_each_host_dev_and_slaves_all is_softiscsi || return 255 | |
170 | return 0 | |
171 | } | |
172 | ||
8bcfd683 | 173 | # called by dracut |
95d2dabc HH |
174 | depends() { |
175 | echo network rootfs-block | |
176 | } | |
177 | ||
8bcfd683 | 178 | # called by dracut |
95d2dabc | 179 | installkernel() { |
4f9f76cd | 180 | local _arch=$(uname -m) |
794b2d2c | 181 | local _funcs='iscsi_register_transport' |
4f9f76cd | 182 | |
b31f3fe0 | 183 | instmods bnx2i qla4xxx cxgb3i cxgb4i be2iscsi qedi |
7929ec19 | 184 | hostonly="" instmods iscsi_tcp iscsi_ibft crc32c iscsi_boot_sysfs |
9c2a1d0d | 185 | |
794b2d2c HH |
186 | if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then |
187 | _s390drivers="=drivers/s390/scsi" | |
188 | fi | |
189 | ||
b31f3fe0 | 190 | dracut_instmods -o -s ${_funcs} =drivers/scsi ${_s390drivers:+"$_s390drivers"} |
95d2dabc HH |
191 | } |
192 | ||
442abd16 HR |
193 | # called by dracut |
194 | cmdline() { | |
c4d8793c HR |
195 | local _iscsiconf=$(install_ibft) |
196 | { | |
197 | if [ "$_iscsiconf" ] ; then | |
198 | echo ${_iscsiconf} | |
199 | else | |
200 | install_softiscsi | |
201 | fi | |
202 | } | sort | uniq | |
442abd16 HR |
203 | } |
204 | ||
8bcfd683 | 205 | # called by dracut |
95d2dabc | 206 | install() { |
af119460 | 207 | inst_multiple -o iscsiuio |
4aad3438 | 208 | inst_libdir_file 'libgcc_s.so*' |
b31f3fe0 DM |
209 | inst_multiple umount hostname iscsi-iname iscsiadm iscsid |
210 | ||
b31f3fe0 DM |
211 | inst_multiple -o \ |
212 | $systemdsystemunitdir/iscsid.socket \ | |
213 | $systemdsystemunitdir/iscsid.service \ | |
214 | $systemdsystemunitdir/iscsiuio.service \ | |
215 | $systemdsystemunitdir/iscsiuio.socket \ | |
216 | $systemdsystemunitdir/sockets.target.wants/iscsid.socket \ | |
217 | $systemdsystemunitdir/sockets.target.wants/iscsiuio.socket | |
218 | ||
5e615f4e LR |
219 | if [[ $hostonly ]]; then |
220 | inst_dir $(/usr/bin/find /etc/iscsi) | |
221 | else | |
222 | inst_simple /etc/iscsi/iscsid.conf | |
223 | fi | |
54e28d79 HR |
224 | |
225 | # Detect iBFT and perform mandatory steps | |
226 | if [[ $hostonly_cmdline == "yes" ]] ; then | |
c4d8793c HR |
227 | local _iscsiconf=$(cmdline) |
228 | [[ $_iscsiconf ]] && printf "%s\n" "$_iscsiconf" >> "${initdir}/etc/cmdline.d/95iscsi.conf" | |
54e28d79 HR |
229 | fi |
230 | ||
95d2dabc | 231 | inst_hook cmdline 90 "$moddir/parse-iscsiroot.sh" |
eef7649e | 232 | inst_hook cleanup 90 "$moddir/cleanup-iscsi.sh" |
552ecca6 | 233 | inst "$moddir/iscsiroot.sh" "/sbin/iscsiroot" |
0a5fd0dc HH |
234 | if ! dracut_module_included "systemd"; then |
235 | inst "$moddir/mount-lun.sh" "/bin/mount-lun.sh" | |
b31f3fe0 DM |
236 | else |
237 | inst_multiple -o \ | |
238 | $systemdsystemunitdir/iscsi.service \ | |
239 | $systemdsystemunitdir/iscsid.service \ | |
240 | $systemdsystemunitdir/iscsid.socket \ | |
241 | $systemdsystemunitdir/iscsiuio.service \ | |
242 | $systemdsystemunitdir/iscsiuio.socket \ | |
243 | iscsiadm iscsid | |
244 | ||
245 | mkdir -p "${initdir}/$systemdsystemunitdir/sockets.target.wants" | |
246 | for i in \ | |
9e82732d | 247 | iscsid.socket \ |
b31f3fe0 DM |
248 | iscsiuio.socket \ |
249 | ; do | |
250 | ln_r "$systemdsystemunitdir/${i}" "$systemdsystemunitdir/sockets.target.wants/${i}" | |
251 | done | |
252 | ||
253 | mkdir -p "${initdir}/$systemdsystemunitdir/basic.target.wants" | |
254 | for i in \ | |
255 | iscsid.service \ | |
256 | iscsiuio.service \ | |
257 | ; do | |
258 | ln_r "$systemdsystemunitdir/${i}" "$systemdsystemunitdir/basic.target.wants/${i}" | |
259 | done | |
0a5fd0dc | 260 | fi |
f5753e18 | 261 | inst_dir /var/lib/iscsi |
41eba87b | 262 | dracut_need_initqueue |
95d2dabc | 263 | } |