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