Use iBFT settings for configure network interface
[opensuse:mkinitrd-old.git] / mkinitrd
1 #! /bin/bash
2
3 # mkinitrd - create the initramfs images
4 # usage: see below usage() or call with -h
5 #
6 # Copyright (C) 1999-2005 SuSE Linux Products GmbH, Nuernberg, Germany
7 #
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
21 # USA.
22
23 # This file is kept in the following CVS repository:
24 #
25 # $Source: /suse/yast2/cvsroot/mkinitrd/mkinitrd,v $
26 # $Revision: 1.312.2.58 $
27
28 usage() {
29     cat<<EOF
30         Create initial ramdisk images that contain all kernel modules
31         needed in the early boot process, before the root file system
32         becomes available. This usually includes SCSI and/or RAID
33         modules, a file system module for the root file system, or
34         a network interface driver module for dhcp.
35
36         mkinitrd [options]
37
38         options:
39           -h               This Text.
40           -k "kernel list" List of kernel images for which initrd files
41                            are created. Defaults to all kernels found
42                            in /boot.
43           -i "initrd list" List of file names for the initrd; position
44                            have match to "kernel list". Defaults to all
45                            all kernels found in /boot.
46           -m "module list" Modules to include in initrd. Defaults to the
47                            INITRD_MODULES variable in /etc/sysconfig/kernel.
48           -u "DomU module list" Modules to include in initrd. Defaults to
49                            the DOMU_INITRD_MODULES variable in
50                            /etc/sysconfig/kernel.
51           -f "feature list" Features to be enabled when generating initrd.
52                            Available features are:
53                            iscsi, md, mpath, lvm, lvm2, evms
54           -b boot_dir      Boot directory. Defaults to /boot.
55           -d root_device   Root device. Defaults to the device from which
56                            / is mounted. Overrides the rootdev enviroment
57                            variable if set.
58           -s size          Add splash animation and bootscreen to initrd.
59           -t tmp_dir       Temporary directory. Defaults to /var/tmp.
60           -D interface     Run dhcp on the specified interface.
61           -I interface     Configure the specified interface statically.
62           -a acpi_dsdt     Attach compiled ACPI DSDT (Differentiated System
63                            Description Table) to initrd. This replaces the
64                            DSDT of the BIOS. Defaults to the ACPI_DSDT
65                            variable in /etc/sysconfig/kernel.
66           -e               Use static binaries where possible.
67           -l keyfile       LUKS Key for decryption.
68           -V script        Vendor specific script to run in linuxrc.
69           -M map           System.map file to use.
70 EOF
71     exit
72 }
73
74 # Readlink is not present on some older distributions: emulate it.
75 readlink() {
76     local path=$1 ll
77
78     if [ -L "$path" ]; then
79         ll="$(LC_ALL=C ls -l "$path" 2> /dev/null)"
80         echo "${ll/* -> }"
81     else
82         return 1
83     fi
84 }
85
86 default_kernel_images() {
87     local regex kernel_image kernel_version version_version initrd_image
88     local qf='%{NAME}-%{VERSION}-%{RELEASE}\n'
89
90     case "$(uname -m)" in
91         s390|s390x)
92             regex='image'
93             ;;
94         ppc|ppc64)
95             regex='vmlinux'
96             ;;
97         *)  regex='vmlinu.'
98             ;;
99     esac
100
101     # user mode linux
102     if grep -q UML /proc/cpuinfo; then
103             regex='linux'
104     fi
105
106     kernel_images=""
107     initrd_images=""
108     for kernel_image in $(ls /boot \
109             | sed -ne "\|^$regex\(-[0-9.]\+-[0-9]\+-[a-z0-9]\+$\)\?|p") ; do
110
111         # Note that we cannot check the RPM database here -- this
112         # script is itself called from within the binary kernel
113         # packages, and rpm does not allow recursive calls.
114
115         [ -L "/boot/$kernel_image" ] && continue
116         [ "${kernel_image%%.gz}" != "$kernel_image" ] && continue
117         kernel_version=$(/sbin/get_kernel_version \
118                          /boot/$kernel_image 2> /dev/null)
119         initrd_image=$(echo $kernel_image | sed -e "s|${regex}|initrd|")
120         if [ "$kernel_image" != "$initrd_image" -a \
121              -n "$kernel_version" -a \
122              -d "/lib/modules/$kernel_version" ]; then
123                 kernel_images="$kernel_images /boot/$kernel_image"
124                 initrd_images="$initrd_images /boot/$initrd_image"
125         fi
126     done
127 }
128
129 # You can specify the root device via the environment variable rootdev (e.g.
130 # "rootdev=/dev/hda mkinitrd").
131
132 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133 # general configurable parameters
134
135 kernel_images=
136 initrd_images=
137 modules=
138 modules_set=
139 domu_modules=
140 domu_modules_set=
141 feature_list=
142 boot_dir=
143 splash=off
144 luks_key=/tmp/luks.key
145 use_static_binaries=
146 acpi_dsdt=
147 use_selinux=
148 sysmap=
149 journaldev=
150
151 # architecture dependend changes:
152 case "$(uname -m)" in
153     i?86|x86_64)
154         splash="auto"
155         ;;
156 esac
157
158 while getopts :ef:hk:i:m:u:b:d:s:l:St:D:I:V:a:M:j: a ; do
159     case $a in
160         \:|\?)  case $OPTARG in
161                 k)  echo "-k requires kernel list parameter"
162                     ;;
163                 i)  echo "-i requires initrd list parameter"
164                     ;;
165                 m)  echo "-m requires module list parameter"
166                     ;;
167                 u)  echo "-u requires module list parameter"
168                     ;;
169                 f)  echo "-f requires feature list parameter"
170                     ;;
171                 b)  echo "-b requires boot dir parameter"
172                     ;;
173                 d)  echo "-d requires root device parameter"
174                     ;;
175                 s)  echo "-s requires image size(s)"
176                     ;;
177                 t)  echo "-t requires tmp dir parameter"
178                     ;;
179                 l)  echo "-l requires LUKS key parameter"
180                     ;;
181                 D)  echo "-D requires dhcp interface parameter"
182                     ;;
183                 I)  echo "-I requires network interface parameter"
184                     ;;
185                 a)  echo "-a requires a DSDT parameter"
186                     ;;
187                 V)  echo "-V requires an executable to run inside linuxrc"
188                     ;;
189                 M)  echo "-M requires the System.map file"
190                     ;;  
191                 j)  echo "-j requires the journal device"
192                     ;;  
193                 *)  echo "Unknown option: -$OPTARG"
194                     echo "Try mkinitrd -h"
195                     ;;
196             esac
197             exit 1
198             ;;
199         e)  use_static_binaries=1
200             ;;
201         f)  feature_list=$OPTARG
202             ;;
203         k)  kernel_images=$OPTARG
204             ;;
205         i)  initrd_images=$OPTARG
206             ;;
207         m)  modules=$OPTARG
208             modules_set=1
209             ;;
210         u)  domu_modules=$OPTARG
211             domu_modules_set=1
212             ;;
213         b)  boot_dir=$OPTARG
214             ;;
215         d)  rootdev=$OPTARG
216             ;;
217         s)  splash=$OPTARG
218             ;;
219         t)  tmp_dir=$OPTARG
220             ;;
221         l)  luks_key=$OPTARG
222             ;;
223         D)  interface=$OPTARG
224             interface=${interface#/dev/}
225             use_dhcp=1
226             ;;
227         I)  interface=$OPTARG
228             interface=${interface#/dev/}
229             use_ipconfig=1
230             ;;
231         a)  acpi_dsdt="$OPTARG"
232             ;;
233         S)  use_selinux=1
234             ;;
235         V)  vendor_init_script="$OPTARG"
236             ;;
237         M)  sysmap="$OPTARG"
238             ;;
239         j)  journaldev="$OPTARG"
240             ;;
241         h)  usage
242             ;;
243     esac
244 done
245 shift $(( $OPTIND - 1 ))
246
247 mkinit_name="mkinitramfs"
248
249 if [ -n "$1" ]; then
250     root_dir=${1%/}  # strip trailing slash
251 else
252     root_dir=
253 fi
254
255 if [ -n "$boot_dir" ]; then
256     boot_dir="${boot_dir#/}"
257     boot_dir="/${boot_dir%/}"
258 else
259     boot_dir="/boot"
260 fi
261 if [ ! -d "$boot_dir" ]; then
262     echo "$boot_dir is not a directory" >&2
263     exit 1
264 fi
265
266 if [ -n "$tmp_dir" ]; then
267     tmp_dir="/${tmp_dir#/}"  # make sure it is an absolute path
268 else
269     tmp_dir=/var/tmp
270 fi
271 if [ ! -d "$tmp_dir" ]; then
272     echo "$tmp_dir is not a directory" >&2
273     exit 1
274 fi
275
276 # Check if the -k and -i settings are valid.
277 if [ $(set -- $kernel_images ; echo $#) -ne \
278      $(set -- $initrd_images ; echo $#) ]; then
279     echo "You have to specify -k and -i, or none of both. The -k" \
280          "and -i options must each contain the same number of items." >&2
281     exit 1
282 fi
283
284 # Mount /usr, required for ldd and other tools to create the initrd tree
285 mounted_usr=
286 if [ ! -x /usr/bin/ldd ]; then
287   mounted_usr=/usr
288   if ! mount -n -v /usr ; then
289     echo "/usr/bin/ldd not available and mount /usr failed." \
290          "mkinitrd does not work without it." >&2
291     exit 1
292   fi
293 fi
294
295 # Mount /proc if not already done so
296 mounted_proc=
297 if [ ! -e /proc/mounts ]; then
298   mounted_proc=/proc
299   mount -n -t proc proc $mounted_proc
300 fi
301
302 # And /sys likewise
303 mounted_sys=
304 if [ ! -d /sys/devices ] ; then
305     mounted_sys=/sys
306     mount -n -t sysfs none /sys
307 fi
308
309 if [ -z "$kernel_images" -o -z "$initrd_images" ]; then
310     default_kernel_images
311 fi
312
313 # Check which shell and insmod binaries to use in initrd.
314 initrd_shell_dynamic=/bin/bash
315 if [ -n "$use_static_binaries" ]; then
316     if [ -x /bin/ash.static ]; then
317         initrd_shell=/bin/ash.static
318     else
319         initrd_shell=/bin/ash
320     fi
321 else
322     initrd_shell=$initrd_shell_dynamic
323 fi
324 # The shell-bang line to use inside initrd.
325 shebang=$initrd_shell
326 shebang=${shebang%.static}
327
328 [ -x /sbin/insmod ] \
329     && initrd_insmod_dynamic=/sbin/insmod
330 if [ -n "$use_static_binaries" ]; then
331     initrd_insmod=/sbin/insmod.static
332 else
333     initrd_insmod=$initrd_insmod_dynamic
334 fi
335
336 [ -x /sbin/modprobe ] \
337     && initrd_modprobe_dynamic=/sbin/modprobe
338 if [ -n "$use_static_binaries" ]; then
339     initrd_modprobe=/sbin/modprobe.static
340 else
341     initrd_modprobe=$initrd_modprobe_dynamic
342 fi
343
344 # maximum initrd size
345 image_blocks=40960
346 image_inodes=2048
347
348 # handle splash screen
349 case "$splash" in
350 off)
351     splashsizes= ;;
352 auto)
353     unset ${!splash_size_*}
354     modes=
355     for file in $root_dir/{etc/lilo.conf,boot/grub/menu.lst,proc/cmdline}; do
356         [ -e $file ] || continue
357         modes="$modes $(sed -e '/^[ \t]*#/d' $file \
358                         | sed -ne 's/^.*vga[ \t]*=[ \t]*\([^ \t]*\).*/\1/p' \
359                         | sed -ne '/^\([0-9]\+\|0[xX][0-9a-fA-F]\+\)$/p')"
360     done
361
362     for mode in $modes; do
363         case $(($mode)) in  # $((...)) : Convert 0xFOO to decimal
364         785|786) splash_size_640x480=1 ;;
365         788|789) splash_size_800x600=1 ;;
366         791|792) splash_size_1024x768=1 ;;
367         794|795) splash_size_1280x1024=1 ;;
368         *)       vgahex=$(printf 0x%04x "$(($mode))")
369                  if [ -x /usr/sbin/hwinfo ] ; then
370                      size=$(/usr/sbin/hwinfo --framebuffer | \
371                          sed -ne 's/^.*Mode '$vgahex': \([^ ]\+\) .*$/\1/p' \
372                          2>/dev/null)
373                      eval splash_size_$size=1
374                  fi ;;
375         esac
376     done
377     # Get current modes from fb
378     for fb in /sys/class/graphics/fb* ; do
379         if [ -d $fb ] && [ -f $fb/virtual_size ] ; then
380             size=$(sed -ne 's/,/x/p' $fb/virtual_size)
381             eval splash_size_$size=1
382         fi
383     done
384     splashsizes="$(for x in ${!splash_size_*}; do
385                         echo ${x#splash_size_}
386                    done)"
387     unset ${!splash_size_*}
388     ;;
389 *)
390     splashsizes=$splash ;;
391 esac
392
393 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
394 # should be nothing to change below...
395
396 PATH=/sbin:/usr/sbin:$PATH
397
398 # Fixup old installations
399 unset CDPATH
400
401 work_dir=$(mktemp -qd $tmp_dir/${mkinit_name}.XXXXXX)
402 if [ $? -ne 0 ]; then
403         echo "$0: Can't create temp dir, exiting." >&2
404         exit 1
405 fi
406
407 umount_proc() {
408     [ "$mounted_proc" ] && umount -n $mounted_proc
409     mounted_proc=
410     [ "$mounted_sys" ] && umount -n $mounted_sys
411     mounted_sys=
412     [ "$mounted_usr" ] && umount -v -n $mounted_usr
413     mounted_usr=
414 }
415
416 cleanup() {
417     rm -f $tmp_initrd $tmp_initrd.gz
418     initrd_bins=()
419 }
420
421 cleanup_finish() {
422     umount_proc
423     [ -d "$work_dir" ] && rm -rf $work_dir
424 }
425
426 handle_terminate() {
427     echo "(received signal)
428
429 Interrupted, cleaning up." >&2
430     cleanup
431     cleanup_finish
432     exit 255
433 }
434
435 trap handle_terminate 1 2 3 15
436
437 error() {
438     echo "$2" >&2
439     cleanup
440     cleanup_finish
441     exit $1
442 }
443
444 oops() {
445     exit_code=$1
446     shift
447     echo "$@" >&2
448 }
449
450 is_xen_kernel() {
451     local kversion=$1
452     local cfg
453
454     for cfg in ${root_dir}/boot/config-$kversion $root_dir/lib/modules/$kversion/build/.config
455     do
456         test -r $cfg || continue
457         grep -q "^CONFIG_XEN=y\$" $cfg
458         return
459     done
460     test $kversion != "${kversion%-xen*}"
461     return 
462 }
463
464 # Check if module $1 is listed in $modules.
465 has_module() {
466     case " $modules " in
467         *" $1 "*)   return 0 ;;
468     esac
469     return 1
470 }
471
472 # Check if any of the modules in $* are listed in $modules.
473 has_any_module() {
474     local module
475     for module in "$@"; do
476         has_module "$module" && return 0
477     done
478 }
479
480 # Add module $1 at the end of the module list.
481 add_module() {
482     local module
483     for module in "$@"; do
484         has_module "$module" || modules="$modules $module"
485     done
486 }
487
488 # Install a binary file
489 cp_bin() {
490     cp -a "$@" \
491     || exit_code=1
492
493     # Remember the binaries installed. We need the list for checking
494     # for dynamic libraries.
495     while [ $# -gt 1 ]; do
496         initrd_bins[${#initrd_bins[@]}]=$1
497         shift
498    done
499 }
500
501 # Resolve dynamic library dependencies. Returns a list of symbolic links
502 # to shared objects and shared object files for the binaries in $*.
503 shared_object_files() {
504     local LDD CHROOT initrd_libs lib_files lib_links lib link
505
506     LDD=/usr/bin/ldd
507     if [ ! -x $LDD ]; then
508         error 2 "I need $LDD."
509     fi
510
511     initrd_libs=( $(
512         $LDD "$@" \
513         | sed -ne 's:\t\(.* => \)\?\(/.*\) (0x[0-9a-f]*):\2:p'
514     ) )
515
516     # Evil hack: On some systems we have generic as well as optimized
517     # libraries, but the optimized libraries may not work with all
518     # kernel versions (e.g., the NPTL glibc libraries don't work with
519     # a 2.4 kernel). Use the generic versions of the libraries in the
520     # initrd (and guess the name).
521     local n optimized
522     for ((n=0; $n<${#initrd_libs[@]}; n++)); do
523         lib=${initrd_libs[$n]}
524         optimized="$(echo "$lib" | sed -e 's:.*/\([^/]\+/\)[^/]\+$:\1:')"
525         lib=${lib/$optimized/}
526         if [ "${optimized:0:3}" != "lib" -a -f "$lib" ]; then
527             #echo "[Using $lib instead of ${initrd_libs[$n]}]" >&2
528             initrd_libs[$n]="${lib/$optimized/}"
529         fi
530     done
531
532     for lib in "${initrd_libs[@]}"; do
533         case "$lib" in
534         linux-gate*)
535             # This library is mapped into the process by the kernel
536             # for vsyscalls (i.e., syscalls that don't need a user/
537             # kernel address space transition) in 2.6 kernels.
538             continue ;;
539         /*)
540             lib="${lib:1}" ;;
541         *)
542             # Library could not be found.
543             oops 7 "Dynamic library $lib not found"
544             continue ;;
545         esac
546
547         while [ -L "/$lib" ]; do
548             echo $lib
549             link="$(readlink "/$lib")"
550             if [ x"${link:0:1}" == x"/" ]; then
551                 lib=${link#/}
552             else
553                 lib="${lib%/*}/$link"
554             fi
555         done
556         echo $lib
557     done \
558     | sort -u
559 }
560
561 # Resolve module dependencies and parameters. Returns a list of modules and
562 # their parameters.
563 resolve_modules() {
564     local kernel_version=$1 module
565     shift
566
567     for module in "$@"; do
568         local with_modprobe_conf
569         module=${module%.o}  # strip trailing ".o" just in case.
570         module=${module%.ko}  # strip trailing ".ko" just in case.
571         if [ -e /etc/modprobe.conf ]; then
572             with_modprobe_conf="-C /etc/modprobe.conf"
573         fi
574         module_list=$(/sbin/modprobe $with_modprobe_conf \
575             --set-version $kernel_version --ignore-install \
576             --show-depends $module 2> /dev/null \
577             | sed -ne 's:.*insmod /\?::p' )
578         if [ "$module" != "af_packet" ] && [ -z "$module_list" ]; then
579             oops 7 "Cannot determine dependencies of module $module." \
580                 "Is modules.dep up to date?"
581         fi
582         echo "$module_list"
583     done \
584     | awk ' # filter duplicates: we must not reorder modules here!
585         NF == 0     { next }
586         $1 in seen  { next }
587                     { seen[$1]=1
588                       # drop module parameters here: modprobe in the initrd
589                       # will pick them up again.
590                       print $1
591                     }
592     '
593     rm -f $temp
594 }
595
596 # Test if file $1 is smaller than file $2 (kilobyte granularity)
597 smaller_file() {
598     local size1=$(ls -l "$1" |awk '{print $5}')
599     local size2=$(ls -l "$2" |awk '{print $5}')
600     [ $size1 -lt $size2 ]
601 }
602
603 # Cat from stdin to linuxrc, removing leading whitespace up to pipe symbol.
604 # Note that here documents can only be indented with tabs, not with spaces.
605 cat_linuxrc() {
606     sed 's/^[ \t]*|//' >> $linuxrc
607     echo >> $linuxrc
608 }
609
610 # Attach ACPI DSDT if necessary.
611 attach_dsdt() {
612     local initrd_image=$1
613
614     if [ -z "$acpi_dsdt" ]; then
615         if [ -f /etc/sysconfig/kernel ]; then
616             . /etc/sysconfig/kernel
617             acpi_dsdt="$ACPI_DSDT"
618         fi
619     fi
620     if [ -z "$acpi_dsdt" ]; then
621         return
622     fi
623     if [ ! -f "$acpi_dsdt" ]; then
624         oops 2 "ACPI DSDT $acpi_dsdt does not exist."
625         return
626     fi
627     if ! grep -q "DSDT" "$acpi_dsdt" ; then
628         oops 2 "File $acpi_dsdt is not a valid ACPI DSDT. Ignoring."
629         return
630     elif grep -qE 'DefinitionBlock' "$acpi_dsdt" ; then
631         oops 2 "ACPI DSDT $acpi_dsdt does not seem to be in binary form." \
632                "Will not attach this to $initrd_image."
633         return
634     fi
635
636     cp "$acpi_dsdt" $tmp_mnt/DSDT.aml
637
638     echo -e "ACPI DSDT:\t$acpi_dsdt"
639 }
640
641 # Check for IDE module
642 check_ide_modules_pcimap() {
643     local ide_modules
644
645     pcimap_file=$1
646     vendor_id=$2
647     device_id=$3
648         
649     pci_vendor_id=$(printf "0x%08x" $(($2)))
650     pci_device_id=$(printf "0x%08x" $(($3)))
651     while read pcimap_module rest; do
652         if [ "$pcimap_module" == "ata_piix" ]; then
653             # FIXME: add_module will have no effect in a sub-shell...
654             add_module "ahci"
655             ide_modules="$ide_modules ahci"
656         fi
657         ide_modules="$ide_modules $pcimap_module"
658     done < <(grep "$pci_vendor_id $pci_device_id" $pcimap_file)
659
660     echo "$ide_modules"
661 }
662
663 check_ide_modules_hwinfo() {
664     local ide_modules
665     local kernel_version
666
667     kernel_version=$(basename ${modules_dir})
668
669     pci_id_vendor=$1
670     pci_id_device=$2
671     pci_revision=$3
672     pci_subid_vendor=$4
673     pci_subid_device=$5
674
675     while read hwinfo_module; do
676         if [ "$hwinfo_module" == "ata_piix" ]; then
677             # Always add ahci prior to ata_piix
678             ide_modules="$ide_modules ahci $hwinfo_module"
679         elif [ "$hwinfo_module" != "ahci" ]; then
680             # Skip ahci module from hwinfo output
681             ide_modules="$ide_modules $hwinfo_module"
682         fi
683     done < <(hwinfo --kernel-version $kernel_version \
684                     --db "pci ${pci_id_vendor:+vendor=$pci_id_vendor} 
685                          ${pci_id_device:+device=$pci_id_device} 
686                          ${pci_subid_vendor:+subvendor=$pci_subid_vendor}  
687                          ${pci_subid_device:+subdevice=$pci_subid_device} 
688                          ${pci_revision:+revision=$pci_revision}")
689
690     echo "$ide_modules"
691 }
692
693 # Check for IDE modules, new version
694 # We'll be asking hwinfo to return the proper module for us
695 check_ide_modules() {
696     local modules_dir=$1 ide_modules
697
698     # Check for PCI bus
699     if [ ! -d /proc/bus/pci ]; then
700         # Not found, no error
701         return
702     fi
703
704     pcimap_file="${modules_dir}/modules.pcimap"
705
706     if [ ! -f "$pcimap_file" ] ; then
707         echo "No modules.pcimap file found" >&2
708         return
709     fi
710
711     while read pci_id none class_id dev_id rev_id; do
712         if [ "$class_id" == "0101:" ] ; then
713             ide_slots="$ide_slots $pci_id"
714         fi
715     done < <(/sbin/lspci -n)
716
717     for pci_id in $ide_slots; do
718         eval $(/sbin/lspci -nmv -s $pci_id | sed '/Class.*/d' | sed 's/:[[:blank:]]/=/g')
719         pci_id_vendor=$(printf "0x%x" $((0x$Vendor)))
720         pci_id_device=$(printf "0x%x" $((0x$Device)))
721         pci_revision=$(printf "0x%x" $((0x$Rev)))
722         if [ "$SVendor" ] ; then
723             pci_subid_vendor=$(printf "0x%x" $((0x$SVendor)))
724         fi
725         if [ "$SDevice" ] ; then
726             pci_subid_device=$(printf "0x%x" $((0x$SDevice)))
727         fi
728         : Slot ${pci_id}: $pci_id_vendor $pci_id_device $pci_subid_vendor $pci_subid_device
729         ide_modules=$(check_ide_modules_hwinfo $pci_id_vendor $pci_id_device $pci_revision $pci_subid_vendor $pci_subid_device)
730         if [ -z "$ide_modules" ]; then
731             ide_modules=$(check_ide_modules_pcimap $pcimap_file $pci_id_vendor $pci_id_device)
732         fi
733
734             if [ "$ide_modules" ]; then
735                 for module in $ide_modules; do
736                     # Only add ahci module if ata_piix is not loaded already
737                     if [ "$module" == "ahci" ]; then
738                         has_module ata_piix || add_module $module
739                     else
740                         add_module $module
741                     fi
742                 done
743                 # All IDE modules are now loaded later
744                 # if grep -q ide-disk ${modules_dir}/modules.dep; then
745                 #     add_module ide-disk
746                 # fi
747                 # IDE-floppy is considered obsolete
748                 # if grep -q ide-floppy ${modules_dir}/modules.dep; then
749                 #     add_module ide-floppy
750                 # fi
751                 # if grep -q ide-cd ${modules_dir}/modules.dep; then
752                 #     add_module ide-cd
753                 # fi
754                 echo
755             fi
756     done
757 }
758
759 # NOTE: The mkdevn, devmajor and block_driver functions are reused
760 #       inside the initrd, so keep them compatible with ash !!!
761 #
762
763 # Convert a major:minor pair into a device number
764 mkdevn() {
765     local major=$1 minor=$2 minorhi minorlo
766     major=$(($major * 256))
767     minorhi=$(($minor / 256))
768     minorlo=$(($minor % 256))
769     minor=$(($minorhi * 256 * 4096))
770     echo $(( $minorlo + $major + $minor ))
771 }
772
773 # Extract the major part from a device number
774 devmajor() {
775     local devn=$(($1 / 256))
776     echo $(( $devn % 4096 ))
777 }
778
779 # Extract the minor part from a device number
780 devminor() {
781     local devn=${1:-0}
782     echo $(( $devn % 256 )) 
783 }
784
785 block_driver() {
786     local devn block major driver
787     case "$1" in
788     /dev/*) devn=$(devnumber $1 2> /dev/null) ;;
789
790     *:*)    # major:minor
791             set -- $(IFS=: ; echo $1)
792             devn=$(mkdevn $1 $2) ;;
793
794     [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
795             # hex device number
796             devn=$((0x$1)) ;;
797     esac
798
799     [ -z "$devn" ] && return 1
800     major=$(devmajor $devn)
801     driver=$(cat /proc/devices | sed -n "/^Block devices:/{n;: n;s/^[ ]*$major \(.*\)/\1/p;n;b n}")
802     case "$driver" in
803         Block*)
804             return 1
805             ;;
806         *)
807             echo $driver
808             return 0
809             ;;
810     esac
811 }
812
813 # (We are using a devnumber binary inside the initrd.)
814 devnumber() {
815     set -- $(ls -lL $1)
816     mkdevn ${5%,} $6
817 }
818
819 # Calculate the netmask for a given prefix
820 calc_netmask() {
821     local prefix=$1
822     local netmask
823
824     netmask=
825     num=0
826     while (( $prefix >= 8 )) ; do
827         if (( $num > 0 )) ; then
828             netmask="${netmask}.255"
829         else
830             netmask="255"
831         fi
832         prefix=$(($prefix - 8))
833         num=$(($num + 1))
834     done
835     if (( $prefix > 0 )) ; then
836         mask=$(( 0xFF00 >> $prefix ))
837     else
838         mask=0
839     fi
840     netmask="${netmask}.$(( $mask & 0xFF ))"
841     num=$(($num + 1))
842     while (( $num < 4 )) ; do
843         netmask="${netmask}.0"
844         num=$(($num + 1))
845     done
846     echo $netmask
847 }
848
849 # Get the interface information for ipconfig
850 get_ip_config() {
851     local iface
852     local iplink
853     local iproute
854
855     iface=$1
856     iplink=$(ip addr show dev $iface | grep "inet ")
857
858     set -- $iplink
859     if [ "$1" == "inet" ]; then
860         shift
861
862         ipaddr=${1%%/*}
863         prefix=${1##*/}
864         shift 
865         if [ "$1" == "peer" ] ; then
866             shift
867             peeraddr=${1%%/*}
868             prefix=${1##*/}
869         fi
870         netmask=$(calc_netmask $prefix)
871         bcast=$3
872     fi
873     iproute=$(ip route list dev $iface | grep default)
874     if [ $? -eq 0 ]; then
875         set -- $iproute
876         gwaddr=$3
877     fi
878     hostname=$(hostname)
879     echo "$ipaddr:$peeraddr:$gwaddr:$netmask:$hostname:$iface:none"
880 }  
881
882 check_iscsi_root() {
883     local devname=$1
884     local sysfs_path
885
886     sysfs_path=$(udevinfo -q path -n $devname 2> /dev/null)
887     if [ -z "$sysfs_path" ] || [ ! -d /sys$sysfs_path ] ; then
888         return;
889     fi
890
891     pushd /sys$sysfs_path > /dev/null
892     if [ ! -d device ] ; then
893         cd ..
894     fi
895
896     if [ ! -d device ] ; then
897         # no device link; return
898         popd > /dev/null
899         return;
900     fi
901
902     cd -P device
903     cd ../..
904
905     if [ -d connection* ]; then
906         cd -P connection*
907         cid=${PWD#*connection}
908         sid=${cid%%:*}
909         if [ -d /sys/class/iscsi_session/session$sid ]; then
910             cd -P /sys/class/iscsi_session/session$sid
911             echo $(basename $PWD)
912         fi
913     fi
914     popd > /dev/null
915 }
916
917 get_default_interface() {
918     local ifname
919
920     # Determine the default network interface
921     if [ -f /etc/install.inf ] ; then
922         # Get info from install.inf during installation
923         BOOTPROTO=$(sed -ne 's/NetConfig: \(.*\)/\1/p' /etc/install.inf)
924         ifname=$(sed -ne 's/Netdevice: \(.*\)/\1/p' /etc/install.inf)
925         macaddress=$(sed -ne 's/HWAddr: \(.*\)/\1/p' /etc/install.inf)
926         if [ "$macaddress" ] ; then
927             for dev in /sys/class/net/* ; do
928                 read tmpmac < $dev/address
929                 if [ "$tmpmac" == "$macaddress" ] ; then
930                     ifname=${dev##*/}
931                 fi
932             done
933         fi
934     else
935     for cfg in /etc/sysconfig/network/ifcfg-*; do
936         if [ $(basename $cfg) = "ifcfg-lo" ] ; then
937             continue;
938         fi
939         eval $(grep STARTMODE $cfg)
940         if [ "$STARTMODE" = "nfsroot" ]; then
941             cfgname=$(basename $cfg)
942             ifname=$(getcfg-interface ${cfg#*/ifcfg-})
943             eval $(grep BOOTPROTO $cfg)
944             break;
945         fi
946     done
947     fi
948     echo $ifname/$BOOTPROTO
949 }
950
951 ###################################################################
952 #
953 # S/390 specific procedures
954 #
955 s390_check_lvm2() {
956     local vgname
957     local devname
958     
959     # Check whether the LVM is on zfcp or DASD
960     vgname=$(lvdisplay -c $1 | cut -d : -f 2)
961
962     if [ "$vgname" ]; then
963         for devname in $(pvdisplay -c | grep $vgname | cut -d : -f 1); do
964             case "$devname" in
965                 */dasd*)
966                     s390_enable_dasd=1
967                     ;;
968                 */sd*)
969                     s390_enable_zfcp=1
970                     ;;
971                 *)
972                     ;;
973             esac
974         done
975     fi
976 }
977
978 s390_check_evms() {
979     local evms_cmd
980     local evms_reg
981     local evms_cont
982     local evms_seg
983     local evms_dsk
984
985     if [ ! -x /sbin/evms ]; then
986         return 1
987     fi
988
989     if [ -n "$1" ]; then
990         evms_cmd="q:r,v=$1"
991
992         while read a b c d; do
993             if [ "$a $b" = "Region Name:" ]; then
994                 evms_reg="$evms_reg $c"
995             fi
996         done < <( echo "$evms_cmd" | /sbin/evms -s -b )
997     fi
998
999     for reg in $evms_reg; do
1000         evms_cmd="q:c,r=$reg"
1001         
1002         while read a b c d; do
1003             if [ "$a $b" = "Container Name:" ]; then
1004                 evms_cont="$evms_cont $c"
1005             fi
1006         done < <(echo "$evms_cmd" | /sbin/evms -s -b )
1007     done
1008     
1009     for cont in $evms_cont; do
1010         evms_cmd="q:s,c=$cont"
1011         
1012         while read a b c d; do
1013             if [ "$a $b" = "Segment Name:" ]; then
1014                 evms_seg="$evms_seg $c"
1015             fi
1016         done < <(echo "$evms_cmd" | /sbin/evms -s -b )
1017     done
1018
1019     for seg in $evms_seg; do
1020         evms_cmd="q:d,s=$seg"
1021         while read a b c d; do
1022             if [ "$a $b $c" = "Logical Disk Name:" ]; then
1023                 evms_dsk="$evms_dsk $d"
1024             fi
1025         done < <(echo "$evms_cmd" | /sbin/evms -s -b )
1026     done
1027
1028     for dsk in $evms_dsk; do
1029         case $dsk in
1030             dasd*)
1031                 s390_enable_dasd=1;
1032                 ;;
1033             sd*)
1034                 s390_enable_zfcp=1
1035                 ;;
1036         esac
1037     done
1038 }
1039
1040 s390_check_dasd() {
1041     local devn=$(devnumber $1)
1042
1043     for dir in /sys/block/*/*; do
1044         if [ -d "$dir" ] && [ -f "$dir/dev" ]; then
1045             IFS=":" read major minor < $dir/dev
1046             if (($devn == $(mkdevn $major $minor) )); then
1047                 path=$dir
1048                 break;
1049             fi
1050         fi
1051     done
1052     if [ "$path" ] && [ -d ${path}/../device ]; then
1053         if [ -r ${path}/../device/discipline ]; then
1054             s390_enable_dasd=1
1055         fi
1056     fi
1057 }
1058
1059 s390_check_zfcp() {
1060     local devn=$(devnumber $1)
1061
1062     for dir in /sys/block/*/*; do
1063         if [ -d "$dir" ] && [ -f "$dir/dev" ]; then
1064             IFS=":" read major minor < $dir/dev
1065             if (($devn == $(mkdevn $major $minor) )); then
1066                 path=$dir
1067                 break;
1068             fi
1069         fi
1070     done
1071     
1072     if [ "$path" ] && [ -d "$path/../device" ] && [ -e "$path/../device/scsi_level" ] ; then
1073         s390_enable_zfcp=1
1074     fi
1075 }
1076
1077 # Detect all zfcp disks
1078 # We need to activate all disks in the same order
1079 # as found in the running system to get the same
1080 # behaviour during booting.
1081 s390_zfcp_sysfs() {
1082     local dev_dir
1083     local fcp_disk_hba
1084     local fcp_disk_wwpn
1085     local fcp_disk_lun
1086
1087     if [ "$s390_enable_zfcp" ] ; then
1088         # Root is on SCSI, detect all SCSI devices
1089         for dev_dir in /sys/block/sd? /sys/block/sd?? /sys/block/sd??? /sys/block/sd???? ; do
1090             if [ -d "$dev_dir" ] && [ -e "$dev_dir/device" ]; then
1091                 pushd $dev_dir > /dev/null;
1092                 cd $(readlink device);
1093                 if [ -r ./hba_id ]; then
1094                     read fcp_disk_hba < ./hba_id
1095                     read fcp_disk_wwpn < ./wwpn
1096                     read fcp_disk_lun < ./fcp_lun
1097             
1098                     s390_zfcp_disks="$s390_zfcp_disks $fcp_disk_hba:$fcp_disk_wwpn:$fcp_disk_lun"
1099
1100                     for id in $s390_zfcp_hbas; do
1101                         if [ "$id" == "$fcp_disk_hba" ]; then
1102                             fcp_disk_hba=
1103                         fi
1104                     done
1105                     [ "$fcp_disk_hba" ] && s390_zfcp_hbas="$s390_zfcp_hbas $fcp_disk_hba"
1106                 else
1107                     s390_zfcp_hbas="iSCSI"
1108                     s390_zfcp_disks="iSCSI"
1109                 fi
1110                 popd > /dev/null
1111             fi
1112         done
1113         if [ "$s390_zfcp_hbas" ] && [ "$s390_zfcp_hbas" != "iSCSI" ] ; then
1114             add_module sd_mod
1115             add_module zfcp
1116         fi
1117     fi
1118
1119 }
1120
1121 s390_dasd_sysfs() {
1122     local type
1123     local discipline
1124
1125     if [ "$s390_enable_dasd" ]; then
1126         # Root device is on a dasd device, enable all dasd disks
1127         for dir in /sys/block/dasd[a-z] /sys/block/dasd[a-z][a-z] /sys/block/dasd[a-z][a-z][a-z] ; do
1128             if [ -d "$dir" ] && [ -d ${dir}/device ]; then
1129                 pushd $dir > /dev/null
1130                 cd $(readlink device)
1131                 if [ -r ./discipline ]; then
1132                     read type < ./discipline
1133                     
1134                     case $type in
1135                         ECKD)
1136                             add_module dasd_eckd_mod
1137                             discipline=0
1138                             ;;
1139                         FBA)
1140                             add_module dasd_fba_mod
1141                             discipline=1
1142                             ;;
1143                         DIAG)
1144                             add_module dasd_diag_mod
1145                             discipline=2
1146                             ;;
1147                         *)
1148                             ;;
1149                     esac
1150                     s390_dasd_disks="$s390_dasd_disks $(basename $PWD):$discipline"
1151                 fi
1152                 popd > /dev/null
1153             fi
1154         done
1155
1156     fi
1157 }
1158
1159 s390_dasd_proc() {
1160     local zipl_conf_with_dasd dasd_module
1161
1162     if [ -f /etc/zipl.conf ] \
1163        && grep -q '^[[:space:]]*parameters[[:space:]]*=' \
1164             /etc/zipl.conf; then
1165             zipl_conf_with_dasd=1
1166     fi
1167
1168     if modprobe -c \
1169        | grep -q '^[[:space:]]*options[[:space:]]\+dasd_mod' ; then
1170         dasd_module=1
1171     fi
1172
1173     if grep -q -e "^dasd" /proc/modules \
1174        || [ -n "$zipl_conf_with_dasd" ] \
1175        || [ -n "$dasd_module" ] \
1176        || has_module dasd_mod ; then
1177
1178         if [ ! "$zipl_conf_with_dasd" -a ! "$dasd_module" ]; then
1179             error 1 "\
1180 The dasd module is required, but no dasd configuration was found in
1181 root_dir/etc/zipl.conf or root_dir/etc/modules.conf."
1182         fi
1183
1184         if grep -q ECKD /proc/dasd/devices ; then
1185             add_module dasd_eckd_mod
1186         fi
1187
1188         if grep -q FBA  /proc/dasd/devices ; then
1189             add_module dasd_fba_mod
1190         fi
1191
1192         if grep -q DIAG /proc/dasd/devices ; then
1193             add_module dasd_diag_mod
1194         fi
1195     else
1196         # /proc not mounted or somesuch. Enable all dasd modules
1197         add_module dasd_mod
1198         add_module dasd_eckd_mod
1199         add_module dasd_fba_mod
1200         add_module dasd_diag_mod
1201     fi
1202 }
1203
1204 s390_get_ctc_ccwdevs()
1205 {
1206     local interface=$1
1207
1208     if [ ! -d /sys/class/net/$interface/device ] ; then
1209         error 1 "No device link for interface $interface"
1210     fi
1211     pushd /sys/class/net/$interface/device > /dev/null 2>&1
1212     cd -P cdev0
1213     cdev0=$(basename $PWD)
1214     popd > /dev/null 2>&1
1215
1216     pushd /sys/class/net/$interface/device > /dev/null 2>&1
1217     cd -P cdev1
1218     cdev1=$(basename $PWD)
1219     popd > /dev/null 2>&1
1220
1221     echo "$cdev0,$cdev1"
1222 }
1223
1224 ###################################################################
1225 #
1226 # Create the initrd image $2 for kernel $1 (both are absolute path names).
1227 #
1228 mkinitrd_kernel() {
1229     local kernel_image=$1 initrd_image=$2
1230     local kernel_version
1231     local need_raidstart
1232     local need_mdadm
1233     local is_kdump
1234     local -a features
1235     local fs_modules drv_modules uld_modules root_modules
1236     local i
1237
1238     tmp_mnt=$work_dir/mnt
1239     tmp_mnt_small=${tmp_mnt}_small
1240     tmp_msg=$work_dir/msg$$
1241     vendor_script=$tmp_mnt/vendor_init.sh
1242
1243     linuxrc=$tmp_mnt/init
1244
1245     if [ ! -f "$kernel_image" ] ; then
1246         echo "No kernel image $kernel_image found" >&2
1247         return
1248     fi
1249
1250     kernel_version=$(/sbin/get_kernel_version $kernel_image)
1251     modules_dep=$root_dir/lib/modules/$kernel_version/modules.dep
1252
1253     #echo -e "Kernel version:\t$kernel_version"
1254     echo -e "Kernel image:\t$kernel_image"
1255     echo -e "Initrd image:\t$initrd_image"
1256
1257     if [ ! -d "/lib/modules/$kernel_version/misc" -a \
1258          ! -d "/lib/modules/$kernel_version/kernel" ]; then
1259         oops 2 "No modules found for kernel $kernel_version"
1260         return
1261     fi
1262
1263     # Check whether this is the kdump kernel
1264     if [ "${kernel_image%%-kdump}" != "${kernel_image}" ] ; then
1265         if [ -f /etc/sysconfig/kdump ] ; then
1266             . /etc/sysconfig/kdump
1267             dumpdev=$KDUMP_DUMPDEV
1268         fi
1269         features=(${features[@]} kdump)
1270         is_kdump=1
1271     fi
1272
1273     # Make sure to always include the module for the root filesystem
1274     # if the root filesystem is modularized.
1275     if [ -z "$is_kdump" ] && ! has_module "$rootfstype" && \
1276        grep -qe "$rootfstype\.ko:" $modules_dep; then
1277         echo "Adding the root filesystem module ($rootfstype)"
1278         add_module $rootfstype
1279     fi
1280
1281     # create an empty initrd
1282     if ! mkdir $tmp_mnt ; then
1283         error 1 "could not create temporary directory"
1284     fi
1285
1286     # fill the initrd
1287     mkdir -p $tmp_mnt/{sbin,bin,etc,dev,proc,sys,root}
1288
1289     mkdir -p -m 4777 $tmp_mnt/tmp
1290
1291     # Create a dummy /etc/mtab for mount/umount
1292     echo -n > $tmp_mnt/etc/mtab
1293
1294     mkdir -p $tmp_mnt${initrd_shell%/*}
1295     cp_bin $initrd_shell $tmp_mnt$initrd_shell
1296     if [ $shebang != $initrd_shell ]; then
1297         ln -s $initrd_shell $tmp_mnt$shebang
1298     fi
1299     if [ $shebang != /bin/sh ]; then
1300         ln -s $shebang $tmp_mnt/bin/sh
1301     fi
1302     
1303     if ! cp_bin $initrd_insmod $tmp_mnt/sbin/insmod 2>/dev/null ; then
1304         error 5 "no static insmod"
1305     fi
1306
1307     # Add modprobe, modprobe.conf*, and a version of /bin/true: modprobe.conf
1308     # might use it.
1309     if ! cp_bin $initrd_modprobe $tmp_mnt/sbin/modprobe 2>/dev/null ; then
1310         error 5 "no static modprobe"
1311     fi
1312     cp -r $root_dir/etc/modprobe.conf $root_dir/etc/modprobe.conf.local \
1313           $root_dir/etc/modprobe.d $tmp_mnt/etc
1314     cat > $tmp_mnt/bin/true <<-EOF
1315         #! /bin/sh
1316         :
1317         EOF
1318     chmod +x $tmp_mnt/bin/true
1319  
1320     # Enable user-selected features
1321     if [ "$feature_list" ] ; then
1322         for f in $feature_list ; do
1323             case $f in
1324                 iscsi)
1325                     add_module iscsi_tcp
1326                     ;;
1327                 mpath)
1328                     add_module dm-multipath
1329                     ;;
1330                 lvm2)
1331                     add_module dm-snapshot
1332                     add_module dm-crypt
1333                     add_module dm-zero
1334                     add_module dm-mirror
1335                     root_lvm2=1
1336                     root_dm=1
1337                     ;;
1338                 lvm)
1339                     add_module lvm-mod
1340                     root_lvm=1
1341                     ;;
1342                 evms)
1343                     add_module dm-mirror
1344                     add_module dm-snapshot
1345                     root_evms=1
1346                     root_dm=1
1347                     ;;
1348                 md)
1349                     add_module raid0
1350                     add_module raid1
1351                     add_module raid5
1352                     add_module linear
1353                     need_mdadm=1
1354                     ;;
1355                 kdump)
1356                     is_kdump=1
1357                     ;;
1358                 *)
1359                     error 6 "invalid feature $f"
1360                     ;;
1361             esac
1362         done
1363     fi
1364
1365     # Enable the LUKS encrypted file systems, if any
1366
1367     if [ -x /usr/sbin/cryptsetup ] ; then
1368         cryptsetup=/usr/sbin/cryptsetup
1369     elif [ -x /usr/sbin/cryptsetup-luks ] ; then
1370         cryptsetup=/usr/sbin/cryptsetup-luks
1371     elif [ -x /sbin/cryptsetup ] ; then
1372         cryptsetup=/sbin/cryptsetup
1373     fi
1374
1375     cipherName="Cipher name:"
1376     cipherMode="Cipher mode:"
1377     hashSpec="Hash spec:"
1378     numLuks=0
1379     for md in $(dmsetup ls | cut -f 1) ; do
1380         device=`$cryptsetup status $md 2> /dev/null | grep device | cut -f 5 -d' ' `
1381         if [ -z "$device" ] ; then
1382             continue;
1383         elif [[ $device == /dev/loop* ]] ; then
1384             continue;
1385         fi
1386         isLuks=`$cryptsetup isLuks $device &>/dev/null`
1387         if [ $? == 0 ]; then
1388             rN=${rootdev#"/dev/mapper/"}
1389             cipher=`$cryptsetup luksDump $device | grep "$cipherName" | cut -f 2 -d: `
1390             hash=`$cryptsetup luksDump $device | grep "$hashSpec" | cut -f 2 -d: `
1391             mode=`$cryptsetup luksDump $device | grep "$cipherMode" | cut -f 3 -d: `
1392
1393             arch=`uname -m`
1394             if [ $cipher == "aes" ] ; then
1395                 case "$(uname -m)" in
1396                     i586)
1397                         cipher="aes-i586"
1398                         ;;
1399                     i686)
1400                         cipher="aes-i586"
1401                         ;;
1402                 esac
1403             fi
1404             add_module $cipher
1405             add_module $hash
1406             add_module $mode
1407             if [ "/dev/mapper/$md" != "$rootdev" ] ; then
1408                 cryptdev[$numLuks]=$device
1409                 dmname[$numLuks]=$md
1410                 numLuks=$(($numLuks + 1))
1411             else
1412                 root_lerfs=1
1413             fi
1414             cp_bin $cryptsetup $tmp_mnt/sbin/cryptsetup
1415             cp_bin /usr/bin/clear $tmp_mnt/bin/
1416         fi
1417     done
1418
1419     if [ "$root_lerfs" -o "$numLuks" -ne 0 ] ; then
1420         features=(${features[@]} LUKS)
1421     fi
1422
1423     if [ ! -z "$vendor_init_script" ] ; then
1424         features=(${features[@]} script\($vendor_script\))
1425         cp_bin $vendor_init_script $vendor_script
1426     fi
1427
1428     if has_module dm-multipath ; then
1429         add_module dm-round-robin
1430         add_module dm-emc
1431         add_module dm-rdac
1432         add_module dm-hp_sw
1433         root_mpath=1
1434         root_dm=1
1435     fi
1436
1437     if has_module iscsi_tcp ; then
1438         features=(${features[@]} iscsi)
1439         add_module crc32c
1440         cp_bin /sbin/iscsid $tmp_mnt/sbin/iscsid
1441         cp_bin /sbin/iscsiadm $tmp_mnt/sbin/iscsiadm
1442         if [ -x /sbin/fwparam_ibft ] ; then
1443             cp_bin /sbin/fwparam_ibft $tmp_mnt/sbin/fwparam_ibft
1444             features=(${features[@]} iBFT)
1445         fi
1446         # Check for open-iscsi in SLES10 SP1
1447         if [ -d /etc/iscsi ] ; then
1448             mkdir -p $tmp_mnt/etc/iscsi
1449             cp -r /etc/iscsi $tmp_mnt/etc
1450             mkdir -p $tmp_mnt/var/lock/iscsi
1451         else
1452             cat /etc/initiatorname.iscsi > $tmp_mnt/etc/initiatorname.iscsi
1453             mkdir -p $tmp_mnt/var/lib/open-iscsi
1454             cp /var/lib/open-iscsi/discovery.db $tmp_mnt/var/lib/open-iscsi
1455             cp /var/lib/open-iscsi/node.db $tmp_mnt/var/lib/open-iscsi
1456         fi
1457         mkdir -p $tmp_mnt/var/run
1458         cp_bin /bin/mv $tmp_mnt/bin/mv
1459         cp_bin /bin/usleep $tmp_mnt/bin/usleep
1460         cp_bin /bin/basename $tmp_mnt/bin/basename
1461         cp_bin /sbin/ip $tmp_mnt/sbin/ip
1462         cp_bin /bin/ping $tmp_mnt/bin/ping
1463     fi
1464
1465     if [ -n "$s390_dasd_disks" ]; then
1466         cp_bin /sbin/dasd_configure $tmp_mnt/sbin
1467         cp_bin /sbin/dasdview $tmp_mnt/sbin
1468         if [ -x /sbin/dasdinfo ] ; then
1469             cp_bin /sbin/dasdinfo $tmp_mnt/sbin
1470         fi
1471     fi
1472
1473     if [ -n "$s390_zfcp_disks" ]; then
1474         cp_bin /sbin/zfcp_host_configure $tmp_mnt/sbin
1475         cp_bin /sbin/zfcp_disk_configure $tmp_mnt/sbin
1476     fi
1477
1478     features=(${features[@]} initramfs)
1479
1480     # Programs /sbin
1481     for prog in killall5 halt reboot; do
1482         cp_bin /sbin/$prog $tmp_mnt/sbin
1483     done
1484
1485     # Programs /bin
1486     for prog in sed sleep cat cp ln ls pidof mount umount; do
1487         cp_bin /bin/$prog $tmp_mnt/bin
1488     done
1489
1490     # Common utilities
1491     for bin in chmod mkdir mknod rm; do
1492         cp_bin /bin/$bin $tmp_mnt/bin
1493     done
1494
1495     for file in /lib/mkinitrd/bin/* ; do
1496         if [ -x $file ] ; then
1497             cp_bin $file $tmp_mnt/bin
1498         fi
1499     done
1500
1501     for dir in /lib/mkinitrd/* ; do
1502         if [ -d "$dir" -a "$dir" != "/lib/mkinitrd/bin" ] ; then
1503             [ -d ${tmp_mnt}${dir#/lib/mkinitrd} ] || mkdir ${tmp_mnt}${dir#/lib/mkinitrd}
1504             for f in $dir/* ; do
1505                 if [ -f "$f" ] ; then
1506                     cp -a $f ${tmp_mnt}${dir#/lib/mkinitrd}
1507                 fi
1508             done
1509         fi
1510     done
1511
1512     # all dev nodes belong to root, but some may be
1513     # owned by a group other than root
1514     # getent passwd | sed '/^root:/s/^\([^:]\+\):[^:]*:\([^:]\+\):\([^:]\+\):.*/\1::\2:\3:::/p;d' > $tmp_mnt/etc/passwd
1515     echo 'root::0:0:::' > $tmp_mnt/etc/passwd
1516     echo 'nobody::65534:65533:::' >> $tmp_mnt/etc/passwd
1517     getent group | sed 's/^\([^:]\+\):[^:]*:\([^:]\+\):.*/\1::\2:/' > $tmp_mnt/etc/group
1518     (echo 'passwd: files';echo 'group: files') > $tmp_mnt/etc/nsswitch.conf
1519
1520     if [ -d /lib64 ]; then
1521         mkdir -p $tmp_mnt/lib64
1522         for nss_lib in /lib64/libnss_files*; do
1523             if [ -f "$nss_lib" ]; then
1524                 cp_bin $nss_lib $tmp_mnt/lib64
1525             fi
1526         done
1527     else
1528         mkdir -p $tmp_mnt/lib
1529         for nss_lib in /lib/libnss_files*; do
1530             if [ -f "$nss_lib" ]; then
1531                 cp_bin $nss_lib $tmp_mnt/lib
1532             fi
1533         done
1534     fi
1535
1536     cp_bin /sbin/udevd $tmp_mnt/sbin/
1537     cp_bin /sbin/udevtrigger $tmp_mnt/sbin/
1538     cp_bin /sbin/udevsettle $tmp_mnt/sbin/
1539     cp_bin /usr/bin/udevinfo $tmp_mnt/sbin/
1540
1541     mkdir -p $tmp_mnt/etc/udev/rules.d
1542     # Create our own udev.conf
1543     echo "udev_root=\"/dev\"" > $tmp_mnt/etc/udev/udev.conf
1544     echo "udev_rules=\"/etc/udev/rules.d\"" >> $tmp_mnt/etc/udev/udev.conf
1545     # copy needed rules
1546     for rule in 05-udev-early.rules 50-udev-default.rules 59-dasd.rules 60-persistent-storage.rules 64-device-mapper.rules; do
1547         if [ -f /etc/udev/rules.d/$rule ]; then
1548             cp /etc/udev/rules.d/$rule $tmp_mnt/etc/udev/rules.d
1549         fi
1550     done
1551     # copy helper scripts
1552     mkdir -p $tmp_mnt/lib/udev
1553     for script in /lib/udev/* ; do
1554         if [ -f "$script" ] ; then
1555             cp_bin $script ${tmp_mnt}${script}
1556         fi
1557     done
1558     rm -f $tmp_mnt/lib/udev/mount.sh
1559     echo '#!/bin/sh' > $tmp_mnt/lib/udev/mount.sh
1560     echo 'exit 0' >> $tmp_mnt/lib/udev/mount.sh
1561
1562     # udev *_id programs
1563     for prog in ata_id scsi_id scsi_tur usb_id vol_id dasd_id edd_id path_id; do
1564         cp_bin /sbin/$prog $tmp_mnt/sbin
1565     done
1566
1567     # scsi_id config file
1568     cp /etc/scsi_id.config $tmp_mnt/etc/scsi_id.config
1569
1570     # HBA firmware
1571     mkdir -p $tmp_mnt/lib/firmware
1572     for fw in /lib/firmware/ql*.bin /lib/firmware/aic94xx* ; do
1573         if [ -f "$fw" ] ; then
1574             cp -a $fw $tmp_mnt/lib/firmware
1575         fi
1576     done
1577
1578     if [ -n "$root_lvm" ] ; then
1579         features=(${features[@]} lvm)
1580         mkdir -p $tmp_mnt/etc/lvmtab.d
1581         cp_bin /sbin/{vgscan,vgchange} $tmp_mnt/sbin
1582         cp_bin /sbin/dmsetup $tmp_mnt/sbin
1583     fi
1584
1585     if [ -n "$root_dm" ] ; then
1586         cp_bin /sbin/dmsetup $tmp_mnt/sbin
1587     fi
1588
1589     if [ -n "$root_mpath" ] ; then
1590         features=(${features[@]} dm/mpath)
1591         cp_bin /sbin/multipath $tmp_mnt/sbin
1592         cp_bin /sbin/kpartx $tmp_mnt/sbin
1593         cp_bin /sbin/dmsetup $tmp_mnt/sbin
1594         cp_bin /sbin/mpath_id $tmp_mnt/sbin
1595         cp_bin /sbin/kpartx_id $tmp_mnt/sbin
1596         for pp in /sbin/mpath_prio_* ; do
1597             cp_bin $pp $tmp_mnt/sbin
1598         done
1599         if [ -f /etc/multipath.conf ] ; then
1600             cp -a /etc/multipath.conf $tmp_mnt/etc
1601         fi
1602         if [ -f /var/lib/multipath/bindings ] ; then
1603             mkdir -p $tmp_mnt/var/lib/multipath
1604             cp -a /var/lib/multipath/bindings $tmp_mnt/var/lib/multipath
1605         fi
1606         cp /etc/udev/rules.d/71-multipath.rules $tmp_mnt/etc/udev/rules.d
1607         cp /etc/udev/rules.d/72-multipath-compat.rules $tmp_mnt/etc/udev/rules.d
1608     fi
1609
1610     if [ -n "$root_lvm2" ] ; then
1611         features=(${features[@]} dm/lvm2)
1612         mkdir -p $tmp_mnt/etc/lvm
1613         mkdir -p $tmp_mnt/var/lock/lvm
1614         cp_bin /sbin/{vgscan,vgchange,lvm} $tmp_mnt/sbin
1615         cp_bin /sbin/dmsetup $tmp_mnt/sbin
1616         cp_bin /bin/{sed,mkdir,mknod,ls} $tmp_mnt/bin
1617         cp -a /etc/lvm/lvm.conf $tmp_mnt/etc/lvm
1618     fi
1619
1620     if [ -n "$root_evms" ] ; then
1621         features=(${features[@]} dm/evms2 evms2/$evms_policy)
1622         cp_bin /sbin/{evms_activate,dmsetup,evms} $tmp_mnt/sbin
1623         cp_bin /bin/{sed,mkdir,mknod,rm} $tmp_mnt/bin
1624         mkdir -p $tmp_mnt/mnt
1625         cp -a /etc/evms.conf $tmp_mnt/etc
1626         [ -d /lib/evms ] && evms_lib="/lib/evms"
1627         [ -d /lib64/evms ] && evms_lib="/lib64/evms"
1628
1629         if [ "$evms_lib" ] ; then
1630             mkdir -p ${tmp_mnt}${evms_lib}
1631             SD=$(ls -A $evms_lib | tail -n 1)
1632             (cd ${tmp_mnt}${evms_lib} && mkdir -p $SD)
1633             cp_bin $evms_lib/$SD/* ${tmp_mnt}${evms_lib}/$SD
1634             rm -f ${tmp_mnt}${evms_lib}/*/*{ext2,jfs,ogfs,reiser,swap,xfs}*so
1635         else
1636             oops 7 "No EVMS modules found"
1637         fi
1638     fi
1639
1640     if [ "$root_md" -o "$md_list" ] ; then
1641         need_mdadm=1
1642         if [ -f /etc/mdadm.conf ] ; then
1643             cat /etc/mdadm.conf > $tmp_mnt/etc/mdadm.conf
1644             md_mod_list="mdconf"
1645         else
1646             echo "DEVICE partitions" > $tmp_mnt/etc/mdadm.conf
1647             for md in $md_list ; do
1648                 mdconf=$(eval echo \$md_conf_$md)
1649                 md_mod=${mdconf#*level=}
1650                 md_mod=${md_mod%% *}
1651                 for mod in $md_mod_list ; do
1652                     if [ "$mod" == $"md_mod" ] ; then
1653                         md_mod=
1654                     fi
1655                 done
1656                 if [ "$md_mod" ] ; then
1657                     if [ "$md_mod_list" ] ; then
1658                         md_mod_list="$md_mod $md_mod_list"
1659                     else
1660                         md_mod_list="$md_mod"
1661                     fi
1662                 fi
1663                 echo $mdconf >> $tmp_mnt/etc/mdadm.conf
1664             done
1665         fi
1666         features=(${features[@]} md\($md_mod_list\))
1667     fi
1668
1669     if [ -n "$need_mdadm" ] ; then
1670         features=(${features[@]} mdadm)
1671         cp_bin /sbin/mdadm $tmp_mnt/sbin
1672     fi
1673
1674     if [ -n "$use_dhcp" ] ; then
1675         features=(${features[@]} dhcp\($macaddress\))
1676         cp_bin /sbin/dhcpcd $tmp_mnt/bin
1677         cp_bin /bin/kill $tmp_mnt/bin
1678         mkdir -p $tmp_mnt/var/lib/dhcpcd
1679         mkdir -p $tmp_mnt/var/run
1680     fi
1681
1682     if [ -n "$use_ipconfig" ] ; then
1683         features=(${features[@]} static\($macaddress\))
1684         cp_bin /bin/ping $tmp_mnt/bin/ping
1685         cp_bin /sbin/ip $tmp_mnt/sbin/ip
1686     fi
1687   
1688     if [ "$rootfstype" = "ext2" ] ; then
1689         features=(${features[@]} fsck.ext2)
1690         cp_bin /sbin/fsck $tmp_mnt/bin
1691         cp_bin /sbin/fsck.ext2 $tmp_mnt/bin
1692     fi
1693
1694     if [ "$rootfstype" = "ext3" ] ; then
1695         features=(${features[@]} fsck.ext3)
1696         cp_bin /sbin/fsck $tmp_mnt/bin
1697         cp_bin /sbin/fsck.ext3 $tmp_mnt/bin
1698     fi
1699
1700     if [ "$rootfstype" = "reiserfs" ] ; then
1701         features=(${features[@]} fsck.reiserfs)
1702         cp_bin /sbin/fsck $tmp_mnt/bin
1703         cp_bin /sbin/fsck.reiserfs $tmp_mnt/bin
1704     fi
1705
1706     if [ "$rootfstype" = "jfs" ] ; then
1707         features=(${features[@]} fsck.jfs)
1708         cp_bin /sbin/fsck $tmp_mnt/bin
1709         cp_bin /sbin/fsck.jfs $tmp_mnt/bin
1710     fi
1711
1712     if [ "$rootfstype" = "xfs" ] ; then
1713         features=(${features[@]} fsck.xfs)
1714         cp_bin /sbin/fsck $tmp_mnt/bin
1715         cp_bin /sbin/fsck.xfs $tmp_mnt/bin
1716     fi
1717
1718     if [ -n "$debug_mkinit" ]; then
1719         features=(${features[@]} debug)
1720         cp_bin /bin/ls $tmp_mnt/bin
1721     fi
1722
1723     echo -ne "Shared libs:\t"
1724     # Copy all required shared libraries and the symlinks that
1725     # refer to them.
1726     lib_files=$(shared_object_files "${initrd_bins[@]}")
1727     if [ -n "$lib_files" ]; then
1728         for lib in $lib_files; do
1729             [ -L $root_dir/$lib ] || echo -n "$lib "
1730             ( cd ${root_dir:-/} ; cp -dp --parents $lib $tmp_mnt )
1731         done
1732         lib_files=
1733         # no symlinks, most point into the running system
1734         for i in `LANG=C LC_ALL=C file -b $tmp_mnt/{,usr/}{lib*/udev/,{,s}bin}/* | awk '/^ELF ..-bit/ { print $2 }' | sort -u`
1735         do
1736                 case "$i" in
1737                         32-bit)
1738                                 lib_dir=lib
1739                                 ;;
1740                         64-bit)
1741                                 lib_dir=lib64
1742                                 ;;
1743                 esac
1744                 if [ $(uname -m) = "ia64" ] ; then
1745                     lib_dir=lib
1746                 fi
1747                 if [ ! -d $tmp_mnt/$lib_dir ] ; then
1748                     mkdir -p $tmp_mnt/$lib_dir
1749                 fi
1750                 lib_files="$lib_files `echo $root_dir/$lib_dir/libnss_files* $root_dir/$lib_dir/libgcc_s.so*`"
1751         done
1752         for lib in $lib_files ; do
1753             if [ -f $lib ] ; then
1754                 echo -n "${lib##$root_dir/} "
1755                 cp -dp --parents $lib $tmp_mnt
1756             fi
1757         done
1758         echo
1759     else
1760         echo "none"
1761     fi
1762
1763     if [ -n "$lib_files" -a -n "$initrd_shell_dynamic" ]; then
1764         # If we have already have all dynamic libraries that
1765         # $initrd_shell_dynamic is using, and if $initrd_shell_dynamic
1766         # is smaller than $initrd_shell, we can save a little space
1767         # by using the dynamic version. The benefit is marginal, though.
1768
1769         if smaller_file $initrd_shell_dynamic $initrd_shell ; then
1770             for lib in $(shared_object_files $initrd_shell_dynamic) ; do
1771                 case $lib_files in
1772                     *$lib*) ;;
1773                     *)  initrd_shell_dynamic=
1774                         break ;;
1775                 esac
1776             done
1777             if [ -n "$initrd_shell_dynamic" ]; then
1778                 #echo " - Using dynamically linked $shebang"
1779                 cp_bin $initrd_shell_dynamic $tmp_mnt$shebang
1780             fi
1781         fi
1782     fi
1783
1784     if [ -n "$lib_files" -a -n "$initrd_insmod_dynamic" ]; then
1785         # If we have already have all dynamic libraries that
1786         # $initrd_insmod_dynamic is using, and if $initrd_insmod_dynamic
1787         # is smaller than $initrd_insmod, we can save a little space
1788         # by using the dynamic version. The benefit is marginal, though.
1789
1790         if smaller_file $initrd_insmod_dynamic $initrd_insmod ; then
1791             for lib in $(shared_object_files $initrd_insmod_dynamic); do
1792                 case $lib_files in
1793                     *$lib*) ;;
1794                     *)  initrd_insmod_dynamic=
1795                         break ;;
1796                 esac
1797             done
1798             if [ -n "$initrd_insmod_dynamic" ]; then
1799                 #echo " - Using dynamically linked /sbin/insmod"
1800                 cp_bin $initrd_insmod_dynamic $tmp_mnt/sbin/insmod
1801                 cp_bin $initrd_modprobe_dynamic $tmp_mnt/sbin/modprobe
1802             fi
1803         fi
1804     fi
1805
1806     cat /dev/null > $linuxrc
1807     chmod 755 $linuxrc
1808
1809     # Note that the in-place documents must be indented with tabs, not spaces.
1810     cat_linuxrc <<-EOF
1811         |#! $shebang
1812         |
1813         |export PATH=/sbin:/usr/sbin:/bin:/usr/bin
1814         |
1815         |die() {
1816         |    umount /proc
1817         |    umount /sys
1818         |    umount /dev
1819         |    exit \$1
1820         |}
1821         |
1822         |mount -t proc  proc  /proc
1823         |mount -t sysfs sysfs /sys
1824         |mount -t tmpfs -o mode=0755 udev /dev
1825         |
1826         |mknod -m 0666 /dev/tty     c 5 0
1827         |mknod -m 0600 /dev/console c 5 1
1828         |mknod -m 0666 /dev/ptmx    c 5 2
1829         |
1830         |exec < /dev/console > /dev/console 2>&1
1831         |
1832         |mknod -m 0666 /dev/null c 1 3
1833         |mknod -m 0600 /dev/kmsg c 1 11
1834         |mknod -m 0660 /dev/snapshot c 10 231
1835         |mknod -m 0666 /dev/random c 1 8
1836         |mknod -m 0644 /dev/urandom c 1 9
1837         |mkdir -m 0755 /dev/pts
1838         |mkdir -m 1777 /dev/shm
1839         |ln -s /proc/self/fd /dev/fd
1840         |ln -s fd/0 /dev/stdin
1841         |ln -s fd/1 /dev/stdout
1842         |ln -s fd/2 /dev/stderr
1843         |echo "" > /proc/sys/kernel/hotplug
1844         |
1845         |kernel_cmdline=(\$@)
1846         |
1847         |# Default timeout is 30 seconds
1848         |udev_timeout=30
1849         |
1850         |for o in \$(cat /proc/cmdline); do
1851         |    if [ "\$z_arg" ] ; then
1852         |       init_args="\$init_args \$o"
1853         |       z_arg=
1854         |       continue
1855         |    fi
1856         |    case \$o in
1857         |    linuxrc=trace)
1858         |       echo -n "cmdline: "
1859         |       for arg in \$@; do
1860         |           echo -n "\$arg "
1861         |       done
1862         |       echo ""
1863         |       set -x
1864         |       debug_linuxrc=1
1865         |       ;;
1866         |    noresume)
1867         |       resume_mode=off
1868         |       ;;
1869         |    sysrq=yes|sysrq=1)
1870         |       echo 1 > /proc/sys/kernel/sysrq
1871         |       ;;
1872         |    -z)
1873         |       init_args="\$init_args \$o"
1874         |       z_arg=1
1875         |       ;;
1876         |    -s)
1877         |       runlevel=s
1878         |       ;;
1879         |    -b|emergency)
1880         |       init_args="\$init_args emergency"
1881         |       ;;
1882         |    -a|auto)
1883         |       init_args="\$init_args auto"
1884         |       ;;
1885         |    1|2|3|4|5|S|s|single)
1886         |       runlevel=\$o
1887         |       ;;
1888         |    rw)
1889         |       read_write=1
1890         |       ;;
1891         |    ro)
1892         |       read_only=1
1893         |       ;;
1894         |    esac
1895         |done
1896         |
1897         |
1898         |for o in \$(cat /proc/cmdline); do
1899         |    case \$o in
1900         |    root=*)
1901         |       rootdev=\${o#root=}
1902         |       rootdev_cmdline=1
1903         |       ;;
1904         |    rootfstype=*)
1905         |       rootfstype=\${o#rootfstype=}
1906         |       ;;
1907         |    rootfsflags=*)
1908         |       rootflags=\${o#rootfsflags=}
1909         |       ;;
1910         |    nfsroot=*)
1911         |       rootdev=\${o#nfsroot=}
1912         |       rootdev_cmdline=1
1913         |       ;;
1914         |    resume=*)
1915         |       resumedev=\${o#resume=}
1916         |       ;;
1917         |    journal=*)
1918         |       journaldev=\${o#journal=}
1919         |       ;;
1920         |    mduuid=*)
1921         |       md_uuid=\${o#mduuid=}
1922         |       ;;
1923         |    init=*)
1924         |       init=\${o#init=}
1925         |       ;;
1926         |    udev_timeout=*)
1927         |       udev_timeout=\${o#udev_timeout=}
1928         |       ;;
1929         |    rootflags=*)
1930         |       rootflags=\${o#rootflags=}
1931         |       ;;
1932         |    dumpdev=*)
1933         |       dumpdev=\${o#dumpdev=}
1934         |       ;;
1935         |    CRASH=*)
1936         |       kdump_kernel=\${o#CRASH=}
1937         |       ;;
1938         |    evms=*)
1939         |       evms_policy=\${o#evms=}
1940         |       ;;
1941         |    esac
1942         |done
1943         |
1944         |if [ -z "\$rootdev" ]; then
1945         |    rootdev=$rootdev
1946         |fi
1947         |if [ -z "\$dumpdev" ]; then
1948         |    dumpdev=$dumpdev
1949         |fi
1950         |if [ -z "\$evms_policy" ]; then
1951         |    evms_policy=$evms_policy
1952         |fi
1953         |# lilo strips off the /dev/prefix from device names!
1954         |case \$rootdev in
1955         |       /dev/disk/by-name/*)
1956         |           rootdevid=\${rootdev#/dev/disk/by-name/}
1957         |           rootdevid=\${rootdevid%-part*}
1958         |           ;;
1959         |       /dev/md*)
1960         |           md_dev=\$rootdev
1961         |           md_minor=\${rootdev#/dev/md}
1962         |           ;;
1963         |       /dev/*)
1964         |           ;;
1965         |       LABEL=*)
1966         |           label=\${rootdev#LABEL=}
1967         |           echo "ENV{ID_FS_USAGE}==\"filesystem|other\", ENV{ID_FS_LABEL_SAFE}==\"\$label\", SYMLINK+=\"root\"" > /etc/udev/rules.d/99-mkinitrd-label.rules
1968         |           rootdev=/dev/root
1969         |           ;;
1970         |       UUID=*)
1971         |           uuid=\${rootdev#UUID=}
1972         |           echo "ENV{ID_FS_USAGE}==\"filesystem|other\", ENV{ID_FS_UUID}==\"\$uuid\", SYMLINK+=\"root\"" > /etc/udev/rules.d/99-mkinitrd-uuid.rules
1973         |           rootdev=/dev/root
1974         |           ;;
1975         |       [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
1976         |           maj=\$((0x0\$rootdev >> 8))
1977         |           min=\$((0x0\$rootdev & 0xff))
1978         |           echo "SUBSYSTEM==\"block\", SYSFS{dev}==\"\$maj:\$min\", SYMLINK+=\"root\"" > /etc/udev/rules.d/05-mkinitrd-lilo.rules
1979         |           rootdev=/dev/root ;;
1980         |       [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
1981         |           maj=\$((0x\$rootdev >> 8))
1982         |           min=\$((0x\$rootdev & 0xff))
1983         |           echo "SUBSYSTEM==\"block\", SYSFS{dev}==\"\$maj:\$min\", SYMLINK+=\"root\"" > /etc/udev/rules.d/05-mkinitrd-lilo.rules
1984         |           rootdev=/dev/root ;;
1985         |       0x[0-9a-fA-F][0-9a-fA-F]*)
1986         |           maj=\$((\$rootdev >> 8))
1987         |           min=\$((\$rootdev & 0xff))
1988         |           echo "SUBSYSTEM==\"block\", SYSFS{dev}==\"\$maj:\$min\", SYMLINK+=\"root\"" > /etc/udev/rules.d/05-mkinitrd-lilo.rules
1989         |           rootdev=/dev/root ;;
1990         |       *:*)
1991         |           rootfstype="nfs"
1992         |           ;;
1993         |       *)
1994         |           rootdev=/dev/\$rootdev
1995         |           ;;
1996         |esac
1997         |md_major=\$(sed -ne 's/\s*\([0-9]\+\)\s*md$/\1/p' /proc/devices)
1998         |if [ -n "\$md_major" -a "\$md_major" = "\$maj" ]; then
1999         |    md_minor="\$min"
2000         |    md_dev="/dev/md\$md_minor"
2001         |fi
2002         |
2003         |# Check whether kdump is enabled
2004         |if [ -e /proc/vmcore ] ; then
2005         |    kdump_kernel=1
2006         |fi
2007         |if [ "\$kdump_kernel" != "1" ] ; then
2008         |    kdump_kernel=
2009         |fi
2010         |# Do not attempt resuming when running under kdump
2011         |if [ "\$dumpdev" -a "\$kdump_kernel" ] ; then
2012         |    resume_mode=off
2013         |    unset resumedev
2014         |fi
2015         |
2016         |# Verify manual resume mode
2017         |if [ "\$resume_mode" != "off" -a -n "\$resumedev" ]; then
2018         |    if [ -w /sys/power/resume ]; then
2019         |       echo "Trying manual resume from \$resumedev"
2020         |       resume_mode=1
2021         |    else
2022         |       resumedev=
2023         |    fi
2024         |else
2025         |    resume_mode=
2026         |fi
2027         |
2028         |# Check for debugging
2029         |if [ -n "\$debug_linuxrc" ]; then
2030         |    echo "udev_log=\"debug\"" >> /etc/udev/udev.conf
2031         |else
2032         |    echo "udev_log=\"error\"" >> /etc/udev/udev.conf
2033         |fi
2034         |
2035         |# Set default for the journal device
2036         |if [ -z "\$journaldev" ]; then
2037         |    journaldev=$journaldev
2038         |fi
2039         EOF
2040
2041     # Transfer the the block_driver function into the initrd
2042     type mkdevn | sed -e '1d' >> $linuxrc
2043     echo >> $linuxrc
2044     type devmajor | sed -e '1d' >> $linuxrc
2045     echo >> $linuxrc
2046     type devminor | sed -e '1d' >> $linuxrc
2047     echo >> $linuxrc
2048     type block_driver | sed -e '1d' >> $linuxrc
2049     echo >> $linuxrc
2050     type readlink | sed -e '1d' >> $linuxrc
2051     echo >> $linuxrc
2052     if [ -z "$use_static_binaries" ]; then
2053         type devnumber | sed -e '1d' >> $linuxrc
2054         echo >> $linuxrc
2055     fi
2056
2057     # Start udev
2058     UDEVD_MAX_CHILDS=64
2059     UDEVD_MAX_CHILDS_RUNNING=16
2060     [ -f /etc/sysconfig/udev ] && . /etc/sysconfig/udev
2061     cat_linuxrc <<-EOF
2062         |
2063         |echo "Starting udevd"
2064         |UDEVD_MAX_CHILDS=${UDEVD_MAX_CHILDS}
2065         |UDEVD_MAX_CHILDS_RUNNING=${UDEVD_MAX_CHILDS_RUNNING}
2066         |export UDEVD_MAX_CHILDS UDEVD_MAX_CHILDS_RUNNING
2067         |/sbin/udevd --daemon
2068         |
2069         |echo "Creating devices"
2070         |/sbin/udevtrigger
2071         |/sbin/udevsettle --timeout=\$udev_timeout
2072         |
2073         EOF
2074
2075     # FIXME: we should only load IDE modules if we need them for booting
2076     # Check for IDE modules
2077     if [ -z "$interface" ] ; then
2078         check_ide_modules $root_dir/lib/modules/$kernel_version
2079     fi
2080
2081     resolved_modules="$(resolve_modules $kernel_version $modules)"
2082
2083     # If a SCSI module is loaded, we will have a dependency on scsi_mod
2084     # for kernels which don't have this built in. In that case, assume
2085     # that the root file system is on a SCSI device, and also include
2086     # sd_mod.
2087     local have_scsi have_sd
2088     case "$resolved_modules" in
2089         */scsi_mod.*)   have_scsi=1
2090                         ;;
2091         */sd_mod.*)     have_sd=1
2092                         ;;
2093     esac
2094     if [ -n "$have_scsi" -a -z "$have_sd" ]; then
2095         modules="sd_mod $modules"
2096         # Re-evaluate module dependencies
2097         resolved_modules="$(resolve_modules $kernel_version $modules)"
2098     fi
2099
2100     # The same reasoning goes for IDE modules
2101     local have_ide have_ide_disk
2102     case "$resolved_modules" in
2103         */ide-core.*)   have_ide=1
2104                         ;;
2105         */ide-disk.*)   have_ide_disk=1
2106                         ;;
2107     esac
2108     if [ -n "$have_ide" -a -z "$have_ide_disk" ]; then
2109         modules="ide-disk $modules"
2110         # Re-evaluate module dependencies
2111         resolved_modules="$(resolve_modules $kernel_version $modules)"
2112     fi
2113
2114     if is_xen_kernel $kernel_version; then
2115         xenu_modules="$(resolve_modules $kernel_version $domu_modules)"
2116     fi
2117
2118     # Copy all modules into the initrd
2119     for module in $resolved_modules $xenu_modules; do
2120         if [ ! -r $root_dir/$module ]; then
2121             oops 9 "Module $module not found."
2122             continue
2123         fi
2124         if ! ( cd ${root_dir:-/} ; cp -p --parents $module $tmp_mnt ) ; then
2125             oops 6 "Failed to add module $module."
2126             rm -rf $tmp_mnt
2127             return
2128         fi
2129     done
2130
2131     # Add modules which might be loaded via udev during booting
2132     uld_modules=
2133     for module in sd_mod osst st sr_mod sg ide-disk ide-scsi \
2134                   ide-cd ide-tape ide-floppy cdrom; do
2135         grep -qw $module $root_dir/lib/modules/$kernel_version/modules.dep \
2136         && uld_modules="$uld_modules $module"
2137     done
2138     uld_modules="$(resolve_modules $kernel_version $uld_modules)"
2139
2140     # Now copy the upper level driver modules
2141     for module in $uld_modules; do
2142         if [ ! -f $tmp_mnt/$module ]; then
2143             if ! ( cd ${root_dir:-/} ; cp -p --parents $module $tmp_mnt ) ; then
2144                 oops 6 "Failed to add module $module."
2145                 rm -rf $tmp_mnt
2146                 return
2147             fi
2148         fi
2149     done
2150
2151     # Filter modules into fs and non-fs (driver) modules.
2152     # We do this to avoid loading xfs when doing a resume: xfs had
2153     # (or still has) a bug that slows down resume a lot.
2154     # FIXME: get rid of this split crap again.
2155     for module in $resolved_modules; do
2156         if [ "$module" != "${module#*/kernel/fs/}" ]; then
2157             fs_modules="$fs_modules $module"
2158         else
2159             drv_modules="$drv_modules $module"
2160         fi
2161     done
2162     #fs_modules="$(echo "$resolved_modules" | grep -e '/kernel/fs/')"
2163     #drv_modules="$(echo "$resolved_modules" | grep -v -e '/kernel/fs/')"
2164
2165     echo -ne "Driver modules:\t"
2166     initrd_is_using_modules=
2167
2168     for modpath in $drv_modules; do
2169         module=${modpath##*/}
2170         module=${module%.ko}
2171         echo -n "${module} "
2172         cat_linuxrc <<-EOF
2173         |params=
2174         |for p in \$(cat /proc/cmdline) ; do
2175         |  case \$p in
2176         |    $module.*)
2177         |      params="\$params \${p#$module.}"
2178         |      ;;
2179         |  esac
2180         |done
2181         EOF
2182
2183         case $module in
2184             dasd_mod)
2185                 # kernel cmdline dasd parameter is placed into the environment.
2186                 # This is tricky. The only reliably way to check whether the
2187                 # dasd parameter is set is to indeed check for it within the
2188                 # initrd environment itself. Unfortunately the dasd module
2189                 # refuses to load when the dasd parameter is empty, so we
2190                 # need introduce an intermediate parameter which might be
2191                 # set to empty entirely so as not to confuse the dasd module.
2192                 #
2193                 # This checks whether the dasd parameter is present
2194                 cat_linuxrc <<-EOF
2195                 |# check for DASD parameter in /proc/cmdline
2196                 |for p in \$(cat /proc/cmdline) ; do
2197                 |  case \$p in
2198                 |    dasd=*)
2199                 |      params="\$params \$p"
2200                 |      dasd_params="\${p#dasd=}"
2201                 |      ;;
2202                 |  esac
2203                 |done
2204                 EOF
2205                 ;;
2206             ide?core)
2207                 # This checks whether an ide= parameter is present
2208                 cat_linuxrc <<-EOF
2209                 |# check for IDE parameter in /proc/cmdline
2210                 |for p in \$(cat /proc/cmdline) ; do
2211                 |  case \$p in
2212                 |    ide=*)
2213                 |      ide_params="\$ide_params \$p"
2214                 |      ;;
2215                 |    hd?=*)
2216                 |      ide_params="\$ide_params \$p"
2217                 |      ;;
2218                 |  esac
2219                 |done
2220                 |if [ -n "\$ide_params" ]; then
2221                 |  params="\$params options=\"\$ide_params\""
2222                 |fi
2223                 EOF
2224                 ;;
2225             scsi_mod)
2226                 # We may have SCSI parameters on the kernel command line,
2227                 # but because scsi_mod is a module, those would be ignored.
2228                 # Hack around this by scanning /proc/cmdline in linuxrc.
2229
2230                 cat_linuxrc <<-EOF
2231                 |# check for SCSI parameters in /proc/cmdline
2232                 |devflags=0
2233                 |for p in \$(cat /proc/cmdline) ; do
2234                 |  case \$p in
2235                 |    scsi_mod.*)
2236                 |       params="\$params \${p#scsi_mod.}"
2237                 |       ;;
2238                 |    scsi_reportlun2=1)
2239                 |       echo "scsi_reportlun2 compat: Use scsi_mod.default_dev_flags=0x20000 instead"
2240                 |       devflags=\$((131072+\$devflags))
2241                 |       ;;
2242                 |    scsi_noreportlun=1)
2243                 |       echo "scsi_noreportlun compat: Use scsi_mod.default_dev_flags=0x40000 instead"
2244                 |       devflags=\$((262144+\$devflags))
2245                 |       ;;
2246                 |    scsi_sparselun=1)
2247                 |       echo "scsi_sparselun compat: Use scsi_mod.default_dev_flags=0x40 instead"
2248                 |       devflags=\$((64+\$devflags))
2249                 |       ;;
2250                 |    scsi_largelun=1)
2251                 |       echo "scsi_largelun compat: Use scsi_mod.default_dev_flags=0x200 instead"
2252                 |       devflags=\$((512+\$devflags))
2253                 |       ;;
2254                 |    llun_blklst=*)
2255                 |       echo "llun_blklst is not supported any more"
2256                 |       echo "use scsi_mod.dev_flags=VENDOR:MODEL:0x240[,V:M:0x240[,...]]"
2257                 |       ;;
2258                 |    max_ghost_devices=*)
2259                 |       echo "max_ghost_devices is not needed any more"
2260                 |       ;;
2261                 |    max_sparseluns=*)
2262                 |       echo "max_sparseluns not supported any more"
2263                 |       echo "use scsi_mod.max_luns or enable the new REPORT_LUNS scsi"
2264                 |       echo "scanning methods; try scsi_mod.default_dev_flags=0x20000"
2265                 |       ;;
2266                 |    max_luns=*|max_report_luns=*|inq_timeout=*|dev_flags=*|default_dev_flags=*)
2267                 |       echo "scsi_mod compat: Please use prefix: scsi_mod.\$p"
2268                 |       params="\$params \$p"
2269                 |      ;;
2270                 |  esac
2271                 |done
2272                 |if [ \$devflags != 0 ]; then 
2273                 |    params="default_dev_flags=\$devflags \$params"
2274                 |fi
2275                 EOF
2276                 ;;
2277             qla2*|lpfc|mptfc)
2278                 # Disable asynchronous scanning
2279                 cat_linuxrc <<-EOF
2280                 |# check for asynchronous scanning
2281                 |for p in \$(cat /proc/cmdline) ; do
2282                 |  case \$p in
2283                 |    rport_scan_timeout=*)
2284                 |      rport_scan_timeout="\${p#rport_scan_timeout=}"
2285                 |      ;;
2286                 |  esac
2287                 |done
2288                 |[ -z "\$rport_scan_timeout" ] && rport_scan_timeout=\$udev_timeout
2289                 |# Disable asynchronous scanning
2290                 |if [ \$rport_scan_timeout != 0 -a -e /sys/module/scsi_transport_fc/parameters/rport_scan_timeout ] ; then
2291                 |  echo \$rport_scan_timeout > /sys/module/scsi_transport_fc/parameters/rport_scan_timeout
2292                 |fi
2293                 EOF
2294                 ;;
2295         esac
2296         cat_linuxrc <<-EOF
2297         |echo "Loading $module"
2298         |modprobe $module \$params
2299         EOF
2300
2301         initrd_is_using_modules=1
2302     done
2303
2304     if [ -z "$initrd_is_using_modules" ]; then
2305         echo "none"
2306     else
2307         echo
2308     fi
2309
2310     if  [ "$xenu_modules" ] && is_xen_kernel $kernel_version; then
2311         cat_linuxrc <<-EOF
2312         |caps="\$(cat /proc/xen/capabilities)"
2313         |if [ "\$caps" == "\${caps%control_d*}" ]; then
2314         EOF
2315         echo -ne "\nXen domU modules:\t"
2316         initrd_is_using_modules=
2317         for modpath in $xenu_modules; do
2318             module=${modpath##*/}
2319             module=${module%.ko}
2320             echo -n "${module} "
2321             cat_linuxrc <<-EOF
2322                 |params=
2323                 |for p in \$(cat /proc/cmdline) ; do
2324                 |  case \$p in
2325                 |    $module.*)
2326                 |      params="\$params \${p#$module.}"
2327                 |      ;;
2328                 |  esac
2329                 |done
2330                 |echo "Loading $module"
2331                 |modprobe $module \$params
2332                 EOF
2333
2334             initrd_is_using_modules=1
2335         done
2336
2337         if [ -z "$initrd_is_using_modules" ]; then
2338             echo "none"
2339         else
2340             echo
2341         fi
2342         cat_linuxrc <<-EOF
2343         |fi
2344         EOF
2345     fi
2346
2347     if [ -n "$s390_dasd_disks" ]; then
2348         # We only need to activate DASDs manually if it
2349         # is not done via the kernel command line
2350         echo -e -n "DASDs:\t\t"
2351         cat_linuxrc <<-EOF
2352         |if test -z "\$dasd_params"; then
2353         |    echo -n "Activating DASDs:"
2354         EOF
2355         s390_dasd_disk_num=0
2356         for disk in $s390_dasd_disks; do
2357             set -- $(IFS=":"; echo $disk)
2358             use_diag=0
2359             case "$2" in
2360                 0)
2361                     echo -n " $1(ECKD)"
2362                     ;;
2363                 1)
2364                     echo -n " $1(FBA)"
2365                     ;;
2366                 2)
2367                     echo -n " $1(DIAG)"
2368                     use_diag=1
2369                     ;;
2370             esac
2371             cat_linuxrc <<-EOF
2372         |    echo -n " $disk"
2373         |    /sbin/dasd_configure $1 1 $use_diag
2374         EOF
2375             s390_dasd_disk_num=$(( $s390_dasd_disk_num + 1 ))
2376         done
2377         echo ""
2378         cat_linuxrc <<-EOF
2379         |    echo " : done"
2380         |fi
2381         EOF
2382     fi
2383
2384     if [ -n "$s390_zfcp_disks" ] && [ "$s390_zfcp_hbas" != "iSCSI" ] ; then
2385         echo -e -n "zfcp HBAs:\t"
2386         for hba in $s390_zfcp_hbas; do
2387             echo -n "$hba "
2388             cat_linuxrc <<-EOF
2389         |echo "Activating zfcp host $hba"
2390         |/sbin/zfcp_host_configure $hba 1
2391         EOF
2392         done
2393         echo
2394
2395         echo -e "zfcp disks:\t"
2396         s390_zfcp_disk_num=0
2397         for disk in $s390_zfcp_disks; do
2398             s390_zfcp_disk_num=$(( $s390_zfcp_disk_num + 1 ))
2399             set -- $(IFS=":"; echo $disk)
2400             echo -e "\t\t$1:$2:$3"
2401             cat_linuxrc <<-EOF
2402         |echo "Activating zfcp disk $1:$2:$3"
2403         |/sbin/zfcp_disk_configure $1 $2 $3 1
2404         EOF
2405         done
2406     fi
2407
2408     case "$(uname -m)" in
2409         s390|s390x)
2410             if [ -z "$s390_zfcp_disks" -a -z "$s390_dasd_disks" ]; then
2411                 echo ""
2412                 echo "WARNING: No boot devices found."
2413                 echo "Make sure to add 'dasd=<dasd-range>' to" \
2414                      "the kernel command line"
2415             fi
2416             ;;
2417     esac
2418
2419     if [ -n "$interface" ] ; then
2420         cat_linuxrc <<-'EOF'
2421         |# configure interface
2422         |for o in $(cat /proc/cmdline); do
2423         |    case $o in
2424         |       eth[[:digit:]]=*)
2425         |           tmp=${o#eth[[:digit:]]=}
2426         |           interface=${o%=*}
2427         |           macaddress=${tmp%,*}
2428         |           ifmode=${tmp#*,}
2429         |           ;;
2430         |       ibft=*)
2431         |           ibft_mode=${o#ibft=}
2432         |           ;;
2433         |    esac
2434         |done
2435         |if [ "$ifmode" = "dhcp" ] ; then
2436         |   dhcp_mode=1
2437         |fi
2438         |if [ "$ibft_mode" = "off" -a "$ifmode" = "ibft" ] ; then
2439         |   ibft_mode=
2440         |fi
2441         EOF
2442     fi
2443
2444     if [ -n "$use_dhcp" ] ; then
2445         cat_linuxrc <<-'EOF'
2446         |# configure interface
2447         |for o in $(cat /proc/cmdline); do
2448         |  case $o in
2449         |    dhcp=*)
2450         |      if [ "${o#dhcp=}" ] && [ "${o#dhcp=}" = "off"] ; then
2451         |          dhcp_mode=
2452         |      else
2453         |          interface="${o#dhcp=}"
2454         |          dhcp_mode=1
2455         |      fi ;;
2456         |  esac
2457         |done
2458         |if [ -z "$dhcp_mode" ] ; then
2459         |   dhcp_mode=1
2460         |fi
2461         EOF
2462     fi
2463
2464     if [ -n "$iscsi_root" ] ; then
2465         cat_linuxrc <<-EOF
2466         |# Check of iBFT settings
2467         |if [ "\$ibft_mode" != "off" ] && [ -x /sbin/fwparam_ibft ] ; then
2468         |    eval \$(/sbin/fwparam_ibft -b 2> /dev/null )
2469         |    if [ "\$iSCSI_INITIATOR_NAME" ] ; then
2470         |        echo "InitiatorName=\$iSCSI_INITIATOR_NAME" > /tmp/initiatorname.iscsi
2471         |    fi
2472         |    if [ "\$iSCSI_INITIATOR_HWADDR" ] ; then
2473         |      ibftspec=\$(/sbin/fwparam_ibft -b -i)
2474         |      if [ "\$ibftspec" ] ; then
2475         |        echo "Setting up network \$ibftspec"
2476         |        /bin/ipconfig.sh \$ibftspec
2477         |      fi
2478         |    fi
2479         |fi
2480         |
2481         |for o in \$(cat /proc/cmdline); do
2482         |  case \$o in
2483         |    TargetAddress=*)
2484         |      if [ "\${o#TargetAddress=}" = "default" ] ; then
2485         |          unset iSCSI_TARGET_IPADDR
2486         |      else
2487         |          iscsiserver="\${o#TargetAddress=}"
2488         |      fi ;;
2489         |    TargetName=*)
2490         |      if [ "\${o#TargetName=}" = "default" ] ; then
2491         |          unset iSCSI_TARGET_NAME
2492         |      else
2493         |          iscsitarget="\${o#TargetName=}"
2494         |      fi ;;
2495         |    TargetPort=*)
2496         |      if [ "\${o#TargetPort=}" = "default" ] ; then
2497         |          unset iSCSI_TARGET_PORT
2498         |      else
2499         |          iscsiport="\${o#TargetPort=}"
2500         |      fi ;;
2501         |    InitiatorName=*)
2502         |      if [ "\${o#InitiatorName=}" = "default" ] ; then
2503         |          rm -f /tmp/initiatorname.iscsi
2504         |      else
2505         |          echo \${o#InitiatorName=} > /tmp/initiatorname.iscsi
2506         |      fi ;;
2507         |  esac
2508         |done
2509         |
2510         |if [ -f /tmp/initiatorname.iscsi ] ; then
2511         |    if [ -d /etc/iscsi ] ; then
2512         |        mv /tmp/initiatorname.iscsi /etc/iscsi
2513         |    else
2514         |        mv /tmp/initatorname.iscsi /etc
2515         |    fi
2516         |fi
2517         |if [ "\$iSCSI_TARGET_IPADDR" ] ; then
2518         |      iscsiserver="\$iSCSI_TARGET_IPADDR"
2519         |fi
2520         |if [ "\$iSCSI_TARGET_PORT" ] ; then
2521         |      iscsiport="\$iSCSI_TARGET_PORT"
2522         |fi
2523         |if [ "\$iSCSI_TARGET_NAME" ] ; then
2524         |      iscsitarget="\$iSCSI_TARGET_NAME"
2525         |fi
2526         EOF
2527     fi
2528
2529     if [ -n "$use_dhcp" ] ; then
2530         cat_linuxrc <<-EOF
2531         |# run dhcp
2532         |if [ -n "\$dhcp_mode" ]; then
2533         |  # Fallback to hardcoded MAC address
2534         |  [ -z "\$macaddress" ] && macaddress="$macaddress"
2535         |  if [ "\$macaddress" ] ; then
2536         |    for dev in /sys/class/net/* ; do
2537         |      read tmpmac < \$dev/address
2538         |      if [ "\$tmpmac" == "$macaddress" ] ; then
2539         |        interface=\${dev##*/}
2540         |        echo "using interface \$interface"
2541         |      fi
2542         |    done
2543         |  fi
2544         |  echo "running dhcpcd on interface \$interface"
2545         |  dhcpcd -R -Y -N -t 60 \$interface
2546         |  if [ -s /var/lib/dhcpcd/dhcpcd-\$interface.info ] ; then
2547         |    . /var/lib/dhcpcd/dhcpcd-\$interface.info
2548         |  else
2549         |    echo "no response from dhcp server."
2550         |  fi
2551         |  kill -9 \$(cat /var/run/dhcpcd-\$interface.pid)
2552         |  if [ -n "\$DNS" ]; then
2553         |    oifs="\$IFS"
2554         |    IFS=","
2555         |    for ns in \$DNS ; do
2556         |      echo "nameserver \$ns" >> /etc/resolv.conf
2557         |    done
2558         |    IFS="\$oifs"
2559         |    if [ -n "\$DOMAIN" ]; then
2560         |       echo "search \$DOMAIN" >> /etc/resolv.conf
2561         |    fi
2562         |    echo 'hosts: dns' > /etc/nsswitch.conf
2563         |  fi
2564         |fi
2565         EOF
2566     fi
2567
2568     if [ -n "$interface" ] ; then
2569         case $interface in
2570             ctc*)
2571                 ccwdevs=$(s390_get_ctc_ccwdevs $interface)
2572         cat_linuxrc <<-EOF
2573         |# configure $interface
2574         |if [ -d /sys/bus/ccwgroup/drivers/ctc ]; then
2575         |  echo "$ccwdevs" > /sys/bus/ccwgroup/drivers/ctc/group
2576         |  # Wait for the device to appear
2577         |  i=100
2578         |  while [ "\$i" -gt 0 ]; do
2579         |    [ -d /sys/bus/ccwgroup/devices/${ccwdevs%%,*} ] && break
2580         |    i=\$(( \$i - 1 ))
2581         |  done
2582         |  if [ "\$i" -le 0 ] ; then
2583         |    echo "Interface $interface could not be setup, exiting to /bin/sh"
2584         |    cd /
2585         |    PATH=$PATH PS1='$ ' /bin/sh -i
2586         |  else
2587         |    echo 1 > /sys/bus/ccwgroup/devices/${ccwdevs%%,*}/online
2588         |  fi
2589         |fi
2590         EOF
2591         ;;
2592         esac
2593     fi
2594
2595     if [ -n "$use_ipconfig" ]; then
2596         ipinterface=$(get_ip_config $interface)
2597         cat_linuxrc <<-EOF
2598         |# configure interface
2599         |for o in \$(cat /proc/cmdline); do
2600         |  case \$o in
2601         |    ip=*)
2602         |      ifspec=\${o#ip=};;
2603         |  esac
2604         |done
2605         |if [ -z "\$ifspec" ]; then
2606         |  # Fallback to configured interface
2607         |  ifspec=$ipinterface
2608         |  # Fallback to hardcoded MAC address
2609         |  [ -z "\$macaddress" ] && macaddress="$macaddress"
2610         |  if [ "\$macaddress" ] ; then
2611         |    ifspec=\${ifspec%:*}
2612         |    interface=\${ifspec##*:}
2613         |    tmpspec=\${ifspec%:*}
2614         |    for dev in /sys/class/net/* ; do
2615         |      read tmpmac < \$dev/address
2616         |      if [ "\$tmpmac" == "$macaddress" ] ; then
2617         |        interface=\${dev##*/}
2618         |        echo "using interface \$interface"
2619         |      fi
2620         |    done
2621         |    ifspec="\${tmpspec}:\${interface}:static"
2622         |  fi
2623         |fi
2624         |if [ -n "\$ifspec" ]; then
2625         |  echo "Setting up network \$ifspec"
2626         |  /bin/ipconfig.sh \$ifspec
2627         |fi
2628         EOF
2629     fi
2630
2631     if [ -n "$iscsi_root" ] ; then
2632         iscsi_tgtname=$(cat /sys/class/iscsi_session/${iscsi_root}/targetname)
2633         iscsi_tgtaddr=$(cat /sys/class/iscsi_connection/connection${iscsi_root#session}:0/address)
2634         cat_linuxrc <<-EOF
2635         |iscsi_mark_root_nodes()
2636         |{
2637         |    local iscsi_tgts
2638         |
2639         |    if [ -z "\$iscsitarget" ] ; then
2640         |        iscsi_tgts=\$(/sbin/iscsiadm -m node | sed -n "s/.*\$iscsiserver:\$iscsiport,.* \(iqn.*\)/\1/p")
2641         |    else
2642         |        iscsi_tgts="\$iscsitarget"
2643         |    fi
2644         |
2645         |    for tgt in \$iscsi_tgts ; do
2646         |        echo "Setup iSCSI target \$tgt"
2647         |        /sbin/iscsiadm -m node -p \$iscsiserver:\$iscsiport -T \$tgt -o update -n node.conn[0].startup -v automatic
2648         |    done
2649         |}
2650         |
2651         |iscsi_discover_nodes()
2652         |{
2653         |    echo -n "Starting discovery on \${iscsiserver},\${iscsiport}: "
2654         |    if /sbin/iscsiadm -m discovery -t st -p \${iscsiserver}:\${iscsiport} 2> /dev/null ; then
2655         |        echo "ok."
2656         |    else
2657         |        echo "failed."
2658         |    fi
2659         |}
2660         |
2661         |echo "Starting iSCSI daemon"
2662         |/sbin/iscsid
2663         |usleep 5000000
2664         |
2665         |[ -z "\$iscsiserver" ] && iscsiserver=$iscsi_tgtaddr
2666         |[ -z "\$iscsiport" ] && iscsiport=3260
2667         |[ -z "\$iscsitarget" ] && iscsitarget=$iscsi_tgtname
2668         |
2669         |if [ "\$iscsiserver" -a "\$iscsiport" ] ; then
2670         |    if [ "\$iscsitarget" ] ; then
2671         |        if ! /sbin/iscsiadm -m node -p \$iscsiserver:\$iscsiport -T \$iscsitarget > /dev/null 2>&1 ; then
2672         |            do_iscsi_discovery=yes
2673         |        fi
2674         |    else
2675         |        if ! /sbin/iscsiadm -m node -p \$iscsiserver:\$iscsiport > /dev/null 2>&1 ; then
2676         |            do_iscsi_discovery=yes
2677         |        fi
2678         |    fi
2679         |    if [ "\$do_iscsi_discovery" ] ; then
2680         |        iscsi_discover_nodes
2681         |    fi
2682         |    iscsi_mark_root_nodes
2683         |fi
2684         |echo "Logging in to all nodes"
2685         |/sbin/iscsiadm -m node -L automatic
2686         |
2687         EOF
2688     fi
2689
2690     if [ "$rootfstype" = "nfs" ]; then
2691         cat_linuxrc <<-'EOF'
2692         |if [ -z "$rootdev_cmdline" ]; then
2693         |  case "$ROOTPATH" in
2694         |    "") ;;
2695         |    *:*)
2696         |       rootfstype="nfs"
2697         |       rootdev="$ROOTPATH" ;;
2698         |    *)
2699         |       if [ -n "$DHCPSIADDR" ]; then
2700         |           rootdev="$DHCPSIADDR:$ROOTPATH"
2701         |           rootfstype="nfs"
2702         |       elif [ -n "$DHCPSNAME" ]; then
2703         |           rootdev="$DHCPSNAME:$ROOTPATH"
2704         |           rootfstype="nfs"
2705         |       fi ;;
2706         |   esac
2707         |   if [ -z "$rootdev" ]; then
2708         |       echo "no local root= kernel option given and no root" \
2709         |            "server set by the dhcp server."
2710         |       echo 256 > /proc/sys/kernel/real-root-dev
2711         |       die 0
2712         |   fi
2713         |fi
2714         EOF
2715     fi
2716
2717     if [ -n "$root_mpath" -o -n "$root_lvm2" -o -n "$root_evms" ]; then
2718         cat_linuxrc <<-'EOF'
2719         |echo -n "Waiting for /dev/mapper/control to appear: "
2720         |for i in 1 2 3 4 5; do
2721         |    [ -e /dev/mapper/control ] && break
2722         |    sleep 1
2723         |    echo -n "."
2724         |done
2725         |if [ -e /dev/mapper/control ]; then
2726         |    echo " ok"
2727         |else
2728         |    echo " failed"
2729         |fi
2730         EOF
2731     fi
2732
2733     cat_linuxrc <<-'EOF'
2734         |
2735         |# Waiting for a device to appear
2736         |# device node will be created by udev
2737         |udev_check_for_device() {
2738         |    local root
2739         |    local retval=1
2740         |    local timeout=$udev_timeout
2741         |    root=$1
2742         |    if [ -n "$root" ]; then
2743         |       echo -n "Waiting for device $root to appear: "
2744         |       while [ $timeout -gt 0 ]; do
2745         |           if [ -e $root ]; then
2746         |               echo " ok"
2747         |               retval=0
2748         |               break;
2749         |           fi
2750         |           sleep 1
2751         EOF
2752
2753     if [ -n "$root_lvm2" ] ; then
2754         cat_linuxrc <<-'EOF'
2755         |           vgscan
2756         |           vgchange -a y $vgname
2757         EOF
2758     fi
2759
2760     cat_linuxrc <<-'EOF'
2761         |           echo -n "."
2762         |           timeout=$(( $timeout - 1 ))
2763         |       done
2764         |    fi
2765         |    return $retval;
2766         |}
2767         |
2768         |udev_discover_resume() {
2769         |    local resume
2770         |    # Waits for the resume device to appear
2771         |    if [ -n "$resume_mode" ]; then
2772         |       if [ -e $resumedev ] ; then
2773         |           # Try major:minor number of the device node
2774         |           devn=$(devnumber $resumedev)
2775         |           major=$(devmajor $devn)
2776         |           minor=$(devminor $devn)
2777         |           devn=
2778         |       fi
2779         |       if [ -n "$major" -a -n "$minor" ]; then
2780         |           echo "$major:$minor" > /sys/power/resume
2781         |           major=
2782         |           minor=
2783         |       else
2784         |           echo "resume device $resumedev not found (ignoring)"
2785         |       fi
2786         |    fi
2787         |}
2788         |
2789         |udev_discover_dump() {
2790         |    local root
2791         |    case "$dumpdev" in
2792         |       *:*) root= ;;
2793         |       /dev/nfs) root= ;;
2794         |       /dev/*) root=${rootdev#/dev/} ;;
2795         |    esac
2796         |    if [ -z "$root" ]; then
2797         |       return 0
2798         |    fi
2799         |    if udev_check_for_device $dumpdev  ; then
2800         |       # Get major:minor number of the device node
2801         |       devn=$(devnumber $rootdev)
2802         |       major=$(devmajor $devn)
2803         |       minor=$(devminor $devn)
2804         |    fi
2805         |    if [ -n "$devn" ]; then
2806         |       echo "rootfs: major=$major minor=$minor" \
2807         |           "devn=$devn"
2808         |       echo $devn > /proc/sys/kernel/real-root-dev
2809         |       return 0
2810         |    else
2811         |       return 1
2812         |    fi
2813         |}
2814         |
2815         |udev_discover_root() {
2816         |    local root
2817         |    case "$rootdev" in
2818         |       *:*) root= ;;
2819         |       /dev/nfs) root= ;;
2820         |       /dev/*) root=${rootdev#/dev/} ;;
2821         |    esac
2822         |    if [ -z "$root" ]; then
2823         |       return 0
2824         |    fi
2825         |    if udev_check_for_device $rootdev  ; then
2826         |       # Get major:minor number of the device node
2827         |       devn=$(devnumber $rootdev)
2828         |       major=$(devmajor $devn)
2829         |       minor=$(devminor $devn)
2830         |    fi
2831         |    if [ -n "$devn" ]; then
2832         |       echo "rootfs: major=$major minor=$minor" \
2833         |           "devn=$devn"
2834         |       echo $devn > /proc/sys/kernel/real-root-dev
2835         |       return 0
2836         |    else
2837         |       return 1
2838         |    fi
2839         |}
2840         |
2841         |# Enable asynchronous scanning again
2842         |if [ -e /sys/module/scsi_transport_fc/parameters/rport_scan_timeout ] ; then
2843         |  echo 0 > /sys/module/scsi_transport_fc/parameters/rport_scan_timeout
2844         |fi
2845         |
2846         |/sbin/udevsettle --timeout=$udev_timeout
<