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