dracut.sh, dracut-functions.sh: add dracut_kernel_post()
[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 readonly TMPDIR="$tmpdir"
469 readonly initdir=$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)
470 [ -d "$initdir" ] || {
471     echo "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXXfailed." >&2
472     exit 1
473 }
474
475 if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
476     . $dracutbasedir/dracut-functions.sh
477 else
478     echo "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
479     echo "dracut: Are you running from a git checkout?" >&2
480     echo "dracut: Try passing -l as an argument to $0" >&2
481     exit 1
482 fi
483
484 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
485     . $dracutbasedir/dracut-version.sh
486 fi
487
488 # Verify bash version, curret minimum is 3.1
489 if (( ${BASH_VERSINFO[0]} < 3 ||
490     ( ${BASH_VERSINFO[0]} == 3 && ${BASH_VERSINFO[1]} < 1 ) )); then
491     dfatal 'You need at least Bash 3.1 to use dracut, sorry.'
492     exit 1
493 fi
494
495 dracutfunctions=$dracutbasedir/dracut-functions.sh
496 export dracutfunctions
497
498 if (( ${#drivers_l[@]} )); then
499     drivers=''
500     while pop drivers_l val; do
501         drivers+="$val "
502     done
503 fi
504 drivers=${drivers/-/_}
505
506 if (( ${#add_drivers_l[@]} )); then
507     while pop add_drivers_l val; do
508         add_drivers+=" $val "
509     done
510 fi
511 add_drivers=${add_drivers/-/_}
512
513 if (( ${#omit_drivers_l[@]} )); then
514     while pop omit_drivers_l val; do
515         omit_drivers+=" $val "
516     done
517 fi
518 omit_drivers=${omit_drivers/-/_}
519
520 omit_drivers_corrected=""
521 for d in $omit_drivers; do
522     strstr " $drivers $add_drivers " " $d " && continue
523     omit_drivers_corrected+="$d|"
524 done
525 omit_drivers="${omit_drivers_corrected%|}"
526 unset omit_drivers_corrected
527
528
529 ddebug "Executing $0 $dracut_args"
530
531 [[ $do_list = yes ]] && {
532     for mod in $dracutbasedir/modules.d/*; do
533         [[ -d $mod ]] || continue;
534         [[ -e $mod/install || -e $mod/installkernel || \
535             -e $mod/module-setup.sh ]] || continue
536         echo ${mod##*/??}
537     done
538     exit 0
539 }
540
541 # This is kinda legacy -- eventually it should go away.
542 case $dracutmodules in
543     ""|auto) dracutmodules="all" ;;
544 esac
545
546 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
547
548 [[ -f $srcmods/modules.dep ]] || {
549     dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
550     exit 1
551 }
552
553 if [[ -f $outfile && ! $force ]]; then
554     dfatal "Will not override existing initramfs ($outfile) without --force"
555     exit 1
556 fi
557
558 outdir=${outfile%/*}
559 [[ $outdir ]] || outdir="/"
560
561 if [[ ! -d "$outdir" ]]; then
562     dfatal "Can't write $outfile: Directory $outdir does not exist."
563     exit 1
564 elif [[ ! -w "$outdir" ]]; then
565     dfatal "No permission to write $outdir."
566     exit 1
567 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
568     dfatal "No permission to write $outfile."
569     exit 1
570 fi
571
572 # clean up after ourselves no matter how we die.
573 trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
574 # clean up after ourselves no matter how we die.
575 trap 'exit 1;' SIGINT
576
577 # Need to be able to have non-root users read stuff (rpcbind etc)
578 chmod 755 "$initdir"
579
580 for line in "${fstab_lines[@]}"; do
581     set -- $line
582     #dev mp fs fsopts
583     push host_devs "$1"
584     push host_fs_types "$1|$3"
585 done
586
587 for f in $add_fstab; do
588     [ -e $f ] || continue
589     while read dev rest; do
590         push host_devs $dev
591     done < $f
592 done
593
594 if [[ $hostonly ]]; then
595     # in hostonly mode, determine all devices, which have to be accessed
596     # and examine them for filesystem types
597
598     push host_mp \
599         "/" \
600         "/etc" \
601         "/usr" \
602         "/usr/bin" \
603         "/usr/sbin" \
604         "/usr/lib" \
605         "/usr/lib64" \
606         "/boot"
607
608     for mp in "${host_mp[@]}"; do
609         mountpoint "$mp" >/dev/null 2>&1 || continue
610         push host_devs $(readlink -f "/dev/block/$(find_block_device "$mp")")
611     done
612 fi
613
614 _get_fs_type() (
615     [[ $1 ]] || return
616     if [[ -b $1 ]] && get_fs_env $1; then
617         echo "$(readlink -f $1)|$ID_FS_TYPE"
618         return 1
619     fi
620     if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
621         echo "$(readlink -f /dev/block/$1)|$ID_FS_TYPE"
622         return 1
623     fi
624     if fstype=$(find_dev_fstype $1); then
625         echo "$1|$fstype"
626         return 1
627     fi
628     return 1
629 )
630
631 for dev in "${host_devs[@]}"; do
632     unset fs_type
633     for fstype in $(_get_fs_type $dev) \
634         $(check_block_and_slaves _get_fs_type $(get_maj_min $dev)); do
635         if ! strstr " ${host_fs_types[*]} " " $fstype ";then
636             push host_fs_types "$fstype"
637         fi
638     done
639 done
640
641 [[ -d $udevdir ]] \
642     || udevdir=$(pkg-config udev --variable=udevdir 2>/dev/null)
643 if ! [[ -d "$udevdir" ]]; then
644     [[ -d /lib/udev ]] && udevdir=/lib/udev
645     [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
646 fi
647
648 [[ -d $systemdutildir ]] \
649     || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
650 [[ -d $systemdsystemunitdir ]] \
651     || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
652
653 if ! [[ -d "$systemdutildir" ]]; then
654     [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
655     [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
656 fi
657 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
658
659 export initdir dracutbasedir dracutmodules drivers \
660     fw_dir drivers_dir debug no_kernel kernel_only \
661     add_drivers omit_drivers mdadmconf lvmconf filesystems \
662     use_fstab fstab_lines libdirs fscks nofscks \
663     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
664     debug host_fs_types host_devs sshkey add_fstab \
665     DRACUT_VERSION udevdir systemdutildir systemdsystemunitdir
666
667 # Create some directory structure first
668 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
669
670 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
671 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
672
673 if [[ $prefix ]]; then
674     for d in bin etc lib sbin tmp usr var $libdirs; do
675         strstr "$d" "/" && continue
676         ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
677     done
678 fi
679
680 if [[ $kernel_only != yes ]]; then
681     for d in usr/bin usr/sbin bin etc lib sbin tmp usr var var/log var/run var/lock $libdirs; do
682         [[ -e "${initdir}${prefix}/$d" ]] && continue
683         if [ -L "/$d" ]; then
684             inst_symlink "/$d" "${prefix}/$d"
685         else
686             mkdir -m 0755 -p "${initdir}${prefix}/$d"
687         fi
688     done
689
690     for d in dev proc sys sysroot root run run/lock run/initramfs; do
691         if [ -L "/$d" ]; then
692             inst_symlink "/$d"
693         else
694             mkdir -m 0755 -p "$initdir/$d"
695         fi
696     done
697
698     ln -sfn /run "$initdir/var/run"
699     ln -sfn /run/lock "$initdir/var/lock"
700 else
701     for d in lib "$libdir"; do
702         [[ -e "${initdir}${prefix}/$d" ]] && continue
703         if [ -h "/$d" ]; then
704             inst "/$d" "${prefix}/$d"
705         else
706             mkdir -m 0755 -p "${initdir}${prefix}/$d"
707         fi
708     done
709 fi
710
711 if [[ $kernel_only != yes ]]; then
712     mkdir -p "${initdir}/etc/cmdline.d"
713     for _d in $hookdirs; do
714         mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
715     done
716     if [[ "$UID" = "0" ]]; then
717         [ -c ${initdir}/dev/null ] || mknod ${initdir}/dev/null c 1 3
718         [ -c ${initdir}/dev/kmsg ] || mknod ${initdir}/dev/kmsg c 1 11
719         [ -c ${initdir}/dev/console ] || mknod ${initdir}/dev/console c 5 1
720     fi
721 fi
722
723 mods_to_load=""
724 # check all our modules to see if they should be sourced.
725 # This builds a list of modules that we will install next.
726 for_each_module_dir check_module
727 for_each_module_dir check_mount
728
729 _isize=0 #initramfs size
730 modules_loaded=" "
731 # source our modules.
732 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
733     _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
734     if strstr "$mods_to_load" " $_d_mod "; then
735         [[ $show_modules = yes ]] && echo "$_d_mod" || \
736             dinfo "*** Including module: $_d_mod ***"
737         if [[ $kernel_only = yes ]]; then
738             module_installkernel $_d_mod || {
739                 dfatal "installkernel failed in module $_d_mod"
740                 exit 1
741             }
742         else
743             module_install $_d_mod
744             if [[ $no_kernel != yes ]]; then
745                 module_installkernel $_d_mod || {
746                     dfatal "installkernel failed in module $_d_mod"
747                     exit 1
748                 }
749             fi
750         fi
751         mods_to_load=${mods_to_load// $_d_mod /}
752         modules_loaded+="$_d_mod "
753
754         #print the module install size
755         if [ -n "$printsize" ]; then
756             _isize_new=$(du -sk ${initdir}|cut -f1)
757             _isize_delta=$(($_isize_new - $_isize))
758             echo "$_d_mod install size: ${_isize_delta}k"
759             _isize=$_isize_new
760         fi
761     fi
762 done
763 unset moddir
764
765 for i in $modules_loaded; do
766     mkdir -p $initdir/lib/dracut
767     echo "$i" >> $initdir/lib/dracut/modules.txt
768 done
769
770 dinfo "*** Including modules done ***"
771
772 ## final stuff that has to happen
773
774 dinfo "*** Installing kernel module dependencies and firmware ***"
775 dracut_kernel_post
776 dinfo "*** Installing kernel module dependencies and firmware done ***"
777
778 while pop include_src src && pop include_target tgt; do
779     if [[ $src && $tgt ]]; then
780         if [[ -f $src ]]; then
781             inst $src $tgt
782         else
783             ddebug "Including directory: $src"
784             mkdir -p "${initdir}/${tgt}"
785             # check for preexisting symlinks, so we can cope with the
786             # symlinks to $prefix
787             for i in "$src"/*; do
788                 [[ -e "$i" || -h "$i" ]] || continue
789                 s=${initdir}/${tgt}/${i#$src/}
790                 if [[ -d "$i" ]]; then
791                     if ! [[ -e "$s" ]]; then
792                         mkdir -m 0755 -p "$s"
793                         chmod --reference="$i" "$s"
794                     fi
795                     cp -a -t "$s" "$i"/*
796                 else
797                     cp -a -t "$s" "$i"
798                 fi
799             done
800         fi
801     fi
802 done
803
804 if [[ $kernel_only != yes ]]; then
805     for item in $install_items; do
806         dracut_install "$item"
807     done
808     unset item
809
810     while pop fstab_lines line; do
811         echo "$line 0 0" >> "${initdir}/etc/fstab"
812     done
813
814     for f in $add_fstab; do
815         cat $f >> "${initdir}/etc/fstab"
816     done
817
818     # make sure that library links are correct and up to date
819     for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
820         [[ -f $f ]] && inst_simple "$f"
821     done
822     if ! ldconfig -r "$initdir"; then
823         if [[ $UID = 0 ]]; then
824             derror "ldconfig exited ungracefully"
825         else
826             derror "ldconfig might need uid=0 (root) for chroot()"
827         fi
828     fi
829 fi
830
831 if (($maxloglvl >= 5)); then
832     ddebug "Listing sizes of included files:"
833     du -c "$initdir" | sort -n | ddebug
834 fi
835
836 # strip binaries
837 if [[ $do_strip = yes ]] ; then
838     for p in strip xargs find; do
839         if ! type -P $p >/dev/null; then
840             derror "Could not find '$p'. You should run $0 with '--nostrip'."
841             do_strip=no
842         fi
843     done
844 fi
845
846 if [[ $do_strip = yes ]] ; then
847     find "$initdir" -type f \
848          \( -perm -0100 -or -perm -0010 -or -perm -0001 \
849         -or -path '*/lib/modules/*.ko' \) -print0 \
850         | xargs -0 strip -g 2>/dev/null
851 fi
852
853 type hardlink &>/dev/null && {
854     hardlink "$initdir" 2>&1
855 }
856
857 if strstr "$modules_loaded" " fips " && command -v prelink >/dev/null; then
858     for dir in "$initdir/bin" \
859        "$initdir/sbin" \
860        "$initdir/usr/bin" \
861        "$initdir/usr/sbin"; do
862         [[ -L "$dir" ]] && continue
863         for i in "$dir"/*; do
864             [[ -x $i ]] && prelink -u $i &>/dev/null
865         done
866     done
867 fi
868
869 if ! ( cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
870     $compress > "$outfile"; ); then
871     dfatal "dracut: creation of $outfile failed"
872     exit 1
873 fi
874
875 dinfo "Wrote $outfile:"
876 dinfo "$(ls -l "$outfile")"
877
878 exit 0