]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
ff0d958535eec7a67ec7106c228f175e00a9d1b3
[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
10 GENINITRD_RCSID='$Revision$ $Date::                            $'
11 R=${GENINITRD_RCSID#* *}; VERSION=${R%% *}
12 PROGRAM=${0##*/}
13
14 . /etc/rc.d/init.d/functions
15 . /lib/geninitrd/functions
16 . /etc/sysconfig/system
17
18 # list of geninitrd modules which need setup routine after commandline args parsing
19 GENINITRD_MODS=""
20 COMPRESS=yes
21 STRIP=/usr/bin/strip
22 target=""
23 kernel=""
24 force=""
25 verbose=""
26 MODULES=""
27 img_vers=""
28 fstab=/etc/fstab
29 modext=.o
30 rootdev_nr=0
31 # device node for rootfs from fstab
32 rootdev=""
33
34 # internal variables
35 # is /dev on tmpfs
36 dev_mounted=no
37 # is /proc mounted
38 proc_mounted=no
39 # is /sys mounted
40 sys_mounted=no
41 # is /tmp mounted on tmpfs
42 tmp_mounted=no
43
44 # are /dev nodes already created from /proc/devices info?
45 proc_partitions=no
46
47 usage() {
48         echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
49         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
50         echo "       [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
51         echo "       [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
52         echo "       [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
53         echo "       [--with-bootsplash] [--without-bootsplash]"
54         echo "       [--with-fbsplash] [--without-fbsplash]"
55         echo "       [--with-fbcondecor] [--without-fbcondecor]"
56         echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
57         echo "       [--with-suspend] [--without-suspend]"
58         echo "       [--with-tuxonice] [--without-tuxonice]"
59         echo "       [--without-dmraid]"
60         echo "       [--with-multipath=DEVPATH] [--without-multipath]"
61         echo "       [--without-blkid] [--without-luks]"
62         echo "       <initrd-image> <kernel-version>"
63         echo ""
64         echo "Example:"
65
66         local kdir kver dir=${target:-/boot}
67         for kdir in /lib/modules/*; do
68                 [ -d $kdir ] || continue
69                 kver=${kdir##*/}
70                 echo "  $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
71         done | sort -V
72 }
73
74 msg() {
75         echo "$PROGRAM: $*"
76 }
77
78 warn() {
79         msg "WARNING: $*" >&2
80 }
81
82 verbose() {
83         [ -n "$verbose" ] && msg "$*" >&3
84 }
85
86 debug() {
87         [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
88 }
89
90 # aborts program abnormally
91 die() {
92         local rc=${2:-1}
93         msg "ERROR: $1" >&2
94         exit $rc
95 }
96
97 # find program from specified paths
98 find_tool() {
99         local x p b n
100         local paths="$initrd_dir /bin /sbin /usr/bin /usr/sbin"
101         for x in "$@"; do
102                 debug "find_tool: checking $x"
103                 if [ -x "$x" ]; then
104                         echo $x
105                         verbose "find_tool: found $x"
106                         return 0
107                 fi
108                 n="$x"
109                 for p in $paths; do
110                         b=$(basename $x)
111                         debug "find_tool: checking $p/$b"
112                         if [ -x "$p/$b" ]; then
113                                 echo $p/$b
114                                 verbose "find_tool: found $p/$b"
115                                 return 0
116                         fi
117                         n="$n $p/$b"
118                 done
119         done
120         debug "find_tool: did not find any of: $n"
121         return 1
122 }
123
124 # loads geninitrd modules
125 geninitrd_load_mods() {
126         local mod
127         for mod in "$@"; do
128                 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
129                         die "$mod geninitrd module can't be loaded"
130                 fi
131                 . /lib/geninitrd/mod-$mod.sh
132
133                 GENINITRD_MODS="$GENINITRD_MODS $mod"
134         done
135 }
136
137 # setup geninitrd modules
138 geninitrd_setup_mods() {
139         local mod rcsid
140
141         for mod in $GENINITRD_MODS; do
142                 eval rcsid=$(echo \$$mod | LC_ALL=C tr '[a-z]' '[A-Z]')_RCSID
143                 debug "# $rcsid (mod-$mod)"
144
145                 # some mods want init
146                 if type setup_mod_$mod > /dev/null; then
147                         eval setup_mod_$mod
148                 fi
149         done
150 }
151
152 # append text to /linuxrc
153 # takes STDIN as input
154 add_linuxrc() {
155         cat >> "$RCFILE"
156 }
157
158 # generate code to mount /dev on tmpfs and create initial nodes
159 # can be called multiple times. /dev is cleaned up (umounted) automatically at
160 # the end of script.
161 mount_dev() {
162         # we already generated tmpfs code; return
163         if is_yes "$dev_mounted"; then
164                 return
165         fi
166
167         dev_mounted=yes
168
169         busybox_applet mount mknod mkdir
170         add_linuxrc <<-EOF
171                 : 'Creating /dev'
172                 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
173                         mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
174                         mknod -m 600 /dev/console c 5 1
175                         mknod -m 666 /dev/null c 1 3
176                         mknod -m 666 /dev/zero c 1 5
177                         mknod -m 666 /dev/random c 1 8
178                         mknod -m 600 /dev/snapshot c 10 231
179                         mknod -m 666 /dev/urandom c 1 9
180                         mknod -m 666 /dev/ptmx c 5 2
181                         mknod -m 644 /dev/kmsg c 1 11
182                 fi
183                 mkdir /dev/pts
184                 mkdir /dev/shm
185         EOF
186 }
187
188 # generate code to mount /proc on initrd
189 # can be called multiple times
190 mount_proc() {
191         if is_yes "$proc_mounted"; then
192                 return
193         fi
194
195         proc_mounted=yes
196     if [ "$INITRDFS" = "initramfs" ]; then
197                 # /proc is mounted with initramfs 2.6.22.14 kernel
198                 # XXX: remove when it is clear why proc was already mounted
199                 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
200         else
201                 echo "mount -t proc none /proc" | add_linuxrc
202         fi
203 }
204
205 # generate code to mount /sys on initrd
206 # can be called multiple times
207 mount_sys() {
208         if is_yes "$sys_mounted"; then
209                 return
210         fi
211
212         sys_mounted=yes
213         echo "mount -t sysfs none /sys" | add_linuxrc
214 }
215
216 # generate code to mount /tmp on initrd
217 # can be called multiple times
218 mount_tmp() {
219     if [ "$INITRDFS" = "initramfs" ]; then
220                 # initramfs is read-write filesystem, no need for tmpfs
221                 return
222         fi
223
224         if is_yes "$tmp_mounted"; then
225                 return
226         fi
227
228         tmp_mounted=yes
229         echo "mount -t tmpfs none /tmp" | add_linuxrc
230 }
231
232 # generate code to mount /run on initrd
233 # can be called multiple times
234 mount_run() {
235         if is_yes "$run_mounted"; then
236                 return
237         fi
238
239         run_mounted=yes
240         echo "mount -t tmpfs run /run" | add_linuxrc
241 }
242
243 # unmount all mountpoints mounted by geninitrd
244 # try to move pseudo filesystems to newroot if possible
245 umount_all() {
246
247         add_linuxrc <<-'EOF'
248         : Last shell before umounting all and giving control over to real init.
249         debugshell
250         EOF
251
252         if is_yes "$run_mounted"; then
253                 add_linuxrc <<-EOF
254                 mount --bind /run /newroot/run
255                 umount /run
256                 EOF
257                 run_mounted=no
258         fi
259         if is_yes "$dev_mounted"; then
260                 add_linuxrc <<-EOF
261                 mount --bind /dev /newroot/dev
262                 umount /dev
263                 EOF
264                 dev_mounted=no
265         fi
266         if is_yes "$sys_mounted"; then
267                 add_linuxrc <<-EOF
268                 mount --bind /sys /newroot/sys
269                 umount /sys
270                 EOF
271                 sys_mounted=no
272         fi
273         if is_yes "$proc_mounted"; then
274                 add_linuxrc <<-EOF
275                 mount --bind /proc /newroot/proc
276                 umount /proc
277                 EOF
278                 proc_mounted=no
279         fi
280         if is_yes "$tmp_mounted"; then
281                 echo 'umount /tmp' | add_linuxrc
282                 tmp_mounted=no
283         fi
284 }
285
286 # Checks if busybox has support for APPLET(s)
287 # Exits from geninitrd if the support is not present.
288 #
289 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
290 busybox_applet() {
291         local err=0 applet
292
293         if [ -z "$busybox_functions" ]; then
294                 local tmp=$($busybox 2>&1)
295
296                 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
297                 if [[ "$tmp" = *applet\ not\ found* ]]; then
298                         local t=$(mktemp -d)
299                         ln -s $busybox $t/busybox
300                         local tmp=$($t/busybox 2>&1)
301                         rm -rf $t
302                 fi
303
304                 busybox_functions=$(echo "$tmp" | \
305                         sed -ne '/Currently defined functions:/,$p' | \
306                         xargs | sed -e 's,.*Currently defined functions: ,,'
307                 )
308         fi
309         for applet in $*; do
310                 local have
311                 # try cache
312                 eval have='$'busybox_have_$applet
313                 if [ -z "$have" ]; then
314                         have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
315                         if [ "$have" = 0 ]; then
316                                 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
317                                 err=1
318                         fi
319                         eval busybox_have_$applet=$have
320                 fi
321         done
322         if [ $err = 1 ]; then
323                 die "Aborted"
324         fi
325 }
326
327 # Extract the .config file from a kernel image
328 # uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
329 ikconfig() {
330         local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
331         if [ -n "$kofile" ]; then
332                 /lib/geninitrd/extract-ikconfig $kofile
333                 return
334         fi
335
336         # see if config available as separate file
337         if [ -f /boot/config-$kernel ]; then
338            cat /boot/config-$kernel
339            return
340         fi
341
342         # finally try vmlinuz itself
343         /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
344 }
345
346 # @param    $module
347 basename_module() {
348         local module=$1
349
350         module=${module##*/}
351         module=${module%$modext*}
352         echo $module
353 }
354
355 # Finds module dependencies
356 #
357 # @param        $module
358 #
359 # Outputs full path to module and it's dependencies
360 find_depmod() {
361         local module="$1"
362         local skiperrors=0
363
364         # if module is prefixed with dash, we should ignore errors if the module
365         # can't be found.
366         if [ ${module#-} != $module ]; then
367                 skiperrors=1
368                 module=${module#-}
369         fi
370
371         # This works when user has module-init-tools installed even on 2.4 kernels
372         local modprobe
373         modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
374
375         if [ $? != 0 ]; then
376                 if [ $skiperrors = 1 ]; then
377                         return 0
378                 fi
379                 echo >&2 "$modprobe"
380
381                 if ! is_no "$EXIT_IF_MISSING"; then
382                         die "$module: module not found for $kernel kernel"
383                 fi
384
385                 warn "$module: module not found for $kernel kernel"
386                 warn "If $module isn't compiled in kernel then this initrd may not start your system."
387         fi
388
389         local smodule
390
391         echo "$modprobe" | \
392         while read insmod modpath options; do
393                 if [ "$insmod" = "insmod" ]; then
394
395                         # XXX: find a away to autodetect
396                         smodule=$(basename_module $modpath)
397                         case "$smodule" in
398                                 crc-t10dif)
399                                         find_depmod "-crct10dif-pclmul"
400                                         find_depmod "-crct10dif"
401                                         ;;
402                                 libcrc32c)
403                                         find_depmod "-crc32c-intel"
404                                         find_depmod "-crc32c"
405                                         ;;
406                                 virtio_blk|virtio_scsi)
407                                         find_depmod "-virtio_pci"
408                                         find_depmod "-virtio_mmio"
409                                         ;;
410                         esac
411
412                         echo $modpath
413                 fi
414         done
415         return 0
416 }
417
418 find_firmware() {
419         local module="$1"
420
421         # no firmware support in 2.4 kernels
422         if [ "$kernel_version_long" -lt "002005048" ]; then
423                 return
424         fi
425         echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
426 }
427
428 # @param        $module
429 find_module() {
430         local mod depmod module=$1
431
432         depmod=$(find_depmod $module) || exit 1
433         for mod in $depmod; do
434                 mod=${mod#/lib/modules/$kernel/}
435
436                 # add each module only once
437                 local m have=0
438                 for m in $MODULES; do
439                         [ $m = $mod ] && have=1
440                 done
441                 if [ $have = 0 ]; then
442                         MODULES="$MODULES $mod"
443                 fi
444         done
445 }
446
447 # install a file to temporary mount image.
448 # it will operate recursively (copying directories)
449 # and will symlink destinations if source is symlink.
450 inst() {
451         if [ $# -lt 2 ]; then
452                 die 'Usage: inst <file> [<file>] <destination>'
453         fi
454
455         local src i=0 c=$(($# - 1))
456         while [ $i -lt $c ]; do
457                 src="$src $1"
458                 i=$((i + 1))
459                 shift
460         done
461         local dest=$1
462         set -- $src
463         local parentDir=$(dirname $DESTDIR$dest)
464         if [ ! -d "$parentDir" ]; then
465                 verbose "+ mkdir -p $parentDir"
466                 mkdir -p $parentDir
467         fi
468         verbose "+ cp $* $DESTDIR$dest"
469         cp -HR "$@" "$DESTDIR$dest"
470 }
471
472 inst_d() {
473         if [ $# = 0 ]; then
474                 die 'Usage: inst_d <destination> <destination>'
475         fi
476         for dir in "$@"; do
477                 install -d "$DESTDIR$dir"
478         done
479 }
480
481 # install executable and it's shared libraries
482 inst_exec() {
483         if [ $# -lt 2 ]; then
484                 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
485         fi
486         local src i=0 c=$(($# - 1))
487         while [ $i -lt $c ]; do
488                 src="$src $1"
489                 i=$((i + 1))
490                 shift
491         done
492         local dest=$1
493         set -- $src
494
495         inst "$@" $dest
496
497         local obj lib libs
498         for obj in "$@"; do
499                 case "$obj" in
500                         /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
501                         continue
502                 esac
503
504                 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
505                 for lib in $libs; do
506                         if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
507                                 inst_d /$_lib
508                                 inst_exec $lib /$_lib
509                         fi
510                 done
511         done
512
513         # hack for uclibc linked binaries requiring this fixed path
514         # XXX: shouldn't rpath be used here instead so th
515         if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
516                 local lib=$DESTDIR/$_lib/libc.so.0
517                 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
518                 local libdir=$(cd $(dirname "$lib"); pwd)
519                 if [ ! -e $DESTDIR$libdir ]; then
520                         libdir=$(dirname "$libdir")
521                         inst_d $libdir
522                         verbose "+ ln -s /$_lib $DESTDIR$libdir"
523                         ln -s /$_lib $DESTDIR$libdir
524                 fi
525         fi
526 }
527
528 # output modules.conf / modprobe.conf
529 modprobe_conf() {
530         echo "$modprobe_conf_cache"
531 }
532
533 # return options for MODULE
534 # @param $1 module name
535 modprobe_options() {
536         local module=$1
537         local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
538         echo ${options# }
539 }
540
541 #
542 # defaults to modprobe -c if not told otherwise, this means include statements
543 # work from there.
544 cache_modprobe_conf() {
545         if [ "$kernel_version" -lt "002005" ]; then
546                 modulefile=/etc/modules.conf
547                 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
548                         modulefile=/etc/conf.modules
549                 fi
550         fi
551
552         if [ -n "$modulefile" ]; then
553                 debug "Using $modulefile for modules config"
554                 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
555
556         else
557                 debug "Using modprobe -c to get modules config"
558                 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
559         fi
560 }
561
562 # find modules for $devpath
563 find_modules_for_devpath() {
564         local devpath="$1"
565         if [ -z "$devpath" ]; then
566                 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
567         fi
568
569         if [[ "$devpath" = /dev/dm-* ]]; then
570                 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
571                 devpath=$(dm_node "$devpath")
572         fi
573
574         if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
575                 # sanitize things like:
576                 # /dev/block/104:2 -> /dev/cciss/c0d0p2
577                 devpath=$(readlink -f "$devpath")
578         fi
579
580         verbose "Finding modules for device path $devpath"
581
582         if is_luks "$devpath"; then
583                 find_modules_luks "$devpath"
584                 return
585         fi
586
587         if is_nfs "$devpath"; then
588                 find_modules_nfs "$devpath"
589                 return
590         fi
591
592         if is_md "$devpath"; then
593                 find_modules_md "$devpath"
594                 return
595         fi
596
597         if is_multipath "$devpath"; then
598                 if find_modules_multipath "$devpath"; then
599                         return
600                 fi
601
602                 # fallback
603         fi
604
605         if is_dmraid "$devpath"; then
606                 if find_modules_dmraid "$devpath"; then
607                         return
608                 fi
609                 # fallback
610         fi
611
612         if is_scsi "$devpath"; then
613                 find_modules_scsi "$devpath"
614                 return
615         fi
616
617         if is_ide "$devpath"; then
618                 find_modules_ide "$devpath"
619                 return
620         fi
621
622         if [[ "$devpath" == /dev/rd/* ]]; then
623                 find_module "DAC960"
624                 rootdev_add=/dev/rd/
625                 return
626         fi
627
628         if [[ "$devpath" == /dev/ida/* ]]; then
629                 find_module "cpqarray"
630                 rootdev_add=/dev/ida/
631                 return
632         fi
633
634         if [[ "$devpath" == /dev/cciss/* ]]; then
635                 rootdev_add=/dev/cciss/
636
637                 # load hpsa for future kernels, cciss for backwards compat
638                 if [ "$kernel_version_long" -ge "003000000" ]; then
639                         find_module "hpsa" "-cciss"
640                         find_modules_scsi "$devpath"
641                 else
642                         find_module "cciss"
643                 fi
644
645                 return
646         fi
647
648         if [[ "$devpath" == /dev/ataraid/* ]]; then
649                 find_modules_ide
650                 find_module "ataraid"
651                 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
652                 if [ -n "$ataraidmodules" ]; then
653                         # FIXME: think about modules compiled in kernel
654                         die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
655                 fi
656                 for n in $ataraidmodules; do
657                         find_module "$n"
658                 done
659                 rootdev_add=/dev/ataraid/
660                 return
661         fi
662
663         # check to see if we need to set up a loopback filesystem
664         if [[ "$devpath" == /dev/loop*  ]]; then
665                 die "Sorry, root on loop device isn't supported."
666                 # TODO: rewrite for bsp and make nfs ready
667                 if [ ! -x /sbin/losetup ]; then
668                         die "losetup is missing"
669                 fi
670                 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
671                 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
672                         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"
673                 fi
674
675                 line="`awk '/'$key'/ { print $0; }' $fstab`"
676                 loopDev="$(echo $line | awk '{print $3}')"
677                 loopFs="$(echo $line | awk '{print $4}')"
678                 loopFile="$(echo $line | awk '{print $5}')"
679
680                 BASICMODULES="$BASICMODULES -loop"
681                 find_module "-$loopFs"
682                 BASICMODULES="$BASICMODULES -${loopFs}"
683                 return
684         fi
685
686         if is_lvm "$devpath"; then
687                 find_modules_lvm "$devpath"
688                 return
689         fi
690 }
691
692 firmware_install_module() {
693         local module="$1"
694         local firmware_files="$2"
695
696         verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
697         # firmware not yet installed
698         if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
699                 inst_d /lib/firmware
700 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
701 #!/bin/sh -e
702 echo 1 > /sys$DEVPATH/loading
703 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
704 echo 0 > /sys$DEVPATH/loading
705 exit 0
706 EOF
707                 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
708
709                 # setup firmware loader agent
710                 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
711         fi
712
713         for firmware in $firmware_files; do
714                 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
715                         FIRMWAREDIR=${firmware%/*}
716                         [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
717                         inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
718                 elif [ -f "/lib/firmware/$firmware" ]; then
719                         FIRMWAREDIR=${firmware%/*}
720                         [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
721                         inst /lib/firmware/$firmware /lib/firmware/$firmware
722                 else
723                         warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
724                 fi
725         done
726
727         mount_sys
728 }
729
730 modules_install() {
731         local modules="$1"
732         local mod
733
734         for mod in $modules; do
735                 MODULEDIR=${mod%/*}
736                 inst_d "/lib/modules/$kernel/$MODULEDIR"
737                 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
738                 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
739                 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
740                         $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
741                 fi
742         done
743 }
744
745 modules_add_linuxrc() {
746         local mod modpath
747
748         for mod in "$@"; do
749                 # module path without optional compression
750                 modpath=${mod%.gz}
751
752                 # name of the module
753                 local module=${modpath##*/}; module=${module%$modext}
754                 local options=$(modprobe_options "$module")
755                 local genericname=$(echo $module | tr - _)
756                 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
757                 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
758
759                 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
760                         options="scan=sync $options"
761                 fi
762
763                 if [ x"$verbose" = x"-v" ]; then
764                         s=""
765                         if [ "$options" ]; then
766                                 s="$s with options [$options]"
767                         fi
768                         if [ "$usleep" ]; then
769                                 s="$s and $usleep usleep"
770                         fi
771                         verbose "Loading module [$module]$s"
772                 fi
773
774                 if [ -n "$firmware" ]; then
775                         firmware_install_module "$module" "$firmware"
776                 else
777                         for file in $(find_firmware "$module"); do
778                                 firmware_install_module "$module" "$file"
779                         done
780                 fi
781
782                 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
783                 if [ -n "$usleep" ]; then
784                         echo "usleep $usleep" | add_linuxrc
785                 fi
786                 if [ "$module" = "scsi_wait_scan" ]; then
787                         if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
788                                 echo "rmmod scsi_wait_scan" | add_linuxrc
789                         fi
790                 fi
791
792         done
793 }
794
795 # Generates /dev nodes based on /proc/partitions information.
796 # Needs /proc mounted.
797 # Can be called multiple times.
798 initrd_gen_devices() {
799         if is_yes "$proc_partitions"; then
800                 return
801         fi
802         proc_partitions=yes
803
804         mount_dev
805         add_linuxrc <<-'EOF'
806                 : 'Making device nodes'
807                 cat /proc/partitions | (
808                         # ignore first two lines: header, empty line
809                         read b; read b
810
811                         while read major minor blocks dev rest; do
812                                 node=/dev/$dev
813                                 mkdir -p ${node%/*}
814                                 [ -e $node ] || mknod -m 660 $node b $major $minor
815                         done
816                 )
817         EOF
818 }
819
820
821 initrd_gen_setrootdev() {
822         verbose "Adding rootfs finding based on kernel cmdline root= option support."
823         busybox_applet ls
824         debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
825         add_linuxrc <<-'EOF'
826                 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
827                         rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
828                         # fallback to ls
829                         if [ -z "$rootnr" ]; then
830                                 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
831                         fi
832                         if [ -n "$rootnr" ]; then
833                                 echo "$rootnr" > /proc/sys/kernel/real-root-dev
834                         fi
835                 fi
836         EOF
837 }
838
839 initrd_gen_initramfs_switchroot() {
840         inst_d /newroot
841         if [ "$rootdev" = "/dev/nfs" ]; then
842                 echo "rootfs on NFS root=/dev/nfs"
843         else
844                 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
845         fi
846
847         # parse 'root=xxx' kernel commandline
848         # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
849
850         # from lilo-23.2/readme/README:
851         # root=<device> changes the root device. This overrides settings that may
852         # have been made in the boot image and on the LILO command line. <device> is
853         # either the hexadecimal device number or the full path name of the device,
854         # e.g. /dev/hda3 [*]
855         #
856         #  *  The device names are hard-coded in the kernel. Therefore, only the
857         #         "standard" names are supported and some less common devices may not be
858         #         recognized. In those cases, only numbers can be used.
859         busybox_applet cat
860         add_linuxrc <<-'EOF'
861                 device=
862                 eval "$(busybox awk -v root="$ROOT" '
863                         # http://9fans.net/archive/2006/09/261
864                         function h2d(str, hstr, res, num, n, digit, i) {
865                                 hstr = "0123456789abdcef";
866                                 res = 0;
867                                 n = split(tolower(str), digit, "");
868
869                                 for (i = 1; i <= n; i++) {
870                                         num = index(hstr, digit[i]) - 1;
871                                         res = res + (num * 16 ^ (n - i));
872                                 }
873
874                                 return res;
875                         }
876                         BEGIN {
877
878                                 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
879                                 num_pattern = "[0-9a-fA-F]" num_pattern_short;
880                                 dev_pattern = "[hms][a-z][a-z]([0-9])+";
881                                 partition = "";
882                                 min = -1; maj = -1;
883
884                                 # see if we have /dev/hdX or hdX, we can just take partition name
885                                 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
886                                         partition = root
887                                         sub("^/dev/", "", partition);
888
889                                 } else {
890                                         # unify values first
891                                         if (root ~ "^" num_pattern_short "$")  {
892                                                 # change "303" => "0x0303"
893                                                 root = "0x0" root
894                                         } else if (root ~ "^" num_pattern "$")  {
895                                                 # change "0303" => "0x0303"
896                                                 root = "0x" root
897                                         }
898
899                                         maj = h2d(substr(root, 3, 2));
900                                         min = h2d(substr(root, 5, 2));
901                                 }
902                         }
903
904                         partition && $4 == partition { maj = $1; min = $2; }
905                         $1 == maj && $2 == min { partition = $4; }
906
907                         END {
908                                 if (maj >= 0 && min >= 0) {
909                                         printf("maj=%s; min=%s;\n", maj, min);
910                                 }
911                                 if (partition) {
912                                         printf("device=/dev/%s;\n", partition);
913                                 }
914                         }
915                         ' /proc/partitions)"
916
917                 if [ -z "$device" ]; then
918                         if [ "$DEBUGINITRD" ]; then
919                                 cat /proc/partitions
920                         fi
921                         device=$ROOT
922                 fi
923
924                 if [ "$device" -a ! -b $device ]; then
925                         mknod -m 660 $device b $maj $min
926                 fi
927
928                 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
929
930                 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
931                 init=$INIT
932                 if [ -z "$init" -o ! -x "/newroot$init" ]; then
933                         init=/sbin/init
934                 fi
935         EOF
936
937         busybox_applet dmesg
938         busybox_applet tail
939         add_linuxrc <<-'EOF'
940                 if [ "$DEBUGINITRD" ]; then
941                         echo "Last 20 lines of dmesg:"
942                         dmesg | tail -n 20
943                 fi
944         EOF
945
946         umount_all
947         busybox_applet switch_root
948         add_linuxrc <<-'EOF'
949                 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
950                 exec switch_root /newroot $init ${1:+"$@"}
951
952                 echo "Error! initramfs should not reach this place."
953                 echo "It probably means you've got old version of busybox, with broken"
954                 echo "initramfs support. Trying to boot anyway, but won't promise anything."
955
956                 exec chroot /newroot $init ${1:+"$@"}
957
958                 echo "Failed to chroot!"
959                 debugshell
960         EOF
961         # we need /init being real file, not symlink, otherwise the initramfs will
962         # not be ran by pid 1 which is required for switch_root
963         mv $DESTDIR/linuxrc $DESTDIR/init
964         ln -s init $DESTDIR/linuxrc
965 }
966
967 # find if $symbol exists in System.map $mapfile
968 sym_exists() {
969         local mapfile="$1"
970         local symbol="$2"
971         if [ ! -f $mapfile ]; then
972                 # missing mapfile (not a pld kernel?)
973                 return 1
974         fi
975
976         awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
977 }
978
979 # find best compressor (or forced one) for initrd
980 find_compressor() {
981         local mode="$1"
982         # fastest initrd decompression speed is first
983         local compressors='lzo gzip xz lzma bzip2'
984
985         # a specified one, take it
986         if ! is_yes "$mode"; then
987                 compressors="$mode"
988         fi
989
990         verbose "finding compressor: $compressors (via $mode)"
991         # check for compressor validity
992         local c prog map=/boot/System.map-$kernel
993         for c in $compressors; do
994                 case $c in
995                 xz)
996                         sym=unxz
997                         prog=/usr/bin/xz
998                         ;;
999                 lzma)
1000                         sym=unlzma
1001                         prog=/usr/bin/xz
1002                         ;;
1003                 bzip2)
1004                         sym=bzip2
1005                         prog=/usr/bin/bzip2
1006                         ;;
1007                 gzip)
1008                         sym=gunzip
1009                         prog=/bin/gzip
1010                         ;;
1011                 lzo)
1012                         sym=unlzo
1013                         prog=/usr/bin/lzop
1014                         ;;
1015                 none|no)
1016                         # any existing sym will work
1017                         sym=initrd_load
1018                         prog=/bin/cat
1019                         ;;
1020                 *)
1021                         die "Unknown compressor $c"
1022                         ;;
1023                 esac
1024                 if sym_exists $map $sym && [ -x $prog ]; then
1025                         echo $c
1026                         return
1027                 fi
1028         done
1029
1030         verbose "using gzip for compressor (fallback)"
1031         echo gzip
1032 }
1033
1034 # compresses kernel image image
1035 # in function so we could retry with other compressor on failure
1036 compress_image() {
1037         local compressor="$1" IMAGE="$2" target="$3" tmp
1038         tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1039
1040         case "$compressor" in
1041         xz)
1042                 # don't use -9 here since kernel won't understand it
1043                 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1044                 ;;
1045         lzma)
1046                 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1047                 ;;
1048         bzip2)
1049                 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1050                 ;;
1051         gzip)
1052                 gzip -9 < "$IMAGE" > "$tmp" || return $?
1053                 ;;
1054         lzo)
1055                 lzop -9 < "$IMAGE" > "$tmp" || return $?
1056                 ;;
1057         none|no)
1058                 cat < "$IMAGE" > "$tmp" || return $?
1059                 ;;
1060         esac
1061
1062         mv -f "$tmp" "$target"
1063 }
1064
1065 if [ -r /etc/sysconfig/geninitrd ]; then
1066         . /etc/sysconfig/geninitrd
1067 fi
1068
1069 if [ ! -f /proc/mounts ]; then
1070         warn "/proc filesystem not mounted, may cause wrong results or failure."
1071 fi
1072
1073 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1074
1075 while [ $# -gt 0 ]; do
1076         case $1 in
1077         --fstab=*)
1078                 fstab=${1#--fstab=}
1079                 ;;
1080         --fstab)
1081                 fstab=$2
1082                 shift
1083                 ;;
1084         --modules-conf=*)
1085                 modulefile=${1#--modules-conf=}
1086                 ;;
1087         --modules-conf)
1088                 modulefile=$2
1089                 shift
1090                 ;;
1091         --with-bootsplash)
1092                 BOOT_SPLASH=yes
1093                 ;;
1094         --without-bootsplash)
1095                 BOOT_SPLASH=no
1096                 ;;
1097         --with-fbsplash)
1098                 FB_SPLASH=yes
1099                 ;;
1100         --without-fbsplash)
1101                 FB_SPLASH=no
1102                 ;;
1103         --with-fbcondecor)
1104                 FB_CON_DECOR=yes
1105                 ;;
1106         --without-fbcondecor)
1107                 FB_CON_DECOR=no
1108                 ;;
1109         --with-suspend)
1110                 USE_SUSPEND=yes
1111                 ;;
1112         --without-suspend)
1113                 USE_SUSPEND=no
1114                 ;;
1115         --with-suspend2 | --with-tuxonice)
1116                 USE_TUXONICE=yes
1117                 ;;
1118         --without-suspend2 | --without-tuxonice)
1119                 USE_TUXONICE=no
1120                 ;;
1121         --lvmversion=*)
1122                 LVMTOOLSVERSION=${1#--lvmversion=}
1123                 ;;
1124         --lvmtoolsversion=*)
1125                 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1126                 ;;
1127         --lvmtoolsversion|--lvmversion)
1128                 LVMTOOLSVERSION=$2
1129                 shift
1130                 ;;
1131         --without-udev)
1132                 USE_UDEV=no
1133                 ;;
1134         --with-udev)
1135                 USE_UDEV=yes
1136                 ;;
1137         --without-dmraid)
1138                 USE_DMRAID=no
1139                 ;;
1140         --without-multipath)
1141                 USE_MULTIPATH=no
1142                 ;;
1143         --with-multipath=*)
1144                 USE_MULTIPATH=${1#--with-multipath=}
1145                 ;;
1146         --without-blkid)
1147                 USE_BLKID=no
1148                 ;;
1149         --without-luks)
1150                 USE_LUKS=no
1151                 ;;
1152         --with=*)
1153                 BASICMODULES="$BASICMODULES ${1#--with=}"
1154                 ;;
1155         --with)
1156                 BASICMODULES="$BASICMODULES $2"
1157                 shift
1158                 ;;
1159         --version)
1160                 echo "$PROGRAM: version $VERSION"
1161                 exit 0
1162                 ;;
1163         -v)
1164                 if [ x"$verbose" = x"-v" ]; then
1165                         verbose="-v -v"
1166                 else
1167                         verbose="-v"
1168                 fi
1169                 exec 3>&1
1170                 ;;
1171         --compress)
1172                 COMPRESS=$2
1173                 ;;
1174         --compress=*)
1175                 COMPRESS="${1#--compress=}"
1176                 ;;
1177         --nocompress)
1178                 COMPRESS=no
1179                 ;;
1180         --nostrip)
1181                 STRIP=
1182                 ;;
1183         --strip=*)
1184                 STRIP="${1#--strip=}"
1185                 ;;
1186         --strip)
1187                 STRIP=$2
1188                 shift
1189                 ;;
1190         --ifneeded)
1191                 ifneeded=1
1192                 ;;
1193         -f)
1194                 force=1
1195                 ;;
1196         --preload=*)
1197                 PREMODS="$PREMODS ${1#--preload=}"
1198                 ;;
1199         --preload)
1200                 PREMODS="$PREMODS $2"
1201                 shift
1202                 ;;
1203         --fs=* | --fs)
1204                 die "--fs option is obsoleted. Use --initrdfs instead"
1205                 ;;
1206         --initrdfs=*)
1207                 INITRDFS=${1#--initrdfs=}
1208                 ;;
1209         --initrdfs)
1210                 INITRDFS=$2
1211                 shift
1212                 ;;
1213         --image-version)
1214                 img_vers=yes
1215                 ;;
1216         --ide-only-root)
1217                 ide_only_root="yes"
1218                 ;;
1219         *)
1220                 if [ -z "$target" ]; then
1221                         target="$1"
1222                 elif [ -z "$kernel" ]; then
1223                         kernel="$1"
1224                 else
1225                         usage
1226                         exit 1
1227                 fi
1228                 ;;
1229         esac
1230
1231         shift
1232 done
1233
1234 if [ -z "$target" -o -z "$kernel" ]; then
1235         usage
1236         exit 1
1237 fi
1238
1239 # main()
1240 if [ "$(id -u)" != 0 ]; then
1241         die "You need to be root to generate initrd"
1242 fi
1243
1244 if [ -d /lib64 -a -d /usr/lib64 ]; then
1245         _lib=lib64
1246 else
1247         _lib=lib
1248 fi
1249
1250 initrd_dir=/usr/$_lib/initrd
1251 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1252 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1253
1254 verbose "# $GENINITRD_RCSID (geninitrd)"
1255 debug "Using _lib: $_lib"
1256 debug "Using initrd_dir: $initrd_dir"
1257
1258 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1259
1260 # we setup mods after parsing command line args
1261 geninitrd_setup_mods
1262
1263 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1264         warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1265 fi
1266
1267 if [ -z "$INITRDFS" ]; then
1268         if [ -n "$FS" ]; then
1269                 # FS= can came only via /etc/sysconfig/geninitrd likely?
1270                 die "FS configuration option is obsoleted. Use INITRDFS instead"
1271         fi
1272
1273         # default value
1274         if [ "$kernel_version" -ge "002005" ]; then
1275                 INITRDFS="initramfs"
1276         else
1277                 INITRDFS="rom"
1278         fi
1279 fi
1280
1281 case "$INITRDFS" in
1282   ext2)
1283         [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1284         ;;
1285   rom|romfs)
1286         [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1287         ;;
1288   cram|cramfs)
1289         [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1290         ;;
1291   initramfs)
1292         [ -x /bin/cpio ] || die "/bin/cpio is missing"
1293         [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1294         ;;
1295   *)
1296         die "Filesystem $INITRDFS on initrd is not supported"
1297         ;;
1298 esac
1299
1300 if [ -L "$target" ]; then
1301         target=$(readlink -f "$target")
1302 fi
1303
1304 if [ -n "$img_vers" ]; then
1305         target="$target-$kernel"
1306 fi
1307
1308 if [ -z "$force" -a -f "$target" ]; then
1309         die "$target already exists."
1310 fi
1311
1312 if [ ! -d "/lib/modules/$kernel" ]; then
1313         die "/lib/modules/$kernel is not a directory."
1314 fi
1315
1316 if [ "$kernel_version" -ge "002005" ]; then
1317         modext=".ko"
1318 fi
1319
1320 cache_modprobe_conf
1321
1322 for n in $PREMODS; do
1323         find_module "$n"
1324 done
1325
1326 if [ "$FBMODULE" ]; then
1327         find_module "$FBMODULE"
1328 fi
1329
1330 # autodetect USB keyboards
1331 find_modules_usbkbd
1332
1333 # allow forcing loading SCSI and/or IDE modules
1334 # XXX: where ADDSCSI cames from? drop?
1335 if is_yes "$ADDSCSI"; then
1336         find_modules_scsi
1337 fi
1338
1339 # autodetect SATA modules
1340 find_modules_sata
1341
1342 # XXX: where ADDIDE cames from? drop?
1343 if is_yes "$ADDIDE"; then
1344         find_modules_ide
1345 fi
1346
1347 if is_yes "$USE_SUSPEND"; then
1348         find_modules_suspend
1349 fi
1350
1351 find_root "$fstab" || exit
1352 verbose "Using $rootdev as device for rootfs"
1353
1354 find_modules_for_devpath "$rootdev"
1355
1356 # if USE_MULTIPATH is path to device, scan that too
1357 # this is to bootstrap multipath setup into initrd.
1358 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1359         find_modules_multipath $USE_MULTIPATH
1360 fi
1361
1362 find_module "-$rootFs"
1363
1364 for n in $BASICMODULES; do
1365         find_module "$n"
1366 done
1367
1368 if is_yes "$USE_TUXONICE"; then
1369         find_module "-lzf"
1370 fi
1371
1372 find_modules_fbsplash
1373
1374 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1375         verbose "No modules are needed -- not building initrd image."
1376         exit 0
1377 fi
1378
1379 verbose "Building initrd..."
1380 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1381 RCFILE="$DESTDIR/linuxrc"
1382 > "$RCFILE"
1383 chmod a+rx "$RCFILE"
1384 ln -s linuxrc $DESTDIR/init
1385
1386 # create dirs that we really need
1387 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1388
1389 modules_install "$MODULES"
1390
1391 # mknod'ing the devices instead of copying them works both with and
1392 # without devfs...
1393 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1394 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1395 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1396 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1397 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1398
1399 inst_exec $busybox /bin/busybox
1400 ln -s busybox $DESTDIR/bin/sh
1401 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1402 ln -s busybox $DESTDIR/bin/initrd-busybox
1403
1404 add_linuxrc <<EOF
1405 #!/bin/sh
1406 # initrd generated
1407 # on $(LC_ALL=C date)
1408 # by $GENINITRD_RCSID
1409
1410 EOF
1411 mount_proc
1412 add_linuxrc <<-EOF
1413         # builtin defaults from geninitrd
1414         ROOT=$rootdev
1415         ROOTFS=$rootFs
1416 EOF
1417 add_linuxrc <<-'EOF'
1418         read CMDLINE < /proc/cmdline
1419
1420         for arg in $CMDLINE; do
1421                 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1422                         DEBUGINITRD=yes
1423                 fi
1424                 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1425                         DEBUGINITRD=${arg##debug*rd=}
1426                 fi
1427                 if [ "${arg##root=}" != "${arg}" ]; then
1428                         ROOT=${arg##root=}
1429                 fi
1430                 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1431                         ROOTFSFLAGS=${arg##rootfsflags=}
1432                 fi
1433                 if [ "${arg##init=}" != "${arg}" ]; then
1434                         INIT=${arg##init=}
1435                 fi
1436         done
1437
1438         if [ "$DEBUGINITRD" = "sh" ]; then
1439                 # export some vars to subshell for debug to work
1440                 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1441                 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1442                 export rootnr attrs majmin major minor device
1443
1444                 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1445                 debugshell() {
1446 EOF
1447 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1448 add_linuxrc <<-'EOF'
1449         echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1450 EOF
1451 else
1452 add_linuxrc <<-'EOF'
1453         sh
1454 EOF
1455 fi
1456 add_linuxrc <<-'EOF'
1457                 }
1458         else
1459                 debugshell() {
1460                         :
1461                 }
1462         fi
1463
1464         if [ "$DEBUGINITRD" ]; then
1465                 set -x
1466         fi
1467 EOF
1468
1469 modules_add_linuxrc $MODULES
1470
1471 # TODO: rewrite for busybox
1472 #if [ -n "$loopDev" ]; then
1473 #       if [ ! -d /initrd ]; then
1474 #               mkdir /initrd
1475 #       fi
1476 #
1477 #       cp -a "$loopDev" "$DESTDIR/dev"
1478 #       cp -a "$rootdev" "$DESTDIR/dev"
1479 #       echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1480 #       echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1481 #       echo "echo Setting up loopback device $rootdev" >> $RCFILE
1482 #       echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1483 #fi
1484
1485 if is_yes "$USE_UDEV"; then
1486         initrd_gen_udev
1487 else
1488         initrd_gen_mdev
1489 fi
1490
1491 find_modules_uvesafb
1492 initrd_gen_uvesafb
1493
1494 initrd_gen_luks
1495 initrd_gen_dmraid
1496 initrd_gen_multipath
1497 initrd_gen_blkid
1498
1499 if is_yes "$have_nfs"; then
1500         initrd_gen_nfs
1501 else
1502         initrd_gen_md
1503         initrd_gen_lvm
1504         initrd_gen_blkid
1505         initrd_gen_luks
1506         initrd_gen_setrootdev
1507 fi
1508
1509 # additional devs always needed
1510 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1511
1512 initrd_gen_stop_udevd
1513 initrd_gen_stop_mdev
1514 initrd_gen_stop_uvesafb
1515
1516 # resume after killing local processes
1517 initrd_gen_tuxonice
1518 initrd_gen_suspend
1519
1520 # clean up env
1521 add_linuxrc <<-'EOF'
1522 if [ ! "$DEBUGINITRD" ]; then
1523         ifs=$IFS
1524         IFS="
1525         "
1526         for i in $(export -p); do
1527                 i=${i#declare -x } # ksh/bash
1528                 i=${i#export } # busybox
1529
1530                 case "$i" in
1531                 *=*)
1532                         : ;;
1533                 *)
1534                         continue ;;
1535                 esac
1536
1537                 i=${i%%=*}
1538
1539                 [ -z "$i" ] && continue
1540
1541                 case "$i" in
1542                         ROOT|PATH|HOME|TERM)
1543                                 :
1544                                 ;;
1545                         *)
1546                                 unset $i
1547                                 ;;
1548                 esac
1549         done
1550         IFS=$ifs
1551 fi
1552 EOF
1553
1554 if [ "$INITRDFS" = "initramfs" ]; then
1555         initrd_gen_initramfs_switchroot
1556 else
1557         umount_all
1558 fi
1559
1560 initrd_gen_fbsplash
1561 initrd_gen_fbcondecor
1562
1563 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1564
1565 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1566
1567 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1568 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1569
1570 verbose "Creating $INITRDFS image $IMAGE"
1571 case "$INITRDFS" in
1572   ext2)
1573         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1574         # NOTE: ext2 label is max 16 chars
1575         mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1576         tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1577
1578         local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1579         debug "Mounting ext2 image $IMAGE to $tmpmnt"
1580         mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1581         # We don't need this directory, so let's save space
1582         rm -rf "$tmpmnt"/lost+found
1583
1584         debug "Copy recursively $DESTDIR -> $tmpmnt"
1585         cp -a $DESTDIR/* $tmpmnt
1586         umount "$IMAGE"
1587         rmdir "$tmpmnt"
1588
1589         ;;
1590   rom|romfs)
1591         genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1592         ;;
1593   cram|cramfs)
1594         mkcramfs "$DESTDIR" "$IMAGE"
1595         ;;
1596   initramfs)
1597         (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1598         ;;
1599   *)
1600         die "Filesystem $INITRDFS not supported by $PROGRAM"
1601 esac
1602
1603 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1604 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1605         CONFIG_BLK_DEV_RAM_SIZE=4096
1606         warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1607 fi
1608
1609 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1610         warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1611 fi
1612
1613 if ! is_no "$COMPRESS"; then
1614         compressor=$(find_compressor "$COMPRESS")
1615         verbose "Compressing $target with $compressor"
1616
1617         # TODO: the image name (specified from kernel.spec) already contains
1618         # extension, which is .gz most of the time.
1619         compress_image "$compressor" "$IMAGE" "$target" || {
1620                 if [ $compressor != gzip ]; then
1621                         warn "Could not compress with $compressor, retrying with gzip"
1622                         compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1623                 else
1624                         die "Could not compress image with $compressor"
1625                 fi
1626         }
1627 else
1628         cp -a "$IMAGE" "$target"
1629 fi
1630
1631 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1632 initrd_gen_bootsplash "$target"
1633
1634 rm -rf "$DESTDIR" "$IMAGE"
1635
1636 # vim:ts=4:sw=4:noet:fdm=marker
This page took 0.145068 seconds and 2 git commands to generate.