]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
beautified shell code
[thirdparty/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-2013 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 -a, --add [LIST] Add a space-separated list of dracut modules.
73 -m, --modules [LIST] Specify a space-separated list of dracut modules to
74 call when building the initramfs. Modules are located
75 in /usr/lib/dracut/modules.d.
76 -o, --omit [LIST] Omit a space-separated list of dracut modules.
77 --force-add [LIST] Force to add a space-separated list of dracut modules
78 to the default set of modules, when -H is specified.
79 -d, --drivers [LIST] Specify a space-separated list of kernel modules to
80 exclusively include in the initramfs.
81 --add-drivers [LIST] Specify a space-separated list of kernel
82 modules to add to the initramfs.
83 --omit-drivers [LIST] Specify a space-separated list of kernel
84 modules not to add to the initramfs.
85 --filesystems [LIST] Specify a space-separated list of kernel filesystem
86 modules to exclusively include in the generic
87 initramfs.
88 -k, --kmoddir [DIR] Specify the directory, where to look for kernel
89 modules
90 --fwdir [DIR] Specify additional directories, where to look for
91 firmwares, separated by :
92 --kernel-only Only install kernel drivers and firmware files
93 --no-kernel Do not install kernel drivers and firmware files
94 --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
95 --strip Strip binaries in the initramfs
96 --nostrip Do not strip binaries in the initramfs
97 --hardlink Hardlink files in the initramfs
98 --nohardlink Do not hardlink files in the initramfs
99 --prefix [DIR] Prefix initramfs files with [DIR]
100 --noprefix Do not prefix initramfs files
101 --mdadmconf Include local /etc/mdadm.conf
102 --nomdadmconf Do not include local /etc/mdadm.conf
103 --lvmconf Include local /etc/lvm/lvm.conf
104 --nolvmconf Do not include local /etc/lvm/lvm.conf
105 --fscks [LIST] Add a space-separated list of fsck helpers.
106 --nofscks Inhibit installation of any fsck helpers.
107 --ro-mnt Mount / and /usr read-only by default.
108 -h, --help This message
109 --debug Output debug information of the build process
110 --profile Output profile information of the build process
111 -L, --stdlog [0-6] Specify logging level (to standard error)
112 0 - suppress any messages
113 1 - only fatal errors
114 2 - all errors
115 3 - warnings
116 4 - info
117 5 - debug info (here starts lots of output)
118 6 - trace info (and even more)
119 -v, --verbose Increase verbosity level
120 -q, --quiet Decrease verbosity level
121 -c, --conf [FILE] Specify configuration file to use.
122 Default: /etc/dracut.conf
123 --confdir [DIR] Specify configuration directory to use *.conf files
124 from. Default: /etc/dracut.conf.d
125 --tmpdir [DIR] Temporary directory to be used instead of default
126 /var/tmp.
127 -l, --local Local mode. Use modules from the current working
128 directory instead of the system-wide installed in
129 /usr/lib/dracut/modules.d.
130 Useful when running dracut from a git checkout.
131 -H, --hostonly Host-Only mode: Install only what is needed for
132 booting the local host instead of a generic host.
133 -N, --no-hostonly Disables Host-Only mode
134 --fstab Use /etc/fstab to determine the root device.
135 --add-fstab [FILE] Add file to the initramfs fstab
136 --mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
137 Mount device [DEV] on mountpoint [MP] with filesystem
138 [FSTYPE] and options [FSOPTS] in the initramfs
139 --add-device "[DEV]" Bring up [DEV] in initramfs
140 -i, --include [SOURCE] [TARGET]
141 Include the files in the SOURCE directory into the
142 Target directory in the final initramfs.
143 If SOURCE is a file, it will be installed to TARGET
144 in the final initramfs.
145 -I, --install [LIST] Install the space separated list of files into the
146 initramfs.
147 --gzip Compress the generated initramfs using gzip.
148 This will be done by default, unless another
149 compression option or --no-compress is passed.
150 --bzip2 Compress the generated initramfs using bzip2.
151 Make sure your kernel has bzip2 decompression support
152 compiled in, otherwise you will not be able to boot.
153 --lzma Compress the generated initramfs using lzma.
154 Make sure your kernel has lzma support compiled in,
155 otherwise you will not be able to boot.
156 --xz Compress the generated initramfs using xz.
157 Make sure that your kernel has xz support compiled
158 in, otherwise you will not be able to boot.
159 --compress [COMPRESSION] Compress the generated initramfs with the
160 passed compression program. Make sure your kernel
161 knows how to decompress the generated initramfs,
162 otherwise you will not be able to boot.
163 --no-compress Do not compress the generated initramfs. This will
164 override any other compression options.
165 --list-modules List all available dracut modules.
166 -M, --show-modules Print included module's name to standard output during
167 build.
168 --keep Keep the temporary initramfs for debugging purposes
169 --printsize Print out the module install size
170 --sshkey [SSHKEY] Add ssh key to initramfs (use with ssh-client module)
171
172 If [LIST] has multiple arguments, then you have to put these in quotes.
173
174 For example:
175
176 # dracut --add-drivers "module1 module2" ...
177
178 EOF
179 }
180
181 # function push()
182 # push values to a stack
183 # $1 = stack variable
184 # $2.. values
185 # example:
186 # push stack 1 2 "3 4"
187 push() {
188 local _i
189 local __stack=$1; shift
190 for _i in "$@"; do
191 eval ${__stack}'[${#'${__stack}'[@]}]="$_i"'
192 done
193 }
194
195 # function pop()
196 # pops the last value from a stack
197 # assigns value to second argument variable
198 # or echo to stdout, if no second argument
199 # $1 = stack variable
200 # $2 = optional variable to store the value
201 # example:
202 # pop stack val
203 # val=$(pop stack)
204 pop() {
205 local __stack=$1; shift
206 local __resultvar=$1
207 local _value;
208 # check for empty stack
209 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
210
211 eval _value='${'${__stack}'[${#'${__stack}'[@]}-1]}'
212
213 if [[ "$__resultvar" ]]; then
214 eval $__resultvar="'$_value'"
215 else
216 printf "%s" "$_value"
217 fi
218 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
219 return 0
220 }
221
222 # Little helper function for reading args from the commandline.
223 # it automatically handles -a b and -a=b variants, and returns 1 if
224 # we need to shift $3.
225 read_arg() {
226 # $1 = arg name
227 # $2 = arg value
228 # $3 = arg parameter
229 local rematch='^[^=]*=(.*)$'
230 if [[ $2 =~ $rematch ]]; then
231 read "$1" <<< "${BASH_REMATCH[1]}"
232 else
233 read "$1" <<< "$3"
234 # There is no way to shift our callers args, so
235 # return 1 to indicate they should do it instead.
236 return 1
237 fi
238 }
239
240 dropindirs_sort()
241 {
242 local suffix=$1; shift
243 local -a files
244 local f d
245
246 readarray -t files < <(
247 for d in "$@"; do
248 for i in "$d/"*"$suffix"; do
249 if [[ -e "$i" ]]; then
250 printf "%s" "${i##*/}"
251 fi
252 done
253 done | sort -Vu
254 )
255
256 for f in "${files[@]}"; do
257 for d in "$@"; do
258 if [[ -e "$d/$f" ]]; then
259 printf "%s" "$d/$f"
260 continue 2
261 fi
262 done
263 done
264 }
265
266 verbosity_mod_l=0
267 unset kernel
268 unset outfile
269
270 # Workaround -i, --include taking 2 arguments
271 set -- "${@/--include/++include}"
272
273 # This prevents any long argument ending with "-i"
274 # -i, like --opt-i but I think we can just prevent that
275 set -- "${@/%-i/++include}"
276
277 TEMP=$(unset POSIXLY_CORRECT; getopt \
278 -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
279 --long kver: \
280 --long add: \
281 --long force-add: \
282 --long add-drivers: \
283 --long omit-drivers: \
284 --long modules: \
285 --long omit: \
286 --long drivers: \
287 --long filesystems: \
288 --long install: \
289 --long fwdir: \
290 --long libdirs: \
291 --long fscks: \
292 --long add-fstab: \
293 --long mount: \
294 --long device: \
295 --long nofscks: \
296 --long ro-mnt \
297 --long kmoddir: \
298 --long conf: \
299 --long confdir: \
300 --long tmpdir: \
301 --long stdlog: \
302 --long compress: \
303 --long prefix: \
304 --long force \
305 --long kernel-only \
306 --long no-kernel \
307 --long kernel-cmdline: \
308 --long strip \
309 --long nostrip \
310 --long hardlink \
311 --long nohardlink \
312 --long noprefix \
313 --long mdadmconf \
314 --long nomdadmconf \
315 --long lvmconf \
316 --long nolvmconf \
317 --long debug \
318 --long profile \
319 --long sshkey: \
320 --long verbose \
321 --long quiet \
322 --long local \
323 --long hostonly \
324 --long host-only \
325 --long no-hostonly \
326 --long no-host-only \
327 --long fstab \
328 --long help \
329 --long bzip2 \
330 --long lzma \
331 --long xz \
332 --long no-compress \
333 --long gzip \
334 --long list-modules \
335 --long show-modules \
336 --long keep \
337 --long printsize \
338 --long regenerate-all \
339 --long noimageifnotneeded \
340 -- "$@")
341
342 if (( $? != 0 )); then
343 usage
344 exit 1
345 fi
346
347 eval set -- "$TEMP"
348
349 while :; do
350 case $1 in
351 --kver) kernel="$2"; shift;;
352 -a|--add) push add_dracutmodules_l "$2"; shift;;
353 --force-add) push force_add_dracutmodules_l "$2"; shift;;
354 --add-drivers) push add_drivers_l "$2"; shift;;
355 --omit-drivers) push omit_drivers_l "$2"; shift;;
356 -m|--modules) push dracutmodules_l "$2"; shift;;
357 -o|--omit) push omit_dracutmodules_l "$2"; shift;;
358 -d|--drivers) push drivers_l "$2"; shift;;
359 --filesystems) push filesystems_l "$2"; shift;;
360 -I|--install) push install_items_l "$2"; shift;;
361 --fwdir) push fw_dir_l "$2"; shift;;
362 --libdirs) push libdirs_l "$2"; shift;;
363 --fscks) push fscks_l "$2"; shift;;
364 --add-fstab) push add_fstab_l "$2"; shift;;
365 --mount) push fstab_lines "$2"; shift;;
366 --add-device|--device)
367 push add_device_l "$2"; shift;;
368 --kernel-cmdline) push kernel_cmdline_l "$2"; shift;;
369 --nofscks) nofscks_l="yes";;
370 --ro-mnt) ro_mnt_l="yes";;
371 -k|--kmoddir) drivers_dir_l="$2"; shift;;
372 -c|--conf) conffile="$2"; shift;;
373 --confdir) confdir="$2"; shift;;
374 --tmpdir) tmpdir_l="$2"; shift;;
375 -L|--stdlog) stdloglvl_l="$2"; shift;;
376 --compress) compress_l="$2"; shift;;
377 --prefix) prefix_l="$2"; shift;;
378 -f|--force) force=yes;;
379 --kernel-only) kernel_only="yes"; no_kernel="no";;
380 --no-kernel) kernel_only="no"; no_kernel="yes";;
381 --strip) do_strip_l="yes";;
382 --nostrip) do_strip_l="no";;
383 --hardlink) do_hardlink_l="yes";;
384 --nohardlink) do_hardlink_l="no";;
385 --noprefix) prefix_l="/";;
386 --mdadmconf) mdadmconf_l="yes";;
387 --nomdadmconf) mdadmconf_l="no";;
388 --lvmconf) lvmconf_l="yes";;
389 --nolvmconf) lvmconf_l="no";;
390 --debug) debug="yes";;
391 --profile) profile="yes";;
392 --sshkey) sshkey="$2"; shift;;
393 -v|--verbose) ((verbosity_mod_l++));;
394 -q|--quiet) ((verbosity_mod_l--));;
395 -l|--local)
396 allowlocal="yes"
397 [[ -f "$(readlink -f "${0%/*}")/dracut-functions.sh" ]] \
398 && dracutbasedir="$(readlink -f "${0%/*}")"
399 ;;
400 -H|--hostonly|--host-only)
401 hostonly_l="yes" ;;
402 -N|--no-hostonly|--no-host-only)
403 hostonly_l="no" ;;
404 --fstab) use_fstab_l="yes" ;;
405 -h|--help) long_usage; exit 1 ;;
406 -i|--include) push include_src "$2"
407 shift;;
408 --bzip2) compress_l="bzip2";;
409 --lzma) compress_l="lzma";;
410 --xz) compress_l="xz";;
411 --no-compress) _no_compress_l="cat";;
412 --gzip) compress_l="gzip";;
413 --list-modules) do_list="yes";;
414 -M|--show-modules)
415 show_modules_l="yes"
416 ;;
417 --keep) keep="yes";;
418 --printsize) printsize="yes";;
419 --regenerate-all) regenerate_all="yes";;
420 --noimageifnotneeded) noimageifnotneeded="yes";;
421
422 --) shift; break;;
423
424 *) # should not even reach this point
425 printf "\n!Unknown option: '%s'\n\n" "$1" >&2; usage; exit 1;;
426 esac
427 shift
428 done
429
430 # getopt cannot handle multiple arguments, so just handle "-I,--include"
431 # the old fashioned way
432
433 while (($# > 0)); do
434 case ${1%%=*} in
435 ++include) push include_src "$2"
436 push include_target "$3"
437 shift 2;;
438 *)
439 if ! [[ ${outfile+x} ]]; then
440 outfile=$1
441 elif ! [[ ${kernel+x} ]]; then
442 kernel=$1
443 else
444 printf "\nUnknown arguments: %s\n\n" "$*" >&2
445 usage; exit 1;
446 fi
447 ;;
448 esac
449 shift
450 done
451
452 if [[ $regenerate_all == "yes" ]]; then
453 ret=0
454 if [[ $kernel ]]; then
455 printf -- "--regenerate-all cannot be called with a kernel version\n" >&2
456 exit 1
457 fi
458
459 if [[ $outfile ]]; then
460 printf -- "--regenerate-all cannot be called with a image file\n" >&2
461 exit 1
462 fi
463
464 ((len=${#dracut_args[@]}))
465 for ((i=0; i < len; i++)); do
466 [[ ${dracut_args[$i]} == "--regenerate-all" ]] && \
467 unset dracut_args[$i]
468 done
469
470 cd /lib/modules
471 for i in *; do
472 [[ -f $i/modules.builtin ]] || continue
473 dracut --kver="$i" "${dracut_args[@]}"
474 ((ret+=$?))
475 done
476 exit $ret
477 fi
478
479 if ! [[ $kernel ]]; then
480 kernel=$(uname -r)
481 fi
482
483 if ! [[ $outfile ]]; then
484 [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id
485
486 if [[ $MACHINE_ID ]] && ( [[ -d /boot/${MACHINE_ID} ]] || [[ -L /boot/${MACHINE_ID} ]] ); then
487 outfile="/boot/${MACHINE_ID}/$kernel/initrd"
488 else
489 outfile="/boot/initramfs-$kernel.img"
490 fi
491 fi
492
493 for i in /usr/sbin /sbin /usr/bin /bin; do
494 rl=$i
495 if [ -L "$i" ]; then
496 rl=$(readlink -f $i)
497 fi
498 if [[ "$NPATH" != "*:$rl*" ]] ; then
499 NPATH+=":$rl"
500 fi
501 done
502 export PATH="${NPATH#:}"
503 unset NPATH
504 unset LD_LIBRARY_PATH
505 unset GREP_OPTIONS
506
507 export DRACUT_LOG_LEVEL=warning
508 [[ $debug ]] && {
509 export DRACUT_LOG_LEVEL=debug
510 export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
511 set -x
512 }
513
514 [[ $profile ]] && {
515 export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
516 set -x
517 debug=yes
518 }
519
520 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
521
522 # if we were not passed a config file, try the default one
523 if [[ ! -f $conffile ]]; then
524 if [[ $allowlocal ]]; then
525 conffile="$dracutbasedir/dracut.conf"
526 else
527 conffile="/etc/dracut.conf"
528 fi
529 fi
530
531 if [[ ! -d $confdir ]]; then
532 if [[ $allowlocal ]]; then
533 confdir="$dracutbasedir/dracut.conf.d"
534 else
535 confdir="/etc/dracut.conf.d"
536 fi
537 fi
538
539 # source our config file
540 [[ -f $conffile ]] && . "$conffile"
541
542 # source our config dir
543 for f in $(dropindirs_sort ".conf" "$confdir" "$dracutbasedir/dracut.conf.d"); do
544 [[ -e $f ]] && . "$f"
545 done
546
547 # these optins add to the stuff in the config file
548 if (( ${#add_dracutmodules_l[@]} )); then
549 while pop add_dracutmodules_l val; do
550 add_dracutmodules+=" $val "
551 done
552 fi
553
554 if (( ${#force_add_dracutmodules_l[@]} )); then
555 while pop force_add_dracutmodules_l val; do
556 force_add_dracutmodules+=" $val "
557 done
558 fi
559
560 if (( ${#fscks_l[@]} )); then
561 while pop fscks_l val; do
562 fscks+=" $val "
563 done
564 fi
565
566 if (( ${#add_fstab_l[@]} )); then
567 while pop add_fstab_l val; do
568 add_fstab+=" $val "
569 done
570 fi
571
572 if (( ${#fstab_lines_l[@]} )); then
573 while pop fstab_lines_l val; do
574 push fstab_lines $val
575 done
576 fi
577
578 if (( ${#install_items_l[@]} )); then
579 while pop install_items_l val; do
580 install_items+=" $val "
581 done
582 fi
583
584 # these options override the stuff in the config file
585 if (( ${#dracutmodules_l[@]} )); then
586 dracutmodules=''
587 while pop dracutmodules_l val; do
588 dracutmodules+="$val "
589 done
590 fi
591
592 if (( ${#omit_dracutmodules_l[@]} )); then
593 omit_dracutmodules=''
594 while pop omit_dracutmodules_l val; do
595 omit_dracutmodules+="$val "
596 done
597 fi
598
599 if (( ${#filesystems_l[@]} )); then
600 filesystems=''
601 while pop filesystems_l val; do
602 filesystems+="$val "
603 done
604 fi
605
606 if (( ${#fw_dir_l[@]} )); then
607 fw_dir=''
608 while pop fw_dir_l val; do
609 fw_dir+="$val "
610 done
611 fi
612
613 if (( ${#libdirs_l[@]} )); then
614 libdirs=''
615 while pop libdirs_l val; do
616 libdirs+="$val "
617 done
618 fi
619
620 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
621 [[ ! $stdloglvl ]] && stdloglvl=4
622 stdloglvl=$((stdloglvl + verbosity_mod_l))
623 ((stdloglvl > 6)) && stdloglvl=6
624 ((stdloglvl < 0)) && stdloglvl=0
625
626 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
627 [[ $do_strip_l ]] && do_strip=$do_strip_l
628 [[ $do_strip ]] || do_strip=yes
629 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
630 [[ $do_hardlink ]] || do_hardlink=yes
631 [[ $prefix_l ]] && prefix=$prefix_l
632 [[ $prefix = "/" ]] && unset prefix
633 [[ $hostonly_l ]] && hostonly=$hostonly_l
634 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
635 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
636 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
637 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
638 [[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware"
639 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
640 [[ $tmpdir ]] || tmpdir=/var/tmp
641 [[ $compress_l ]] && compress=$compress_l
642 [[ $show_modules_l ]] && show_modules=$show_modules_l
643 [[ $nofscks_l ]] && nofscks="yes"
644 [[ $ro_mnt_l ]] && ro_mnt="yes"
645 # eliminate IFS hackery when messing with fw_dir
646 fw_dir=${fw_dir//:/ }
647
648 # handle compression options.
649 [[ $compress ]] || compress="gzip"
650 case $compress in
651 bzip2) compress="bzip2 -9";;
652 lzma) compress="lzma -9";;
653 xz) compress="xz --check=crc32 --lzma2=dict=1MiB";;
654 gzip) compress="gzip -9"; command -v pigz > /dev/null 2>&1 && compress="pigz -9";;
655 esac
656 if [[ $_no_compress_l = "cat" ]]; then
657 compress="cat"
658 fi
659
660 [[ $hostonly = yes ]] && hostonly="-h"
661 [[ $hostonly != "-h" ]] && unset hostonly
662
663 readonly TMPDIR="$tmpdir"
664 readonly initdir="$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)"
665 [ -d "$initdir" ] || {
666 printf "%s\n" "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXX failed." >&2
667 exit 1
668 }
669
670 # clean up after ourselves no matter how we die.
671 trap 'ret=$?;[[ $outfile ]] && [[ -f $outfile.$$ ]] && rm -f -- "$outfile.$$";[[ $keep ]] && printf "%s\n" "Not removing $initdir." >&2 || { [[ $initdir ]] && rm -rf -- "$initdir";exit $ret; };' EXIT
672 # clean up after ourselves no matter how we die.
673 trap 'exit 1;' SIGINT
674
675 export DRACUT_KERNEL_LAZY="1"
676 export DRACUT_RESOLVE_LAZY="1"
677
678 if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
679 . $dracutbasedir/dracut-functions.sh
680 else
681 printf "%s\n" "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
682 printf "%s\n" "dracut: Are you running from a git checkout?" >&2
683 printf "%s\n" "dracut: Try passing -l as an argument to $0" >&2
684 exit 1
685 fi
686
687 inst /bin/sh
688 if ! $DRACUT_INSTALL ${initdir+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
689 unset DRACUT_RESOLVE_LAZY
690 export DRACUT_RESOLVE_DEPS=1
691 fi
692 rm -fr -- ${initdir}/*
693
694 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
695 . $dracutbasedir/dracut-version.sh
696 fi
697
698 # Verify bash version, current minimum is 3.1
699 if (( BASH_VERSINFO[0] < 4 )); then
700 dfatal 'You need at least Bash 4 to use dracut, sorry.'
701 exit 1
702 fi
703
704 dracutfunctions=$dracutbasedir/dracut-functions.sh
705 export dracutfunctions
706
707 if (( ${#drivers_l[@]} )); then
708 drivers=''
709 while pop drivers_l val; do
710 drivers+="$val "
711 done
712 fi
713 drivers=${drivers/-/_}
714
715 if (( ${#add_drivers_l[@]} )); then
716 while pop add_drivers_l val; do
717 add_drivers+=" $val "
718 done
719 fi
720 add_drivers=${add_drivers/-/_}
721
722 if (( ${#omit_drivers_l[@]} )); then
723 while pop omit_drivers_l val; do
724 omit_drivers+=" $val "
725 done
726 fi
727 omit_drivers=${omit_drivers/-/_}
728
729 if (( ${#kernel_cmdline_l[@]} )); then
730 while pop kernel_cmdline_l val; do
731 kernel_cmdline+=" $val "
732 done
733 fi
734
735 omit_drivers_corrected=""
736 for d in $omit_drivers; do
737 [[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
738 omit_drivers_corrected+="$d|"
739 done
740 omit_drivers="${omit_drivers_corrected%|}"
741 unset omit_drivers_corrected
742
743 # prepare args for logging
744 for ((i=0; i < ${#dracut_args[@]}; i++)); do
745 [[ "${dracut_args[$i]}" == *\ * ]] && \
746 dracut_args[$i]="\"${dracut_args[$i]}\""
747 #" keep vim happy
748 done
749 ddebug "Executing: $0 ${dracut_args[@]}"
750
751 [[ $do_list = yes ]] && {
752 for mod in $dracutbasedir/modules.d/*; do
753 [[ -d $mod ]] || continue;
754 [[ -e $mod/install || -e $mod/installkernel || \
755 -e $mod/module-setup.sh ]] || continue
756 printf "%s\n" "${mod##*/??}"
757 done
758 exit 0
759 }
760
761 # This is kinda legacy -- eventually it should go away.
762 case $dracutmodules in
763 ""|auto) dracutmodules="all" ;;
764 esac
765
766 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
767
768 if [[ -d $srcmods ]]; then
769 [[ -f $srcmods/modules.dep ]] || {
770 dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
771 }
772 fi
773
774 if [[ -f $outfile && ! $force ]]; then
775 dfatal "Will not override existing initramfs ($outfile) without --force"
776 exit 1
777 fi
778
779 outdir=${outfile%/*}
780 [[ $outdir ]] || outdir="/"
781
782 if [[ ! -d "$outdir" ]]; then
783 dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
784 exit 1
785 elif [[ ! -w "$outdir" ]]; then
786 dfatal "No permission to write to $outdir."
787 exit 1
788 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
789 dfatal "No permission to write $outfile."
790 exit 1
791 fi
792
793 # Need to be able to have non-root users read stuff (rpcbind etc)
794 chmod 755 "$initdir"
795
796 if [[ $hostonly ]]; then
797 for i in /sys /proc /run /dev; do
798 if ! findmnt --target "$i" &>/dev/null; then
799 dwarning "Turning off host-only mode: '$i' is not mounted!"
800 unset hostonly
801 fi
802 done
803 if ! [[ -d /run/udev/data ]]; then
804 dwarning "Turning off host-only mode: udev database not found!"
805 unset hostonly
806 fi
807 fi
808
809 declare -A host_fs_types
810
811 for line in "${fstab_lines[@]}"; do
812 set -- $line
813 #dev mp fs fsopts
814 push host_devs "$1"
815 host_fs_types["$1"]="$3"
816 done
817
818 for f in $add_fstab; do
819 [[ -e $f ]] || continue
820 while read dev rest; do
821 push host_devs "$dev"
822 done < "$f"
823 done
824
825 for dev in $add_device; do
826 push host_devs "$dev"
827 done
828
829 if (( ${#add_device_l[@]} )); then
830 while pop add_device_l val; do
831 add_device+=" $val "
832 push host_devs "$val"
833 done
834 fi
835
836 if [[ $hostonly ]]; then
837 # in hostonly mode, determine all devices, which have to be accessed
838 # and examine them for filesystem types
839
840 for mp in \
841 "/" \
842 "/etc" \
843 "/usr" \
844 "/usr/bin" \
845 "/usr/sbin" \
846 "/usr/lib" \
847 "/usr/lib64" \
848 "/boot";
849 do
850 mountpoint "$mp" >/dev/null 2>&1 || continue
851 push host_devs "$(readlink -f "/dev/block/$(find_block_device "$mp")")"
852 done
853
854 while read dev type rest; do
855 [[ -b $dev ]] || continue
856 [[ "$type" == "partition" ]] || continue
857 while read _d _m _t _o _r; do
858 [[ "$_d" == \#* ]] && continue
859 [[ $_d ]] || continue
860 [[ $_t != "swap" ]] || [[ $_m != "swap" ]] && continue
861 [[ "$_o" == *noauto* ]] && continue
862 [[ "$_d" == UUID\=* ]] && _d="/dev/disk/by-uuid/${_d#UUID=}"
863 [[ "$_d" == LABEL\=* ]] && _d="/dev/disk/by-label/$_d#LABEL=}"
864 [[ "$_d" -ef "$dev" ]] || continue
865
866 while read _mapper _a _p _o; do
867 [[ $_mapper = \#* ]] && continue
868 [[ "$_d" -ef /dev/mapper/"$_mapper" ]] || continue
869 [[ "$_o" ]] || _o="$_p"
870 # skip mkswap swap
871 [[ $_o == *swap* ]] && continue 2
872 done < /etc/crypttab
873
874 push host_devs "$(readlink -f "$dev")"
875 break
876 done < /etc/fstab
877 done < /proc/swaps
878 fi
879
880 _get_fs_type() { (
881 [[ $1 ]] || return
882 if [[ -b /dev/block/$1 ]] && ID_FS_TYPE=$(get_fs_env "/dev/block/$1"); then
883 printf "%s\n" "$(readlink -f "/dev/block/$1")" "$ID_FS_TYPE"
884 return 1
885 fi
886 if [[ -b $1 ]] && ID_FS_TYPE=$(get_fs_env "$1"); then
887 printf "%s\n" "$(readlink -f "$1")" "$ID_FS_TYPE"
888 return 1
889 fi
890 if fstype=$(find_dev_fstype "$1"); then
891 printf "%s\n" "$1" "$fstype"
892 return 1
893 fi
894 return 1
895 ) }
896
897 for dev in "${host_devs[@]}"; do
898 while read key; do
899 read val
900 host_fs_types["$key"]="$val"
901 done < <(
902 _get_fs_type "$dev"
903 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
904 )
905 done
906
907 [[ -d $udevdir ]] \
908 || udevdir="$(pkg-config udev --variable=udevdir 2>/dev/null)"
909 if ! [[ -d "$udevdir" ]]; then
910 [[ -d /lib/udev ]] && udevdir=/lib/udev
911 [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
912 fi
913
914 [[ -d $systemdutildir ]] \
915 || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
916
917 if ! [[ -d "$systemdutildir" ]]; then
918 [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
919 [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
920 fi
921
922 [[ -d $systemdsystemunitdir ]] \
923 || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
924
925 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
926
927 [[ -d $systemdsystemconfdir ]] \
928 || systemdsystemconfdir=$(pkg-config systemd --variable=systemdsystemconfdir 2>/dev/null)
929
930 [[ -d "$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
931
932 export initdir dracutbasedir dracutmodules \
933 fw_dir drivers_dir debug no_kernel kernel_only \
934 omit_drivers mdadmconf lvmconf \
935 use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
936 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
937 debug host_fs_types host_devs sshkey add_fstab \
938 DRACUT_VERSION udevdir prefix filesystems drivers \
939 systemdutildir systemdsystemunitdir systemdsystemconfdir
940
941 # Create some directory structure first
942 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
943
944 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
945 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
946
947 if [[ $prefix ]]; then
948 for d in bin etc lib sbin tmp usr var $libdirs; do
949 [[ "$d" == */* ]] && continue
950 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
951 done
952 fi
953
954 if [[ $kernel_only != yes ]]; then
955 for d in usr/bin usr/sbin bin etc lib sbin tmp usr var $libdirs; do
956 [[ -e "${initdir}${prefix}/$d" ]] && continue
957 if [ -L "/$d" ]; then
958 inst_symlink "/$d" "${prefix}/$d"
959 else
960 mkdir -m 0755 -p "${initdir}${prefix}/$d"
961 fi
962 done
963
964 for d in dev proc sys sysroot root run run/lock run/initramfs; do
965 if [ -L "/$d" ]; then
966 inst_symlink "/$d"
967 else
968 mkdir -m 0755 -p "$initdir/$d"
969 fi
970 done
971
972 ln -sfn ../run "$initdir/var/run"
973 ln -sfn ../run/lock "$initdir/var/lock"
974 ln -sfn ../run/log "$initdir/var/log"
975 else
976 for d in lib "$libdir"; do
977 [[ -e "${initdir}${prefix}/$d" ]] && continue
978 if [ -h "/$d" ]; then
979 inst "/$d" "${prefix}/$d"
980 else
981 mkdir -m 0755 -p "${initdir}${prefix}/$d"
982 fi
983 done
984 fi
985
986 if [[ $kernel_only != yes ]]; then
987 mkdir -p "${initdir}/etc/cmdline.d"
988 for _d in $hookdirs; do
989 mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
990 done
991 if [[ "$UID" = "0" ]]; then
992 [ -c ${initdir}/dev/null ] || mknod ${initdir}/dev/null c 1 3
993 [ -c ${initdir}/dev/kmsg ] || mknod ${initdir}/dev/kmsg c 1 11
994 [ -c ${initdir}/dev/console ] || mknod ${initdir}/dev/console c 5 1
995 fi
996 fi
997
998 mods_to_load=""
999 # check all our modules to see if they should be sourced.
1000 # This builds a list of modules that we will install next.
1001 for_each_module_dir check_module
1002 for_each_module_dir check_mount
1003
1004 [[ "$mods_to_load " == *01fips\ * ]] && export DRACUT_FIPS_MODE=1
1005
1006 _isize=0 #initramfs size
1007 modules_loaded=" "
1008 # source our modules.
1009 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1010 _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
1011 if [[ "$mods_to_load" == *\ $_d_mod\ * ]]; then
1012 if [[ $show_modules = yes ]]; then
1013 printf "%s\n" "$_d_mod"
1014 else
1015 dinfo "*** Including module: $_d_mod ***"
1016 fi
1017 if [[ $kernel_only == yes ]]; then
1018 module_installkernel "$_d_mod" || {
1019 dfatal "installkernel failed in module $_d_mod"
1020 exit 1
1021 }
1022 else
1023 module_install "$_d_mod"
1024 if [[ $no_kernel != yes ]]; then
1025 module_installkernel "$_d_mod" || {
1026 dfatal "installkernel failed in module $_d_mod"
1027 exit 1
1028 }
1029 fi
1030 fi
1031 mods_to_load=${mods_to_load// $_d_mod /}
1032 modules_loaded+="$_d_mod "
1033
1034 #print the module install size
1035 if [ -n "$printsize" ]; then
1036 _isize_new=$(du -sk ${initdir}|cut -f1)
1037 _isize_delta=$((_isize_new - _isize))
1038 printf "%s\n" "$_d_mod install size: ${_isize_delta}k"
1039 _isize=$_isize_new
1040 fi
1041 fi
1042 done
1043 unset moddir
1044
1045 for i in $modules_loaded; do
1046 mkdir -p $initdir/lib/dracut
1047 printf "%s\n" "$i" >> $initdir/lib/dracut/modules.txt
1048 done
1049
1050 dinfo "*** Including modules done ***"
1051
1052 ## final stuff that has to happen
1053 if [[ $no_kernel != yes ]]; then
1054
1055 if [[ $drivers ]]; then
1056 hostonly='' instmods $drivers
1057 fi
1058
1059 if [[ $add_drivers ]]; then
1060 hostonly='' instmods -c $add_drivers
1061 fi
1062 if [[ $filesystems ]]; then
1063 hostonly='' instmods -c $filesystems
1064 fi
1065
1066 dinfo "*** Installing kernel module dependencies and firmware ***"
1067 dracut_kernel_post
1068 dinfo "*** Installing kernel module dependencies and firmware done ***"
1069
1070 if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
1071 if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
1072 [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
1073 for i in ${initdir}/etc/cmdline.d/*.conf; do
1074 # We need no initramfs image and do not generate one.
1075 [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
1076 done
1077 fi
1078 fi
1079 fi
1080
1081 if [[ $kernel_only != yes ]]; then
1082 (( ${#install_items[@]} > 0 )) && dracut_install ${install_items[@]}
1083
1084 [[ $kernel_cmdline ]] && printf "%s\n" "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
1085
1086 while pop fstab_lines line; do
1087 printf "%s\n" "$line 0 0" >> "${initdir}/etc/fstab"
1088 done
1089
1090 for f in $add_fstab; do
1091 cat "$f" >> "${initdir}/etc/fstab"
1092 done
1093
1094 if [ -d ${initdir}/$systemdutildir ]; then
1095 mkdir -p ${initdir}/etc/conf.d
1096 {
1097 printf "%s\n" "systemdutildir=\"$systemdutildir\""
1098 printf "%s\n" "systemdsystemunitdir=\"$systemdsystemunitdir\""
1099 printf "%s\n" "systemdsystemconfdir=\"$systemdsystemconfdir\""
1100 } > ${initdir}/etc/conf.d/systemd.conf
1101 fi
1102
1103 if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
1104 dinfo "*** Resolving executable dependencies ***"
1105 find "$initdir" -type f \
1106 '(' -perm -0100 -or -perm -0010 -or -perm -0001 ')' \
1107 -not -path '*.ko' -print0 \
1108 | xargs -r -0 $DRACUT_INSTALL ${initdir+-D "$initdir"} -R ${DRACUT_FIPS_MODE+-H} --
1109 dinfo "*** Resolving executable dependencies done***"
1110 fi
1111 fi
1112
1113 while pop include_src src && pop include_target tgt; do
1114 if [[ $src && $tgt ]]; then
1115 if [[ -f $src ]]; then
1116 inst $src $tgt
1117 else
1118 ddebug "Including directory: $src"
1119 mkdir -p "${initdir}/${tgt}"
1120 # check for preexisting symlinks, so we can cope with the
1121 # symlinks to $prefix
1122 for i in "$src"/*; do
1123 [[ -e "$i" || -h "$i" ]] || continue
1124 s=${initdir}/${tgt}/${i#$src/}
1125 if [[ -d "$i" ]]; then
1126 if ! [[ -e "$s" ]]; then
1127 mkdir -m 0755 -p "$s"
1128 chmod --reference="$i" "$s"
1129 fi
1130 cp --reflink=auto --sparse=auto -fa -t "$s" "$i"/*
1131 else
1132 cp --reflink=auto --sparse=auto -fa -t "$s" "$i"
1133 fi
1134 done
1135 fi
1136 fi
1137 done
1138
1139 if [[ $kernel_only != yes ]]; then
1140 # make sure that library links are correct and up to date
1141 for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
1142 [[ -f $f ]] && inst_simple "$f"
1143 done
1144 if ! ldconfig -r "$initdir"; then
1145 if [[ $UID = 0 ]]; then
1146 derror "ldconfig exited ungracefully"
1147 else
1148 derror "ldconfig might need uid=0 (root) for chroot()"
1149 fi
1150 fi
1151 fi
1152
1153 if (( maxloglvl >= 5 )); then
1154 ddebug "Listing sizes of included files:"
1155 du -c "$initdir" | sort -n | ddebug
1156 fi
1157
1158 PRELINK_BIN="$(command -v prelink)"
1159 if [[ $UID = 0 ]] && [[ $PRELINK_BIN ]]; then
1160 if [[ $DRACUT_FIPS_MODE ]]; then
1161 dinfo "*** Installing prelink files ***"
1162 dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf /etc/prelink.cache
1163 else
1164 dinfo "*** Pre-linking files ***"
1165 dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf
1166 chroot "$initdir" "$PRELINK_BIN" -a
1167 rm -f -- "$initdir/$PRELINK_BIN"
1168 rm -fr -- "$initdir"/etc/prelink.*
1169 dinfo "*** Pre-linking files done ***"
1170 fi
1171 fi
1172
1173 if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
1174 dinfo "*** Hardlinking files ***"
1175 hardlink "$initdir" 2>&1
1176 dinfo "*** Hardlinking files done ***"
1177 fi
1178
1179 # strip binaries
1180 if [[ $do_strip = yes ]] ; then
1181 for p in strip xargs find; do
1182 if ! type -P $p >/dev/null; then
1183 dinfo "Could not find '$p'. Not stripping the initramfs."
1184 do_strip=no
1185 fi
1186 done
1187 fi
1188
1189 if [[ $do_strip = yes ]] ; then
1190 dinfo "*** Stripping files ***"
1191 if [[ $DRACUT_FIPS_MODE ]]; then
1192 find "$initdir" -type f \
1193 -executable -not -path '*/lib/modules/*.ko' -print0 \
1194 | while read -r -d $'\0' f; do
1195 if ! [[ -e "${f%/*}/.${f##*/}.hmac" ]] \
1196 && ! [[ -e "/lib/hmaccalc/${f##*/}.hmac" ]] \
1197 && ! [[ -e "/lib64/hmaccalc/${f##*/}.hmac" ]] \
1198 && ! [[ -e "/lib/fipscheck/${f##*/}.hmac" ]] \
1199 && ! [[ -e "/lib64/fipscheck/${f##*/}.hmac" ]]; then
1200 printf "%s\000" "$f";
1201 fi
1202 done | xargs -r -0 strip -g 2>/dev/null
1203 else
1204 find "$initdir" -type f \
1205 -executable -not -path '*/lib/modules/*.ko' -print0 \
1206 | xargs -r -0 strip -g 2>/dev/null
1207 fi
1208
1209 # strip kernel modules, but do not touch signed modules
1210 find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
1211 | while read -r -d $'\0' f; do
1212 SIG=$(tail -c 28 "$f")
1213 [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
1214 done | xargs -r -0 strip -g
1215
1216 dinfo "*** Stripping files done ***"
1217 fi
1218
1219 rm -f -- "$outfile"
1220 dinfo "*** Creating image file ***"
1221 if ! ( umask 077; cd "$initdir"; find . | cpio -R 0:0 -H newc -o --quiet | \
1222 $compress > "$outfile.$$"; ); then
1223 dfatal "dracut: creation of $outfile.$$ failed"
1224 exit 1
1225 fi
1226 mv -- "$outfile.$$" "$outfile"
1227 dinfo "*** Creating image file done ***"
1228
1229 dinfo "Wrote $outfile:"
1230 dinfo "$(ls -l "$outfile")"
1231
1232 exit 0