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