fixed instmods() return code and set pipefail globally
[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 [[ $debug ]] && {
321     export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
322     set -x
323 }
324
325 [[ $profile ]] && {
326     export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
327     set -x
328     debug=yes
329 }
330
331 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
332
333 # if we were not passed a config file, try the default one
334 if [[ ! -f $conffile ]]; then
335     [[ $allowlocal ]] && conffile="$dracutbasedir/dracut.conf" || \
336         conffile="/etc/dracut.conf"
337 fi
338
339 if [[ ! -d $confdir ]]; then
340     [[ $allowlocal ]] && confdir="$dracutbasedir/dracut.conf.d" || \
341         confdir="/etc/dracut.conf.d"
342 fi
343
344 # source our config file
345 [[ -f $conffile ]] && . "$conffile"
346
347 # source our config dir
348 if [[ $confdir && -d $confdir ]]; then
349     for f in "$confdir"/*.conf; do
350         [[ -e $f ]] && . "$f"
351     done
352 fi
353
354 # these optins add to the stuff in the config file
355 if (( ${#add_dracutmodules_l[@]} )); then
356     while pop add_dracutmodules_l val; do
357         add_dracutmodules+=" $val "
358     done
359 fi
360
361 if (( ${#force_add_dracutmodules_l[@]} )); then
362     while pop force_add_dracutmodules_l val; do
363         force_add_dracutmodules+=" $val "
364     done
365 fi
366
367 if (( ${#fscks_l[@]} )); then
368     while pop fscks_l val; do
369         fscks+=" $val "
370     done
371 fi
372
373 if (( ${#add_fstab_l[@]} )); then
374     while pop add_fstab_l val; do
375         add_fstab+=" $val "
376     done
377 fi
378
379 if (( ${#fstab_lines_l[@]} )); then
380     while pop fstab_lines_l val; do
381         push fstab_lines $val
382     done
383 fi
384
385 if (( ${#install_items_l[@]} )); then
386     while pop install_items_l val; do
387         install_items+=" $val "
388     done
389 fi
390
391 # these options override the stuff in the config file
392 if (( ${#dracutmodules_l[@]} )); then
393     dracutmodules=''
394     while pop dracutmodules_l val; do
395         dracutmodules+="$val "
396     done
397 fi
398
399 if (( ${#omit_dracutmodules_l[@]} )); then
400     omit_dracutmodules=''
401     while pop omit_dracutmodules_l val; do
402         omit_dracutmodules+="$val "
403     done
404 fi
405
406 if (( ${#filesystems_l[@]} )); then
407     filesystems=''
408     while pop filesystems_l val; do
409         filesystems+="$val "
410     done
411 fi
412
413 if (( ${#fw_dir_l[@]} )); then
414     fw_dir=''
415     while pop fw_dir_l val; do
416         fw_dir+="$val "
417     done
418 fi
419
420 if (( ${#libdirs_l[@]} )); then
421     libdirs=''
422     while pop libdirs_l val; do
423         libdirs+="$val "
424     done
425 fi
426
427 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
428 [[ ! $stdloglvl ]] && stdloglvl=4
429 stdloglvl=$((stdloglvl + verbosity_mod_l))
430 ((stdloglvl > 6)) && stdloglvl=6
431 ((stdloglvl < 0)) && stdloglvl=0
432
433 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
434 [[ $do_strip_l ]] && do_strip=$do_strip_l
435 [[ $prefix_l ]] && prefix=$prefix_l
436 [[ $prefix = "/" ]] && unset prefix
437 [[ $hostonly_l ]] && hostonly=$hostonly_l
438 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
439 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
440 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
441 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
442 [[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware"
443 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
444 [[ $tmpdir ]] || tmpdir=/var/tmp
445 [[ $do_strip ]] || do_strip=no
446 [[ $compress_l ]] && compress=$compress_l
447 [[ $show_modules_l ]] && show_modules=$show_modules_l
448 [[ $nofscks_l ]] && nofscks="yes"
449 # eliminate IFS hackery when messing with fw_dir
450 fw_dir=${fw_dir//:/ }
451
452 # handle compression options.
453 [[ $compress ]] || compress="gzip"
454 case $compress in
455     bzip2) compress="bzip2 -9";;
456     lzma)  compress="lzma -9";;
457     xz)    compress="xz --check=crc32 --lzma2=dict=1MiB";;
458     gzip)  command -v pigz > /dev/null 2>&1 && compress="pigz -9" || \
459                                          compress="gzip -9";;
460 esac
461 if [[ $_no_compress_l = "cat" ]]; then
462     compress="cat"
463 fi
464
465 [[ $hostonly = yes ]] && hostonly="-h"
466 [[ $hostonly != "-h" ]] && unset hostonly
467
468 if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
469     . $dracutbasedir/dracut-functions.sh
470 else
471     echo "Cannot find $dracutbasedir/dracut-functions.sh." >&2
472     echo "Are you running from a git checkout?" >&2
473     echo "Try passing -l as an argument to $0" >&2
474     exit 1
475 fi
476
477 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
478     . $dracutbasedir/dracut-version.sh
479 fi
480
481 # Verify bash version, curret minimum is 3.1
482 if (( ${BASH_VERSINFO[0]} < 3 ||
483     ( ${BASH_VERSINFO[0]} == 3 && ${BASH_VERSINFO[1]} < 1 ) )); then
484     dfatal 'You need at least Bash 3.1 to use dracut, sorry.'
485     exit 1
486 fi
487
488 dracutfunctions=$dracutbasedir/dracut-functions.sh
489 export dracutfunctions
490
491 if (( ${#drivers_l[@]} )); then
492     drivers=''
493     while pop drivers_l val; do
494         drivers+="$val "
495     done
496 fi
497 drivers=${drivers/-/_}
498
499 if (( ${#add_drivers_l[@]} )); then
500     while pop add_drivers_l val; do
501         add_drivers+=" $val "
502     done
503 fi
504 add_drivers=${add_drivers/-/_}
505
506 if (( ${#omit_drivers_l[@]} )); then
507     while pop omit_drivers_l val; do
508         omit_drivers+=" $val "
509     done
510 fi
511 omit_drivers=${omit_drivers/-/_}
512
513 omit_drivers_corrected=""
514 for d in $omit_drivers; do
515     strstr " $drivers $add_drivers " " $d " && continue
516     omit_drivers_corrected+="$d|"
517 done
518 omit_drivers="${omit_drivers_corrected%|}"
519 unset omit_drivers_corrected
520
521
522 ddebug "Executing $0 $dracut_args"
523
524 [[ $do_list = yes ]] && {
525     for mod in $dracutbasedir/modules.d/*; do
526         [[ -d $mod ]] || continue;
527         [[ -e $mod/install || -e $mod/installkernel || \
528             -e $mod/module-setup.sh ]] || continue
529         echo ${mod##*/??}
530     done
531     exit 0
532 }
533
534 # Detect lib paths
535 if ! [[ $libdirs ]] ; then
536     if strstr "$(ldd /bin/sh)" "/lib64/" &>/dev/null \
537         && [[ -d /lib64 ]]; then
538         libdirs+=" /lib64"
539         [[ -d /usr/lib64 ]] && libdirs+=" /usr/lib64"
540     else
541         libdirs+=" /lib"
542         [[ -d /usr/lib ]] && libdirs+=" /usr/lib"
543     fi
544 fi
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 srcmods="/lib/modules/$kernel/"
554 [[ $drivers_dir ]] && {
555     if vercmp $(modprobe --version | cut -d' ' -f3) lt 3.7; then
556         dfatal 'To use --kmoddir option module-init-tools >= 3.7 is required.'
557         exit 1
558     fi
559     srcmods="$drivers_dir"
560 }
561 export srcmods
562
563 [[ -f $srcmods/modules.dep ]] || {
564     dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
565     exit 1
566 }
567
568 if [[ -f $outfile && ! $force ]]; then
569     dfatal "Will not override existing initramfs ($outfile) without --force"
570     exit 1
571 fi
572
573 outdir=${outfile%/*}
574 [[ $outdir ]] || outdir="/"
575
576 if [[ ! -d "$outdir" ]]; then
577     dfatal "Can't write $outfile: Directory $outdir does not exist."
578     exit 1
579 elif [[ ! -w "$outdir" ]]; then
580     dfatal "No permission to write $outdir."
581     exit 1
582 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
583     dfatal "No permission to write $outfile."
584     exit 1
585 fi
586
587 readonly TMPDIR="$tmpdir"
588 readonly initdir=$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)
589 [ -d "$initdir" ] || {
590     dfatal "mktemp failed."
591     exit 1
592 }
593
594 # clean up after ourselves no matter how we die.
595 trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
596 # clean up after ourselves no matter how we die.
597 trap 'exit 1;' SIGINT
598
599 # Need to be able to have non-root users read stuff (rpcbind etc)
600 chmod 755 "$initdir"
601
602 for line in "${fstab_lines[@]}"; do
603     set -- $line
604     #dev mp fs fsopts
605     push host_devs "$1"
606     push host_fs_types "$1|$3"
607 done
608
609 for f in $add_fstab; do
610     [ -e $f ] || continue
611     while read dev rest; do
612         push host_devs $dev
613     done < $f
614 done
615
616 if [[ $hostonly ]]; then
617     # in hostonly mode, determine all devices, which have to be accessed
618     # and examine them for filesystem types
619
620     push host_mp \
621         "/" \
622         "/etc" \
623         "/usr" \
624         "/usr/bin" \
625         "/usr/sbin" \
626         "/usr/lib" \
627         "/usr/lib64" \
628         "/boot"
629
630     for mp in "${host_mp[@]}"; do
631         mountpoint "$mp" >/dev/null 2>&1 || continue
632         push host_devs $(readlink -f "/dev/block/$(find_block_device "$mp")")
633     done
634 fi
635
636 _get_fs_type() (
637     [[ $1 ]] || return
638     if [[ -b $1 ]] && get_fs_env $1; then
639         echo "$(readlink -f $1)|$ID_FS_TYPE"
640         return 1
641     fi
642     if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
643         echo "$(readlink -f /dev/block/$1)|$ID_FS_TYPE"
644         return 1
645     fi
646     if fstype=$(find_dev_fstype $1); then
647         echo "$1|$fstype"
648         return 1
649     fi
650     return 1
651 )
652
653 for dev in "${host_devs[@]}"; do
654     unset fs_type
655     for fstype in $(_get_fs_type $dev) \
656         $(check_block_and_slaves _get_fs_type $(get_maj_min $dev)); do
657         if ! strstr " ${host_fs_types[*]} " " $fstype ";then
658             push host_fs_types "$fstype"
659         fi
660     done
661 done
662
663 [[ -d $udevdir ]] \
664     || udevdir=$(pkg-config udev --variable=udevdir 2>/dev/null)
665 if ! [[ -d "$udevdir" ]]; then
666     [[ -d /lib/udev ]] && udevdir=/lib/udev
667     [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
668 fi
669
670 [[ -d $systemdutildir ]] \
671     || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
672 [[ -d $systemdsystemunitdir ]] \
673     || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
674
675 if ! [[ -d "$systemdutildir" ]]; then
676     [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
677     [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
678 fi
679 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
680
681 export initdir dracutbasedir dracutmodules drivers \
682     fw_dir drivers_dir debug no_kernel kernel_only \
683     add_drivers omit_drivers mdadmconf lvmconf filesystems \
684     use_fstab fstab_lines libdirs fscks nofscks \
685     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
686     debug host_fs_types host_devs sshkey add_fstab \
687     DRACUT_VERSION udevdir systemdutildir systemdsystemunitdir
688
689 # Create some directory structure first
690 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
691
692 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
693 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
694
695 if [[ $prefix ]]; then
696     for d in bin etc lib sbin tmp usr var $libdirs; do
697         strstr "$d" "/" && continue
698         ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
699     done
700 fi
701
702 if [[ $kernel_only != yes ]]; then
703     for d in usr/bin usr/sbin bin etc lib sbin tmp usr var var/log var/run var/lock $libdirs; do
704         [[ -e "${initdir}${prefix}/$d" ]] && continue
705         if [ -L "/$d" ]; then
706             inst_symlink "/$d" "${prefix}/$d"
707         else
708             mkdir -m 0755 -p "${initdir}${prefix}/$d"
709         fi
710     done
711
712     for d in dev proc sys sysroot root run run/lock run/initramfs; do
713         if [ -L "/$d" ]; then
714             inst_symlink "/$d"
715         else
716             mkdir -m 0755 -p "$initdir/$d"
717         fi
718     done
719
720     ln -sfn /run "$initdir/var/run"
721     ln -sfn /run/lock "$initdir/var/lock"
722 else
723     for d in lib "$libdir"; do
724         [[ -e "${initdir}${prefix}/$d" ]] && continue
725         if [ -h "/$d" ]; then
726             inst "/$d" "${prefix}/$d"
727         else
728             mkdir -m 0755 -p "${initdir}${prefix}/$d"
729         fi
730     done
731 fi
732
733 if [[ $kernel_only != yes ]]; then
734     mkdir -p "${initdir}/etc/cmdline.d"
735     for _d in $hookdirs; do
736         mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
737     done
738     if [[ "$UID" = "0" ]]; then
739         for i in /dev/kmsg /dev/null /dev/console; do
740             [ -e $i ] || continue
741             cp -a $i $initdir/dev
742         done
743     fi
744 fi
745
746 mkdir -p "$initdir/.kernelmodseen"
747
748 mods_to_load=""
749 # check all our modules to see if they should be sourced.
750 # This builds a list of modules that we will install next.
751 for_each_module_dir check_module
752 for_each_module_dir check_mount
753
754 _isize=0 #initramfs size
755 modules_loaded=" "
756 # source our modules.
757 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
758     _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
759     if strstr "$mods_to_load" " $_d_mod "; then
760         [[ $show_modules = yes ]] && echo "$_d_mod" || \
761             dinfo "*** Including module: $_d_mod ***"
762         if [[ $kernel_only = yes ]]; then
763             module_installkernel $_d_mod || {
764                 dfatal "installkernel failed in module $_d_mod"
765                 exit 1
766             }
767         else
768             module_install $_d_mod
769             if [[ $no_kernel != yes ]]; then
770                 module_installkernel $_d_mod || {
771                     dfatal "installkernel failed in module $_d_mod"
772                     exit 1
773                 }
774             fi
775         fi
776         mods_to_load=${mods_to_load// $_d_mod /}
777         modules_loaded+="$_d_mod "
778
779         #print the module install size
780         if [ -n "$printsize" ]; then
781             _isize_new=$(du -sk ${initdir}|cut -f1)
782             _isize_delta=$(($_isize_new - $_isize))
783             echo "$_d_mod install size: ${_isize_delta}k"
784             _isize=$_isize_new
785         fi
786     fi
787 done
788 unset moddir
789
790 for i in $modules_loaded; do
791     mkdir -p $initdir/lib/dracut
792     echo "$i" >> $initdir/lib/dracut/modules.txt
793 done
794
795 dinfo "*** Including modules done ***"
796
797 ## final stuff that has to happen
798
799 # generate module dependencies for the initrd
800 if [[ -d $initdir/lib/modules/$kernel ]] && \
801     ! depmod -a -b "$initdir" $kernel; then
802     dfatal "\"depmod -a $kernel\" failed."
803     exit 1
804 fi
805
806 while pop include_src src && pop include_target tgt; do
807     if [[ $src && $tgt ]]; then
808         if [[ -f $src ]]; then
809             inst $src $tgt
810         else
811             ddebug "Including directory: $src"
812             mkdir -p "${initdir}/${tgt}"
813             # check for preexisting symlinks, so we can cope with the
814             # symlinks to $prefix
815             for i in "$src"/*; do
816                 [[ -e "$i" || -h "$i" ]] || continue
817                 s=${initdir}/${tgt}/${i#$src/}
818                 if [[ -d "$i" ]]; then
819                     if ! [[ -e "$s" ]]; then
820                         mkdir -m 0755 -p "$s"
821                         chmod --reference="$i" "$s"
822                     fi
823                     cp -a -t "$s" "$i"/*
824                 else
825                     cp -a -t "$s" "$i"
826                 fi
827             done
828         fi
829     fi
830 done
831
832 if [[ $kernel_only != yes ]]; then
833     for item in $install_items; do
834         dracut_install "$item"
835     done
836     unset item
837
838     while pop fstab_lines line; do
839         echo "$line 0 0" >> "${initdir}/etc/fstab"
840     done
841
842     for f in $add_fstab; do
843         cat $f >> "${initdir}/etc/fstab"
844     done
845
846     # make sure that library links are correct and up to date
847     for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
848         [[ -f $f ]] && inst_simple "$f"
849     done
850     if ! ldconfig -r "$initdir"; then
851         if [[ $UID = 0 ]]; then
852             derror "ldconfig exited ungracefully"
853         else
854             derror "ldconfig might need uid=0 (root) for chroot()"
855         fi
856     fi
857 fi
858
859 rm -fr "$initdir/.kernelmodseen"
860
861
862 if (($maxloglvl >= 5)); then
863     ddebug "Listing sizes of included files:"
864     du -c "$initdir" | sort -n | ddebug
865 fi
866
867 # strip binaries
868 if [[ $do_strip = yes ]] ; then
869     for p in strip grep find; do
870         if ! type -P $p >/dev/null; then
871             derror "Could not find '$p'. You should run $0 with '--nostrip'."
872             do_strip=no
873         fi
874     done
875 fi
876
877 if [[ $do_strip = yes ]] ; then
878     for f in $(find "$initdir" -type f \
879         \( -perm -0100 -or -perm -0010 -or -perm -0001 \
880            -or -path '*/lib/modules/*.ko' \) ); do
881         dinfo "Stripping $f"
882         strip -g "$f" 2>/dev/null|| :
883     done
884 fi
885
886 type hardlink &>/dev/null && {
887     hardlink "$initdir" 2>&1
888 }
889
890 if strstr "$modules_loaded" " fips " && command -v prelink >/dev/null; then
891     for dir in "$initdir/bin" \
892        "$initdir/sbin" \
893        "$initdir/usr/bin" \
894        "$initdir/usr/sbin"; do
895         [[ -L "$dir" ]] && continue
896         for i in "$dir"/*; do
897             [[ -x $i ]] && prelink -u $i &>/dev/null
898         done
899     done
900 fi
901
902 if ! ( cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
903     $compress > "$outfile"; ); then
904     dfatal "dracut: creation of $outfile failed"
905     exit 1
906 fi
907
908 dinfo "Wrote $outfile:"
909 dinfo "$(ls -l "$outfile")"
910
911 exit 0