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