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