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