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