]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
- nfsroot patch from wolverine
[projects/geninitrd.git] / geninitrd
1 #!/bin/sh
2
3 # geninitrd
4 #
5 #       by PLD Linux Team
6 #
7 # based on mkinitrd from RedHat Linux
8 #
9 # TODO:
10 # - make udev start before insmods
11 # - make proper use of USE_UDEV - don't copy rules if USE_UDEV is off no!
12 #
13
14 RCSID='$Id$'
15 R=${RCSID#* * }; VERSION=${R%% *}
16 PROGRAM=${0##*/}
17
18 . /etc/rc.d/init.d/functions
19 . /etc/geninitrd/functions
20
21 COMPRESS=yes
22 USERAIDSTART=yes
23 USEMDADMSTATIC=no
24 USEINSMODSTATIC=no
25 USE_SUSPEND=yes
26 USE_TUXONICE=no
27 # it should be safe to remove scsi_mod from here, but I'm not sure...
28 PRESCSIMODS="-scsi_mod unknown -sd_mod"
29 PREIDEMODS="-ide-core unknown -ide-detect -ide-disk"
30 PREIDEMODSOLD="-ide-probe -ide-probe-mod -ide-disk"
31 target=""
32 kernel=""
33 force=""
34 verbose=""
35 MODULES=""
36 img_vers=""
37 fstab=/etc/fstab
38 insmod=insmod
39 modext=.o
40 rootdev_nr=0
41 # device node for rootfs from fstab
42 rootdev=""
43 # default bootsplash is off, if it have to be on, install bootsplash package
44 BOOT_SPLASH=no
45 # default same as bootsplash, if on install splashutils and some splashutils theme
46 FB_SPLASH=no
47 # defualt we don't use udev to make nodes for static modules, as per default
48 # PLD loads the modules needed to mount and boot
49 PROBESTATICMODULES=no
50
51 # internal variables
52 # is /dev on tmpfs
53 dev_mounted=no
54 # is /proc mounted
55 proc_mounted=no
56 # is /sys mounted
57 sys_mounted=no
58 # is /tmp mounted on tmpfs
59 tmp_mounted=no
60
61 # are /dev nodes already created from /proc/devices info?
62 proc_partitions=no
63
64 # LVM devices that should not be included in vgscan on initrd
65 lvm_ignore_devices=''
66 # LVM volume that is used for rootfs
67 VGVOLUME=
68
69 # if we should init NFS at boot
70 have_nfs=no
71 # if we should init LVM at boot
72 have_lvm=no
73 # if we should init md (softraid) at boot
74 have_md=no
75 # if we should init dmraid at boot
76 have_dmraid=no
77 # if we should init dm-multipath at boot
78 have_multipath=no
79 # dm-multipath wwid which is used for rootfs
80 MPATH_WWID=
81
82 usage() {
83         uname_r=$(uname -r)
84         echo "usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
85         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
86         echo "       [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
87         echo "       [--with-raidstart] [--without-raidstart] [--with-insmod-static]"
88         echo "       [--with-bootsplash] [--without-bootsplash]"
89         echo "       [ --with-fbsplash] [--without-fbsplash]"
90         echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
91         echo "       [--with-suspend] [--without-suspend]"
92         echo "       [--with-tuxonice] [--without-tuxonice]"
93         echo "       [--without-dmraid] [--without-multipath]"
94         echo "       <initrd-image> <kernel-version>"
95         echo ""
96         echo "example:"
97         echo "  $PROGRAM -f --initrdfs=rom /boot/initrd-$uname_r.gz $uname_r"
98         exit 1
99 }
100
101 msg() {
102         echo "$PROGRAM: $*"
103 }
104
105 warn() {
106         msg "$*" >&2
107 }
108
109 debug() {
110         [ -n "$verbose" ] && warn "$*"
111 }
112
113 # aborts program abnormally
114 die() {
115         local rc=${2:-1}
116         warn "ERROR: $1"
117         exit $rc
118 }
119
120 # append text to /linuxrc
121 # takes STDIN as input
122 add_linuxrc() {
123         cat >> "$RCFILE"
124 }
125
126 # generate code to mount /dev on tmpfs and create initial nodes
127 # can be called multiple times. /dev is cleaned up (umounted) automatically at
128 # the end of script.
129 mount_dev() {
130     if [ "$INITRDFS" = "initramfs" ]; then
131                 # initramfs is read-write filesystem, no need for tmpfs
132                 return
133         fi
134
135         # we already generated tmpfs code; return
136         if is_yes "$dev_mounted"; then
137                 return
138         fi
139
140         dev_mounted=yes
141
142         busybox_applet mount mknod mkdir
143         add_linuxrc <<-EOF
144                 : 'Creating /dev'
145                 mount -o mode=0755 -t tmpfs none /dev
146                 mknod /dev/console c 5 1
147                 mknod /dev/null c 1 3
148                 mknod /dev/zero c 1 5
149                 mkdir /dev/pts
150                 mkdir /dev/shm
151         EOF
152 }
153
154 # generate code to mount /proc on initrd
155 # can be called multiple times
156 mount_proc() {
157         if is_yes "$proc_mounted"; then
158                 return
159         fi
160
161         proc_mounted=yes
162     if [ "$INITRDFS" = "initramfs" ]; then
163                 # /proc is mounted with initramfs 2.6.22.14 kernel
164                 # XXX: remove when it is clear why proc was already mounted
165                 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
166         else
167                 echo "mount -t proc none /proc" | add_linuxrc
168         fi
169 }
170
171 # generate code to mount /sys on initrd
172 # can be called multiple times
173 mount_sys() {
174         if is_yes "$sys_mounted"; then
175                 return
176         fi
177
178         sys_mounted=yes
179         echo "mount -t sysfs none /sys" | add_linuxrc
180 }
181
182 # generate code to mount /tmp on initrd
183 # can be called multiple times
184 mount_tmp() {
185     if [ "$INITRDFS" = "initramfs" ]; then
186                 # initramfs is read-write filesystem, no need for tmpfs
187                 return
188         fi
189
190         if is_yes "$tmp_mounted"; then
191                 return
192         fi
193
194         tmp_mounted=yes
195         echo "mount -t tmpfs none /tmp" | add_linuxrc
196 }
197
198 # unmount all mountpoints mounted by geninitrd
199 umount_all() {
200
201         add_linuxrc <<-'EOF'
202         : Last shell before umounting all and giving control over to real init.
203         debugshell
204         EOF
205
206         if is_yes "$dev_mounted"; then
207                 echo 'umount /dev' | add_linuxrc
208                 dev_mounted=no
209         fi
210         if is_yes "$proc_mounted"; then
211                 echo 'umount /proc' | add_linuxrc
212                 proc_mounted=no
213         fi
214         if is_yes "$sys_mounted"; then
215                 echo 'umount /sys' | add_linuxrc
216                 sys_mounted=no
217         fi
218         if is_yes "$tmp_mounted"; then
219                 echo 'umount /tmp' | add_linuxrc
220                 tmp_mounted=no
221         fi
222 }
223
224
225 # Checks if busybox has support for APPLET(s)
226 # Exits from geninitrd if the support is not present.
227 #
228 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
229 busybox_applet() {
230         local err=0
231
232         if [ -z "$busybox_functions" ]; then
233                 local tmp=$(/bin/initrd-busybox 2>&1)
234
235                 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
236                 if [[ "$tmp" = *applet\ not\ found* ]]; then
237                         local t=$(mktemp -d)
238                         ln -s /bin/initrd-busybox $t/busybox
239                         local tmp=$($t/busybox 2>&1)
240                         rm -rf $t
241                 fi
242
243                 busybox_functions=$(echo "$tmp" | \
244                         sed -ne '/Currently defined functions:/,$p' | \
245                         xargs | sed -e 's,.*Currently defined functions: ,,'
246                 )
247         fi
248         for applet in $*; do
249                 local have
250                 # try cache
251                 eval have='$'busybox_have_$applet
252                 if [ -z "$have" ]; then
253                         have=$(echo "$busybox_functions" | egrep -c "( |^)$applet(,|$)")
254                         if [ "$have" = 0 ]; then
255                                 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
256                                 err=1
257                         fi
258                         eval busybox_have_$applet=$have
259                 fi
260         done
261         if [ $err = 1 ]; then
262                 die "Aborted"
263         fi
264 }
265
266 # Finds module dependencies
267 #
268 # @param        $mode   silent | normal
269 # @param        $module
270 #
271 # Outputs each dependant module full path including the module itself.
272 find_depmod() {
273         local mode="$1"
274         local module="$2"
275
276         # backwards compatible, process $mode
277         local modfile
278         if [ "$mode" = silent ]; then
279                 modfile=$(modinfo -n $module 2>/dev/null)
280         else
281                 modfile=$(modinfo -n $module)
282         fi
283         if [ ! -f "$modfile" ]; then
284                 if [ "$mode" != silent ]; then
285                         warn "$module: module not found for $kernel kernel"
286                 fi
287                 if ! is_no "$EXIT_IF_MISSING"; then
288                         exit 1
289                 else
290                         warn "If $module isn't compiled in kernel then this initrd may not start your system."
291                 fi
292         fi
293
294         # This works when user has module-init-tools installed even on 2.4 kernels
295         modprobe --set-version $kernel --show-depends $module | \
296         while read insmod modpath; do
297                 echo $modpath
298         done
299 }
300
301 find_depmod_old () {
302         typeset mods module f level depfile first
303
304         depfile=/lib/modules/$kernel/modules.dep
305
306         if [ ! -f $depfile ]; then
307                 die "No $depfile! Run depmod and rerun $PROGRAM."
308         fi
309
310         # prepend / if no path given, append $modext.gz if not given,
311         # quote /
312         origmodule="$2"
313         module=$(echo "$2" | \
314                 awk '/\// {print;next} {print "/" $0}' | \
315                 awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
316                 awk '{gsub("/","\\/");print}')
317         mods=$(awk '
318 BEGIN { here = 0 }
319 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
320 /:/ { here = 0 }
321 /(.*)/ { gsub(/\\/," "); if (here) print }
322 ' $depfile | xargs)
323
324         # fallback to $modext
325         if [ "$mods" = "" ]; then
326                 module=$(echo "$module" | awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
327                 # ") - vim
328         fi
329
330         mods=$(awk '
331 BEGIN { here = 0 }
332 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
333 /:/ { here = 0 }
334 /(.*)/ { gsub(/\\/," "); if (here) print }
335 ' $depfile | xargs)
336
337         if [ "$mods" = "" ]; then
338                 if [ "$1" != silent ]; then
339                         warn "$origmodule: module not found in $depfile"
340                 fi
341                 if ! is_no "$EXIT_IF_MISSING"; then
342                         exit 1
343                 else
344                         warn "If $origmodule isn't compiled in kernel then this initrd may not start your system."
345                 fi
346         fi
347
348         level=$3
349         if [ "$level" = "" ]; then
350                 level=0
351         fi
352         level=$((level + 1))
353         if [ $level -gt 20 ]; then
354                 die "$origmodule: cycle in $depfile"
355         fi
356
357         first=
358         for f in $mods; do
359                 if [ "$first" = "" ]; then
360                         first=$f
361                 else
362                         find_depmod $1 $f $level
363                 fi
364         done
365
366         echo $first
367 }
368
369 addmodule() {
370         local fmPath=$1
371         local skiperrors=$2
372
373         if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
374                 if [ -n "$skiperrors" ]; then
375                         # XXX should not ignore here errors
376                         return
377                 fi
378
379                 die "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)"
380         fi
381
382         # only need to add each module once
383         local m have=0
384         for m in $MODULES; do
385                 [ $m = $fmPath ] && have=1
386         done
387         if [ $have = 0 ]; then
388                 MODULES="$MODULES $fmPath"
389         fi
390 }
391
392 findmodule() {
393         local skiperrors=""
394         local modName=$1
395
396         if [ ${modName#-} != ${modName} ]; then
397                 skiperrors=1
398                 modName=${modName#-}
399         fi
400
401         # what's that?
402         if [ "$modName" = "pluto" ]; then
403                 findmodule fc4
404                 findmodule soc
405         fi
406         if [ "$modName" = "fcal" ]; then
407                 findmodule fc4
408                 findmodule socal
409         fi
410
411         local mod allModulesToFind
412         if [ "$skiperrors" = 1 ]; then
413                 allModulesToFind=$(find_depmod silent $modName)
414         else
415                 allModulesToFind=$(find_depmod normal $modName)
416                 if [ $? != 0 ]; then
417                         exit 1
418                 fi
419         fi
420
421         for mod in $allModulesToFind; do
422                 mod=${mod#/lib/modules/$kernel/}
423                 addmodule $mod "$skiperrors"
424         done
425 }
426
427 # install a file to temporary mount image.
428 # it will operate recursively (copying directories)
429 # and will symlink destinations if source is symlink.
430 inst() {
431         if [ $# -lt 2 ]; then
432                 die 'Usage: inst <file> [<file>] <destination>'
433         fi
434
435         local src i=0 c=$(($# - 1))
436         while [ $i -lt $c ]; do
437                 src="$src $1"
438                 i=$((i + 1))
439                 shift
440         done
441         local dest=$1
442         set -- $src
443
444         debug "+ cp $* $DESTDIR$dest"
445         cp -HR "$@" "$DESTDIR$dest"
446 }
447
448 inst_d() {
449         if [ $# = 0 ]; then
450                 die 'Usage: inst_d <destination> <destination>'
451         fi
452         for dir in "$@"; do
453                 install -d "$DESTDIR$dir"
454         done
455 }
456
457 # install executable and it's shared libraries
458 inst_exec() {
459         if [ $# -lt 2 ]; then
460                 die 'Usage: inst_exec <file> [, <file>] <destination>'
461         fi
462         local src i=0 c=$(($# - 1))
463         while [ $i -lt $c ]; do
464                 src="$src $1"
465                 i=$((i + 1))
466                 shift
467         done
468         local dest=$1
469         set -- $src
470
471         inst "$@" $dest
472
473         local lib libs=$(ldd "$@" | awk '/statically|linux-gate\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
474         for lib in $libs; do
475                 if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
476                         inst_d /$_lib
477                         inst_exec $lib /$_lib
478                 fi
479         done
480 }
481
482 # output modules.conf / modprobe.conf
483 modprobe_conf() {
484         echo "$modprobe_conf_cache"
485 }
486
487 #
488 # defaults to modprobe -c if not told otherwise, this means include statements
489 # work from there.
490 cache_modprobe_conf() {
491         if [ "$pack_version" -lt "002005" ]; then
492                 modulefile=/etc/modules.conf
493                 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
494                         modulefile=/etc/conf.modules
495                 fi
496         fi
497
498         if [ -n "$modulefile" ]; then
499                 debug "Using $modulefile for modules config"
500                 modprobe_conf_cache=$(cat $modulefile)
501         else
502                 debug "Using modprobe -c to get modules config"
503                 modprobe_conf_cache=$(modprobe -c)
504         fi
505 }
506
507 find_modules_md() {
508         local found raidlevel
509
510         if [ -f /etc/mdadm.conf ]; then
511                 debug "Finding RAID details using mdadm for rootdev=$1"
512                 eval `/sbin/mdadm -v --examine --scan --config=/etc/mdadm.conf | awk -v rootdev="$1" '
513                 BEGIN {
514                         found = "no";
515                         dev_list = "";
516                         raidlevel = ""
517                         rootdev_devfs = rootdev;
518                         if (rootdev ~ /\/dev\/md\/[0-9]/) {
519                                 gsub(/\/dev\/md\//,"/dev/md",rootdev_devfs);
520                         }
521                 }
522
523                 /^ARRAY/ {
524                         if (($2 == rootdev) || ($2 == rootdev_devfs)) {
525                                 raidlevel=$3;
526                                 gsub(/level=/,NUL,raidlevel);
527                                 if (raidlevel ~ /^raid([0-6]|10)/) {
528                                         gsub(/raid/,NUL,raidlevel);
529                                 };
530                                 found="yes";
531                                 getline x;
532                                 if (x ~ /devices=/) {
533                                         dev_list = x;
534                                         gsub(".*devices=", NUL, dev_list);
535                                         gsub(",", " ", dev_list);
536                                 }
537                         }
538                 }
539
540                 END {
541                         print "have_md=" found;
542                         print "raidlevel=" raidlevel;
543                         print "dev_list=\"" dev_list "\"";
544                 }'`
545         fi
546
547         if [ "$have_md" != "yes" -a -f /etc/raidtab ]; then
548                 die "raidtools are not longer supported. Please migrate to mdadm setup!"
549         fi
550
551         if is_yes "$have_md"; then
552                 case "$raidlevel" in
553                 [01]|10)
554                         findmodule "raid$raidlevel"
555                         ;;
556                 [456])
557                         findmodule "-raid$raidlevel"
558                         findmodule "-raid456"
559                         ;;
560                 linear)
561                         findmodule "linear"
562                         ;;
563                 *)
564                         warn "raid level $number (in mdadm config) not recognized"
565                         ;;
566                 esac
567         else
568                 die "RAID devices not found for \"$1\", check your configuration!"
569         fi
570
571         rootdev_nr=$(( $rootdev_nr + 1 ))
572         eval "rootdev${rootdev_nr}=\"$1\""
573         eval "dev_list${rootdev_nr}=\"${dev_list}\""
574
575         for device in $dev_list; do
576                 find_modules_for_devpath $device
577         done
578 }
579
580 find_modules_scsi() {
581         local n
582         for n in $PRESCSIMODS; do
583                 if [ "X$n" = "Xunknown" ]; then
584                         debug "Finding SCSI modules using scsi_hostadapter"
585                         local mod scsimodules=$(modprobe_conf | awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
586                         for mod in $scsimodules; do
587                                 # for now allow scsi modules to come from anywhere. There are some
588                                 # RAID controllers with drivers in block
589                                 findmodule "$mod"
590                         done
591                 else
592                         findmodule "$n"
593                 fi
594         done
595         findmodule "-scsi_wait_scan"
596 }
597
598 find_modules_ide() {
599         local devpath=$1
600         # remove partition, if any
601         local disk=${devpath%[0-9]*}
602         # set blockdev for rootfs (hda, sdc, ...)
603         local rootblkdev=${disk#/dev/}
604
605         local n
606         if [ "$pack_version_long" -lt "002004021" ]; then
607                 debug "Finding IDE modules for kernels <= 2.4.20"
608                 for n in $PREIDEMODSOLD; do
609                         findmodule "$n"
610                 done
611         else
612                 local tryauto=1
613                 for n in $PREIDEMODS; do
614                         if [ "X$n" = "Xunknown" ]; then
615                                 debug "Finding IDE modules using ide_hostadapter"
616                                 local mod idemodules=$(modprobe_conf | awk '/ide_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
617                                 for mod in $idemodules; do
618                                         tryauto=0;
619                                         findmodule "$mod"
620                                 done
621
622                                 if [ "$tryauto" -eq 1 ]; then
623                                         # If tryauto {{{
624                                         if [ -r /usr/share/pci-database/ide.pci -a -r /proc/bus/pci/devices ]; then
625                                                 debug "Finding IDE modules using PCI ID database"
626                                                 # Finding IDE modules using PCI ID database {{{
627                                                 if is_yes "${ide_only_root}"; then
628                                                         if [ -f /sys/block/${rootblkdev}/device/../../vendor -a -f /sys/block/${rootblkdev}/device/../../device ]; then
629                                                                 vendorid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootblkdev}/device/../../vendor)"
630                                                                 deviceid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootblkdev}/device/../../device)"
631                                                                 searchpciid="${vendorid}${deviceid}"
632                                                         elif [ -f /proc/ide/${rootblkdev}/../config ]; then
633                                                                 searchpciid="$(awk ' /pci bus/ { print $7$9 } ' /proc/ide/${rootblkdev}/../config)"
634                                                         fi
635                                                 fi
636
637                                                 if [ -z "${searchpciid}" ]; then
638                                                         searchpciid="$(awk ' { print $2 } ' /proc/bus/pci/devices)"
639                                                 fi
640
641                                                 idemodules=""
642
643                                                 for nb in $searchpciid; do
644                                                         eval `awk -v pciid="$nb" '{
645                                                                 gsub("\t"," ");
646                                                                 gsub("  +", " ");
647                                                                 gsub("^ ","");
648                                                                 if (/^[\t ]*#/)
649                                                                         next;
650                                                                 compmod = $1 "";        # make sure comparison type will be string
651                                                                                         # cause pci IDs are hexadecimal numeric
652                                                                 if (compmod == pciid) {
653                                                                         module=$2;
654                                                         #               min_kernel=$3;  # now in ide.pci $3,$4 = vendor and device name
655                                                         #               max_kernel=$4;  #
656                                                                         exit 0;
657                                                                 }
658                                                         }
659
660                                                         END {
661                                                                 print "module=" module "\nmin_kernel=" min_kernel "\nmax_kernel=\"" max_kernel "\"\n";
662                                                         }' /usr/share/pci-database/ide.pci`
663                                                         [ -n "$module" ] && idemodules="$idemodules $module"
664                                                 done
665                                                 if is_yes "$(awk ' /ide=reverse/ { print "yes" } ' /proc/cmdline)"; then
666                                                         new_idemodules=""
667                                                         for nc in idemodules; do
668                                                                 new_idemodules="$nc $new_idemodules"
669                                                         done
670                                                         idemodules="${new_idemodules}"
671                                                 fi
672
673                                                 if [ -z "$idemodules" ]; then
674                                                         echo "WARNING: rootfs on IDE device but no related modules found, loading ide-generic."
675                                                         idemodules="ide-generic"
676                                                 fi
677
678                                                 # }}}
679                                                 for nd in $idemodules; do
680                                                         findmodule "-$nd"
681                                                 done
682                                         # }}}
683                                         # else tryauto {{{
684                                         else
685                                                 [ -r /usr/share/pci-database/ide.pci ] || echo "WARNING: /usr/share/pci-database/ide.pci missing."
686                                                 [ -r /proc/bus/pci/devices ] || echo "WARNING: /proc/bus/pci/devices missing."
687                                                 echo "Automatic IDE modules finding not available."
688                                         fi
689                                         # }}}
690                                 fi
691                         else
692                                 findmodule "$n"
693                         fi
694                 done
695         fi
696 }
697
698 # return true if node is lvm node
699 _check_lvm() {
700         local node="$1"
701         if [ ! -e "$node" ]; then
702                 warn "WARNING: check_lvm(): node $node doesn't exist!"
703                 return 1
704         fi
705
706         # block-major-58 is lvm1
707         ls -lL "$node" 2> /dev/null | awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'
708         rc=$?
709
710         if [ $rc = 0 ]; then
711                 debug "LVM check: $node is LVM v1 node"
712                 # is lvm1
713                 return 0
714         fi
715
716         /sbin/lvm lvdisplay "$node" > /dev/null 2>&1
717         rc=$?
718         if [ $rc -gt 127 ]; then
719                 # lvdisplay terminated by signal! most likely it segfaulted.
720                 die "Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
721         fi
722
723         if [ $rc = 0 ]; then
724                 debug "LVM check: $node is LVM v2 node"
725         else
726                 debug "LVM check: $node is not any LVM node"
727         fi
728         return $rc
729 }
730
731 # return dependencies MAJOR:MINOR [MAJOR:MINOR] for DM_NAME
732 # TODO: patch `dmsetup export`
733 dm_deps() {
734         local dm_name="$1"
735         dmsetup deps $dm_name | sed -e 's/, /:/g;s/^.\+ dependencies[^:]: //;s/[()]//g;'
736 }
737
738 # export info from dmsetup
739 # param can be:
740 # - MAJOR:MINOR
741 # - /dev/dm-MINOR
742 # - /dev/mapper/DM_NAME
743 dm_export() {
744         local arg="$1"
745
746         case "$arg" in
747         *:*)
748                 local maj=${arg%:*} min=${arg#*:}
749                 dmsetup -j $maj -m $min export
750                 ;;
751         /dev/dm-*)
752                 local min=${arg#*dm-}
753                 local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
754                 dm_export $maj:$min
755                 ;;
756         /dev/mapper/*)
757                 local dm_name=${arg#/dev/mapper/}
758                 dmsetup export $dm_name
759                 ;;
760         *)
761                 die "dm_export: unexpected $arg"
762                 ;;
763         esac
764 }
765
766 # find dm-multipath modules for $devpath
767 # returns false if $devpath is not dm-multipath
768 find_modules_multipath() {
769         local devpath="$1"
770
771         DM_NAME=
772         eval $(dm_export "$devpath")
773         if [ -z "$DM_NAME" ]; then
774                 die "dm_export failed unexpectedly"
775         fi
776
777         # Partition:
778         #  DM_NAME=LUN-28p1
779         #  DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
780         # Disk:
781         #  DM_NAME=LUN-28
782         #  DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
783         MPATH_WWID=${DM_UUID##*-}
784
785         local info=$(multipath -l $MPATH_WWID)
786         if [ -z "$info" ]; then
787                 return 1
788         fi
789
790         debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
791         have_multipath=yes
792         local dev phydevs=$(echo "$info" | awk '$2 ~ /^[0-9]+:[0-9]+:[0-9]+:[0-9]+$/{printf("/dev/%s\n", $3)}')
793         for dev in $phydevs; do
794                 find_modules_for_devpath $dev
795                 lvm_ignore_devices="$lvm_ignore_devices $dev"
796         done
797
798         local hw hwhandlers=$(echo "$info" | awk '/hwhandler=1/{sub(/.*hwhandler=1 /, ""); sub(/\]$/, ""); print}')
799         for hw in $hwhandlers; do
800                 findmodule "dm-$hw"
801         done
802
803         local target targets=$(echo "$info" | awk '/prio=/{print $2}' | sort -u)
804         for target in $targets; do
805                 findmodule "dm-$target"
806         done
807
808         findmodule "dm-mod"
809         return 0
810 }
811
812 # find dmraid modules for $devpath
813 # returns false if $devpath is not on dmraid
814 find_modules_dmraid() {
815         local devpath="$1"
816
817         # get blockdev itself (without partition)
818         # /dev/mapper/sil_ahbgadcbchfc3 -> /dev/mapper/sil_ahbgadcbchfc
819         local blockdev=${devpath%%[0-9]*}
820         local raidname=${blockdev#/dev/mapper/}
821         local found=0
822
823         local dev phydevs=$(dmraid -r -cdevpath,raidname | awk -F, -vv="$raidname" '{if ($2 == v) print $1}')
824         for dev in $phydevs; do
825                 find_modules_for_devpath $dev
826                 lvm_ignore_devices="$lvm_ignore_devices $dev"
827                 found=1
828         done
829
830         if [ $found = 0 ]; then
831                 return 1
832         fi
833
834         findmodule "dm-mirror"
835         have_dmraid=yes
836         return 0
837 }
838
839 # find modules for $devpath
840 find_modules_for_devpath() {
841         local devpath="$1"
842         if [ -z "$devpath" ]; then
843                 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
844         fi
845
846         # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
847         case "$devpath" in
848         /dev/dm-*)
849                 devpath=$(dm_longname "$devpath")
850                 ;;
851         esac
852         debug "Finding modules for device path $devpath"
853
854         if is_yes "`echo "$devpath" | awk '/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:|\/dev\/nfs)/ { print "yes"; }'`"; then
855                 if [ ! -x /usr/bin/pcidev -a -z "$NFS_ETH_MODULES" ]; then
856                         die "root on NFS but /usr/bin/pcidev not found. Please install correct pci-database package and rerun $PROGRAM."
857                 fi
858                 local m
859                 [ -z "$NFS_ETH_MODULES" ] && NFS_ETH_MODULES=$(/usr/bin/pcidev /m net | xargs)
860                 for m in $NFS_ETH_MODULES; do
861                         findmodule "$m"
862                 done
863                 findmodule "-ipv4"
864                 findmodule "nfs"
865                 have_nfs=yes
866                 warn "Remember to use \`root=/dev/ram0 init=/linuxrc' when starting kernel"
867                 warn "or you will have problems like init(xx) being child process of swapper(1)."
868                 return
869         fi
870
871         if [[ "$devpath" == /dev/md* ]]; then
872                 find_modules_md "$devpath"
873                 return
874         fi
875
876         if is_yes "$USE_MULTIPATH" && [[ "$devpath" == /dev/mapper/* ]]; then
877                 if find_modules_multipath "$devpath"; then
878                         return
879                 fi
880                 # fallback
881         fi
882
883         if is_yes "$USE_DMRAID" && is_yes "$(echo "$devpath" | awk '/^\/dev\/mapper\/(sil|hpt37x|hpt45x|isw|lsi|nvidia|pdc|sil|via|dos)_/ { print "yes"; }')"; then
884                 if find_modules_dmraid "$devpath"; then
885                         return
886                 fi
887                 # fallback
888         fi
889
890         if is_yes "$(echo "$devpath" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')"; then
891                 find_modules_scsi
892                 return
893         fi
894
895         if is_yes "$(echo "$devpath" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }')"; then
896                 find_modules_ide "$devpath"
897                 return
898         fi
899
900         if [[ "$devpath" == /dev/rd/* ]]; then
901                 findmodule "DAC960"
902                 return
903         fi
904
905         if [[ "$devpath" == /dev/ida/* ]]; then
906                 findmodule "cpqarray"
907                 return
908         fi
909
910         if [[ "$devpath" == /dev/ccis/* ]]; then
911                 findmodule "cciss"
912                 return
913         fi
914
915         if [[ "$devpath" == /dev/ataraid/* ]]; then
916                 find_modules_ide
917                 findmodule "ataraid"
918                 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
919                 if [ -n "$ataraidmodules" ]; then
920                         # FIXME: think about modules compiled in kernel
921                         die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
922                 fi
923                 for n in $ataraidmodules; do
924                         findmodule "$n"
925                 done
926                 return
927         fi
928
929         # check to see if we need to set up a loopback filesystem
930         if [[ "$devpath" == /dev/loop*  ]]; then
931                 die "Sorry, root on loop device isn't supported."
932                 # TODO: rewrite for bsp and make nfs ready
933                 if [ ! -x /sbin/losetup ]; then
934                         die "losetup is missing"
935                 fi
936                 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
937                 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
938                         die "The root filesystem is on a $devpath, but there is no magic entry in $fstab for this device. Consult the $PROGRAM man page for more information"
939                 fi
940
941                 line="`awk '/'$key'/ { print $0; }' $fstab`"
942                 loopDev="$(echo $line | awk '{print $3}')"
943                 loopFs="$(echo $line | awk '{print $4}')"
944                 loopFile="$(echo $line | awk '{print $5}')"
945
946                 BASICMODULES="$BASICMODULES -loop"
947                 findmodule "-$loopFs"
948                 BASICMODULES="$BASICMODULES -${loopFs}"
949                 return
950         fi
951
952         if _check_lvm "$devpath"; then
953                 node="$devpath"
954
955                 if [ ! -f /sbin/initrd-lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ]; then
956                         die "root on LVM but /sbin/initrd-lvm, /sbin/lvdisplay and /sbin/pvdisplay not found. Please install lvm(2) and lvm(2)-initrd package and rerun $PROGRAM."
957                 fi
958                 if [ -z "$LVMTOOLSVERSION" ]; then
959                         LVMTOOLSVERSION=$(/sbin/initrd-lvm vgchange --version 2>/dev/null|head -n 1|awk '{gsub("vgchange: Logical Volume Manager ",NIL); gsub("LVM version:     ",NIL); gsub(/\..*/,NIL); print $1}')
960                         if [ -z "$LVMTOOLSVERSION" ]; then
961                                 die "Can't determine LVM tools version. Please set LVMTOOLSVERSION and rerun $PROGRAM."
962                         fi
963                 fi
964                 if [ -z "$PVDEVICES" ]; then
965                         VGVOLUME=$(/sbin/lvdisplay -c "$node" 2> /dev/null | awk -F":" ' { print $2 } ')
966                         PVDEVICES=$(/sbin/pvdisplay -c 2>/dev/null | awk -F":" -v vg="$VGVOLUME" ' BEGIN { devices="" } { if ($2 == vg) { devices = devices " " $1 } } END { print devices } ')
967                 fi
968                 if [ -n "$PVDEVICES" ]; then
969                         for device in $PVDEVICES; do
970                                 find_modules_for_devpath $device
971                         done
972                 else
973                         die "I wasn't able to find PV (via lvdisplay and pvdisplay). You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
974                 fi
975                 if [ "$LVMTOOLSVERSION" = "2" ]; then
976                         findmodule "-dm-mod"
977                 elif [ "$LVMTOOLSVERSION" = "1" ]; then
978                         findmodule "-lvm"
979                         findmodule "-lvm-mod"
980                 else
981                         die "LVM version $LVMTOOLSVERSION is not supported yet."
982                 fi
983                 debug "LVM v$LVMTOOLSVERSION enabled"
984                 have_lvm=yes
985                 return
986         fi
987 }
988
989 firmware_install_module() {
990         local module="$1"
991         local firmware_files="$2"
992
993         debug "Adding Firmwares ($firmware_files) to initrd for module $module"
994         # firmware not yet installed
995         if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
996                 inst_d /lib/firmware
997 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
998 #!/bin/sh -e
999 echo 1 > /sys$DEVPATH/loading
1000 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
1001 echo 0 > /sys$DEVPATH/loading
1002 exit 0
1003 EOF
1004                 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
1005         fi
1006
1007         for firmware in $firmware_files; do
1008                 inst /lib/firmware/$firmware /lib/firmware/$firmware
1009         done
1010
1011         mount_sys
1012         echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
1013 }
1014
1015 modules_install() {
1016         local modules="$1"
1017         local mod
1018
1019         for mod in $modules; do
1020                 MODULEDIR=$(dirname "$mod")
1021                 inst_d "/lib/modules/$kernel/$MODULEDIR"
1022                 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
1023                 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
1024         done
1025 }
1026
1027 modules_add_linuxrc() {
1028         local modules="$1"
1029         local mod
1030
1031         for mod in $modules; do
1032                 MODULE2="`dirname "$mod"`"
1033                 NAME2=`basename "$mod" .gz`
1034                 MODULE2=$MODULE2/$NAME2
1035                 module="`echo $mod | awk -F/ '{ $0=$NF } /'$modext'.*$/ { gsub(/'$modext'.*/, NIL, $0); } { print $0; }'`"
1036                 options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
1037
1038                 generic_module=$(echo "${module}" | awk ' { gsub("-", "_", $0) } { print $0; } ')
1039                 sleep_var="$(eval echo \$MODULE_${generic_module}_USLEEP)"
1040                 firmware_var="$(eval echo \$MODULE_${generic_module}_FIRMWARE)"
1041
1042                 if [ -n "$verbose" ]; then
1043                         warn "Loading module [$module]${options:+ with options [$options]}${options:- without options}${sleep_var:+ and $sleep_var usleep}."
1044                 fi
1045
1046                 if [ -n "$firmware_var" ]; then
1047                         firmware_install_module "$module" "$firmware_var"
1048                 fi
1049                 echo "$insmod /lib/modules/$kernel/$MODULE2 $options" | add_linuxrc
1050                 if [ -n "${sleep_var}" ]; then
1051                         echo "usleep $sleep_var" | add_linuxrc
1052                 fi
1053         done
1054 }
1055
1056 initrd_gen_suspend() {
1057         if [ ! -x /usr/${_lib}/suspend/resume -a ! -x /usr/sbin/resume ]; then
1058                 die "/usr/${_lib}/suspend/resume is missing!"
1059         fi
1060         resume_dev="$(awk '/^resume device =/ { print $4 } ' /etc/suspend.conf)"
1061         mknod $DESTDIR/dev/snapshot c 10 231
1062         inst $resume_dev /dev
1063         inst /etc/suspend.conf /etc/suspend.conf
1064         if [ -x /usr/${_lib}/suspend/resume ]; then
1065                 inst /usr/${_lib}/suspend/resume /bin/resume
1066         else
1067                 inst /usr/sbin/resume /bin/resume
1068         fi
1069
1070         add_linuxrc <<-'EOF'
1071         resume
1072         EOF
1073 }
1074
1075 initrd_gen_tuxonice() {
1076         mount_sys
1077         add_linuxrc <<-'EOF'
1078                 resume2=no
1079                 for arg in $CMDLINE; do
1080                         if [ "${arg##resume2=}" != "${arg}" ]; then
1081                                 resume2=yes
1082                         fi
1083                 done
1084                 if [ "$resume2" = "yes" ]; then
1085                         [ -e /proc/suspend2/do_resume ] && echo > /proc/suspend2/do_resume
1086                         [ -e /sys/power/suspend2/do_resume ] && echo > /sys/power/suspend2/do_resume
1087                         [ -e /sys/power/tuxonice/do_resume ] && echo > /sys/power/tuxonice/do_resume
1088                 fi
1089         EOF
1090 }
1091
1092 initrd_gen_udev() {
1093         debug "Setting up udev..."
1094         inst_d /sbin /etc/udev
1095
1096         if [ ! -x /sbin/initrd-udevd ]; then
1097                 die "/sbin/initrd-udevd not present"
1098         fi
1099
1100         inst /sbin/initrd-udevd /sbin/udevd
1101         inst /etc/udev/udev.conf /etc/udev/udev.conf
1102
1103         mount_dev
1104         mount_sys
1105         add_linuxrc <<-'EOF'
1106                 : 'Starting udev'
1107                 /sbin/udevd --daemon
1108         EOF
1109         if is_yes "$PROBESTATICMODS"; then
1110                 inst /sbin/initrd-udevtrigger /sbin/udevtrigger
1111                 inst /sbin/initrd-udevsettle /sbin/udevsettle
1112                 add_linuxrc <<-'EOF'
1113                         /sbin/udevtrigger
1114                         /sbin/udevsettle
1115                 EOF
1116         fi
1117
1118         busybox_applet killall
1119         add_linuxrc     <<-'EOF'
1120                 killall udevd
1121         EOF
1122 }
1123
1124 initrd_gen_multipath() {
1125         inst_d /sbin /lib/udev /etc/multipath
1126         inst_exec /sbin/kpartx /sbin
1127         inst_exec /sbin/multipath /sbin
1128         # for udev callouts
1129         inst_exec /sbin/scsi_id /lib/udev
1130         inst_exec /sbin/mpath* /sbin
1131         egrep -v '^([   ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
1132
1133         if [ -f /etc/multipath/bindings ]; then
1134                 egrep -v '^([   ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
1135         else
1136                 touch $DESTDIR/etc/multipath/bindings
1137         fi
1138
1139         mount_dev
1140         initrd_gen_devices
1141
1142         mount_sys
1143         echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
1144         add_linuxrc <<-'EOF'
1145                 # parse mpath_wwid= from kernel commandline
1146                 for arg in $CMDLINE; do
1147                         if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
1148                                 MPATH_WWID=${arg##mpath_wwid=}
1149                                 if [ "$MPATH_WWID" = "*" ]; then
1150                                         # '*' would mean activate all WWID-s
1151                                         MPATH_WWID=
1152                                         echo "multipath: Activating all WWID-s"
1153                                 else
1154                                         echo "multipath: Activating WWID=$WWID"
1155                                 fi
1156                         fi
1157                 done
1158
1159                 debugshell
1160                 /sbin/multipath -v 0 $MPATH_WWID
1161
1162                 for a in /dev/mapper/*; do
1163                         [ $a = /dev/mapper/control ] && continue
1164                         /sbin/kpartx -a -p p $a
1165                 done
1166                 debugshell
1167         EOF
1168 }
1169
1170 initrd_gen_dmraid() {
1171         if [ ! -x /sbin/dmraid-initrd ]; then
1172                 die "/sbin/dmraid-initrd is missing!"
1173         fi
1174
1175         inst_d /sbin
1176         inst /sbin/dmraid-initrd /sbin/dmraid
1177
1178         mount_dev
1179         mount_sys
1180         initrd_gen_devices
1181         add_linuxrc <<-EOF
1182                 # 2 secs was enough for my system to initialize. but really this is udev issue?
1183                 usleep 2000000
1184                 : 'Activating Device-Mapper RAID(s)'
1185                 /sbin/dmraid -ay -i
1186
1187                 debugshell
1188         EOF
1189 }
1190
1191 initrd_gen_bootsplash() {
1192         local target="$1"
1193
1194         debug "Generating bootsplash"
1195
1196         if [ "$INITRDFS" != "initramfs" ]; then
1197                 warn "Using bootsplash requires INITRDFS=initramfs; skipping bootsplash generation"
1198                 return
1199         fi
1200
1201         if [ ! -x /bin/splash.bin ]; then
1202                 warn "Failed to execute /bin/splash.bin. Is bootsplash package installed?"
1203                 return
1204         fi
1205
1206         if [ -r /etc/sysconfig/bootsplash ]; then
1207                 . /etc/sysconfig/bootsplash
1208         fi
1209
1210         if [ -z "$THEME" ]; then
1211                 warn "Please configure your /etc/sysconfig/bootsplash first."
1212                 warn "Generating bootsplashes skipped."
1213                 return
1214         fi
1215
1216         if [ -z "$BOOT_SPLASH_RESOLUTIONS" ]; then
1217                 warn "No BOOT_SPLASH_RESOLUTIONS specified in /etc/sysconfig/bootsplash."
1218                 warn "Not adding bootsplash to initrd."
1219         fi
1220
1221         for res in $BOOT_SPLASH_RESOLUTIONS; do
1222                 if [ -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" ]; then
1223                         /bin/splash.bin -s -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" >> "$target" && \
1224                         debug "Added $res $THEME theme to initrd."
1225                 else
1226                         warn "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg doesn't exist, skipped"
1227                 fi
1228         done
1229 }
1230
1231 initrd_gen_fbsplash() {
1232         debug "Generating fbsplash"
1233
1234         if [ "$INITRDFS" != "initramfs" ]; then
1235                 warn "Using fbsplash requires INITRDFS=initramfs; skipping fbsplash generation"
1236                 return
1237         fi
1238
1239         if [ ! -x /usr/bin/splash_geninitramfs ]; then
1240                 warn "Failed to execute /usr/bin/splash_geninitramfs. Is splashutils package installed?"
1241                 return
1242         fi
1243
1244         if [ -r /etc/sysconfig/fbsplash ]; then
1245                 . /etc/sysconfig/fbsplash
1246         fi
1247
1248         if [ -z "$SPLASH_THEME" ]; then
1249                 warn "Please configure your /etc/sysconfig/fbsplash first."
1250                 warn "Generating fbsplashes skipped."
1251                 return
1252         fi
1253
1254         if [ -z "$FB_SPLASH_RESOLUTIONS" ]; then
1255                 warn "No FB_SPLASH_RESOLUTIONS specified in /etc/sysconfig/fbsplash."
1256                 warn "Not adding fbsplash to initramfs."
1257                 return
1258         fi
1259
1260         for res in $FB_SPLASH_RESOLUTIONS; do
1261                 if [ -f "/etc/splash/$SPLASH_THEME/$res.cfg" ]; then
1262                         /usr/bin/splash_geninitramfs -c $DESTDIR -r $res $SPLASH_THEME && \
1263                         debug "Added $res $SPLASH_THEME theme to initramfs."
1264                 else
1265                         warn "/etc/splash/$SPLASH_THEME/$res.cfg doesn't exist, skipped"
1266                 fi
1267         done
1268 }
1269
1270 # Generates /dev nodes based on /proc/partitions information.
1271 # Needs /proc mounted.
1272 # Can be called multiple times.
1273 initrd_gen_devices() {
1274         if is_yes "$proc_partitions"; then
1275                 return
1276         fi
1277         proc_partitions=yes
1278
1279         mount_dev
1280         add_linuxrc <<-'EOF'
1281                 : 'Making device nodes'
1282                 cat /proc/partitions | (
1283                         # ignore first two lines, header, empty line and process rest
1284                         read b; read b
1285
1286                         while read major minor blocks dev rest; do
1287                                 node=/dev/$dev
1288                                 mkdir -p ${node%/*}
1289                                 mknod $node b $major $minor
1290                         done
1291                 )
1292         EOF
1293 }
1294
1295 initrd_gen_md() {
1296         debug "Setting up mdadm..."
1297
1298         if [ ! -x /sbin/mdadm -o ! -x /sbin/initrd-mdassemble ]; then
1299                 die "/sbin/mdadm or /sbin/initrd-mdassemble is missing!"
1300         fi
1301
1302         inst /sbin/initrd-mdassemble /bin/mdassemble
1303
1304         # LVM on RAID case
1305         dev_list_extra=$(awk '/^DEVICE / { for (i=2; i<=NF; i++) { printf "%s ", $i; }; } ' /etc/mdadm.conf)
1306         for ex_dev in $dev_list_extra; do
1307                 echo "DEVICE $ex_dev" >> "$DESTDIR/etc/mdadm.conf"
1308         done
1309         do_md0=1
1310         for nr in `seq 1 $rootdev_nr`; do
1311                 eval cr_rootdev="\$rootdev${nr}"
1312                 eval cr_dev_list="\$dev_list${nr}"
1313                 debug echo "Setting up array ($cr_rootdev = $cr_dev_list)"
1314
1315                 [ "$cr_rootdev" = "/dev/md0" ] && do_md0=0
1316
1317                 echo "DEVICE $cr_dev_list" >> "$DESTDIR/etc/mdadm.conf"
1318                 cr_dev_list_md="$(echo "$cr_dev_list" | xargs | awk ' { gsub(/ +/,",",$0); print $0; }')"
1319                 cr_md_conf=$(/sbin/mdadm --detail --brief --config=/etc/mdadm.conf $cr_rootdev | awk ' { gsub(/spares=[0-9]+/, "", $0); print $0; }')
1320                 if [ -n "$cr_md_conf" ]; then
1321                         echo "$cr_md_conf" >> "$DESTDIR/etc/mdadm.conf"
1322                 else
1323                         echo "ARRAY $cr_rootdev devices=$cr_dev_list_md" >> "$DESTDIR/etc/mdadm.conf"
1324                 fi
1325
1326                 for f in $cr_dev_list $cr_rootdev $dev_list_extra; do
1327                         # mkdir in case of devfs name
1328                         inst_d $(dirname $f)
1329                         [ -e "$DESTDIR/$f" ] && continue
1330                         # this works fine with and without devfs
1331                         inst $f $f
1332                 done
1333         done
1334
1335         echo "mdassemble" | add_linuxrc
1336
1337         # needed to determine md-version
1338         if [ "$do_md0" -eq 1 ]; then
1339                 mknod $DESTDIR/dev/md0 b 9 0
1340         fi
1341 }
1342
1343 initrd_gen_nfs() {
1344         # use root=/dev/ram0 init=/linuxrc when starting kernel or you will
1345         # have problems like init(XX) being child process of swapper(1).
1346         debug "Adding rootfs on NFS support to initrd (dhcp)"
1347         mknod "$DESTDIR/dev/urandom" c 1 9
1348         mkdir "$DESTDIR/newroot"
1349         mkdir "$DESTDIR/proc"
1350         echo "ifconfig lo 127.0.0.1 up" | add_linuxrc
1351         echo "route add -net 127.0.0.0 netmask 255.0.0.0 lo" | add_linuxrc
1352         echo "ifconfig eth0 0.0.0.0 up" | add_linuxrc
1353         echo "udhcpc -i eth0 -f -q -s /bin/setdhcp" | add_linuxrc
1354
1355         cat <<-'EOF' > "$DESTDIR/bin/setdhcp"
1356                 #!/bin/sh
1357                 [ "$1" != "bound" ] && exit
1358                 [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
1359                 [ -n "$subnet" ] && NETMASK="netmask $subnet"
1360                 ifconfig $interface $ip $BROADCAST $NETMASK up
1361                 if [ -n "$router" ]; then
1362                         for r in $router; do
1363                                 route add default gw $r dev $interface
1364                         done
1365                 fi
1366         EOF
1367
1368         cat <<-'EOF' > "$DESTDIR/bin/setdhcp"
1369                 for o in $CMDLINE; do
1370                         case $o in
1371                         nfsroot=*)
1372                                 rootpath=${o#nfsroot=}
1373                                 ;;
1374                         esac
1375                 done
1376
1377                 if [ -n "$rootpath" ]; then
1378                         mount -n -t nfs -o ro,nolock,posix,tcp,wsize=8192,rsize=8192 $rootpath /newroot
1379                 else
1380                         echo "Missing rootpath in what DHCP server sent to us. Failing..."
1381                         echo "All seen variables are listed below:"
1382                         set
1383                 fi
1384         EOF
1385
1386         chmod 755 "$DESTDIR/bin/setdhcp"
1387         add_linuxrc <<-'EOF'
1388                 cd /newroot
1389                 pivot_root . initrd
1390                 [ -x /sbin/chroot ] && exec /sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1
1391                 exec /usr/sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1
1392         EOF
1393 }
1394
1395 initrd_gen_lvm() {
1396         debug "Adding LVM support to initrd"
1397         inst_d /tmp /newroot
1398         inst /sbin/initrd-lvm /bin/lvm.static
1399
1400         # always make /dev on tmpfs for LVM2
1401         if [ "$LVMTOOLSVERSION" = "2" ]; then
1402                 mount_dev
1403         fi
1404
1405         if ! is_yes "$dev_mounted"; then
1406                 inst_d /dev/mapper
1407                 mknod $DESTDIR/dev/mapper/control c 10 63
1408                 for device in $PVDEVICES; do
1409                         # if LVM on RAID then device might be copied already in gen_md
1410                         [ -e "$DESTDIR/dev/$(basename $device)" ] && continue
1411                         inst $device /dev
1412                 done
1413         fi
1414
1415         mount_tmp
1416         if [ "$LVMTOOLSVERSION" = "1" ]; then
1417                 add_linuxrc <<-EOF
1418                         lvm vgscan -T
1419                         lvm vgchange -T -a y $VGVOLUME
1420                 EOF
1421         else
1422                 echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
1423                 echo "global {" > "$DESTDIR/etc/lvm.conf"
1424                 echo "  locking_type = 0" >> "$DESTDIR/etc/lvm.conf"
1425                 echo "  locking_dir = \"/tmp\"" >> "$DESTDIR/etc/lvm.conf"
1426                 echo "}" >> "$DESTDIR/etc/lvm.conf"
1427                 echo "devices {" >> "$DESTDIR/etc/lvm.conf"
1428                 echo "  sysfs_scan=0" >> "$DESTDIR/etc/lvm.conf"
1429                 if is_yes "$have_md"; then
1430                         echo "  md_component_detection = 1" >> "$DESTDIR/etc/lvm.conf"
1431                 fi
1432                 if is_yes "$have_dmraid" || is_yes "$have_multipath"; then
1433                         echo '  types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf"
1434                 fi
1435                 if [ "$lvm_ignore_devices" ]; then
1436                         # TODO: think of merging with lvm dumpconfig output
1437                         echo '  filter = [' >> "$DESTDIR/etc/lvm.conf"
1438                         local dev
1439                         for dev in $lvm_ignore_devices; do
1440                                 debug "LVM v2: ignore device $dev"
1441                                 printf '  "r|^%s.*|",\n' $dev
1442                         done >> "$DESTDIR/etc/lvm.conf"
1443                         echo ']' >> "$DESTDIR/etc/lvm.conf"
1444                 fi
1445                 # XXX filter= must be on one line!
1446                 lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
1447                 echo "}" >> "$DESTDIR/etc/lvm.conf"
1448
1449                 initrd_gen_devices
1450
1451                 add_linuxrc <<-EOF
1452                         export ROOTDEV=$rootdev
1453                         export VGVOLUME=$VGVOLUME
1454                 EOF
1455                 add_linuxrc <<-'EOF'
1456                         # parse rootdev from kernel commandline
1457                         for arg in $CMDLINE; do
1458                                 if [ "${arg##root=}" != "${arg}" ]; then
1459                                         local rdev=${arg##root=}
1460                                         if [ "$rdev" != "$ROOTDEV" ]; then
1461                                                 ROOTDEV=$rdev
1462                                                 echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
1463                                                 local tmp=${ROOTDEV#/dev/}
1464                                                 if [ "$tmp" != "$ROOTDEV" ]; then
1465                                                         VGVOLUME=${tmp%/*}
1466                                                         echo "LVM: Using Volume Group '$VGVOLUME'"
1467                                                 fi
1468                                         fi
1469                                 fi
1470                         done
1471
1472                         # disable noise from LVM accessing devices that aren't ready.
1473                         read printk < /proc/sys/kernel/printk
1474                         echo 0 > /proc/sys/kernel/printk
1475
1476                         export LVM_SYSTEM_DIR=/tmp
1477                         : 'Scanning for Volume Groups'
1478                         lvm.static vgscan --mknodes --ignorelockingfailure 2>/dev/null
1479
1480                         : 'Activating Volume Groups'
1481                         lvm.static vgchange --ignorelockingfailure -a y $VGVOLUME 2>/dev/null
1482
1483                         echo "$printk" > /proc/sys/kernel/printk
1484
1485                         # Find out major/minor
1486                         attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV 2>/dev/null)"
1487                         if [ "$attrs" ]; then
1488                                 majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
1489                                 if [ "$majmin" != "$attrs" ]; then
1490                                         major="${majmin%:*}"
1491                                         minor="${majmin#*:}"
1492                                 fi
1493                         fi
1494
1495                         if [ "$major" -a "$minor" ]; then
1496                                 # Pass it to kernel
1497                                 echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
1498                         else
1499                                 echo 2>&1 "Error figuring out real root device for $ROOTDEV!"
1500                                 echo 2>&1 "System will not most likely boot up! So dropping you to a shell!"
1501                                 echo 2>&1 ""
1502                                 sh
1503                         fi
1504                 EOF
1505         fi
1506 }
1507
1508 initrd_gen_procdata() {
1509         debug "Adding rootfs finding based on kernel cmdline root= option support."
1510         add_linuxrc <<-'EOF'
1511                 root="$(echo "$CMDLINE" | busybox awk ' /root=\/dev\// { gsub(/.*root=\/dev\//,NIL,$0); gsub(/ .*/,NIL,$0); print $0; } ')"
1512                 if [ -n "$root" ]; then
1513                         rootnr="$(busybox awk -v root="$root" ' { if ($4 == root) { print 256*$1+$2; } } ' /proc/partitions)"
1514                         if [ -n "$rootnr" ]; then
1515                                 echo "$rootnr" > /proc/sys/kernel/real-root-dev
1516                         fi
1517                 fi
1518         EOF
1519 }
1520
1521 # main()
1522 if [ "$(id -u)" != 0 ]; then
1523         die "You need to be root to generate initrd"
1524 fi
1525
1526 if [ -f /etc/udev/udev.conf -a -x /sbin/initrd-udevd ]; then
1527         USE_UDEV=yes
1528         . /etc/udev/udev.conf
1529 fi
1530
1531 if [ -x /sbin/dmraid-initrd ]; then
1532         USE_DMRAID=yes
1533 fi
1534
1535 if [ -x /sbin/multipath ]; then
1536         USE_MULTIPATH=yes
1537 fi
1538
1539 if [ -r /etc/sysconfig/geninitrd ]; then
1540         . /etc/sysconfig/geninitrd
1541 fi
1542
1543 if [ ! -x /bin/initrd-busybox ]; then
1544         die "/bin/initrd-busybox is missing!"
1545 fi
1546
1547 # backwards compatible
1548 if [ "$USE_SUSPEND2" ]; then
1549         USE_TUXONICE=$USE_SUSPEND2
1550         warn "USE_SUSPEND2 is deprecated, use USE_TUXONICE now instead."
1551 fi
1552
1553 while [ $# -gt 0 ]; do
1554         case $1 in
1555         --fstab=*)
1556                 fstab=${1#--fstab=}
1557                 ;;
1558         --fstab)
1559                 fstab=$2
1560                 shift
1561                 ;;
1562         --modules-conf=*)
1563                 modulefile=${1#--modules-conf=}
1564                 ;;
1565         --modules-conf)
1566                 modulefile=$2
1567                 shift
1568                 ;;
1569         --use-raidstart|--with-raidstart)
1570                 USERAIDSTART=yes
1571                 ;;
1572         --without-raidstart)
1573                 USERAIDSTART=no
1574                 ;;
1575         --use-insmod-static|--with-insmod-static)
1576                 USEINSMODSTATIC=yes
1577                 ;;
1578         --without-insmod-static)
1579                 USEINSMODSTATIC=no
1580                 ;;
1581         --with-bootsplash)
1582                 BOOT_SPLASH=yes
1583                 ;;
1584         --without-bootsplash)
1585                 BOOT_SPLASH=no
1586                 ;;
1587         --with-fbsplash)
1588                 FB_SPLASH=yes
1589                 ;;
1590         --without-fbsplash)
1591                 FB_SPLASH=no
1592                 ;;
1593         --with-suspend)
1594                 USE_SUSPEND=yes
1595                 ;;
1596         --without-suspend)
1597                 USE_SUSPEND=no
1598                 ;;
1599         --with-suspend2 | --with-tuxonice)
1600                 USE_TUXONICE=yes
1601                 ;;
1602         --without-suspend2 | --without-tuxonice)
1603                 USE_TUXONICE=no
1604                 ;;
1605         --lvmtoolsversion=|--lvmversion=)
1606                 LVMTOOLSVERSION="`echo $1 | awk -F= '{print $2;}'`"
1607                 ;;
1608         --lvmtoolsversion|--lvmversion)
1609                 LVMTOOLSVERSION=$2
1610                 shift
1611                 ;;
1612         --without-udev)
1613                 USE_UDEV=no
1614                 ;;
1615         --with-udev)
1616                 USE_UDEV=yes
1617                 ;;
1618         --without-dmraid)
1619                 USE_DMRAID=no
1620                 ;;
1621         --without-multipath)
1622                 USE_MULTPATH=no
1623                 ;;
1624         --with=*)
1625                 BASICMODULES="$BASICMODULES ${1#--with=}"
1626                 ;;
1627         --with)
1628                 BASICMODULES="$BASICMODULES $2"
1629                 shift
1630                 ;;
1631         --version)
1632                 echo "$PROGRAM: version $VERSION"
1633                 exit 0
1634                 ;;
1635         -v)
1636                 verbose=-v
1637                 ;;
1638         --nocompress)
1639                 COMPRESS=no
1640                 ;;
1641         --ifneeded)
1642                 ifneeded=1
1643                 ;;
1644         -f)
1645                 force=1
1646                 ;;
1647         --preload=*)
1648                 PREMODS="$PREMODS ${1#--preload=}"
1649                 ;;
1650         --preload)
1651                 PREMODS="$PREMODS $2"
1652                 shift
1653                 ;;
1654         --fs=*)
1655                 warn "Warning: --fs option is obsoleted. Use --initrdfs instead"
1656                 INITRDFS=${1#--fs=}
1657                 ;;
1658         --fs)
1659                 warn "Warning: --fs option is obsoleted. Use --initrdfs instead"
1660                 INITRDFS=$2
1661                 shift
1662                 ;;
1663         --initrdfs=*)
1664                 INITRDFS=${1#--initrdfs=}
1665                 ;;
1666         --initrdfs)
1667                 INITRDFS=$2
1668                 shift
1669                 ;;
1670         --image-version)
1671                 img_vers=yes
1672                 ;;
1673         --ide-only-root)
1674                 ide_only_root="yes"
1675                 ;;
1676         *)
1677                 if [ -z "$target" ]; then
1678                         target="$1"
1679                 elif [ -z "$kernel" ]; then
1680                         kernel="$1"
1681                 else
1682                         usage
1683                 fi
1684                 ;;
1685         esac
1686
1687         shift
1688 done
1689
1690 if [ -z "$target" -o -z "$kernel" ]; then
1691         usage
1692 fi
1693
1694 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1695         warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1696 fi
1697
1698 pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
1699 pack_version_long="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}'`"
1700
1701 if [ -z "$INITRDFS" ]; then
1702         if [ -z "$FS" ]; then
1703                 # default value
1704                 if [ "$pack_version" -ge "002005" ]; then
1705                         INITRDFS="initramfs"
1706                 else
1707                         INITRDFS="rom"
1708                 fi
1709         else
1710                 warn "Warning: FS configuration options is obsoleted. Use INITRDFS instead"
1711                 INITRDFS="$FS"
1712         fi
1713 fi
1714
1715 if [ "$pack_version" -lt "002006" ]; then
1716         USE_UDEV=no
1717         USE_DMRAID=no
1718 fi
1719
1720 if [ "$pack_version" -ge "002005" ]; then
1721         modext=".ko"
1722         insmod="insmod"
1723 fi
1724
1725 if is_yes "$USEINSMODSTATIC"; then
1726         insmod="insmod.static"
1727         INSMOD="/sbin/insmod.static"
1728         if [ "$pack_version" -lt "002005" -a -f /sbin/insmod.static.modutils ]; then
1729                 INSMOD="/sbin/insmod.static.modutils"
1730         fi
1731         if [ ! -f "$INSMOD" ]; then
1732                 die "insmod.static requested but /sbin/insmod.static not found!"
1733         fi
1734 fi
1735
1736 case "$INITRDFS" in
1737         ext2)
1738                 if [ ! -x /sbin/mke2fs ]; then
1739                         die "/sbin/mke2fs is missing"
1740                 fi
1741                 ;;
1742         rom|romfs)
1743                 if [ ! -x /sbin/genromfs ]; then
1744                         die "/sbin/genromfs is missing"
1745                 fi
1746                 ;;
1747         cram|cramfs)
1748                 if [ ! -x /sbin/mkcramfs ]; then
1749                         die "/sbin/mkcramfs is missing"
1750                 fi
1751                 ;;
1752         initramfs)
1753                 if [ ! -x /bin/cpio ]; then
1754                         die "/bin/cpio is missing"
1755                 fi
1756                 if [ ! -x /usr/bin/find ]; then
1757                         die "/usr/bin/find is missing"
1758                 fi
1759                 ;;
1760         *)
1761                 die "Filesystem $INITRDFS on initrd is not supported"
1762                 ;;
1763 esac
1764
1765 if [ -n "$img_vers" ]; then
1766         target="$target-$kernel"
1767 fi
1768
1769 if [ -z "$force" -a -f "$target" ]; then
1770         die "$target already exists."
1771 fi
1772
1773 if [ ! -d "/lib/modules/$kernel" ]; then
1774         die "/lib/modules/$kernel is not a directory."
1775 fi
1776
1777 if is_yes "$USE_SUSPEND" && is_yes "$USE_TUXONICE"; then
1778         warn "Tuxonice can't be used in parallel with mainline suspend! Disabling both inclustion to initrd"
1779         USE_SUSPEND=no
1780         USE_TUXONICE=no
1781 fi
1782
1783 if is_yes "$FB_SPLASH"  && is_yes "$BOOT_SPLASH"; then
1784         warn "You can't use bootsplash and fbsplash together! Disabling both inclusion to initrd"
1785         FB_SPLASH=no
1786         BOOT_SPLASH=no
1787 fi
1788
1789 if [ ! -f /proc/mounts ]; then
1790         warn "WARNING: /proc filesystem not mounted, may cause wrong results or failure."
1791 fi
1792
1793 if [ -d /usr/lib64 ]; then
1794         _lib=lib64
1795 else
1796         _lib=lib
1797 fi
1798 debug "Using libdir: $_lib"
1799
1800 cache_modprobe_conf
1801
1802 for n in $PREMODS; do
1803         findmodule "$n"
1804 done
1805
1806 # allow forcing loading SCSI and/or IDE modules
1807 if is_yes "$ADDSCSI"; then
1808         find_modules_scsi
1809 fi
1810
1811 if is_yes "$ADDIDE"; then
1812         find_modules_ide
1813 fi
1814
1815 find_root "$fstab" || exit
1816 debug "Using $rootdev as device for rootfs"
1817
1818 find_modules_for_devpath "$rootdev"
1819 [ -n "$rootdev_add" ] && find_modules_for_devpath "$rootdev_add"
1820
1821 findmodule "-$rootFs"
1822
1823 for n in $BASICMODULES; do
1824         findmodule "$n"
1825 done
1826
1827 if is_yes "$USE_TUXONICE"; then
1828         findmodule "-lzf"
1829 fi
1830
1831 if is_yes "$FB_SPLASH"; then
1832         findmodule "-evdev"
1833 fi
1834
1835 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1836         debug "No modules are needed -- not building initrd image."
1837         exit 0
1838 fi
1839
1840 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1841 RCFILE="$DESTDIR/linuxrc"
1842 > "$RCFILE"
1843 chmod a+rx "$RCFILE"
1844 ln -s linuxrc $DESTDIR/init
1845
1846 # create dirs that we really need
1847 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,sys}
1848
1849 modules_install "$MODULES"
1850
1851 # mknod'ing the devices instead of copying them works both with and
1852 # without devfs...
1853 mknod "$DESTDIR/dev/console" c 5 1
1854 mknod "$DESTDIR/dev/null" c 1 3
1855 mknod "$DESTDIR/dev/zero" c 1 5
1856
1857 inst /bin/initrd-busybox /bin/initrd-busybox
1858 ln -s initrd-busybox $DESTDIR/bin/sh
1859 ln -s initrd-busybox $DESTDIR/bin/busybox # for older busyboxes who had /bin/busybox as EXEPATH
1860
1861 if is_yes "$USEINSMODSTATIC"; then
1862         inst "$INSMOD" /bin/insmod.static
1863 fi
1864
1865 add_linuxrc <<EOF
1866 #!/bin/sh
1867 # initrd generated by:
1868 # $RCSID
1869
1870 EOF
1871 mount_proc
1872 add_linuxrc <<-'EOF'
1873         read CMDLINE < /proc/cmdline; export CMDLINE
1874
1875         for arg in $CMDLINE; do
1876                 if [ "${arg}" = "debuginitrd" ]; then
1877                         DEBUGINITRD=yes
1878                 fi
1879                 if [ "${arg##debuginitrd=}" != "${arg}" ]; then
1880                         DEBUGINITRD=${arg##debuginitrd=}
1881                 fi
1882         done
1883
1884         # make debugshell() invoke subshell if $DEBUGINITRD=sh
1885         if [ "$DEBUGINITRD" = "sh" ]; then
1886                 debugshell() {
1887                         sh
1888                 }
1889         else
1890                 debugshell() {
1891                         :
1892                 }
1893         fi
1894
1895         if [ "$DEBUGINITRD" ]; then
1896                 set -x
1897         fi
1898 EOF
1899
1900 modules_add_linuxrc "$MODULES"
1901
1902 # TODO: rewrite for busybox
1903 #if [ -n "$loopDev" ]; then
1904 #       if [ ! -d /initrd ]; then
1905 #               mkdir /initrd
1906 #       fi
1907 #
1908 #       cp -a "$loopDev" "$DESTDIR/dev"
1909 #       cp -a "$rootdev" "$DESTDIR/dev"
1910 #       echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1911 #       echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1912 #       echo "echo Setting up loopback device $rootdev" >> $RCFILE
1913 #       echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1914 #fi
1915
1916 if is_yes "$USE_UDEV"; then
1917         initrd_gen_udev
1918 fi
1919
1920 if is_yes "$USE_SUSPEND"; then
1921         initrd_gen_suspend
1922 fi
1923
1924 if is_yes "$USE_TUXONICE"; then
1925         initrd_gen_tuxonice
1926 fi
1927
1928 if is_yes "$have_dmraid" ]; then
1929         initrd_gen_dmraid
1930 fi
1931
1932 if is_yes "$have_multipath"; then
1933         initrd_gen_multipath
1934 fi
1935
1936 if is_yes "$have_nfs"; then
1937         initrd_gen_nfs
1938 elif is_yes "$USERAIDSTART" && is_yes "$have_md"; then
1939         initrd_gen_md
1940         if is_yes "$have_lvm"; then
1941                 initrd_gen_lvm
1942         else
1943                 initrd_gen_procdata
1944         fi
1945 elif is_yes "$have_lvm"; then
1946         initrd_gen_lvm
1947 else
1948         initrd_gen_procdata
1949 fi
1950
1951 # additional devs always needed
1952 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1953
1954 if [ "$INITRDFS" = "initramfs" ]; then
1955         inst_d /newroot
1956         if [ "$rootdev" = "/dev/nfs" ]; then
1957                 echo "rootfs on NFS root=/dev/nfs"
1958         else
1959                 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev /dev
1960         fi
1961         # Parsing root parameter
1962         # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
1963         add_linuxrc <<-'EOF'
1964                 eval "$(busybox awk -v c="$CMDLINE" '
1965                 BEGIN {
1966                         num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
1967                         num_pattern = "[0-9a-f]" num_pattern_short;
1968                         dev_pattern = "[hms][a-z][a-z]([0-9])+";
1969                         partition = "no_partition_found";
1970                         min = -1; maj = -1;
1971
1972                         gsub(/.*root=/,NIL,c);
1973                         gsub(/ .*/,NIL,c);
1974
1975                         sub("^0x", "", c);
1976                         if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
1977                         if (c ~ "^" num_pattern  "$") {
1978                                 maj = sprintf("%s",substr(c,1,2));
1979                                 min = sprintf("%s",substr(c,3));
1980                         }
1981                         if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
1982                         if (c ~ "^" dev_pattern "$") partition = c;
1983                 }
1984
1985                 $4 ~ partition { maj = $1; min = $2; }
1986                 $1 ~ maj && $2 ~ min { partition = $4; }
1987
1988                 END {
1989                         print sprintf("device=/dev/%s\nmaj=%s\nmin=%s",
1990                                 partition, maj, min);
1991                 }
1992                 ' /proc/partitions)"
1993                 if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
1994                         mknod $device b $maj $min
1995                 fi
1996         EOF
1997
1998         add_linuxrc <<-EOF
1999                 rootdev=$rootdev
2000                 rootfs=$rootFs
2001         EOF
2002
2003         add_linuxrc <<-'EOF'
2004                 if [ "$device" = '/dev/no_partition_found' ]; then
2005                         device=$rootdev
2006                 fi
2007
2008                 mount -t $rootfs -r $device /newroot
2009                 init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
2010                 if [ -z "$init" -o ! -x "/newroot$init" ]; then
2011                         init=/sbin/init
2012                 fi
2013         EOF
2014
2015         umount_all
2016         busybox_applet switch_root
2017         add_linuxrc <<-'EOF'
2018                 exec switch_root /newroot $init
2019
2020                 echo "Error! initramfs should not reach this place."
2021                 echo "It probably means you've got old version of busybox, with broken"
2022                 echo "initramfs support. Trying to boot anyway, but won't promise anything."
2023
2024                 exec chroot /newroot $init
2025
2026                 echo "Failed to chroot!"
2027         EOF
2028         # we need /init being real file, not symlink, otherwise the initramfs will
2029         # not be ran by pid 1 which is required for switch_root
2030         mv $DESTDIR/linuxrc $DESTDIR/init
2031         ln -s init $DESTDIR/linuxrc
2032 else
2033         # other than initramfs
2034         umount_all
2035 fi
2036
2037 if is_yes "$FB_SPLASH"; then
2038         initrd_gen_fbsplash
2039 fi
2040
2041 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
2042 case "$INITRDFS" in
2043         ext2)
2044                 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
2045                 debug   "ext2 image size: $IMAGESIZE ($DESTDIR)"
2046                 if [ "$IMAGESIZE" -gt 4096 ]; then
2047                         warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
2048                 fi
2049
2050                 debug "Creating ext2 image $IMAGE"
2051                 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
2052                 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
2053                 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
2054
2055                 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
2056                 debug "Mounting ext2 image $IMAGE to $tmpmnt"
2057                 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
2058                 # We don't need this directory, so let's save space
2059                 rm -rf "$tmpmnt"/lost+found
2060
2061                 debug "Copy recursively $DESTDIR -> $tmpmnt"
2062                 cp -a $DESTDIR/* $tmpmnt
2063                 umount "$IMAGE"
2064                 rmdir "$tmpmnt"
2065
2066                 ;;
2067         rom|romfs)
2068                 debug "Generating romfs image: $IMAGE"
2069                 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD initrd for kernel $kernel"
2070                 IMAGESIZE=$(stat -c %s $IMAGE | awk '{print int((($1/1024)+1023)/1024)*1024}')
2071                 debug "Image size for romfs: ${IMAGESIZE}KiB ($IMAGE)"
2072                 if [ "$IMAGESIZE" -gt 4096 ]; then
2073                         warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
2074                 fi
2075                 ;;
2076         cram|cramfs)
2077                 mkcramfs "$DESTDIR" "$IMAGE"
2078                 ;;
2079         initramfs)
2080                 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
2081                 ;;
2082         *)
2083                 echo "Filesystem $INITRDFS not supported by $PROGRAM";
2084 esac
2085
2086 if is_yes "$COMPRESS"; then
2087         local tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
2088         debug "Compressing $target"
2089         gzip -9 < "$IMAGE" > "$tmp"
2090         mv -f "$tmp" "$target"
2091 else
2092         cp -a "$IMAGE" "$target"
2093 fi
2094
2095 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
2096 if is_yes "$BOOT_SPLASH"; then
2097         initrd_gen_bootsplash "$target"
2098 fi
2099
2100 rm -rf "$DESTDIR" "$IMAGE"
2101
2102 # vim:ts=4:sw=4:noet:fdm=marker
This page took 0.188169 seconds and 3 git commands to generate.