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