fixed fips mode
[platform/upstream/dracut.git] / dracut.sh
1 #!/bin/bash
2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
4 #
5 # Generator script for a dracut initramfs
6 # Tries to retain some degree of compatibility with the command line
7 # of the various mkinitrd implementations out there
8 #
9
10 # Copyright 2005-2013 Red Hat, Inc.  All rights reserved.
11 #
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
16 #
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 #
25
26 # store for logging
27 dracut_args=( "$@" )
28
29 set -o pipefail
30
31 usage() {
32     [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
33     if [[ -f $dracutbasedir/dracut-version.sh ]]; then
34         . $dracutbasedir/dracut-version.sh
35     fi
36
37 #                                                       80x25 linebreak here ^
38     cat << EOF
39 Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
40
41 Version: $DRACUT_VERSION
42
43 Creates initial ramdisk images for preloading modules
44
45   -h, --help  Display all options
46
47 If a [LIST] has multiple arguments, then you have to put these in quotes.
48
49 For example:
50
51     # dracut --add-drivers "module1 module2"  ...
52
53 EOF
54 }
55
56 long_usage() {
57     [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
58     if [[ -f $dracutbasedir/dracut-version.sh ]]; then
59         . $dracutbasedir/dracut-version.sh
60     fi
61
62 #                                                       80x25 linebreak here ^
63     cat << EOF
64 Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
65
66 Version: $DRACUT_VERSION
67
68 Creates initial ramdisk images for preloading modules
69
70   --kver [VERSION]      Set kernel version to [VERSION].
71   -f, --force           Overwrite existing initramfs file.
72   -a, --add [LIST]      Add a space-separated list of dracut modules.
73   -m, --modules [LIST]  Specify a space-separated list of dracut modules to
74                          call when building the initramfs. Modules are located
75                          in /usr/lib/dracut/modules.d.
76   -o, --omit [LIST]     Omit a space-separated list of dracut modules.
77   --force-add [LIST]    Force to add a space-separated list of dracut modules
78                          to the default set of modules, when -H is specified.
79   -d, --drivers [LIST]  Specify a space-separated list of kernel modules to
80                          exclusively include in the initramfs.
81   --add-drivers [LIST]  Specify a space-separated list of kernel
82                          modules to add to the initramfs.
83   --omit-drivers [LIST] Specify a space-separated list of kernel
84                          modules not to add to the initramfs.
85   --filesystems [LIST]  Specify a space-separated list of kernel filesystem
86                          modules to exclusively include in the generic
87                          initramfs.
88   -k, --kmoddir [DIR]   Specify the directory, where to look for kernel
89                          modules
90   --fwdir [DIR]         Specify additional directories, where to look for
91                          firmwares, separated by :
92   --kernel-only         Only install kernel drivers and firmware files
93   --no-kernel           Do not install kernel drivers and firmware files
94   --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
95   --strip               Strip binaries in the initramfs
96   --nostrip             Do not strip binaries in the initramfs
97   --hardlink            Hardlink files in the initramfs
98   --nohardlink          Do not hardlink files in the initramfs
99   --prefix [DIR]        Prefix initramfs files with [DIR]
100   --noprefix            Do not prefix initramfs files
101   --mdadmconf           Include local /etc/mdadm.conf
102   --nomdadmconf         Do not include local /etc/mdadm.conf
103   --lvmconf             Include local /etc/lvm/lvm.conf
104   --nolvmconf           Do not include local /etc/lvm/lvm.conf
105   --fscks [LIST]        Add a space-separated list of fsck helpers.
106   --nofscks             Inhibit installation of any fsck helpers.
107   --ro-mnt              Mount / and /usr read-only by default.
108   -h, --help            This message
109   --debug               Output debug information of the build process
110   --profile             Output profile information of the build process
111   -L, --stdlog [0-6]    Specify logging level (to standard error)
112                          0 - suppress any messages
113                          1 - only fatal errors
114                          2 - all errors
115                          3 - warnings
116                          4 - info
117                          5 - debug info (here starts lots of output)
118                          6 - trace info (and even more)
119   -v, --verbose         Increase verbosity level
120   -q, --quiet           Decrease verbosity level
121   -c, --conf [FILE]     Specify configuration file to use.
122                          Default: /etc/dracut.conf
123   --confdir [DIR]       Specify configuration directory to use *.conf files
124                          from. Default: /etc/dracut.conf.d
125   --tmpdir [DIR]        Temporary directory to be used instead of default
126                          /var/tmp.
127   -l, --local           Local mode. Use modules from the current working
128                          directory instead of the system-wide installed in
129                          /usr/lib/dracut/modules.d.
130                          Useful when running dracut from a git checkout.
131   -H, --hostonly        Host-Only mode: Install only what is needed for
132                          booting the local host instead of a generic host.
133   -N, --no-hostonly     Disables Host-Only mode
134   --fstab               Use /etc/fstab to determine the root device.
135   --add-fstab [FILE]    Add file to the initramfs fstab
136   --mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
137                         Mount device [DEV] on mountpoint [MP] with filesystem
138                         [FSTYPE] and options [FSOPTS] in the initramfs
139   --add-device "[DEV]"  Bring up [DEV] in initramfs
140   -i, --include [SOURCE] [TARGET]
141                         Include the files in the SOURCE directory into the
142                          Target directory in the final initramfs.
143                         If SOURCE is a file, it will be installed to TARGET
144                          in the final initramfs.
145   -I, --install [LIST]  Install the space separated list of files into the
146                          initramfs.
147   --gzip                Compress the generated initramfs using gzip.
148                          This will be done by default, unless another
149                          compression option or --no-compress is passed.
150   --bzip2               Compress the generated initramfs using bzip2.
151                          Make sure your kernel has bzip2 decompression support
152                          compiled in, otherwise you will not be able to boot.
153   --lzma                Compress the generated initramfs using lzma.
154                          Make sure your kernel has lzma support compiled in,
155                          otherwise you will not be able to boot.
156   --xz                  Compress the generated initramfs using xz.
157                          Make sure that your kernel has xz support compiled
158                          in, otherwise you will not be able to boot.
159   --compress [COMPRESSION] Compress the generated initramfs with the
160                          passed compression program.  Make sure your kernel
161                          knows how to decompress the generated initramfs,
162                          otherwise you will not be able to boot.
163   --no-compress         Do not compress the generated initramfs.  This will
164                          override any other compression options.
165   --list-modules        List all available dracut modules.
166   -M, --show-modules    Print included module's name to standard output during
167                          build.
168   --keep                Keep the temporary initramfs for debugging purposes
169   --printsize           Print out the module install size
170   --sshkey [SSHKEY]     Add ssh key to initramfs (use with ssh-client module)
171
172 If [LIST] has multiple arguments, then you have to put these in quotes.
173
174 For example:
175
176     # dracut --add-drivers "module1 module2"  ...
177
178 EOF
179 }
180
181 # function push()
182 # push values to a stack
183 # $1 = stack variable
184 # $2.. values
185 # example:
186 # push stack 1 2 "3 4"
187 push() {
188     local _i
189     local __stack=$1; shift
190     for _i in "$@"; do
191         eval ${__stack}'[${#'${__stack}'[@]}]="$_i"'
192     done
193 }
194
195 # function pop()
196 # pops the last value from a stack
197 # assigns value to second argument variable
198 # or echo to stdout, if no second argument
199 # $1 = stack variable
200 # $2 = optional variable to store the value
201 # example:
202 # pop stack val
203 # val=$(pop stack)
204 pop() {
205     local __stack=$1; shift
206     local __resultvar=$1
207     local _value;
208     # check for empty stack
209     eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
210
211     eval _value='${'${__stack}'[${#'${__stack}'[@]}-1]}'
212
213     if [[ "$__resultvar" ]]; then
214         eval $__resultvar="'$_value'"
215     else
216         echo "$_value"
217     fi
218     eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
219     return 0
220 }
221
222 # Little helper function for reading args from the commandline.
223 # it automatically handles -a b and -a=b variants, and returns 1 if
224 # we need to shift $3.
225 read_arg() {
226     # $1 = arg name
227     # $2 = arg value
228     # $3 = arg parameter
229     local rematch='^[^=]*=(.*)$'
230     if [[ $2 =~ $rematch ]]; then
231         read "$1" <<< "${BASH_REMATCH[1]}"
232     else
233         read "$1" <<< "$3"
234         # There is no way to shift our callers args, so
235         # return 1 to indicate they should do it instead.
236         return 1
237     fi
238 }
239
240
241 dropindirs_sort()
242 {
243     suffix=$1; shift
244     args=("$@")
245     files=$(
246         while (( $# > 0 )); do
247             for i in ${1}/*${suffix}; do
248                 [[ -f $i ]] && echo ${i##*/}
249             done
250             shift
251         done | sort -Vu
252     )
253
254     for f in $files; do
255         for d in "${args[@]}"; do
256             if [[ -f "$d/$f" ]]; then
257                 echo "$d/$f"
258                 continue 2
259             fi
260         done
261     done
262 }
263
264 verbosity_mod_l=0
265 unset kernel
266 unset outfile
267
268 # Workaround -i, --include taking 2 arguments
269 set -- "${@/--include/++include}"
270
271 # This prevents any long argument ending with "-i"
272 # -i, like --opt-i but I think we can just prevent that
273 set -- "${@/%-i/++include}"
274
275 TEMP=$(unset POSIXLY_CORRECT; getopt \
276     -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
277     --long kver: \
278     --long add: \
279     --long force-add: \
280     --long add-drivers: \
281     --long omit-drivers: \
282     --long modules: \
283     --long omit: \
284     --long drivers: \
285     --long filesystems: \
286     --long install: \
287     --long fwdir: \
288     --long libdirs: \
289     --long fscks: \
290     --long add-fstab: \
291     --long mount: \
292     --long device: \
293     --long nofscks: \
294     --long ro-mnt \
295     --long kmoddir: \
296     --long conf: \
297     --long confdir: \
298     --long tmpdir: \
299     --long stdlog: \
300     --long compress: \
301     --long prefix: \
302     --long force \
303     --long kernel-only \
304     --long no-kernel \
305     --long kernel-cmdline: \
306     --long strip \
307     --long nostrip \
308     --long hardlink \
309     --long nohardlink \
310     --long noprefix \
311     --long mdadmconf \
312     --long nomdadmconf \
313     --long lvmconf \
314     --long nolvmconf \
315     --long debug \
316     --long profile \
317     --long sshkey: \
318     --long verbose \
319     --long quiet \
320     --long local \
321     --long hostonly \
322     --long host-only \
323     --long no-hostonly \
324     --long no-host-only \
325     --long fstab \
326     --long help \
327     --long bzip2 \
328     --long lzma \
329     --long xz \
330     --long no-compress \
331     --long gzip \
332     --long list-modules \
333     --long show-modules \
334     --long keep \
335     --long printsize \
336     --long regenerate-all \
337     --long noimageifnotneeded \
338     -- "$@")
339
340 if (( $? != 0 )); then
341     usage
342     exit 1
343 fi
344
345 eval set -- "$TEMP"
346
347 while :; do
348     case $1 in
349         --kver)        kernel="$2"; shift;;
350         -a|--add)      push add_dracutmodules_l  "$2"; shift;;
351         --force-add)   push force_add_dracutmodules_l  "$2"; shift;;
352         --add-drivers) push add_drivers_l        "$2"; shift;;
353         --omit-drivers) push omit_drivers_l      "$2"; shift;;
354         -m|--modules)  push dracutmodules_l      "$2"; shift;;
355         -o|--omit)     push omit_dracutmodules_l "$2"; shift;;
356         -d|--drivers)  push drivers_l            "$2"; shift;;
357         --filesystems) push filesystems_l        "$2"; shift;;
358         -I|--install)  push install_items_l      "$2"; shift;;
359         --fwdir)       push fw_dir_l             "$2"; shift;;
360         --libdirs)     push libdirs_l            "$2"; shift;;
361         --fscks)       push fscks_l              "$2"; shift;;
362         --add-fstab)   push add_fstab_l          "$2"; shift;;
363         --mount)       push fstab_lines          "$2"; shift;;
364         --add-device|--device)
365                        push add_device_l         "$2"; shift;;
366         --kernel-cmdline) push kernel_cmdline_l  "$2"; shift;;
367         --nofscks)     nofscks_l="yes";;
368         --ro-mnt)      ro_mnt_l="yes";;
369         -k|--kmoddir)  drivers_dir_l="$2"; shift;;
370         -c|--conf)     conffile="$2"; shift;;
371         --confdir)     confdir="$2"; shift;;
372         --tmpdir)      tmpdir_l="$2"; shift;;
373         -L|--stdlog)   stdloglvl_l="$2"; shift;;
374         --compress)    compress_l="$2"; shift;;
375         --prefix)      prefix_l="$2"; shift;;
376         -f|--force)    force=yes;;
377         --kernel-only) kernel_only="yes"; no_kernel="no";;
378         --no-kernel)   kernel_only="no"; no_kernel="yes";;
379         --strip)       do_strip_l="yes";;
380         --nostrip)     do_strip_l="no";;
381         --hardlink)    do_hardlink_l="yes";;
382         --nohardlink)  do_hardlink_l="no";;
383         --noprefix)    prefix_l="/";;
384         --mdadmconf)   mdadmconf_l="yes";;
385         --nomdadmconf) mdadmconf_l="no";;
386         --lvmconf)     lvmconf_l="yes";;
387         --nolvmconf)   lvmconf_l="no";;
388         --debug)       debug="yes";;
389         --profile)     profile="yes";;
390         --sshkey)      sshkey="$2"; shift;;
391         -v|--verbose)  ((verbosity_mod_l++));;
392         -q|--quiet)    ((verbosity_mod_l--));;
393         -l|--local)
394                        allowlocal="yes"
395                        [[ -f "$(readlink -f ${0%/*})/dracut-functions.sh" ]] \
396                            && dracutbasedir="$(readlink -f ${0%/*})"
397                        ;;
398         -H|--hostonly|--host-only)
399                        hostonly_l="yes" ;;
400         -N|--no-hostonly|--no-host-only)
401                        hostonly_l="no" ;;
402         --fstab)       use_fstab_l="yes" ;;
403         -h|--help)     long_usage; exit 1 ;;
404         -i|--include)  push include_src "$2"
405                        shift;;
406         --bzip2)       compress_l="bzip2";;
407         --lzma)        compress_l="lzma";;
408         --xz)          compress_l="xz";;
409         --no-compress) _no_compress_l="cat";;
410         --gzip)        compress_l="gzip";;
411         --list-modules) do_list="yes";;
412         -M|--show-modules)
413                        show_modules_l="yes"
414                        ;;
415         --keep)        keep="yes";;
416         --printsize)   printsize="yes";;
417         --regenerate-all) regenerate_all="yes";;
418         --noimageifnotneeded) noimageifnotneeded="yes";;
419
420         --) shift; break;;
421
422         *)  # should not even reach this point
423             printf "\n!Unknown option: '%s'\n\n" "$1" >&2; usage; exit 1;;
424     esac
425     shift
426 done
427
428 # getopt cannot handle multiple arguments, so just handle "-I,--include"
429 # the old fashioned way
430
431 while (($# > 0)); do
432     case ${1%%=*} in
433         ++include) push include_src "$2"
434                        push include_target "$3"
435                        shift 2;;
436         *)
437             if ! [[ ${outfile+x} ]]; then
438                 outfile=$1
439             elif ! [[ ${kernel+x} ]]; then
440                 kernel=$1
441             else
442                 printf "\nUnknown arguments: %s\n\n" "$*" >&2
443                 usage; exit 1;
444             fi
445             ;;
446     esac
447     shift
448 done
449
450 if [[ $regenerate_all == "yes" ]]; then
451     ret=0
452     if [[ $kernel ]]; then
453         echo "--regenerate-all cannot be called with a kernel version" >&2
454         exit 1
455     fi
456
457     if [[ $outfile ]]; then
458         echo "--regenerate-all cannot be called with a image file" >&2
459         exit 1
460     fi
461
462     ((len=${#dracut_args[@]}))
463     for ((i=0; i < len; i++)); do
464         [[ ${dracut_args[$i]} == "--regenerate-all" ]] && \
465             unset dracut_args[$i]
466     done
467
468     cd /lib/modules
469     for i in *; do
470         [[ -f $i/modules.builtin ]] || continue
471         dracut --kver=$i "${dracut_args[@]}"
472         ((ret+=$?))
473     done
474     exit $ret
475 fi
476
477 if ! [[ $kernel ]]; then
478     kernel=$(uname -r)
479 fi
480
481 if ! [[ $outfile ]]; then
482     [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id
483
484     if [[ $MACHINE_ID ]] && ( [[ -d /boot/${MACHINE_ID} ]] || [[ -L /boot/${MACHINE_ID} ]] ); then
485         outfile="/boot/${MACHINE_ID}/$kernel/initrd"
486     else
487         outfile="/boot/initramfs-$kernel.img"
488     fi
489 fi
490
491 for i in /usr/sbin /sbin /usr/bin /bin; do
492     rl=$i
493     if [ -L "$i" ]; then
494         rl=$(readlink -f $i)
495     fi
496     if [[ "$NPATH" != "*:$rl*" ]] ; then
497         NPATH+=":$rl"
498     fi
499 done
500 export PATH="${NPATH#:}"
501 unset NPATH
502 unset LD_LIBRARY_PATH
503 unset GREP_OPTIONS
504
505 export DRACUT_LOG_LEVEL=warning
506 [[ $debug ]] && {
507     export DRACUT_LOG_LEVEL=debug
508     export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
509     set -x
510 }
511
512 [[ $profile ]] && {
513     export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
514     set -x
515     debug=yes
516 }
517
518 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
519
520 # if we were not passed a config file, try the default one
521 if [[ ! -f $conffile ]]; then
522     [[ $allowlocal ]] && conffile="$dracutbasedir/dracut.conf" || \
523         conffile="/etc/dracut.conf"
524 fi
525
526 if [[ ! -d $confdir ]]; then
527     [[ $allowlocal ]] && confdir="$dracutbasedir/dracut.conf.d" || \
528         confdir="/etc/dracut.conf.d"
529 fi
530
531 # source our config file
532 [[ -f $conffile ]] && . "$conffile"
533
534 # source our config dir
535 for f in $(dropindirs_sort ".conf" "$confdir" "$dracutbasedir/dracut.conf.d"); do
536     [[ -e $f ]] && . "$f"
537 done
538
539 # these optins add to the stuff in the config file
540 if (( ${#add_dracutmodules_l[@]} )); then
541     while pop add_dracutmodules_l val; do
542         add_dracutmodules+=" $val "
543     done
544 fi
545
546 if (( ${#force_add_dracutmodules_l[@]} )); then
547     while pop force_add_dracutmodules_l val; do
548         force_add_dracutmodules+=" $val "
549     done
550 fi
551
552 if (( ${#fscks_l[@]} )); then
553     while pop fscks_l val; do
554         fscks+=" $val "
555     done
556 fi
557
558 if (( ${#add_fstab_l[@]} )); then
559     while pop add_fstab_l val; do
560         add_fstab+=" $val "
561     done
562 fi
563
564 if (( ${#fstab_lines_l[@]} )); then
565     while pop fstab_lines_l val; do
566         push fstab_lines $val
567     done
568 fi
569
570 if (( ${#install_items_l[@]} )); then
571     while pop install_items_l val; do
572         install_items+=" $val "
573     done
574 fi
575
576 # these options override the stuff in the config file
577 if (( ${#dracutmodules_l[@]} )); then
578     dracutmodules=''
579     while pop dracutmodules_l val; do
580         dracutmodules+="$val "
581     done
582 fi
583
584 if (( ${#omit_dracutmodules_l[@]} )); then
585     omit_dracutmodules=''
586     while pop omit_dracutmodules_l val; do
587         omit_dracutmodules+="$val "
588     done
589 fi
590
591 if (( ${#filesystems_l[@]} )); then
592     filesystems=''
593     while pop filesystems_l val; do
594         filesystems+="$val "
595     done
596 fi
597
598 if (( ${#fw_dir_l[@]} )); then
599     fw_dir=''
600     while pop fw_dir_l val; do
601         fw_dir+="$val "
602     done
603 fi
604
605 if (( ${#libdirs_l[@]} )); then
606     libdirs=''
607     while pop libdirs_l val; do
608         libdirs+="$val "
609     done
610 fi
611
612 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
613 [[ ! $stdloglvl ]] && stdloglvl=4
614 stdloglvl=$((stdloglvl + verbosity_mod_l))
615 ((stdloglvl > 6)) && stdloglvl=6
616 ((stdloglvl < 0)) && stdloglvl=0
617
618 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
619 [[ $do_strip_l ]] && do_strip=$do_strip_l
620 [[ $do_strip ]] || do_strip=yes
621 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
622 [[ $do_hardlink ]] || do_hardlink=yes
623 [[ $prefix_l ]] && prefix=$prefix_l
624 [[ $prefix = "/" ]] && unset prefix
625 [[ $hostonly_l ]] && hostonly=$hostonly_l
626 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
627 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
628 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
629 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
630 [[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware"
631 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
632 [[ $tmpdir ]] || tmpdir=/var/tmp
633 [[ $compress_l ]] && compress=$compress_l
634 [[ $show_modules_l ]] && show_modules=$show_modules_l
635 [[ $nofscks_l ]] && nofscks="yes"
636 [[ $ro_mnt_l ]] && ro_mnt="yes"
637 # eliminate IFS hackery when messing with fw_dir
638 fw_dir=${fw_dir//:/ }
639
640 # handle compression options.
641 [[ $compress ]] || compress="gzip"
642 case $compress in
643     bzip2) compress="bzip2 -9";;
644     lzma)  compress="lzma -9";;
645     xz)    compress="xz --check=crc32 --lzma2=dict=1MiB";;
646     gzip)  command -v pigz > /dev/null 2>&1 && compress="pigz -9" || \
647                                          compress="gzip -9";;
648 esac
649 if [[ $_no_compress_l = "cat" ]]; then
650     compress="cat"
651 fi
652
653 [[ $hostonly = yes ]] && hostonly="-h"
654 [[ $hostonly != "-h" ]] && unset hostonly
655
656 readonly TMPDIR="$tmpdir"
657 readonly initdir=$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)
658 [ -d "$initdir" ] || {
659     echo "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXX failed." >&2
660     exit 1
661 }
662
663 # clean up after ourselves no matter how we die.
664 trap 'ret=$?;[[ $outfile ]] && [[ -f $outfile.$$ ]] && rm -f "$outfile.$$";[[ $keep ]] && echo "Not removing $initdir." >&2 || { [[ $initdir ]] && rm -rf "$initdir";exit $ret; };' EXIT
665 # clean up after ourselves no matter how we die.
666 trap 'exit 1;' SIGINT
667
668 export DRACUT_KERNEL_LAZY="1"
669 export DRACUT_RESOLVE_LAZY="1"
670
671 if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
672     . $dracutbasedir/dracut-functions.sh
673 else
674     echo "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
675     echo "dracut: Are you running from a git checkout?" >&2
676     echo "dracut: Try passing -l as an argument to $0" >&2
677     exit 1
678 fi
679
680 inst /bin/sh
681 if ! $DRACUT_INSTALL ${initdir+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
682     unset DRACUT_RESOLVE_LAZY
683     export DRACUT_RESOLVE_DEPS=1
684 fi
685 rm -fr ${initdir}/*
686
687 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
688     . $dracutbasedir/dracut-version.sh
689 fi
690
691 # Verify bash version, current minimum is 3.1
692 if (( ${BASH_VERSINFO[0]} < 3 ||
693     ( ${BASH_VERSINFO[0]} == 3 && ${BASH_VERSINFO[1]} < 1 ) )); then
694     dfatal 'You need at least Bash 3.1 to use dracut, sorry.'
695     exit 1
696 fi
697
698 dracutfunctions=$dracutbasedir/dracut-functions.sh
699 export dracutfunctions
700
701 if (( ${#drivers_l[@]} )); then
702     drivers=''
703     while pop drivers_l val; do
704         drivers+="$val "
705     done
706 fi
707 drivers=${drivers/-/_}
708
709 if (( ${#add_drivers_l[@]} )); then
710     while pop add_drivers_l val; do
711         add_drivers+=" $val "
712     done
713 fi
714 add_drivers=${add_drivers/-/_}
715
716 if (( ${#omit_drivers_l[@]} )); then
717     while pop omit_drivers_l val; do
718         omit_drivers+=" $val "
719     done
720 fi
721 omit_drivers=${omit_drivers/-/_}
722
723 if (( ${#kernel_cmdline_l[@]} )); then
724     while pop kernel_cmdline_l val; do
725         kernel_cmdline+=" $val "
726     done
727 fi
728
729 omit_drivers_corrected=""
730 for d in $omit_drivers; do
731     strstr " $drivers $add_drivers " " $d " && continue
732     omit_drivers_corrected+="$d|"
733 done
734 omit_drivers="${omit_drivers_corrected%|}"
735 unset omit_drivers_corrected
736
737 # prepare args for logging
738 for ((i=0; i < ${#dracut_args[@]}; i++)); do
739     strstr "${dracut_args[$i]}" " " && \
740         dracut_args[$i]="\"${dracut_args[$i]}\""
741         #" keep vim happy
742 done
743 ddebug "Executing: $0 ${dracut_args[@]}"
744
745 [[ $do_list = yes ]] && {
746     for mod in $dracutbasedir/modules.d/*; do
747         [[ -d $mod ]] || continue;
748         [[ -e $mod/install || -e $mod/installkernel || \
749             -e $mod/module-setup.sh ]] || continue
750         echo ${mod##*/??}
751     done
752     exit 0
753 }
754
755 # This is kinda legacy -- eventually it should go away.
756 case $dracutmodules in
757     ""|auto) dracutmodules="all" ;;
758 esac
759
760 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
761
762 if [[ -d $srcmods ]]; then
763     [[ -f $srcmods/modules.dep ]] || {
764       dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
765     }
766 fi
767
768 if [[ -f $outfile && ! $force ]]; then
769     dfatal "Will not override existing initramfs ($outfile) without --force"
770     exit 1
771 fi
772
773 outdir=${outfile%/*}
774 [[ $outdir ]] || outdir="/"
775
776 if [[ ! -d "$outdir" ]]; then
777     dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
778     exit 1
779 elif [[ ! -w "$outdir" ]]; then
780     dfatal "No permission to write to $outdir."
781     exit 1
782 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
783     dfatal "No permission to write $outfile."
784     exit 1
785 fi
786
787 # Need to be able to have non-root users read stuff (rpcbind etc)
788 chmod 755 "$initdir"
789
790 if [[ $hostonly ]]; then
791     for i in /sys /proc /run /dev; do
792         if ! findmnt "$i" &>/dev/null; then
793             dwarning "Turning off host-only mode: '$i' is not mounted!"
794             unset hostonly
795         fi
796     done
797     if ! [[ -d /run/udev/data ]]; then
798         dwarning "Turning off host-only mode: udev database not found!"
799         unset hostonly
800     fi
801 fi
802
803 declare -A host_fs_types
804
805 for line in "${fstab_lines[@]}"; do
806     set -- $line
807     #dev mp fs fsopts
808     push host_devs "$1"
809     host_fs_types["$1"]="$3"
810 done
811
812 for f in $add_fstab; do
813     [ -e $f ] || continue
814     while read dev rest; do
815         push host_devs $dev
816     done < $f
817 done
818
819 if (( ${#add_device_l[@]} )); then
820     while pop add_device_l val; do
821         add_device+=" $val "
822     done
823 fi
824
825 for dev in $add_device; do
826     push host_devs $dev
827 done
828
829 if [[ $hostonly ]]; then
830     # in hostonly mode, determine all devices, which have to be accessed
831     # and examine them for filesystem types
832
833     push host_mp \
834         "/" \
835         "/etc" \
836         "/usr" \
837         "/usr/bin" \
838         "/usr/sbin" \
839         "/usr/lib" \
840         "/usr/lib64" \
841         "/boot"
842
843     for mp in "${host_mp[@]}"; do
844         mountpoint "$mp" >/dev/null 2>&1 || continue
845         push host_devs $(readlink -f "/dev/block/$(find_block_device "$mp")")
846     done
847
848     while read dev type rest; do
849         [[ -b $dev ]] || continue
850         [[ "$type" == "partition" ]] || continue
851         while read _d _m _t _o _r; do
852             [[ "$_d" == \#* ]] && continue
853             [[ $_d ]] || continue
854             [[ $_t != "swap" ]] || [[ $_m != "swap" ]] && continue
855             [[ "$_o" == *noauto* ]] && continue
856             [[ "$_d" == UUID\=* ]] && _d="/dev/disk/by-uuid/${_d#UUID=}"
857             [[ "$_d" == LABEL\=* ]] && _d="/dev/disk/by-label/$_d#LABEL=}"
858             [[ "$_d" -ef "$dev" ]] || continue
859             push host_devs $(readlink -f $dev)
860             break
861         done < /etc/fstab
862     done < /proc/swaps
863
864 fi
865
866 _get_fs_type() (
867     [[ $1 ]] || return
868     if [[ -b $1 ]] && get_fs_env $1; then
869         echo "$(readlink -f $1) $ID_FS_TYPE"
870         return 1
871     fi
872     if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
873         echo "$(readlink -f /dev/block/$1) $ID_FS_TYPE"
874         return 1
875     fi
876     if fstype=$(find_dev_fstype $1); then
877         echo "$1 $fstype"
878         return 1
879     fi
880     return 1
881 )
882
883 for dev in "${host_devs[@]}"; do
884     while read key val; do
885         host_fs_types["$key"]="$val"
886     done < <(
887         _get_fs_type $dev
888         check_block_and_slaves_all _get_fs_type $(get_maj_min $dev)
889     )
890 done
891
892 [[ -d $udevdir ]] \
893     || udevdir=$(pkg-config udev --variable=udevdir 2>/dev/null)
894 if ! [[ -d "$udevdir" ]]; then
895     [[ -d /lib/udev ]] && udevdir=/lib/udev
896     [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
897 fi
898
899 [[ -d $systemdutildir ]] \
900     || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
901
902 if ! [[ -d "$systemdutildir" ]]; then
903     [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
904     [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
905 fi
906
907 [[ -d $systemdsystemunitdir ]] \
908     || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
909
910 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
911
912 [[ -d $systemdsystemconfdir ]] \
913     || systemdsystemconfdir=$(pkg-config systemd --variable=systemdsystemconfdir 2>/dev/null)
914
915 [[ -d "$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
916
917 export initdir dracutbasedir dracutmodules \
918     fw_dir drivers_dir debug no_kernel kernel_only \
919     omit_drivers mdadmconf lvmconf \
920     use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
921     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
922     debug host_fs_types host_devs sshkey add_fstab \
923     DRACUT_VERSION udevdir prefix filesystems drivers \
924     systemdutildir systemdsystemunitdir systemdsystemconfdir
925
926 # Create some directory structure first
927 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
928
929 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
930 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
931
932 if [[ $prefix ]]; then
933     for d in bin etc lib sbin tmp usr var $libdirs; do
934         strstr "$d" "/" && continue
935         ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
936     done
937 fi
938
939 if [[ $kernel_only != yes ]]; then
940     for d in usr/bin usr/sbin bin etc lib sbin tmp usr var $libdirs; do
941         [[ -e "${initdir}${prefix}/$d" ]] && continue
942         if [ -L "/$d" ]; then
943             inst_symlink "/$d" "${prefix}/$d"
944         else
945             mkdir -m 0755 -p "${initdir}${prefix}/$d"
946         fi
947     done
948
949     for d in dev proc sys sysroot root run run/lock run/initramfs; do
950         if [ -L "/$d" ]; then
951             inst_symlink "/$d"
952         else
953             mkdir -m 0755 -p "$initdir/$d"
954         fi
955     done
956
957     ln -sfn ../run "$initdir/var/run"
958     ln -sfn ../run/lock "$initdir/var/lock"
959     ln -sfn ../run/log "$initdir/var/log"
960 else
961     for d in lib "$libdir"; do
962         [[ -e "${initdir}${prefix}/$d" ]] && continue
963         if [ -h "/$d" ]; then
964             inst "/$d" "${prefix}/$d"
965         else
966             mkdir -m 0755 -p "${initdir}${prefix}/$d"
967         fi
968     done
969 fi
970
971 if [[ $kernel_only != yes ]]; then
972     mkdir -p "${initdir}/etc/cmdline.d"
973     for _d in $hookdirs; do
974         mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
975     done
976     if [[ "$UID" = "0" ]]; then
977         [ -c ${initdir}/dev/null ] || mknod ${initdir}/dev/null c 1 3
978         [ -c ${initdir}/dev/kmsg ] || mknod ${initdir}/dev/kmsg c 1 11
979         [ -c ${initdir}/dev/console ] || mknod ${initdir}/dev/console c 5 1
980     fi
981 fi
982
983 mods_to_load=""
984 # check all our modules to see if they should be sourced.
985 # This builds a list of modules that we will install next.
986 for_each_module_dir check_module
987 for_each_module_dir check_mount
988
989 strstr "$mods_to_load" "fips" && export DRACUT_FIPS_MODE=1
990
991 _isize=0 #initramfs size
992 modules_loaded=" "
993 # source our modules.
994 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
995     _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
996     if strstr "$mods_to_load" " $_d_mod "; then
997         [[ $show_modules = yes ]] && echo "$_d_mod" || \
998             dinfo "*** Including module: $_d_mod ***"
999         if [[ $kernel_only = yes ]]; then
1000             module_installkernel $_d_mod || {
1001                 dfatal "installkernel failed in module $_d_mod"
1002                 exit 1
1003             }
1004         else
1005             module_install $_d_mod
1006             if [[ $no_kernel != yes ]]; then
1007                 module_installkernel $_d_mod || {
1008                     dfatal "installkernel failed in module $_d_mod"
1009                     exit 1
1010                 }
1011             fi
1012         fi
1013         mods_to_load=${mods_to_load// $_d_mod /}
1014         modules_loaded+="$_d_mod "
1015
1016         #print the module install size
1017         if [ -n "$printsize" ]; then
1018             _isize_new=$(du -sk ${initdir}|cut -f1)
1019             _isize_delta=$(($_isize_new - $_isize))
1020             echo "$_d_mod install size: ${_isize_delta}k"
1021             _isize=$_isize_new
1022         fi
1023     fi
1024 done
1025 unset moddir
1026
1027 for i in $modules_loaded; do
1028     mkdir -p $initdir/lib/dracut
1029     echo "$i" >> $initdir/lib/dracut/modules.txt
1030 done
1031
1032 dinfo "*** Including modules done ***"
1033
1034 ## final stuff that has to happen
1035 if [[ $no_kernel != yes ]]; then
1036
1037     if [[ $drivers ]]; then
1038         hostonly='' instmods $drivers
1039     fi
1040
1041     if [[ $add_drivers ]]; then
1042         hostonly='' instmods -c $add_drivers
1043     fi
1044     if [[ $filesystems ]]; then
1045         hostonly='' instmods -c $filesystems
1046     fi
1047
1048     dinfo "*** Installing kernel module dependencies and firmware ***"
1049     dracut_kernel_post
1050     dinfo "*** Installing kernel module dependencies and firmware done ***"
1051
1052     if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
1053         if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
1054             [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
1055             for i in ${initdir}/etc/cmdline.d/*.conf; do
1056                 # We need no initramfs image and do not generate one.
1057                 [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
1058             done
1059         fi
1060     fi
1061 fi
1062
1063 if [[ $kernel_only != yes ]]; then
1064     (( ${#install_items[@]} > 0 )) && dracut_install  ${install_items[@]}
1065
1066     [[ $kernel_cmdline ]] && echo "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
1067
1068     while pop fstab_lines line; do
1069         echo "$line 0 0" >> "${initdir}/etc/fstab"
1070     done
1071
1072     for f in $add_fstab; do
1073         cat $f >> "${initdir}/etc/fstab"
1074     done
1075
1076     if [ -d ${initdir}/$systemdutildir ]; then
1077         mkdir -p ${initdir}/etc/conf.d
1078         {
1079             echo "systemdutildir=\"$systemdutildir\""
1080             echo "systemdsystemunitdir=\"$systemdsystemunitdir\""
1081             echo "systemdsystemconfdir=\"$systemdsystemconfdir\""
1082         } > ${initdir}/etc/conf.d/systemd.conf
1083     fi
1084
1085     if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
1086         dinfo "*** Resolving executable dependencies ***"
1087         find "$initdir" -type f \
1088             '(' -perm -0100 -or -perm -0010 -or -perm -0001 ')' \
1089             -not -path '*.ko' -print0 \
1090         | xargs -r -0 $DRACUT_INSTALL ${initdir+-D "$initdir"} -R ${DRACUT_FIPS_MODE+-H}
1091         dinfo "*** Resolving executable dependencies done***"
1092     fi
1093 fi
1094
1095 while pop include_src src && pop include_target tgt; do
1096     if [[ $src && $tgt ]]; then
1097         if [[ -f $src ]]; then
1098             inst $src $tgt
1099         else
1100             ddebug "Including directory: $src"
1101             mkdir -p "${initdir}/${tgt}"
1102             # check for preexisting symlinks, so we can cope with the
1103             # symlinks to $prefix
1104             for i in "$src"/*; do
1105                 [[ -e "$i" || -h "$i" ]] || continue
1106                 s=${initdir}/${tgt}/${i#$src/}
1107                 if [[ -d "$i" ]]; then
1108                     if ! [[ -e "$s" ]]; then
1109                         mkdir -m 0755 -p "$s"
1110                         chmod --reference="$i" "$s"
1111                     fi
1112                     cp --reflink=auto --sparse=auto -fa -t "$s" "$i"/*
1113                 else
1114                     cp --reflink=auto --sparse=auto -fa -t "$s" "$i"
1115                 fi
1116             done
1117         fi
1118     fi
1119 done
1120
1121 if [[ $kernel_only != yes ]]; then
1122     # make sure that library links are correct and up to date
1123     for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
1124         [[ -f $f ]] && inst_simple "$f"
1125     done
1126     if ! ldconfig -r "$initdir"; then
1127         if [[ $UID = 0 ]]; then
1128             derror "ldconfig exited ungracefully"
1129         else
1130             derror "ldconfig might need uid=0 (root) for chroot()"
1131         fi
1132     fi
1133 fi
1134
1135 if (($maxloglvl >= 5)); then
1136     ddebug "Listing sizes of included files:"
1137     du -c "$initdir" | sort -n | ddebug
1138 fi
1139
1140 PRELINK_BIN=$(command -v prelink)
1141 if [[ $UID = 0 ]] && [[ $PRELINK_BIN ]]; then
1142     if [[ $DRACUT_FIPS_MODE ]]; then
1143         dinfo "*** Pre-unlinking files ***"
1144         dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf /etc/prelink.cache
1145         chroot "$initdir" $PRELINK_BIN -u -a
1146         rm -f "$initdir"/$PRELINK_BIN
1147         rm -fr "$initdir"/etc/prelink.*
1148         dinfo "*** Pre-unlinking files done ***"
1149     else
1150         dinfo "*** Pre-linking files ***"
1151         dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf
1152         chroot "$initdir" $PRELINK_BIN -a
1153         rm -f "$initdir"/$PRELINK_BIN
1154         rm -fr "$initdir"/etc/prelink.*
1155         dinfo "*** Pre-linking files done ***"
1156     fi
1157 fi
1158
1159 if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
1160     dinfo "*** Hardlinking files ***"
1161     hardlink "$initdir" 2>&1
1162     dinfo "*** Hardlinking files done ***"
1163 fi
1164
1165 # strip binaries
1166 if [[ $do_strip = yes ]] ; then
1167     for p in strip xargs find; do
1168         if ! type -P $p >/dev/null; then
1169             dwarn "Could not find '$p'. Not stripping the initramfs."
1170             do_strip=no
1171         fi
1172     done
1173 fi
1174
1175 if [[ $do_strip = yes ]] ; then
1176     dinfo "*** Stripping files ***"
1177     if [[ $DRACUT_FIPS_MODE ]]; then
1178         find "$initdir" -type f \
1179             -executable -not -path '*/lib/modules/*.ko' -print0 \
1180             | while read -r -d $'\0' f; do
1181             if ! [[ -e "${f%/*}/.${f##*/}.hmac" ]] \
1182                 && ! [[ -e "/lib/hmaccalc/${f##*/}.hmac" ]] \
1183                 && ! [[ -e "/lib64/hmaccalc/${f##*/}.hmac" ]] \
1184                 && ! [[ -e "/lib/fipscheck/${f##*/}.hmac" ]] \
1185                 && ! [[ -e "/lib64/fipscheck/${f##*/}.hmac" ]]; then
1186                 echo -n "$f"; echo -n -e "\000"
1187             fi
1188         done | xargs -r -0 strip -g 2>/dev/null
1189     else
1190         find "$initdir" -type f \
1191             -executable -not -path '*/lib/modules/*.ko' -print0 \
1192             | xargs -r -0 strip -g 2>/dev/null
1193     fi
1194
1195     # strip kernel modules, but do not touch signed modules
1196     find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
1197         | while read -r -d $'\0' f; do
1198         SIG=$(tail -c 28 "$f")
1199         [[ $SIG == '~Module signature appended~' ]] || { echo -n "$f"; echo -n -e "\000"; }
1200     done | xargs -r -0 strip -g
1201
1202     dinfo "*** Stripping files done ***"
1203 fi
1204
1205 rm -f "$outfile"
1206 dinfo "*** Creating image file ***"
1207 if ! ( umask 077; cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
1208     $compress > "$outfile.$$"; ); then
1209     dfatal "dracut: creation of $outfile.$$ failed"
1210     exit 1
1211 fi
1212 mv $outfile.$$ $outfile
1213 dinfo "*** Creating image file done ***"
1214
1215 dinfo "Wrote $outfile:"
1216 dinfo "$(ls -l "$outfile")"
1217
1218 exit 0