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