]> git.ipfire.org Git - thirdparty/dracut.git/blame_incremental - test/TEST-40-NBD/test.sh
fix(zfcp_rules): correct shellcheck regression when parsing ccw args
[thirdparty/dracut.git] / test / TEST-40-NBD / test.sh
... / ...
CommitLineData
1#!/bin/bash
2
3# shellcheck disable=SC2034
4TEST_DESCRIPTION="root filesystem on NBD with $USE_NETWORK"
5
6# Uncomment this to debug failures
7# DEBUGFAIL="rd.debug systemd.log_target=console loglevel=7"
8#DEBUGFAIL="rd.shell rd.break rd.debug systemd.log_target=console loglevel=7 systemd.log_level=debug"
9#SERIAL="tcp:127.0.0.1:9999"
10
11test_check() {
12 if ! type -p nbd-server &> /dev/null; then
13 echo "Test needs nbd-server... Skipping"
14 return 1
15 fi
16
17 if ! modinfo -k "$KVERSION" nbd &> /dev/null; then
18 echo "Kernel module nbd does not exist"
19 return 1
20 fi
21
22 return 0
23}
24
25run_server() {
26 # Start server first
27 echo "NBD TEST SETUP: Starting DHCP/NBD server"
28
29 declare -a disk_args=()
30 # shellcheck disable=SC2034
31 declare -i disk_index=0
32 qemu_add_drive_args disk_index disk_args "$TESTDIR"/unencrypted.img unencrypted
33 qemu_add_drive_args disk_index disk_args "$TESTDIR"/encrypted.img encrypted
34 qemu_add_drive_args disk_index disk_args "$TESTDIR"/server.img serverroot
35
36 "$testdir"/run-qemu \
37 "${disk_args[@]}" \
38 -serial "${SERIAL:-"file:$TESTDIR/server.log"}" \
39 -net nic,macaddr=52:54:00:12:34:56,model=e1000 \
40 -net socket,listen=127.0.0.1:12340 \
41 -append "panic=1 oops=panic softlockup_panic=1 rd.luks=0 systemd.crash_reboot quiet root=/dev/disk/by-id/ata-disk_serverroot rootfstype=ext4 rw console=ttyS0,115200n81 selinux=0 $SERVER_DEBUG" \
42 -initrd "$TESTDIR"/initramfs.server \
43 -pidfile "$TESTDIR"/server.pid -daemonize || return 1
44 chmod 644 "$TESTDIR"/server.pid || return 1
45
46 # Cleanup the terminal if we have one
47 tty -s && stty sane
48
49 if ! [[ $SERIAL ]]; then
50 echo "Waiting for the server to startup"
51 while :; do
52 grep Serving "$TESTDIR"/server.log && break
53 tail "$TESTDIR"/server.log
54 sleep 1
55 done
56 else
57 echo Sleeping 10 seconds to give the server a head start
58 sleep 10
59 fi
60}
61
62client_test() {
63 local test_name="$1"
64 local mac=$2
65 local cmdline="$3"
66 local fstype=$4
67 local fsopt=$5
68 local found opts nbdinfo
69
70 [[ $fstype ]] || fstype=ext4
71 [[ $fsopt ]] || fsopt="ro"
72
73 echo "CLIENT TEST START: $test_name"
74
75 declare -a disk_args=()
76 declare -i disk_index=0
77 qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker
78
79 test_marker_reset
80 "$testdir"/run-qemu \
81 "${disk_args[@]}" \
82 -net nic,macaddr="$mac",model=e1000 \
83 -net socket,connect=127.0.0.1:12340 \
84 -append "panic=1 oops=panic softlockup_panic=1 systemd.crash_reboot rd.shell=0 $cmdline $DEBUGFAIL rd.auto rd.info rd.retry=10 ro console=ttyS0,115200n81 selinux=0 " \
85 -initrd "$TESTDIR"/initramfs.testing
86
87 # shellcheck disable=SC2181
88 if [[ $? -ne 0 ]] || ! test_marker_check nbd-OK "$TESTDIR"/marker.img; then
89 echo "CLIENT TEST END: $test_name [FAILED - BAD EXIT]"
90 return 1
91 fi
92
93 # nbdinfo=( fstype fsoptions )
94 read -r -a nbdinfo < <(awk '{print $2, $3; exit}' "$TESTDIR"/marker.img)
95
96 if [[ ${nbdinfo[0]} != "$fstype" ]]; then
97 echo "CLIENT TEST END: $test_name [FAILED - WRONG FS TYPE] \"${nbdinfo[0]}\" != \"$fstype\""
98 return 1
99 fi
100
101 opts=${nbdinfo[1]},
102 while [[ $opts ]]; do
103 if [[ ${opts%%,*} == "$fsopt" ]]; then
104 found=1
105 break
106 fi
107 opts=${opts#*,}
108 done
109
110 if [[ ! $found ]]; then
111 echo "CLIENT TEST END: $test_name [FAILED - BAD FS OPTS] \"${nbdinfo[1]}\" != \"$fsopt\""
112 return 1
113 fi
114
115 echo "CLIENT TEST END: $test_name [OK]"
116}
117
118test_run() {
119 if ! run_server; then
120 echo "Failed to start server" 1>&2
121 return 1
122 fi
123 client_run
124 kill_server
125}
126
127client_run() {
128 # The default is ext4,errors=continue so use that to determine
129 # if our options were parsed and used
130 client_test "NBD root=nbd:IP:port" 52:54:00:12:34:00 \
131 "root=nbd:192.168.50.1:raw rd.luks=0" || return 1
132
133 client_test "NBD root=nbd:IP:port::fsopts" 52:54:00:12:34:00 \
134 "root=nbd:192.168.50.1:raw::errors=panic rd.luks=0" \
135 ext4 errors=panic || return 1
136
137 client_test "NBD root=nbd:IP:port:fstype" 52:54:00:12:34:00 \
138 "root=nbd:192.168.50.1:raw:ext4 rd.luks=0" ext4 || return 1
139
140 client_test "NBD root=nbd:IP:port:fstype:fsopts" 52:54:00:12:34:00 \
141 "root=nbd:192.168.50.1:raw:ext4:errors=panic rd.luks=0" \
142 ext4 errors=panic || return 1
143
144 # DHCP root-path parsing
145
146 client_test "NBD root=/dev/root netroot=dhcp DHCP root-path nbd:srv:port" 52:54:00:12:34:01 \
147 "root=/dev/root netroot=dhcp ip=dhcp rd.luks=0" || return 1
148
149 client_test "NBD root=/dev/root netroot=dhcp DHCP root-path nbd:srv:port:fstype" \
150 52:54:00:12:34:02 "root=/dev/root netroot=dhcp ip=dhcp rd.luks=0" ext2 || return 1
151
152 client_test "NBD root=/dev/root netroot=dhcp DHCP root-path nbd:srv:port::fsopts" \
153 52:54:00:12:34:03 "root=/dev/root netroot=dhcp ip=dhcp rd.luks=0" ext4 errors=panic || return 1
154
155 client_test "NBD root=/dev/root netroot=dhcp DHCP root-path nbd:srv:port:fstype:fsopts" \
156 52:54:00:12:34:04 "root=/dev/root netroot=dhcp ip=dhcp rd.luks=0" ext2 errors=panic || return 1
157
158 # netroot handling
159
160 client_test "NBD netroot=nbd:IP:port" 52:54:00:12:34:00 \
161 "root=LABEL=dracut netroot=nbd:192.168.50.1:raw ip=dhcp rd.luks=0" || return 1
162
163 client_test "NBD root=/dev/root netroot=dhcp DHCP root-path nbd:srv:port:fstype:fsopts" \
164 52:54:00:12:34:04 "root=/dev/root netroot=dhcp ip=dhcp rd.luks=0" ext2 errors=panic || return 1
165
166 # Encrypted root handling via LVM/LUKS over NBD
167
168 # shellcheck disable=SC1090
169 . "$TESTDIR"/luks.uuid
170
171 client_test "NBD root=LABEL=dracut netroot=nbd:IP:port" \
172 52:54:00:12:34:00 \
173 "root=LABEL=dracut rd.luks.uuid=$ID_FS_UUID rd.lv.vg=dracut ip=dhcp netroot=nbd:192.168.50.1:encrypted" || return 1
174
175 # XXX This should be ext4,errors=panic but that doesn't currently
176 # XXX work when you have a real root= line in addition to netroot=
177 # XXX How we should work here needs clarification
178 # client_test "NBD root=LABEL=dracut netroot=dhcp (w/ fstype and opts)" \
179 # 52:54:00:12:34:05 \
180 # "root=LABEL=dracut rd.luks.uuid=$ID_FS_UUID rd.lv.vg=dracut netroot=dhcp" || return 1
181
182 if [[ -s server.pid ]]; then
183 kill -TERM "$(cat "$TESTDIR"/server.pid)"
184 rm -f -- "$TESTDIR"/server.pid
185 fi
186
187}
188
189make_encrypted_root() {
190 rm -fr "$TESTDIR"/overlay
191 kernel=$KVERSION
192 # Create what will eventually be our root filesystem onto an overlay
193 (
194 # shellcheck disable=SC2030
195 export initdir=$TESTDIR/overlay/source
196 # shellcheck disable=SC1090
197 . "$PKGLIBDIR"/dracut-init.sh
198 mkdir -p "$initdir"
199 (
200 cd "$initdir" || exit
201 mkdir -p dev sys proc etc run var/run tmp
202 )
203
204 inst_multiple sh df free ls shutdown poweroff stty cat ps ln ip \
205 mount dmesg mkdir cp ping dd sync
206 for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
207 [ -f ${_terminfodir}/l/linux ] && break
208 done
209 inst_multiple -o ${_terminfodir}/l/linux
210
211 inst_simple "${PKGLIBDIR}/modules.d/99base/dracut-lib.sh" "/lib/dracut-lib.sh"
212 inst_simple "${PKGLIBDIR}/modules.d/99base/dracut-dev-lib.sh" "/lib/dracut-dev-lib.sh"
213 inst_binary "${PKGLIBDIR}/dracut-util" "/usr/bin/dracut-util"
214 ln -s dracut-util "${initdir}/usr/bin/dracut-getarg"
215 ln -s dracut-util "${initdir}/usr/bin/dracut-getargs"
216
217 inst ./client-init.sh /sbin/init
218 inst_simple /etc/os-release
219 find_binary plymouth > /dev/null && inst_multiple plymouth
220 cp -a /etc/ld.so.conf* "$initdir"/etc
221 ldconfig -r "$initdir"
222 )
223
224 # second, install the files needed to make the root filesystem
225 (
226 # shellcheck disable=SC2030
227 # shellcheck disable=SC2031
228 export initdir=$TESTDIR/overlay
229 # shellcheck disable=SC1090
230 . "$PKGLIBDIR"/dracut-init.sh
231 (
232 cd "$initdir" || exit
233 mkdir -p dev sys proc etc tmp var run root
234 ln -s ../run var/run
235 )
236 inst_multiple mkfs.ext4 poweroff cp umount dd sync
237 inst_hook shutdown-emergency 000 ./hard-off.sh
238 inst_hook emergency 000 ./hard-off.sh
239 inst_hook initqueue 01 ./create-encrypted-root.sh
240 inst_hook initqueue/finished 01 ./finished-false.sh
241 )
242
243 # create an initramfs that will create the target root filesystem.
244 # We do it this way so that we do not risk trashing the host mdraid
245 # devices, volume groups, encrypted partitions, etc.
246 "$DRACUT" -l -i "$TESTDIR"/overlay / \
247 -m "dash crypt lvm mdraid kernel-modules qemu" \
248 -d "piix ide-gd_mod ata_piix ext4 sd_mod" \
249 --no-hostonly-cmdline -N \
250 -f "$TESTDIR"/initramfs.makeroot "$KVERSION" || return 1
251 rm -rf -- "$TESTDIR"/overlay
252
253 declare -a disk_args=()
254 # shellcheck disable=SC2034
255 declare -i disk_index=0
256 qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker 1
257 qemu_add_drive_args disk_index disk_args "$TESTDIR"/encrypted.img root 120
258
259 # Invoke KVM and/or QEMU to actually create the target filesystem.
260 "$testdir"/run-qemu \
261 "${disk_args[@]}" \
262 -append "root=/dev/fakeroot rw quiet console=ttyS0,115200n81 selinux=0" \
263 -initrd "$TESTDIR"/initramfs.makeroot || return 1
264 test_marker_check dracut-root-block-created || return 1
265 grep -F -a -m 1 ID_FS_UUID "$TESTDIR"/marker.img > "$TESTDIR"/luks.uuid
266}
267
268make_client_root() {
269 rm -fr "$TESTDIR"/overlay
270 kernel=$KVERSION
271 (
272 mkdir -p "$TESTDIR"/overlay/source
273 # shellcheck disable=SC2030
274 # shellcheck disable=SC2031
275 export initdir=$TESTDIR/overlay/source
276 # shellcheck disable=SC1090
277 . "$PKGLIBDIR"/dracut-init.sh
278 mkdir -p "$initdir"
279 (
280 cd "$initdir" || exit
281 mkdir -p dev sys proc etc run var/run tmp
282 )
283 inst_multiple sh ls shutdown poweroff stty cat ps ln ip \
284 dmesg mkdir cp ping dd mount sync
285 for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
286 [ -f ${_terminfodir}/l/linux ] && break
287 done
288 inst_multiple -o ${_terminfodir}/l/linux
289
290 inst_simple "${PKGLIBDIR}/modules.d/99base/dracut-lib.sh" "/lib/dracut-lib.sh"
291 inst_simple "${PKGLIBDIR}/modules.d/99base/dracut-dev-lib.sh" "/lib/dracut-dev-lib.sh"
292 inst_binary "${PKGLIBDIR}/dracut-util" "/usr/bin/dracut-util"
293 ln -s dracut-util "${initdir}/usr/bin/dracut-getarg"
294 ln -s dracut-util "${initdir}/usr/bin/dracut-getargs"
295
296 inst ./client-init.sh /sbin/init
297 inst_simple /etc/os-release
298 inst_multiple -o {,/usr}/etc/nsswitch.conf
299 inst /etc/passwd /etc/passwd
300 inst /etc/group /etc/group
301 for i in /usr/lib*/libnss_files* /lib*/libnss_files*; do
302 [ -e "$i" ] || continue
303 inst "$i"
304 done
305 cp -a /etc/ld.so.conf* "$initdir"/etc
306 ldconfig -r "$initdir"
307 )
308
309 # second, install the files needed to make the root filesystem
310 (
311 # shellcheck disable=SC2030
312 # shellcheck disable=SC2031
313 export initdir=$TESTDIR/overlay
314 # shellcheck disable=SC1090
315 . "$PKGLIBDIR"/dracut-init.sh
316 inst_multiple sfdisk mkfs.ext4 poweroff cp umount sync dd
317 inst_hook initqueue 01 ./create-client-root.sh
318 inst_hook initqueue/finished 01 ./finished-false.sh
319 )
320
321 # create an initramfs that will create the target root filesystem.
322 # We do it this way so that we do not risk trashing the host mdraid
323 # devices, volume groups, encrypted partitions, etc.
324 "$DRACUT" -l -i "$TESTDIR"/overlay / \
325 -m "dash rootfs-block kernel-modules qemu" \
326 -d "piix ide-gd_mod ata_piix ext4 sd_mod" \
327 --nomdadmconf \
328 --no-hostonly-cmdline -N \
329 -f "$TESTDIR"/initramfs.makeroot "$KVERSION" || return 1
330
331 declare -a disk_args=()
332 # shellcheck disable=SC2034
333 declare -i disk_index=0
334 qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker 1
335 qemu_add_drive_args disk_index disk_args "$TESTDIR"/unencrypted.img root 120
336
337 # Invoke KVM and/or QEMU to actually create the target filesystem.
338 "$testdir"/run-qemu \
339 "${disk_args[@]}" \
340 -append "root=/dev/dracut/root rw rootfstype=ext4 quiet console=ttyS0,115200n81 selinux=0" \
341 -initrd "$TESTDIR"/initramfs.makeroot || return 1
342 test_marker_check dracut-root-block-created || return 1
343 rm -fr "$TESTDIR"/overlay
344}
345
346make_server_root() {
347 rm -fr "$TESTDIR"/overlay
348 # shellcheck disable=SC2031
349 export kernel=$KVERSION
350 (
351 mkdir -p "$TESTDIR"/overlay/source
352 # shellcheck disable=SC2030
353 # shellcheck disable=SC2031
354 export initdir=$TESTDIR/overlay/source
355 # shellcheck disable=SC1090
356 . "$PKGLIBDIR"/dracut-init.sh
357 mkdir -p "$initdir"
358 (
359 cd "$initdir" || exit
360 mkdir -p run dev sys proc etc var var/lib/dhcpd tmp etc/nbd-server
361 ln -s ../run var/run
362 )
363 cat > "$initdir/etc/nbd-server/config" << EOF
364[generic]
365[raw]
366exportname = /dev/disk/by-id/ata-disk_unencrypted
367port = 2000
368bs = 4096
369[encrypted]
370exportname = /dev/disk/by-id/ata-disk_encrypted
371port = 2001
372bs = 4096
373EOF
374 inst_multiple sh ls shutdown poweroff stty cat ps ln ip \
375 dmesg mkdir cp ping grep \
376 sleep nbd-server chmod modprobe vi pidof
377 for _terminfodir in /lib/terminfo /etc/terminfo /usr/share/terminfo; do
378 [ -f ${_terminfodir}/l/linux ] && break
379 done
380 inst_multiple -o ${_terminfodir}/l/linux
381 instmods nfsd sunrpc ipv6 lockd af_packet 8021q ipvlan macvlan
382 type -P dhcpd > /dev/null && inst_multiple dhcpd
383 inst ./server-init.sh /sbin/init
384 inst_simple /etc/os-release
385 inst ./hosts /etc/hosts
386 inst ./dhcpd.conf /etc/dhcpd.conf
387 inst_multiple -o {,/usr}/etc/nsswitch.conf
388 inst /etc/passwd /etc/passwd
389 inst /etc/group /etc/group
390 _nsslibs=$(
391 cat "$dracutsysrootdir"/{,usr/}etc/nsswitch.conf 2> /dev/null \
392 | sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' \
393 | tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|'
394 )
395 _nsslibs=${_nsslibs#|}
396 _nsslibs=${_nsslibs%|}
397
398 inst_libdir_file -n "$_nsslibs" 'libnss_*.so*'
399
400 cp -a /etc/ld.so.conf* "$initdir"/etc
401 ldconfig -r "$initdir"
402 dracut_kernel_post
403 )
404
405 # second, install the files needed to make the root filesystem
406 (
407 # shellcheck disable=SC2030
408 # shellcheck disable=SC2031
409 export initdir=$TESTDIR/overlay
410 # shellcheck disable=SC1090
411 . "$PKGLIBDIR"/dracut-init.sh
412 inst_multiple sfdisk mkfs.ext4 poweroff cp umount sync dd sync
413 inst_hook initqueue 01 ./create-server-root.sh
414 inst_hook initqueue/finished 01 ./finished-false.sh
415 )
416
417 # create an initramfs that will create the target root filesystem.
418 # We do it this way so that we do not risk trashing the host mdraid
419 # devices, volume groups, encrypted partitions, etc.
420 "$DRACUT" -l -i "$TESTDIR"/overlay / \
421 -m "dash rootfs-block kernel-modules qemu" \
422 -d "piix ide-gd_mod ata_piix ext4 sd_mod" \
423 --nomdadmconf \
424 --no-hostonly-cmdline -N \
425 -f "$TESTDIR"/initramfs.makeroot "$KVERSION" || return 1
426
427 declare -a disk_args=()
428 # shellcheck disable=SC2034
429 declare -i disk_index=0
430 qemu_add_drive_args disk_index disk_args "$TESTDIR"/marker.img marker 1
431 qemu_add_drive_args disk_index disk_args "$TESTDIR"/server.img root 120
432
433 # Invoke KVM and/or QEMU to actually create the target filesystem.
434 "$testdir"/run-qemu \
435 "${disk_args[@]}" \
436 -append "root=/dev/dracut/root rw rootfstype=ext4 quiet console=ttyS0,115200n81 selinux=0" \
437 -initrd "$TESTDIR"/initramfs.makeroot || return 1
438 test_marker_check dracut-root-block-created || return 1
439 rm -fr "$TESTDIR"/overlay
440}
441
442test_setup() {
443 make_encrypted_root || return 1
444 make_client_root || return 1
445 make_server_root || return 1
446
447 rm -fr "$TESTDIR"/overlay
448 # Make the test image
449 (
450 # shellcheck disable=SC2031
451 # shellcheck disable=SC2030
452 export initdir=$TESTDIR/overlay
453 # shellcheck disable=SC1090
454 . "$PKGLIBDIR"/dracut-init.sh
455 inst_multiple poweroff shutdown dd
456 inst_hook shutdown-emergency 000 ./hard-off.sh
457 inst ./cryptroot-ask.sh /sbin/cryptroot-ask
458
459 # inst ./debug-shell.service /lib/systemd/system/debug-shell.service
460 # mkdir -p "${initdir}/lib/systemd/system/sysinit.target.wants"
461 # ln -fs ../debug-shell.service "${initdir}/lib/systemd/system/sysinit.target.wants/debug-shell.service"
462
463 # shellcheck disable=SC1090
464 . "$TESTDIR"/luks.uuid
465 mkdir -p "$initdir"/etc
466 echo "luks-$ID_FS_UUID /dev/nbd0 /etc/key" > "$initdir"/etc/crypttab
467 echo -n test > "$initdir"/etc/key
468 inst_simple ./client.link /etc/systemd/network/01-client.link
469 )
470
471 "$DRACUT" -l -i "$TESTDIR"/overlay / \
472 -o "plymouth iscsi nfs" \
473 -a "debug watchdog ${USE_NETWORK}" \
474 --no-hostonly-cmdline -N \
475 -f "$TESTDIR"/initramfs.testing "$KVERSION" || return 1
476
477 (
478 # shellcheck disable=SC2031
479 export initdir="$TESTDIR"/overlay
480 # shellcheck disable=SC1090
481 . "$PKGLIBDIR"/dracut-init.sh
482 rm "$initdir"/etc/systemd/network/01-client.link
483 inst_simple ./server.link /etc/systemd/network/01-server.link
484 inst_hook pre-mount 99 ./wait-if-server.sh
485 )
486 "$DRACUT" -l -i "$TESTDIR"/overlay / \
487 -a "rootfs-block debug kernel-modules network network-legacy" \
488 -d "af_packet piix ide-gd_mod ata_piix ext4 sd_mod e1000 drbg" \
489 --no-hostonly-cmdline -N \
490 -f "$TESTDIR"/initramfs.server "$KVERSION" || return 1
491
492 rm -rf -- "$TESTDIR"/overlay
493}
494
495kill_server() {
496 if [[ -s $TESTDIR/server.pid ]]; then
497 kill -TERM "$(cat "$TESTDIR"/server.pid)"
498 rm -f -- "$TESTDIR"/server.pid
499 fi
500}
501
502test_cleanup() {
503 kill_server
504}
505
506# shellcheck disable=SC1090
507. "$testdir"/test-functions