]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
fix(dracut.sh): correct path for UEFI stub on split-usr systems
[thirdparty/dracut.git] / dracut.sh
1 #!/bin/bash -p
2 #
3 # Generator script for a dracut initramfs
4
5 # Copyright 2005-2013 Red Hat, Inc. All rights reserved.
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #
20
21 # store for logging
22
23 unset BASH_ENV
24 unset GZIP
25
26 # Verify bash version, current minimum is 4
27 if ((BASH_VERSINFO[0] < 4)); then
28 printf "%s\n" "dracut[F]: dracut requires at least Bash 4." >&2
29 exit 1
30 fi
31
32 dracut_args=("$@")
33 # shellcheck disable=SC2155
34 readonly dracut_cmd=$(readlink -f "$0")
35
36 set -o pipefail
37
38 usage() {
39 [[ $sysroot_l ]] && dracutsysrootdir="$sysroot_l"
40 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
41 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
42 # shellcheck source=./dracut-version.sh
43 . "$dracutbasedir"/dracut-version.sh
44 fi
45
46 # 80x25 linebreak here ^
47 cat << EOF
48 Usage: $dracut_cmd [OPTION]... [<initramfs> [<kernel-version>]]
49
50 Version: $DRACUT_VERSION
51
52 Creates initial ramdisk images for preloading modules
53
54 -h, --help Display all options
55
56 If a [LIST] has multiple arguments, then you have to put these in quotes.
57
58 For example:
59
60 # dracut --add-drivers "module1 module2" ...
61
62 EOF
63 }
64
65 long_usage() {
66 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
67 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
68 # shellcheck source=./dracut-version.sh
69 . "$dracutbasedir"/dracut-version.sh
70 fi
71
72 # 80x25 linebreak here ^
73 cat << EOF
74 Usage: $dracut_cmd [OPTION]... [<initramfs> [<kernel-version>]]
75
76 Version: $DRACUT_VERSION
77
78 Creates initial ramdisk images for preloading modules
79
80 --kver [VERSION] Set kernel version to [VERSION].
81 -f, --force Overwrite existing initramfs file.
82 [OUTPUT_FILE] --rebuild
83 Append the current arguments to those with which the
84 input initramfs image was built. This option helps in
85 incrementally building the initramfs for testing.
86 If optional [OUTPUT_FILE] is not provided, the input
87 initramfs provided to rebuild will be used as output
88 file.
89 -a, --add [LIST] Add a space-separated list of dracut modules.
90 --force-add [LIST] Force to add a space-separated list of dracut modules
91 to the default set of modules, when -H is specified.
92 -o, --omit [LIST] Omit a space-separated list of dracut modules.
93 -m, --modules [LIST] Specify a space-separated list of dracut modules to
94 call when building the initramfs. Modules are located
95 in /usr/lib/dracut/modules.d.
96 This option forces dracut to only include the specified
97 dracut modules.
98 In most cases the --add option is what you want to use.
99 --add-drivers [LIST] Specify a space-separated list of kernel
100 modules to add to the initramfs.
101 --force-drivers [LIST]
102 Specify a space-separated list of kernel
103 modules to add to the initramfs and make sure they
104 are tried to be loaded via modprobe same as passing
105 rd.driver.pre=DRIVER kernel parameter.
106 --omit-drivers [LIST] Specify a space-separated list of kernel
107 modules not to add to the initramfs.
108 -d, --drivers [LIST] Specify a space-separated list of kernel modules to
109 exclusively include in the initramfs.
110 --filesystems [LIST] Specify a space-separated list of kernel filesystem
111 modules to exclusively include in the generic
112 initramfs.
113 -k, --kmoddir [DIR] Specify the directory where to look for kernel
114 modules.
115 --fwdir [DIR] Specify additional colon-separated list of directories
116 where to look for firmware files.
117 --libdirs [LIST] Specify a space-separated list of directories
118 where to look for libraries.
119 --kernel-only Only install kernel drivers and firmware files.
120 --no-kernel Do not install kernel drivers and firmware files.
121 --print-cmdline Print the kernel command line for the given disk layout.
122 --early-microcode Combine early microcode with ramdisk.
123 --no-early-microcode Do not combine early microcode with ramdisk.
124 --kernel-cmdline [PARAMETERS]
125 Specify default kernel command line parameters.
126 --strip Strip binaries in the initramfs.
127 --aggressive-strip Strip more than just debug symbol and sections,
128 for a smaller initramfs build. The --strip option must
129 also be specified.
130 --nostrip Do not strip binaries in the initramfs.
131 --hardlink Hardlink files in the initramfs.
132 --nohardlink Do not hardlink files in the initramfs.
133 --prefix [DIR] Prefix initramfs files with [DIR].
134 --noprefix Do not prefix initramfs files.
135 --mdadmconf Include local /etc/mdadm.conf file.
136 --nomdadmconf Do not include local /etc/mdadm.conf file.
137 --lvmconf Include local /etc/lvm/lvm.conf file.
138 --nolvmconf Do not include local /etc/lvm/lvm.conf file.
139 --fscks [LIST] Add a space-separated list of fsck helpers.
140 --nofscks Inhibit installation of any fsck helpers.
141 --ro-mnt Mount / and /usr read-only by default.
142 -h, --help This message.
143 --debug Output debug information of the build process.
144 --profile Output profile information of the build process.
145 -L, --stdlog [0-6] Specify logging level (to standard error)
146 0 - suppress any messages
147 1 - only fatal errors
148 2 - all errors
149 3 - warnings
150 4 - info
151 5 - debug info (here starts lots of output)
152 6 - trace info (and even more)
153 -v, --verbose Increase verbosity level.
154 -q, --quiet Decrease verbosity level.
155 -c, --conf [FILE] Specify configuration file to use.
156 Default: /etc/dracut.conf
157 --confdir [DIR] Specify configuration directory to use *.conf files
158 from. Default: /etc/dracut.conf.d
159 --tmpdir [DIR] Temporary directory to be used instead of default
160 ${TMPDIR:-/var/tmp}.
161 -r, --sysroot [DIR] Specify sysroot directory to collect files from.
162 -l, --local Local mode. Use modules from the current working
163 directory instead of the system-wide installed in
164 /usr/lib/dracut/modules.d.
165 Useful when running dracut from a git checkout.
166 -H, --hostonly Host-only mode: Install only what is needed for
167 booting the local host instead of a generic host.
168 -N, --no-hostonly Disables host-only mode.
169 --hostonly-mode [MODE]
170 Specify the host-only mode to use. [MODE] could be
171 one of "sloppy" or "strict". "sloppy" mode is used
172 by default.
173 In "sloppy" host-only mode, extra drivers and modules
174 will be installed, so minor hardware change won't make
175 the image unbootable (e.g. changed keyboard), and the
176 image is still portable among similar hosts.
177 With "strict" mode enabled, anything not necessary
178 for booting the local host in its current state will
179 not be included, and modules may do some extra job
180 to save more space. Minor change of hardware or
181 environment could make the image unbootable.
182 DO NOT use "strict" mode unless you know what you
183 are doing.
184 --hostonly-cmdline Store kernel command line arguments needed
185 in the initramfs.
186 --no-hostonly-cmdline Do not store kernel command line arguments needed
187 in the initramfs.
188 --no-hostonly-default-device
189 Do not generate implicit host devices like root,
190 swap, fstab, etc. Use "--mount" or "--add-device"
191 to explicitly add devices as needed.
192 --hostonly-i18n Install only needed keyboard and font files according
193 to the host configuration (default).
194 --no-hostonly-i18n Install all keyboard and font files available.
195 --hostonly-nics [LIST]
196 Only enable listed NICs in the initramfs. The list can
197 be empty, so other modules can install only the
198 necessary network drivers.
199 --persistent-policy [POLICY]
200 Use [POLICY] to address disks and partitions.
201 POLICY can be any directory name found in /dev/disk
202 (e.g. "by-uuid", "by-label"), or "mapper" to use
203 /dev/mapper device names (default).
204 --fstab Use /etc/fstab to determine the root device.
205 --add-fstab [FILE] Add file to the initramfs fstab.
206 --mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
207 Mount device [DEV] on mountpoint [MP] with filesystem
208 [FSTYPE] and options [FSOPTS] in the initramfs.
209 --mount "[MP]" Same as above, but [DEV], [FSTYPE] and [FSOPTS] are
210 determined by looking at the current mounts.
211 --add-device "[DEV]" Bring up [DEV] in initramfs.
212 -i, --include [SOURCE] [TARGET]
213 Include the files in the SOURCE directory into the
214 Target directory in the final initramfs.
215 If SOURCE is a file, it will be installed to TARGET
216 in the final initramfs.
217 -I, --install [LIST] Install the space separated list of files into the
218 initramfs.
219 --install-optional [LIST]
220 Install the space separated list of files into the
221 initramfs, if they exist.
222 --gzip Compress the generated initramfs using gzip.
223 This will be done by default, unless another
224 compression option or --no-compress is passed.
225 --bzip2 Compress the generated initramfs using bzip2.
226 Make sure your kernel has bzip2 decompression support
227 compiled in, otherwise you will not be able to boot.
228 --lzma Compress the generated initramfs using lzma.
229 Make sure your kernel has lzma support compiled in,
230 otherwise you will not be able to boot.
231 --xz Compress the generated initramfs using xz.
232 Make sure that your kernel has xz support compiled
233 in, otherwise you will not be able to boot.
234 --lzo Compress the generated initramfs using lzop.
235 Make sure that your kernel has lzo support compiled
236 in, otherwise you will not be able to boot.
237 --lz4 Compress the generated initramfs using lz4.
238 Make sure that your kernel has lz4 support compiled
239 in, otherwise you will not be able to boot.
240 --zstd Compress the generated initramfs using Zstandard.
241 Make sure that your kernel has zstd support compiled
242 in, otherwise you will not be able to boot.
243 --compress [COMPRESSION]
244 Compress the generated initramfs with the
245 passed compression program. Make sure your kernel
246 knows how to decompress the generated initramfs,
247 otherwise you will not be able to boot.
248 --no-compress Do not compress the generated initramfs. This will
249 override any other compression options.
250 --squash-compressor [COMPRESSION]
251 Specify the compressor and compressor specific options
252 used by mksquashfs if squash module is called when
253 building the initramfs.
254 --enhanced-cpio Attempt to reflink cpio file data using dracut-cpio.
255 --list-modules List all available dracut modules.
256 -M, --show-modules Print included module's name to standard output during
257 build.
258 --keep Keep the temporary initramfs for debugging purposes.
259 --printsize Print out the module install size.
260 --sshkey [SSHKEY] Add SSH key to initramfs (use with ssh-client module).
261 --logfile [FILE] Logfile to use (overrides configuration setting).
262 --reproducible Create reproducible images.
263 --no-reproducible Do not create reproducible images.
264 --loginstall [DIR] Log all files installed from the host to [DIR].
265 --uefi Create an UEFI executable with the kernel cmdline and
266 kernel combined.
267 --no-uefi Disables UEFI mode.
268 --no-machineid Affects the default output filename of the UEFI
269 executable, discarding the <MACHINE_ID> part.
270 --uefi-stub [FILE] Use the UEFI stub [FILE] to create an UEFI executable.
271 --uefi-splash-image [FILE]
272 Use [FILE] as a splash image when creating an UEFI
273 executable. Requires bitmap (.bmp) image format.
274 --kernel-image [FILE] Location of the kernel image.
275 --regenerate-all Regenerate all initramfs images at the default location
276 for the kernel versions found on the system.
277 -p, --parallel Use parallel processing if possible (currently only
278 supported --regenerate-all)
279 images simultaneously.
280 --version Display version.
281
282 If [LIST] has multiple arguments, then you have to put these in quotes.
283
284 For example:
285
286 # dracut --add-drivers "module1 module2" ...
287
288 EOF
289 }
290
291 long_version() {
292 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
293 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
294 # shellcheck source=./dracut-version.sh
295 . "$dracutbasedir"/dracut-version.sh
296 fi
297 echo "dracut $DRACUT_VERSION"
298 }
299
300 # Fills up host_devs stack variable and makes sure there are no duplicates
301 push_host_devs() {
302 local _dev
303 for _dev in "$@"; do
304 [[ " ${host_devs[*]} " == *" $_dev "* ]] && return
305 host_devs+=("$_dev")
306 done
307 }
308
309 # Little helper function for reading args from the commandline.
310 # it automatically handles -a b and -a=b variants, and returns 1 if
311 # we need to shift $3.
312 read_arg() {
313 # $1 = arg name
314 # $2 = arg value
315 # $3 = arg parameter
316 local rematch='^[^=]*=(.*)$'
317 if [[ $2 =~ $rematch ]]; then
318 read -r "$1" <<< "${BASH_REMATCH[1]}"
319 else
320 read -r "$1" <<< "$3"
321 # There is no way to shift our callers args, so
322 # return 1 to indicate they should do it instead.
323 return 1
324 fi
325 }
326
327 check_conf_file() {
328 if grep -H -e '^[^#]*[+]=\("[^ ]\|.*[^ ]"\)' "$@"; then
329 printf '\ndracut[W]: <key>+=" <values> ": <values> should have surrounding white spaces!\n' >&2
330 printf 'dracut[W]: This will lead to unwanted side effects! Please fix the configuration file.\n\n' >&2
331 fi
332 }
333
334 dropindirs_sort() {
335 local suffix=$1
336 shift
337 local -a files
338 local f d
339
340 for d in "$@"; do
341 for i in "$d/"*"$suffix"; do
342 if [[ -e $i ]]; then
343 printf "%s\n" "${i##*/}"
344 fi
345 done
346 done | sort -Vu | {
347 readarray -t files
348
349 for f in "${files[@]}"; do
350 for d in "$@"; do
351 if [[ -e "$d/$f" ]]; then
352 printf "%s\n" "$d/$f"
353 continue 2
354 fi
355 done
356 done
357 }
358 }
359
360 rearrange_params() {
361 # Workaround -i, --include taking 2 arguments
362 newat=()
363 for i in "$@"; do
364 if [[ $i == "-i" ]] || [[ $i == "--include" ]]; then
365 newat+=("++include") # Replace --include by ++include
366 else
367 newat+=("$i")
368 fi
369 done
370 set -- "${newat[@]}" # Set new $@
371
372 TEMP=$(
373 unset POSIXLY_CORRECT
374 getopt \
375 -o "a:m:o:d:I:k:c:r:L:fvqlHhMNp" \
376 --long kver: \
377 --long add: \
378 --long force-add: \
379 --long add-drivers: \
380 --long force-drivers: \
381 --long omit-drivers: \
382 --long modules: \
383 --long omit: \
384 --long drivers: \
385 --long filesystems: \
386 --long install: \
387 --long install-optional: \
388 --long fwdir: \
389 --long libdirs: \
390 --long fscks: \
391 --long add-fstab: \
392 --long mount: \
393 --long device: \
394 --long add-device: \
395 --long nofscks \
396 --long ro-mnt \
397 --long kmoddir: \
398 --long conf: \
399 --long confdir: \
400 --long tmpdir: \
401 --long sysroot: \
402 --long stdlog: \
403 --long compress: \
404 --long squash-compressor: \
405 --long prefix: \
406 --long rebuild: \
407 --long force \
408 --long kernel-only \
409 --long no-kernel \
410 --long print-cmdline \
411 --long kernel-cmdline: \
412 --long strip \
413 --long aggressive-strip \
414 --long nostrip \
415 --long hardlink \
416 --long nohardlink \
417 --long noprefix \
418 --long mdadmconf \
419 --long nomdadmconf \
420 --long lvmconf \
421 --long nolvmconf \
422 --long debug \
423 --long profile \
424 --long sshkey: \
425 --long logfile: \
426 --long verbose \
427 --long quiet \
428 --long local \
429 --long hostonly \
430 --long host-only \
431 --long no-hostonly \
432 --long no-host-only \
433 --long hostonly-mode: \
434 --long hostonly-cmdline \
435 --long no-hostonly-cmdline \
436 --long no-hostonly-default-device \
437 --long persistent-policy: \
438 --long fstab \
439 --long help \
440 --long bzip2 \
441 --long lzma \
442 --long xz \
443 --long lzo \
444 --long lz4 \
445 --long zstd \
446 --long no-compress \
447 --long gzip \
448 --long enhanced-cpio \
449 --long list-modules \
450 --long show-modules \
451 --long keep \
452 --long printsize \
453 --long regenerate-all \
454 --long parallel \
455 --long noimageifnotneeded \
456 --long early-microcode \
457 --long no-early-microcode \
458 --long reproducible \
459 --long no-reproducible \
460 --long loginstall: \
461 --long uefi \
462 --long no-uefi \
463 --long uefi-stub: \
464 --long uefi-splash-image: \
465 --long kernel-image: \
466 --long no-hostonly-i18n \
467 --long hostonly-i18n \
468 --long hostonly-nics: \
469 --long no-machineid \
470 --long version \
471 -- "$@"
472 )
473
474 # shellcheck disable=SC2181
475 if (($? != 0)); then
476 usage
477 exit 1
478 fi
479 }
480
481 verbosity_mod_l=0
482 unset kernel
483 unset outfile
484
485 rearrange_params "$@"
486 eval set -- "$TEMP"
487
488 # parse command line args to check if '--rebuild' option is present
489 unset append_args_l
490 unset rebuild_file
491 while :; do
492 if [ "$1" == "--" ]; then
493 shift
494 break
495 fi
496 if [ "$1" == "--rebuild" ]; then
497 append_args_l="yes"
498 rebuild_file="$2"
499 if [ ! -e "$rebuild_file" ]; then
500 echo "Image file '$rebuild_file', for rebuild, does not exist!"
501 exit 1
502 fi
503 abs_rebuild_file=$(readlink -f "$rebuild_file") && rebuild_file="$abs_rebuild_file"
504 shift
505 continue
506 fi
507 shift
508 done
509
510 # get output file name and kernel version from command line arguments
511 while (($# > 0)); do
512 case ${1%%=*} in
513 ++include)
514 shift 2
515 ;;
516 *)
517 if ! [[ ${outfile+x} ]]; then
518 outfile=$1
519 elif ! [[ ${kernel+x} ]]; then
520 kernel=$1
521 else
522 printf "\nUnknown arguments: %s\n\n" "$*" >&2
523 usage
524 exit 1
525 fi
526 ;;
527 esac
528 shift
529 done
530
531 # extract input image file provided with rebuild option to get previous parameters, if any
532 if [[ $append_args_l == "yes" ]]; then
533 unset rebuild_param
534
535 # determine resultant file
536 if ! [[ $outfile ]]; then
537 outfile=$rebuild_file
538 fi
539
540 if ! rebuild_param=$(lsinitrd "$rebuild_file" '*lib/dracut/build-parameter.txt'); then
541 echo "Image '$rebuild_file' has no rebuild information stored"
542 exit 1
543 fi
544
545 # prepend previous parameters to current command line args
546 if [[ $rebuild_param ]]; then
547 TEMP="$rebuild_param $TEMP"
548 eval set -- "$TEMP"
549 rearrange_params "$@"
550 fi
551 fi
552
553 unset PARMS_TO_STORE
554 PARMS_TO_STORE=""
555
556 eval set -- "$TEMP"
557
558 while :; do
559 if [[ $1 != "--" ]] && [[ $1 != "--rebuild" ]]; then
560 PARMS_TO_STORE+=" $1"
561 fi
562 case $1 in
563 --kver)
564 kernel="$2"
565 PARMS_TO_STORE+=" '$2'"
566 shift
567 ;;
568 -a | --add)
569 add_dracutmodules_l+=("$2")
570 PARMS_TO_STORE+=" '$2'"
571 shift
572 ;;
573 --force-add)
574 force_add_dracutmodules_l+=("$2")
575 PARMS_TO_STORE+=" '$2'"
576 shift
577 ;;
578 --add-drivers)
579 add_drivers_l+=("$2")
580 PARMS_TO_STORE+=" '$2'"
581 shift
582 ;;
583 --force-drivers)
584 force_drivers_l+=("$2")
585 PARMS_TO_STORE+=" '$2'"
586 shift
587 ;;
588 --omit-drivers)
589 omit_drivers_l+=("$2")
590 PARMS_TO_STORE+=" '$2'"
591 shift
592 ;;
593 -m | --modules)
594 dracutmodules_l+=("$2")
595 PARMS_TO_STORE+=" '$2'"
596 shift
597 ;;
598 -o | --omit)
599 omit_dracutmodules_l+=("$2")
600 PARMS_TO_STORE+=" '$2'"
601 shift
602 ;;
603 -d | --drivers)
604 drivers_l+=("$2")
605 PARMS_TO_STORE+=" '$2'"
606 shift
607 ;;
608 --filesystems)
609 filesystems_l+=("$2")
610 PARMS_TO_STORE+=" '$2'"
611 shift
612 ;;
613 -I | --install)
614 install_items_l+=("$2")
615 PARMS_TO_STORE+=" '$2'"
616 shift
617 ;;
618 --install-optional)
619 install_optional_items_l+=("$2")
620 PARMS_TO_STORE+=" '$2'"
621 shift
622 ;;
623 --fwdir)
624 fw_dir_l+=("$2")
625 PARMS_TO_STORE+=" '$2'"
626 shift
627 ;;
628 --libdirs)
629 libdirs_l+=("$2")
630 PARMS_TO_STORE+=" '$2'"
631 shift
632 ;;
633 --fscks)
634 fscks_l+=("$2")
635 PARMS_TO_STORE+=" '$2'"
636 shift
637 ;;
638 --add-fstab)
639 add_fstab_l+=("$2")
640 PARMS_TO_STORE+=" '$2'"
641 shift
642 ;;
643 --mount)
644 fstab_lines+=("$2")
645 PARMS_TO_STORE+=" '$2'"
646 shift
647 ;;
648 --add-device | --device)
649 add_device_l+=("$2")
650 PARMS_TO_STORE+=" '$2'"
651 shift
652 ;;
653 --kernel-cmdline)
654 kernel_cmdline_l+=("$2")
655 PARMS_TO_STORE+=" '$2'"
656 shift
657 ;;
658 --nofscks) nofscks_l="yes" ;;
659 --ro-mnt) ro_mnt_l="yes" ;;
660 -k | --kmoddir)
661 drivers_dir_l="$2"
662 PARMS_TO_STORE+=" '$2'"
663 shift
664 ;;
665 -c | --conf)
666 conffile="$2"
667 PARMS_TO_STORE+=" '$2'"
668 shift
669 ;;
670 --confdir)
671 confdir="$2"
672 PARMS_TO_STORE+=" '$2'"
673 shift
674 ;;
675 --tmpdir)
676 tmpdir_l="$2"
677 PARMS_TO_STORE+=" '$2'"
678 shift
679 ;;
680 -r | --sysroot)
681 sysroot_l="$2"
682 PARMS_TO_STORE+=" '$2'"
683 shift
684 ;;
685 -L | --stdlog)
686 stdloglvl_l="$2"
687 PARMS_TO_STORE+=" '$2'"
688 shift
689 ;;
690 --compress)
691 compress_l="$2"
692 PARMS_TO_STORE+=" '$2'"
693 shift
694 ;;
695 --squash-compressor)
696 squash_compress_l="$2"
697 PARMS_TO_STORE+=" '$2'"
698 shift
699 ;;
700 --prefix)
701 prefix_l="$2"
702 PARMS_TO_STORE+=" '$2'"
703 shift
704 ;;
705 --loginstall)
706 loginstall_l="$2"
707 PARMS_TO_STORE+=" '$2'"
708 shift
709 ;;
710 --rebuild)
711 if [[ $rebuild_file == "$outfile" ]]; then
712 force=yes
713 fi
714 shift
715 ;;
716 -f | --force) force=yes ;;
717 --kernel-only)
718 kernel_only="yes"
719 no_kernel="no"
720 ;;
721 --no-kernel)
722 kernel_only="no"
723 no_kernel="yes"
724 ;;
725 --print-cmdline)
726 print_cmdline="yes"
727 hostonly_l="yes"
728 kernel_only="yes"
729 no_kernel="yes"
730 ;;
731 --early-microcode)
732 early_microcode_l="yes"
733 ;;
734 --no-early-microcode)
735 early_microcode_l="no"
736 ;;
737 --strip) do_strip_l="yes" ;;
738 --aggressive-strip) aggressive_strip_l="yes" ;;
739 --nostrip) do_strip_l="no" ;;
740 --hardlink) do_hardlink_l="yes" ;;
741 --nohardlink) do_hardlink_l="no" ;;
742 --noprefix) prefix_l="/" ;;
743 --mdadmconf) mdadmconf_l="yes" ;;
744 --nomdadmconf) mdadmconf_l="no" ;;
745 --lvmconf) lvmconf_l="yes" ;;
746 --nolvmconf) lvmconf_l="no" ;;
747 --debug) debug="yes" ;;
748 --profile) profile="yes" ;;
749 --sshkey)
750 sshkey="$2"
751 PARMS_TO_STORE+=" '$2'"
752 shift
753 ;;
754 --logfile)
755 logfile_l="$2"
756 shift
757 ;;
758 -v | --verbose) ((verbosity_mod_l++)) ;;
759 -q | --quiet) ((verbosity_mod_l--)) ;;
760 -l | --local)
761 allowlocal="yes"
762 [[ -f "$(readlink -f "${0%/*}")/dracut-init.sh" ]] \
763 && dracutbasedir="$(readlink -f "${0%/*}")"
764 ;;
765 -H | --hostonly | --host-only)
766 hostonly_l="yes"
767 ;;
768 -N | --no-hostonly | --no-host-only)
769 hostonly_l="no"
770 ;;
771 --hostonly-mode)
772 hostonly_mode_l="$2"
773 PARMS_TO_STORE+=" '$2'"
774 shift
775 ;;
776 --hostonly-cmdline)
777 hostonly_cmdline_l="yes"
778 ;;
779 --hostonly-i18n)
780 i18n_install_all_l="no"
781 ;;
782 --hostonly-nics)
783 hostonly_nics_l+=("$2")
784 PARMS_TO_STORE+=" '$2'"
785 shift
786 ;;
787 --no-hostonly-i18n)
788 i18n_install_all_l="yes"
789 ;;
790 --no-hostonly-cmdline)
791 hostonly_cmdline_l="no"
792 ;;
793 --no-hostonly-default-device)
794 hostonly_default_device="no"
795 ;;
796 --persistent-policy)
797 persistent_policy_l="$2"
798 PARMS_TO_STORE+=" '$2'"
799 shift
800 ;;
801 --fstab) use_fstab_l="yes" ;;
802 -h | --help)
803 long_usage
804 exit 0
805 ;;
806 --bzip2) compress_l="bzip2" ;;
807 --lzma) compress_l="lzma" ;;
808 --xz) compress_l="xz" ;;
809 --lzo) compress_l="lzop" ;;
810 --lz4) compress_l="lz4" ;;
811 --zstd) compress_l="zstd" ;;
812 --no-compress) _no_compress_l="cat" ;;
813 --gzip) compress_l="gzip" ;;
814 --enhanced-cpio) enhanced_cpio_l="yes" ;;
815 --list-modules) do_list="yes" ;;
816 -M | --show-modules)
817 show_modules_l="yes"
818 ;;
819 --keep) keep="yes" ;;
820 --printsize) printsize="yes" ;;
821 --regenerate-all) regenerate_all_l="yes" ;;
822 -p | --parallel) parallel_l="yes" ;;
823 --noimageifnotneeded) noimageifnotneeded="yes" ;;
824 --reproducible) reproducible_l="yes" ;;
825 --no-reproducible) reproducible_l="no" ;;
826 --uefi) uefi_l="yes" ;;
827 --no-uefi) uefi_l="no" ;;
828 --uefi-stub)
829 uefi_stub_l="$2"
830 PARMS_TO_STORE+=" '$2'"
831 shift
832 ;;
833 --uefi-splash-image)
834 uefi_splash_image_l="$2"
835 PARMS_TO_STORE+=" '$2'"
836 shift
837 ;;
838 --kernel-image)
839 kernel_image_l="$2"
840 PARMS_TO_STORE+=" '$2'"
841 shift
842 ;;
843 --no-machineid)
844 machine_id_l="no"
845 ;;
846 --version)
847 long_version
848 exit 0
849 ;;
850 --)
851 shift
852 break
853 ;;
854
855 *) # should not even reach this point
856 printf "\n!Unknown option: '%s'\n\n" "$1" >&2
857 usage
858 exit 1
859 ;;
860 esac
861 shift
862 done
863
864 # getopt cannot handle multiple arguments, so just handle "-I,--include"
865 # the old fashioned way
866
867 while (($# > 0)); do
868 if [ "${1%%=*}" == "++include" ]; then
869 include_src+=("$2")
870 include_target+=("$3")
871 PARMS_TO_STORE+=" --include '$2' '$3'"
872 shift 2
873 fi
874 shift
875 done
876
877 [[ $sysroot_l ]] && dracutsysrootdir="$sysroot_l"
878
879 export LC_ALL=C
880 export LANG=C
881 unset LC_MESSAGES
882 unset LC_CTYPE
883 unset LD_LIBRARY_PATH
884 unset LD_PRELOAD
885 unset GREP_OPTIONS
886
887 export DRACUT_LOG_LEVEL=warning
888 [[ $debug ]] && {
889 export DRACUT_LOG_LEVEL=debug
890 export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]-}): '
891 set -x
892 }
893
894 [[ $profile ]] && {
895 export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: '
896 set -x
897 debug=yes
898 }
899
900 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
901
902 # if we were not passed a config file, try the default one
903 if [[ -z $conffile ]]; then
904 if [[ $allowlocal ]]; then
905 conffile="$dracutbasedir/dracut.conf"
906 else
907 conffile="$dracutsysrootdir/etc/dracut.conf"
908 fi
909 elif [[ ! -e $conffile ]]; then
910 printf "%s\n" "dracut[F]: Configuration file '$conffile' not found." >&2
911 exit 1
912 fi
913
914 if [[ -z $confdir ]]; then
915 if [[ $allowlocal ]]; then
916 confdir="$dracutbasedir/dracut.conf.d"
917 else
918 confdir="$dracutsysrootdir/etc/dracut.conf.d"
919 fi
920 elif [[ ! -d $confdir ]]; then
921 printf "%s\n" "dracut[F]: Configuration directory '$confdir' not found." >&2
922 exit 1
923 fi
924
925 # source our config file
926 if [[ -f $conffile ]]; then
927 check_conf_file "$conffile"
928 # shellcheck disable=SC1090
929 . "$conffile"
930 fi
931
932 # source our config dir
933 for f in $(dropindirs_sort ".conf" "$confdir" "$dracutbasedir/dracut.conf.d"); do
934 check_conf_file "$f"
935 # shellcheck disable=SC1090
936 [[ -e $f ]] && . "$f"
937 done
938
939 # regenerate_all shouldn't be set in conf files
940 regenerate_all=$regenerate_all_l
941 if [[ $parallel_l == "yes" ]]; then
942 parallel=yes
943 fi
944
945 if [[ $regenerate_all == "yes" ]]; then
946 ret=0
947 if [[ $kernel ]]; then
948 printf "%s\n" "dracut[F]: --regenerate-all cannot be called with a kernel version." >&2
949 exit 1
950 fi
951
952 if [[ $outfile ]]; then
953 printf "%s\n" "dracut[F]: --regenerate-all cannot be called with an image file." >&2
954 exit 1
955 fi
956
957 ((len = ${#dracut_args[@]}))
958 for ((i = 0; i < len; i++)); do
959 case ${dracut_args[$i]} in
960 --regenerate-all | --parallel)
961 # shellcheck disable=SC2184
962 unset dracut_args["$i"]
963 ;;
964 esac
965 done
966
967 cd "$dracutsysrootdir"/lib/modules || exit 1
968 if [[ $parallel != "yes" ]]; then
969 for i in *; do
970 [[ -f $i/modules.dep ]] || [[ -f $i/modules.dep.bin ]] || continue
971 "$dracut_cmd" --kver="$i" "${dracut_args[@]}"
972 ((ret += $?))
973 done
974 else
975 for i in *; do
976 [[ -f $i/modules.dep ]] || [[ -f $i/modules.dep.bin ]] || continue
977 "$dracut_cmd" --kver="$i" "${dracut_args[@]}" &
978 done
979 while true; do
980 wait -n
981 wst=$?
982 if [[ $wst == 127 ]]; then
983 break
984 else
985 ((ret += wst))
986 fi
987 done
988 fi
989 exit "$ret"
990 fi
991
992 if ! [[ $kernel ]]; then
993 kernel=$(uname -r)
994 fi
995
996 DRACUT_PATH=${DRACUT_PATH:-/sbin /bin /usr/sbin /usr/bin}
997
998 for i in $DRACUT_PATH; do
999 rl=$i
1000 if [ -L "$dracutsysrootdir$i" ]; then
1001 rl=$(readlink -f "$dracutsysrootdir$i")
1002 fi
1003 rl="${rl#"$dracutsysrootdir"}"
1004 if [[ $NPATH != *:$rl* ]]; then
1005 NPATH+=":$rl"
1006 fi
1007 done
1008 [[ -z $dracutsysrootdir ]] && export PATH="${NPATH#:}"
1009 unset NPATH
1010
1011 export SYSTEMCTL=${SYSTEMCTL:-systemctl}
1012
1013 # these options add to the stuff in the config file
1014 ((${#add_dracutmodules_l[@]})) && add_dracutmodules+=" ${add_dracutmodules_l[*]} "
1015 ((${#omit_dracutmodules_l[@]})) && omit_dracutmodules+=" ${omit_dracutmodules_l[*]} "
1016 ((${#force_add_dracutmodules_l[@]})) && force_add_dracutmodules+=" ${force_add_dracutmodules_l[*]} "
1017 ((${#fscks_l[@]})) && fscks+=" ${fscks_l[*]} "
1018 ((${#add_fstab_l[@]})) && add_fstab+=" ${add_fstab_l[*]} "
1019 ((${#install_items_l[@]})) && install_items+=" ${install_items_l[*]} "
1020 ((${#install_optional_items_l[@]})) && install_optional_items+=" ${install_optional_items_l[*]} "
1021 ((${#hostonly_nics_l[@]})) && hostonly_nics+=" ${hostonly_nics_l[*]} "
1022
1023 # these options override the stuff in the config file
1024 ((${#dracutmodules_l[@]})) && dracutmodules="${dracutmodules_l[*]}"
1025 ((${#filesystems_l[@]})) && filesystems="${filesystems_l[*]}"
1026 ((${#fw_dir_l[@]})) && fw_dir="${fw_dir_l[*]}"
1027 ((${#libdirs_l[@]})) && libdirs="${libdirs_l[*]}"
1028
1029 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
1030 [[ ! $stdloglvl ]] && stdloglvl=4
1031 stdloglvl=$((stdloglvl + verbosity_mod_l))
1032 ((stdloglvl > 6)) && stdloglvl=6
1033 ((stdloglvl < 0)) && stdloglvl=0
1034
1035 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
1036 drivers_dir="${drivers_dir%"${drivers_dir##*[!/]}"}"
1037 [[ $do_strip_l ]] && do_strip=$do_strip_l
1038 [[ $do_strip ]] || do_strip=yes
1039 [[ $aggressive_strip_l ]] && aggressive_strip=$aggressive_strip_l
1040 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
1041 [[ $do_hardlink ]] || do_hardlink=yes
1042 [[ $prefix_l ]] && prefix=$prefix_l
1043 [[ $prefix == "/" ]] && unset prefix
1044 [[ $hostonly_l ]] && hostonly=$hostonly_l
1045 [[ $hostonly_cmdline_l ]] && hostonly_cmdline=$hostonly_cmdline_l
1046 [[ $hostonly_mode_l ]] && hostonly_mode=$hostonly_mode_l
1047 [[ $hostonly == "yes" ]] && ! [[ $hostonly_cmdline ]] && hostonly_cmdline="yes"
1048 # shellcheck disable=SC2034
1049 [[ $i18n_install_all_l ]] && i18n_install_all=$i18n_install_all_l
1050 # shellcheck disable=SC2034
1051 [[ $persistent_policy_l ]] && persistent_policy=$persistent_policy_l
1052 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
1053 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
1054 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
1055 [[ $dracutbasedir ]] || dracutbasedir="$dracutsysrootdir"/usr/lib/dracut
1056 [[ $fw_dir ]] || {
1057 fw_path_para=$(< /sys/module/firmware_class/parameters/path)
1058 fw_dir="${fw_path_para:+$dracutsysrootdir$fw_path_para:}$dracutsysrootdir/lib/firmware/updates/$kernel:$dracutsysrootdir/lib/firmware/updates:$dracutsysrootdir/lib/firmware/$kernel:$dracutsysrootdir/lib/firmware"
1059 }
1060 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
1061 [[ $tmpdir ]] || tmpdir="$TMPDIR"
1062 [[ $tmpdir ]] || tmpdir="$dracutsysrootdir"/var/tmp
1063 [[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
1064 [[ $compress_l ]] && compress=$compress_l
1065 [[ $squash_compress_l ]] && squash_compress=$squash_compress_l
1066 [[ $enhanced_cpio_l ]] && enhanced_cpio=$enhanced_cpio_l
1067 [[ $show_modules_l ]] && show_modules=$show_modules_l
1068 [[ $nofscks_l ]] && nofscks="yes"
1069 [[ $ro_mnt_l ]] && ro_mnt="yes"
1070 [[ $early_microcode_l ]] && early_microcode=$early_microcode_l
1071 [[ $early_microcode ]] || early_microcode=yes
1072 [[ $early_microcode_image_dir ]] || early_microcode_image_dir=('/boot')
1073 [[ $early_microcode_image_name ]] \
1074 || early_microcode_image_name=('intel-uc.img' 'intel-ucode.img' 'amd-uc.img' 'amd-ucode.img' 'early_ucode.cpio' 'microcode.cpio')
1075 [[ $logfile_l ]] && logfile="$logfile_l"
1076 [[ $reproducible_l ]] && reproducible="$reproducible_l"
1077 [[ $loginstall_l ]] && loginstall="$loginstall_l"
1078 [[ $uefi_l ]] && uefi=$uefi_l
1079 [[ $uefi_stub_l ]] && uefi_stub="$uefi_stub_l"
1080 [[ $uefi_splash_image_l ]] && uefi_splash_image="$uefi_splash_image_l"
1081 [[ $kernel_image_l ]] && kernel_image="$kernel_image_l"
1082 [[ $machine_id_l ]] && machine_id="$machine_id_l"
1083
1084 if ! [[ $outfile ]]; then
1085 if [[ $machine_id != "no" ]]; then
1086 if [[ -d "$dracutsysrootdir"/efi/Default ]] \
1087 || [[ -d "$dracutsysrootdir"/boot/Default ]] \
1088 || [[ -d "$dracutsysrootdir"/boot/efi/Default ]]; then
1089 MACHINE_ID="Default"
1090 elif [[ -s "$dracutsysrootdir"/etc/machine-id ]]; then
1091 read -r MACHINE_ID < "$dracutsysrootdir"/etc/machine-id
1092 [[ $MACHINE_ID == "uninitialized" ]] && MACHINE_ID="Default"
1093 else
1094 MACHINE_ID="Default"
1095 fi
1096 fi
1097
1098 if [[ $uefi == "yes" ]]; then
1099 # shellcheck disable=SC2154
1100 if [[ -n $uefi_secureboot_key && -z $uefi_secureboot_cert ]] || [[ -z $uefi_secureboot_key && -n $uefi_secureboot_cert ]]; then
1101 printf "%s\n" "dracut[F]: Need 'uefi_secureboot_key' and 'uefi_secureboot_cert' both to be set." >&2
1102 exit 1
1103 fi
1104
1105 if [[ -n $uefi_secureboot_key && -n $uefi_secureboot_cert ]] && ! command -v sbsign &> /dev/null; then
1106 printf "%s\n" "dracut[F]: Need 'sbsign' to create a signed UEFI executable." >&2
1107 exit 1
1108 fi
1109
1110 BUILD_ID=$(cat "$dracutsysrootdir"/etc/os-release "$dracutsysrootdir"/usr/lib/os-release \
1111 | while read -r line || [[ $line ]]; do
1112 [[ $line =~ BUILD_ID\=* ]] && eval "$line" && echo "$BUILD_ID" && break
1113 done)
1114 if [[ -z $dracutsysrootdir ]]; then
1115 if [[ -d /efi ]] && mountpoint -q /efi; then
1116 efidir=/efi/EFI
1117 else
1118 efidir=/boot/EFI
1119 if [[ -d /boot/efi/EFI ]]; then
1120 efidir=/boot/efi/EFI
1121 fi
1122 fi
1123 else
1124 efidir=/boot/EFI
1125 if [[ -d $dracutsysrootdir/boot/efi/EFI ]]; then
1126 efidir=/boot/efi/EFI
1127 fi
1128 fi
1129 mkdir -p "$dracutsysrootdir$efidir/Linux"
1130 outfile="$dracutsysrootdir$efidir/Linux/linux-$kernel${MACHINE_ID:+-${MACHINE_ID}}${BUILD_ID:+-${BUILD_ID}}.efi"
1131 else
1132 if [[ -d "$dracutsysrootdir"/efi/loader/entries || -L "$dracutsysrootdir"/efi/loader/entries ]] \
1133 && [[ $MACHINE_ID ]] \
1134 && [[ -d "$dracutsysrootdir"/efi/${MACHINE_ID} || -L "$dracutsysrootdir"/efi/${MACHINE_ID} ]]; then
1135 outfile="$dracutsysrootdir/efi/${MACHINE_ID}/${kernel}/initrd"
1136 elif [[ -d "$dracutsysrootdir"/boot/loader/entries || -L "$dracutsysrootdir"/boot/loader/entries ]] \
1137 && [[ $MACHINE_ID ]] \
1138 && [[ -d "$dracutsysrootdir"/boot/${MACHINE_ID} || -L "$dracutsysrootdir"/boot/${MACHINE_ID} ]]; then
1139 outfile="$dracutsysrootdir/boot/${MACHINE_ID}/${kernel}/initrd"
1140 elif [[ -d "$dracutsysrootdir"/boot/efi/loader/entries || -L "$dracutsysrootdir"/boot/efi/loader/entries ]] \
1141 && [[ $MACHINE_ID ]] \
1142 && [[ -d "$dracutsysrootdir"/boot/efi/${MACHINE_ID} || -L "$dracutsysrootdir"/boot/efi/${MACHINE_ID} ]]; then
1143 outfile="$dracutsysrootdir/boot/efi/${MACHINE_ID}/${kernel}/initrd"
1144 elif [[ -f "$dracutsysrootdir"/lib/modules/${kernel}/initrd ]]; then
1145 outfile="$dracutsysrootdir/lib/modules/${kernel}/initrd"
1146 elif [[ -e $dracutsysrootdir/boot/vmlinuz-${kernel} ]]; then
1147 outfile="$dracutsysrootdir/boot/initramfs-${kernel}.img"
1148 elif [[ -z $dracutsysrootdir ]] \
1149 && [[ $MACHINE_ID ]] \
1150 && mountpoint -q /efi; then
1151 outfile="/efi/${MACHINE_ID}/${kernel}/initrd"
1152 elif [[ -z $dracutsysrootdir ]] \
1153 && [[ $MACHINE_ID ]] \
1154 && mountpoint -q /boot/efi; then
1155 outfile="/boot/efi/${MACHINE_ID}/${kernel}/initrd"
1156 else
1157 outfile="$dracutsysrootdir/boot/initramfs-${kernel}.img"
1158 fi
1159 fi
1160 fi
1161
1162 # eliminate IFS hackery when messing with fw_dir
1163 export DRACUT_FIRMWARE_PATH=${fw_dir// /:}
1164 fw_dir=${fw_dir//:/ }
1165
1166 # check for logfile and try to create one if it doesn't exist
1167 if [[ -n $logfile ]]; then
1168 if [[ ! -f $logfile ]]; then
1169 if touch "$logfile"; then
1170 printf "%s\n" "dracut[W]: touch $logfile failed." >&2
1171 fi
1172 fi
1173 fi
1174
1175 # handle compression options.
1176 DRACUT_COMPRESS_BZIP2=${DRACUT_COMPRESS_BZIP2:-bzip2}
1177 DRACUT_COMPRESS_LBZIP2=${DRACUT_COMPRESS_LBZIP2:-lbzip2}
1178 DRACUT_COMPRESS_LZMA=${DRACUT_COMPRESS_LZMA:-lzma}
1179 DRACUT_COMPRESS_XZ=${DRACUT_COMPRESS_XZ:-xz}
1180 DRACUT_COMPRESS_GZIP=${DRACUT_COMPRESS_GZIP:-gzip}
1181 DRACUT_COMPRESS_PIGZ=${DRACUT_COMPRESS_PIGZ:-pigz}
1182 DRACUT_COMPRESS_LZOP=${DRACUT_COMPRESS_LZOP:-lzop}
1183 DRACUT_COMPRESS_ZSTD=${DRACUT_COMPRESS_ZSTD:-zstd}
1184 DRACUT_COMPRESS_LZ4=${DRACUT_COMPRESS_LZ4:-lz4}
1185 DRACUT_COMPRESS_CAT=${DRACUT_COMPRESS_CAT:-cat}
1186
1187 if [[ $_no_compress_l == "$DRACUT_COMPRESS_CAT" ]]; then
1188 compress="$DRACUT_COMPRESS_CAT"
1189 fi
1190
1191 [[ $hostonly == yes ]] && hostonly="-h"
1192 [[ $hostonly != "-h" ]] && unset hostonly
1193
1194 case $hostonly_mode in
1195 '')
1196 [[ $hostonly ]] && hostonly_mode="sloppy"
1197 ;;
1198 sloppy | strict)
1199 if [[ ! $hostonly ]]; then
1200 unset hostonly_mode
1201 fi
1202 ;;
1203 *)
1204 printf "%s\n" "dracut[F]: Invalid hostonly mode '$hostonly_mode'." >&2
1205 exit 1
1206 ;;
1207 esac
1208
1209 [[ $reproducible == yes ]] && DRACUT_REPRODUCIBLE=1
1210
1211 if [[ -z $DRACUT_KMODDIR_OVERRIDE && -n $drivers_dir ]]; then
1212 drivers_basename="${drivers_dir##*/}"
1213 if [[ -n $drivers_basename && $drivers_basename != "$kernel" ]]; then
1214 printf "%s\n" "dracut[F]: The provided directory where to look for kernel modules ($drivers_basename)" >&2
1215 printf "%s\n" "dracut[F]: does not match the kernel version set for the initramfs ($kernel)." >&2
1216 printf "%s\n" "dracut[F]: Set DRACUT_KMODDIR_OVERRIDE=1 to ignore this check." >&2
1217 exit 1
1218 fi
1219 drivers_dirname="${drivers_dir%/*}/"
1220 if [[ ! $drivers_dirname =~ .*/lib/modules/$ ]]; then
1221 printf "%s\n" "dracut[F]: drivers_dir path ${drivers_dir_l:+"set via -k/--kmoddir "}must contain \"/lib/modules/\" as a parent of your kernel module directory," >&2
1222 printf "%s\n" "dracut[F]: or modules may not be placed in the correct location inside the initramfs." >&2
1223 printf "%s\n" "dracut[F]: was given: ${drivers_dir}" >&2
1224 printf "%s\n" "dracut[F]: expected: ${drivers_dirname}lib/modules/${kernel}" >&2
1225 printf "%s\n" "dracut[F]: Please move your modules into the correct directory structure and pass the new location," >&2
1226 printf "%s\n" "dracut[F]: or set DRACUT_KMODDIR_OVERRIDE=1 to ignore this check." >&2
1227 exit 1
1228 fi
1229 fi
1230
1231 # shellcheck disable=SC2155
1232 readonly TMPDIR="$(realpath -e "$tmpdir")"
1233 [ -d "$TMPDIR" ] || {
1234 printf "%s\n" "dracut[F]: Invalid tmpdir '$tmpdir'." >&2
1235 exit 1
1236 }
1237
1238 if findmnt --raw -n --target "$tmpdir" --output=options | grep -q noexec; then
1239 [[ $debug == yes ]] && printf "%s\n" "dracut[D]: Tmpdir '$tmpdir' is mounted with 'noexec'." >&2
1240 noexec=1
1241 fi
1242
1243 # shellcheck disable=SC2155
1244 readonly DRACUT_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t dracut.XXXXXX)"
1245 [ -d "$DRACUT_TMPDIR" ] || {
1246 printf "%s\n" "dracut[F]: mktemp -p '$TMPDIR/' -d -t dracut.XXXXXX failed." >&2
1247 exit 1
1248 }
1249
1250 # Cache file used to optimize get_maj_min()
1251 declare -x -r get_maj_min_cache_file="${DRACUT_TMPDIR}/majmin_cache"
1252 : > "$get_maj_min_cache_file"
1253
1254 # clean up after ourselves no matter how we die.
1255 trap '
1256 ret=$?;
1257 [[ $keep ]] && echo "Not removing $DRACUT_TMPDIR." >&2 || { [[ $DRACUT_TMPDIR ]] && rm -rf -- "$DRACUT_TMPDIR"; };
1258 if [[ ${FSFROZEN} ]]; then
1259 fsfreeze -u "${FSFROZEN}"
1260 fi
1261 exit $ret;
1262 ' EXIT
1263
1264 # clean up after ourselves no matter how we die.
1265 trap 'exit 1;' SIGINT
1266
1267 readonly initdir="${DRACUT_TMPDIR}/initramfs"
1268 mkdir -p "$initdir"
1269
1270 # shellcheck disable=SC2154
1271 if [[ $early_microcode == yes ]] || { [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; }; then
1272 readonly early_cpio_dir="${DRACUT_TMPDIR}/earlycpio"
1273 mkdir "$early_cpio_dir"
1274 fi
1275
1276 [[ "$dracutsysrootdir" ]] || [[ "$noexec" ]] || export DRACUT_RESOLVE_LAZY="1"
1277
1278 if [[ $print_cmdline ]]; then
1279 stdloglvl=0
1280 sysloglvl=0
1281 fileloglvl=0
1282 kmsgloglvl=0
1283 fi
1284
1285 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
1286 # shellcheck source=./dracut-version.sh
1287 . "$dracutbasedir"/dracut-version.sh
1288 fi
1289
1290 if systemd-detect-virt -c &> /dev/null; then
1291 export DRACUT_NO_MKNOD=1 DRACUT_NO_XATTR=1
1292 if [[ $hostonly ]]; then
1293 printf "%s\n" "dracut[W]: Running in hostonly mode in a container!" >&2
1294 fi
1295 fi
1296
1297 if [[ -f $dracutbasedir/dracut-init.sh ]]; then
1298 # shellcheck source=./dracut-init.sh
1299 . "$dracutbasedir"/dracut-init.sh
1300 else
1301 printf "%s\n" "dracut[F]: Cannot find $dracutbasedir/dracut-init.sh." >&2
1302 printf "%s\n" "dracut[F]: Are you running from a git checkout?" >&2
1303 printf "%s\n" "dracut[F]: Try passing -l as an argument to $dracut_cmd" >&2
1304 exit 1
1305 fi
1306
1307 if [[ $persistent_policy == "mapper" ]]; then
1308 unset persistent_policy
1309 elif [[ -n $persistent_policy && ! -d "/dev/disk/${persistent_policy}" ]]; then
1310 dwarn "Invalid persistent policy, your system does not have a /dev/disk/${persistent_policy} directory."
1311 unset persistent_policy
1312 fi
1313
1314 if [[ $enhanced_cpio == "yes" ]]; then
1315 enhanced_cpio="$dracutbasedir/dracut-cpio"
1316 if [[ -x $enhanced_cpio ]]; then
1317 # align based on statfs optimal transfer size
1318 cpio_align=$(stat --file-system -c "%s" -- "$initdir")
1319 else
1320 dinfo "--enhanced-cpio ignored due to lack of dracut-cpio"
1321 unset enhanced_cpio
1322 fi
1323 else
1324 unset enhanced_cpio
1325 fi
1326
1327 # shellcheck disable=SC2154
1328 if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
1329 dfatal "Cannot find module directory $srcmods"
1330 dfatal "and --no-kernel was not specified"
1331 exit 1
1332 fi
1333
1334 if ! [[ $print_cmdline ]]; then
1335 inst "$DRACUT_TESTBIN"
1336 if ! $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R "$DRACUT_TESTBIN" &> /dev/null; then
1337 unset DRACUT_RESOLVE_LAZY
1338 export DRACUT_RESOLVE_DEPS=1
1339 fi
1340 rm -fr -- "${initdir:?}"/*
1341 fi
1342
1343 dracutfunctions=$dracutbasedir/dracut-functions.sh
1344 export dracutfunctions
1345
1346 ((${#drivers_l[@]})) && drivers="${drivers_l[*]}"
1347 drivers=${drivers/-/_}
1348
1349 ((${#add_drivers_l[@]})) && add_drivers+=" ${add_drivers_l[*]} "
1350 add_drivers=${add_drivers/-/_}
1351
1352 ((${#force_drivers_l[@]})) && force_drivers+=" ${force_drivers_l[*]} "
1353 force_drivers=${force_drivers/-/_}
1354
1355 ((${#omit_drivers_l[@]})) && omit_drivers+=" ${omit_drivers_l[*]} "
1356 omit_drivers=${omit_drivers/-/_}
1357
1358 ((${#kernel_cmdline_l[@]})) && kernel_cmdline+=" ${kernel_cmdline_l[*]} "
1359
1360 omit_drivers_corrected=""
1361 for d in $omit_drivers; do
1362 [[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
1363 [[ " $drivers $force_drivers " == *\ $d\ * ]] && continue
1364 omit_drivers_corrected+="^$d$|"
1365 done
1366 omit_drivers="${omit_drivers_corrected%|}"
1367 unset omit_drivers_corrected
1368
1369 # prepare args for logging
1370 for ((i = 0; i < ${#dracut_args[@]}; i++)); do
1371 [[ ${dracut_args[$i]} == *\ * ]] \
1372 && dracut_args[$i]="\"${dracut_args[$i]}\""
1373 #" keep vim happy
1374 done
1375
1376 dinfo "Executing: $dracut_cmd ${dracut_args[*]}"
1377
1378 [[ $do_list == yes ]] && {
1379 for mod in "$dracutbasedir"/modules.d/*; do
1380 [[ -d $mod ]] || continue
1381 [[ -e $mod/install || -e $mod/installkernel || -e $mod/module-setup.sh ]] || continue
1382 printf "%s\n" "${mod##*/??}"
1383 done
1384 exit 0
1385 }
1386
1387 # This is kinda legacy -- eventually it should go away.
1388 case $dracutmodules in
1389 "" | auto) dracutmodules="all" ;;
1390 esac
1391
1392 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
1393
1394 # Helper function to set global variables
1395 # set_global_var <pkg_config> <pkg_var[:exported_var]> <value[:check_file]> [<value[:check_file]>] ...
1396 set_global_var() {
1397 local _pkgconfig="$1"
1398 local _pkgvar="${2%:*}"
1399 local _var="${2#*:}"
1400 [[ -z ${!_var} || ! -d ${dracutsysrootdir}${!_var} ]] \
1401 && export "$_var"="$(pkg-config "$_pkgconfig" --variable="$_pkgvar" 2> /dev/null)"
1402 if [[ -z ${!_var} || ! -d ${dracutsysrootdir}${!_var} ]]; then
1403 shift 2
1404 if (($# == 1)); then
1405 export "$_var"="$1"
1406 else
1407 local _val
1408 for _val in "$@"; do
1409 _check=${_val##*:}
1410 _val=${_val%:*}
1411 [[ -e ${dracutsysrootdir}${_check} ]] && export "$_var"="$_val"
1412 done
1413 fi
1414 fi
1415 }
1416
1417 # dbus global variables
1418 set_global_var "dbus" "dbus" "/usr/share/dbus-1"
1419 set_global_var "dbus" "dbusconfdir" "/etc/dbus-1"
1420 set_global_var "dbus" "dbusinterfaces" "${dbus}/interfaces"
1421 set_global_var "dbus" "dbusinterfacesconfdir" "${dbusconfdir}/interfaces"
1422 set_global_var "dbus" "dbusservices" "${dbus}/services"
1423 set_global_var "dbus" "dbusservicesconfdir" "${dbusconfdir}/services"
1424 set_global_var "dbus" "dbussession" "${dbus}/session.d"
1425 set_global_var "dbus" "dbussessionconfdir" "${dbusconfdir}/session.d"
1426 set_global_var "dbus" "dbussystem" "${dbus}/system.d"
1427 set_global_var "dbus" "dbussystemconfdir" "${dbusconfdir}/system.d"
1428 set_global_var "dbus" "dbussystemservices" "${dbus}/system-services"
1429 set_global_var "dbus" "dbussystemservicesconfdir" "${dbusconfdir}/system-services"
1430
1431 # udev global variables
1432 set_global_var "udev" "udevdir" "/lib/udev:/lib/udev/ata_id" "/usr/lib/udev:/usr/lib/udev/ata_id"
1433 set_global_var "udev" "udevconfdir" "/etc/udev"
1434 set_global_var "udev" "udevrulesdir" "${udevdir}/rules.d"
1435 set_global_var "udev" "udevrulesconfdir" "${udevconfdir}/rules.d"
1436
1437 # systemd global variables
1438 set_global_var "systemd" "prefix:systemdprefix" "/usr"
1439 set_global_var "systemd" "systemdutildir" "/lib/systemd:/lib/systemd/systemd-udevd" "/usr/lib/systemd:/usr/lib/systemd/systemd-udevd"
1440 set_global_var "systemd" "systemdutilconfdir" "/etc/systemd"
1441 set_global_var "systemd" "environment" "/usr/lib/environment.d"
1442 set_global_var "systemd" "environmentconfdir" "/etc/environment.d"
1443 set_global_var "systemd" "modulesload" "/usr/lib/modules-load.d"
1444 set_global_var "systemd" "modulesloadconfdir" "/etc/modules-load.d"
1445 set_global_var "systemd" "sysctld" "/usr/lib/sysctl.d"
1446 set_global_var "systemd" "sysctlconfdir" "/etc/sysctl.d"
1447 set_global_var "systemd" "systemdcatalog" "${systemdutildir}/catalog"
1448 set_global_var "systemd" "systemdnetwork" "${systemdutildir}/network"
1449 set_global_var "systemd" "systemdnetworkconfdir" "${systemdutilconfdir}/network"
1450 set_global_var "systemd" "systemdntpunits" "${systemdutildir}/ntp-units.d"
1451 set_global_var "systemd" "systemdntpunitsconfdir" "${systemdutilconfdir}/ntp-units.d"
1452 set_global_var "systemd" "systemdportable" "${systemdutildir}/portable"
1453 set_global_var "systemd" "systemdportableconfdir" "${systemdutilconfdir}/portable"
1454 set_global_var "systemd" "systemdsystemunitdir" "${systemdutildir}/system"
1455 set_global_var "systemd" "systemdsystemconfdir" "${systemdutilconfdir}/system"
1456 set_global_var "systemd" "systemduser" "${systemdutildir}/user"
1457 set_global_var "systemd" "systemduserconfdir" "${systemdutilconfdir}/user"
1458 set_global_var "systemd" "sysusers" "/usr/lib/sysusers.d"
1459 set_global_var "systemd" "sysusersconfdir" "/etc/sysusers.d"
1460 set_global_var "systemd" "tmpfilesdir" "/lib/tmpfiles.d" "/usr/lib/tmpfiles.d"
1461 set_global_var "systemd" "tmpfilesconfdir" "/etc/tmpfiles.d"
1462
1463 # libkmod global variables
1464 set_global_var "libkmod" "depmodd" "/usr/lib/depmod.d"
1465 set_global_var "libkmod" "depmodconfdir" "/etc/depmod.d"
1466
1467 if [[ $no_kernel != yes ]] && [[ -d $srcmods ]]; then
1468 if ! [[ -f $srcmods/modules.dep ]]; then
1469 if [[ -n "$(find "$srcmods" -name '*.ko*')" ]]; then
1470 dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
1471 exit 1
1472 else
1473 dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
1474 fi
1475 fi
1476 fi
1477
1478 if [[ ! $print_cmdline ]]; then
1479 if [[ -f $outfile && ! $force ]]; then
1480 dfatal "Will not override existing initramfs ($outfile) without --force"
1481 exit 1
1482 fi
1483
1484 outdir=${outfile%/*}
1485 [[ $outdir ]] || outdir="/"
1486
1487 if [[ ! -d $outdir ]]; then
1488 dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
1489 exit 1
1490 elif [[ ! -w $outdir ]]; then
1491 dfatal "No permission to write to $outdir."
1492 exit 1
1493 elif [[ -f $outfile && ! -w $outfile ]]; then
1494 dfatal "No permission to write $outfile."
1495 exit 1
1496 fi
1497
1498 if [[ $loginstall ]]; then
1499 if ! mkdir -p "$loginstall"; then
1500 dfatal "Could not create directory to log installed files to '$loginstall'."
1501 exit 1
1502 fi
1503 loginstall=$(readlink -f "$loginstall")
1504 fi
1505
1506 if [[ $uefi == yes ]]; then
1507 if ! command -v objcopy &> /dev/null; then
1508 dfatal "Need 'objcopy' to create a UEFI executable"
1509 exit 1
1510 fi
1511 unset EFI_MACHINE_TYPE_NAME
1512 case "${DRACUT_ARCH:-$(uname -m)}" in
1513 x86_64)
1514 EFI_MACHINE_TYPE_NAME=x64
1515 ;;
1516 i?86)
1517 EFI_MACHINE_TYPE_NAME=ia32
1518 ;;
1519 aarch64)
1520 EFI_MACHINE_TYPE_NAME=aa64
1521 ;;
1522 *)
1523 dfatal "Architecture '${DRACUT_ARCH:-$(uname -m)}' not supported to create a UEFI executable"
1524 exit 1
1525 ;;
1526 esac
1527
1528 if ! [[ -s $uefi_stub ]]; then
1529 uefi_stub="$dracutsysrootdir${systemdprefix}/lib/systemd/boot/efi/linux${EFI_MACHINE_TYPE_NAME}.efi.stub"
1530 fi
1531
1532 if ! [[ -s $uefi_stub ]]; then
1533 dfatal "Can't find a uefi stub '$uefi_stub' to create a UEFI executable"
1534 exit 1
1535 fi
1536
1537 if ! [[ $kernel_image ]]; then
1538 for kernel_image in "$dracutsysrootdir/lib/modules/$kernel/vmlinuz" "$dracutsysrootdir/boot/vmlinuz-$kernel"; do
1539 [[ -s $kernel_image ]] || continue
1540 break
1541 done
1542 fi
1543 if ! [[ -s $kernel_image ]]; then
1544 dfatal "Can't find a kernel image '$kernel_image' to create a UEFI executable"
1545 exit 1
1546 fi
1547 fi
1548 fi
1549
1550 if [[ $acpi_override == yes ]] && ! (check_kernel_config CONFIG_ACPI_TABLE_UPGRADE || check_kernel_config CONFIG_ACPI_INITRD_TABLE_OVERRIDE); then
1551 dwarn "Disabling ACPI override, because kernel does not support it. CONFIG_ACPI_INITRD_TABLE_OVERRIDE!=y or CONFIG_ACPI_TABLE_UPGRADE!=y"
1552 unset acpi_override
1553 fi
1554
1555 if [[ $early_microcode == yes ]]; then
1556 if [[ $hostonly ]]; then
1557 if [[ $(get_cpu_vendor) == "AMD" ]]; then
1558 check_kernel_config CONFIG_MICROCODE_AMD || unset early_microcode
1559 elif [[ $(get_cpu_vendor) == "Intel" ]]; then
1560 check_kernel_config CONFIG_MICROCODE_INTEL || unset early_microcode
1561 else
1562 unset early_microcode
1563 fi
1564 else
1565 ! check_kernel_config CONFIG_MICROCODE_AMD \
1566 && ! check_kernel_config CONFIG_MICROCODE_INTEL \
1567 && unset early_microcode
1568 fi
1569 # Do not complain on non-x86 architectures as it makes no sense
1570 case "${DRACUT_ARCH:-$(uname -m)}" in
1571 x86_64 | i?86)
1572 [[ $early_microcode != yes ]] \
1573 && dwarn "Disabling early microcode, because kernel does not support it. CONFIG_MICROCODE_[AMD|INTEL]!=y"
1574 ;;
1575 *) ;;
1576 esac
1577 fi
1578
1579 # Need to be able to have non-root users read stuff (rpcbind etc)
1580 chmod 755 "$initdir"
1581
1582 if [[ $hostonly ]]; then
1583 for i in /sys /proc /run /dev; do
1584 if ! findmnt --target "$i" &> /dev/null; then
1585 dwarning "Turning off host-only mode: '$i' is not mounted!"
1586 unset hostonly
1587 fi
1588 done
1589 fi
1590
1591 declare -A host_fs_types
1592
1593 for line in "${fstab_lines[@]}"; do
1594 # shellcheck disable=SC2086
1595 set -- $line
1596 dev="$1"
1597 #dev mp fs fsopts
1598 case "$dev" in
1599 UUID=*)
1600 dev=$(blkid -l -t "UUID=${dev#UUID=}" -o device)
1601 ;;
1602 LABEL=*)
1603 dev=$(blkid -l -t "LABEL=${dev#LABEL=}" -o device)
1604 ;;
1605 PARTUUID=*)
1606 dev=$(blkid -l -t "PARTUUID=${dev#PARTUUID=}" -o device)
1607 ;;
1608 PARTLABEL=*)
1609 dev=$(blkid -l -t "PARTLABEL=${dev#PARTLABEL=}" -o device)
1610 ;;
1611 esac
1612 [ -z "$dev" ] && dwarn "Bad fstab entry $*" && continue
1613 if [[ $3 == btrfs ]]; then
1614 for mp in $(findmnt --source "$1" -o TARGET -n); do
1615 for i in $(btrfs_devs "$mp"); do
1616 push_host_devs "$i"
1617 done
1618 done
1619 elif [[ $3 == zfs ]]; then
1620 for mp in $(zfs_devs "$1"); do
1621 push_host_devs "$mp"
1622 done
1623 fi
1624 push_host_devs "$dev"
1625 host_fs_types["$dev"]="$3"
1626 done
1627
1628 for f in $add_fstab; do
1629 [[ -e $f ]] || continue
1630 while read -r dev rest || [ -n "$dev" ]; do
1631 push_host_devs "$dev"
1632 done < "$f"
1633 done
1634
1635 for dev in $add_device; do
1636 push_host_devs "$dev"
1637 done
1638
1639 if ((${#add_device_l[@]})); then
1640 add_device+=" ${add_device_l[*]} "
1641 push_host_devs "${add_device_l[@]}"
1642 fi
1643
1644 if [[ $hostonly ]] && [[ $hostonly_default_device != "no" ]]; then
1645 # in hostonly mode, determine all devices, which have to be accessed
1646 # and examine them for filesystem types
1647
1648 for mp in \
1649 "/" \
1650 "/etc" \
1651 "/bin" \
1652 "/sbin" \
1653 "/lib" \
1654 "/lib64" \
1655 "/usr" \
1656 "/usr/bin" \
1657 "/usr/sbin" \
1658 "/usr/lib" \
1659 "/usr/lib64" \
1660 "/boot" \
1661 "/boot/efi" \
1662 "/boot/zipl"; do
1663 mp=$(readlink -f "$dracutsysrootdir$mp")
1664 mountpoint "$mp" > /dev/null 2>&1 || continue
1665 _dev=$(find_block_device "$mp")
1666 _bdev=$(readlink -f "/dev/block/$_dev")
1667 [[ -b $_bdev ]] && _dev=$_bdev
1668 [[ $mp == "/" ]] && root_devs+=("$_dev")
1669 push_host_devs "$_dev"
1670 if [[ $(find_mp_fstype "$mp") == btrfs ]]; then
1671 for i in $(btrfs_devs "$mp"); do
1672 [[ $mp == "/" ]] && root_devs+=("$i")
1673 push_host_devs "$i"
1674 done
1675 elif [[ $(find_mp_fstype "$mp") == zfs ]]; then
1676 for i in $(zfs_devs "$(findmnt -n -o SOURCE "$mp")"); do
1677 [[ $mp == "/" ]] && root_devs+=("$i")
1678 push_host_devs "$i"
1679 done
1680 fi
1681
1682 done
1683
1684 # TODO - with sysroot, /proc/swaps is not relevant
1685 if [[ -f /proc/swaps ]] && [[ -f $dracutsysrootdir/etc/fstab ]]; then
1686 while read -r dev type rest || [ -n "$dev" ]; do
1687 [[ -b $dev ]] || continue
1688 [[ $type == "partition" ]] || continue
1689
1690 while read -r _d _m _t _o _ || [ -n "$_d" ]; do
1691 [[ $_d == \#* ]] && continue
1692 [[ $_d ]] || continue
1693 [[ $_t != "swap" ]] && continue
1694 [[ $_m != "swap" ]] && [[ $_m != "none" ]] && continue
1695 [[ $_o == *noauto* ]] && continue
1696 _d=$(expand_persistent_dev "$_d")
1697 [[ $_d -ef $dev ]] || continue
1698
1699 if [[ -f $dracutsysrootdir/etc/crypttab ]]; then
1700 while read -r _mapper _ _p _o || [ -n "$_mapper" ]; do
1701 [[ $_mapper == \#* ]] && continue
1702 [[ $_d -ef /dev/mapper/"$_mapper" ]] || continue
1703 [[ "$_o" ]] || _o="$_p"
1704 # skip entries with password files
1705 [[ $_p == /* ]] && [[ -f $_p ]] && continue 2
1706 # skip mkswap swap
1707 [[ $_o == *swap* ]] && continue 2
1708 done < "$dracutsysrootdir"/etc/crypttab
1709 fi
1710
1711 _dev="$(readlink -f "$dev")"
1712 push_host_devs "$_dev"
1713 swap_devs+=("$_dev")
1714 break
1715 done < "$dracutsysrootdir"/etc/fstab
1716 done < /proc/swaps
1717 fi
1718
1719 # collect all "x-initrd.mount" entries from /etc/fstab
1720 if [[ -f $dracutsysrootdir/etc/fstab ]]; then
1721 while read -r _d _m _t _o _ || [ -n "$_d" ]; do
1722 [[ $_d == \#* ]] && continue
1723 [[ $_d ]] || continue
1724 [[ $_o != *x-initrd.mount* ]] && continue
1725 _dev=$(expand_persistent_dev "$_d")
1726 _dev="$(readlink -f "$_dev")"
1727 [[ -b $_dev ]] || continue
1728
1729 push_host_devs "$_dev"
1730 if [[ $_t == btrfs ]]; then
1731 for i in $(btrfs_devs "$_m"); do
1732 push_host_devs "$i"
1733 done
1734 elif [[ $_t == zfs ]]; then
1735 for i in $(zfs_devs "$_d"); do
1736 push_host_devs "$i"
1737 done
1738 fi
1739 done < "$dracutsysrootdir"/etc/fstab
1740 fi
1741 fi
1742
1743 unset m
1744 unset rest
1745
1746 _get_fs_type() {
1747 [[ $1 ]] || return
1748 if [[ -b /dev/block/$1 ]]; then
1749 ID_FS_TYPE=$(get_fs_env "/dev/block/$1") && host_fs_types["$(readlink -f "/dev/block/$1")"]="$ID_FS_TYPE"
1750 return 1
1751 fi
1752 if [[ -b $1 ]]; then
1753 ID_FS_TYPE=$(get_fs_env "$1") && host_fs_types["$(readlink -f "$1")"]="$ID_FS_TYPE"
1754 return 1
1755 fi
1756 if fstype=$(find_dev_fstype "$1"); then
1757 host_fs_types["$1"]="$fstype"
1758 return 1
1759 fi
1760 return 1
1761 }
1762
1763 for dev in "${host_devs[@]}"; do
1764 _get_fs_type "$dev"
1765 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1766 done
1767
1768 for dev in "${!host_fs_types[@]}"; do
1769 [[ ${host_fs_types[$dev]} == "reiserfs" ]] || [[ ${host_fs_types[$dev]} == "xfs" ]] || continue
1770 rootopts=$(find_dev_fsopts "$dev")
1771 if [[ ${host_fs_types[$dev]} == "reiserfs" ]]; then
1772 journaldev=$(fs_get_option "$rootopts" "jdev")
1773 elif [[ ${host_fs_types[$dev]} == "xfs" ]]; then
1774 journaldev=$(fs_get_option "$rootopts" "logdev")
1775 fi
1776 if [[ $journaldev ]]; then
1777 dev="$(readlink -f "$dev")"
1778 push_host_devs "$dev"
1779 _get_fs_type "$dev"
1780 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1781 fi
1782 done
1783
1784 export initdir dracutbasedir \
1785 dracutmodules force_add_dracutmodules add_dracutmodules omit_dracutmodules \
1786 mods_to_load \
1787 fw_dir drivers_dir debug no_kernel kernel_only \
1788 omit_drivers mdadmconf lvmconf root_devs \
1789 use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
1790 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
1791 host_fs_types host_devs swap_devs sshkey add_fstab \
1792 DRACUT_VERSION \
1793 prefix filesystems drivers \
1794 hostonly_cmdline loginstall
1795
1796 mods_to_load=""
1797 # check all our modules to see if they should be sourced.
1798 # This builds a list of modules that we will install next.
1799 for_each_module_dir check_module
1800 for_each_module_dir check_mount
1801
1802 dracut_module_included "fips" && export DRACUT_FIPS_MODE=1
1803
1804 do_print_cmdline() {
1805 local -A _mods_to_print
1806 for i in $modules_loaded $mods_to_load; do
1807 _mods_to_print[$i]=1
1808 done
1809
1810 # source our modules.
1811 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1812 _d_mod=${moddir##*/}
1813 _d_mod=${_d_mod#[0-9][0-9]}
1814 [[ ${_mods_to_print[$_d_mod]} ]] || continue
1815 module_cmdline "$_d_mod" "$moddir"
1816 done
1817 unset moddir
1818 }
1819
1820 if [[ $print_cmdline ]]; then
1821 do_print_cmdline
1822 printf "\n"
1823 exit 0
1824 fi
1825
1826 # Create some directory structure first
1827 # shellcheck disable=SC2174
1828 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
1829
1830 # shellcheck disable=SC2174
1831 [[ -L $dracutsysrootdir/lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
1832 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
1833
1834 if [[ $prefix ]]; then
1835 for d in bin etc lib sbin tmp usr var $libdirs; do
1836 d=${d#/}
1837 [[ $d == */* ]] && continue
1838 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
1839 done
1840 fi
1841
1842 if [[ $kernel_only != yes ]]; then
1843 for d in usr usr/bin usr/sbin bin etc lib sbin tmp var var/tmp $libdirs; do
1844 d=${d#/}
1845 [[ -e "${initdir}${prefix}/$d" ]] && continue
1846 if [ -L "/$d" ]; then
1847 inst_symlink "/$d" "${prefix}/$d"
1848 else
1849 # shellcheck disable=SC2174
1850 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1851 fi
1852 done
1853
1854 for d in dev proc sys sysroot root run; do
1855 if [ -L "/$d" ]; then
1856 inst_symlink "/$d"
1857 else
1858 # shellcheck disable=SC2174
1859 mkdir -m 0755 -p "$initdir/$d"
1860 fi
1861 done
1862
1863 ln -sfn ../run "$initdir/var/run"
1864 ln -sfn ../run/lock "$initdir/var/lock"
1865 else
1866 for d in lib "$libdirs"; do
1867 [[ -e "${initdir}${prefix}/$d" ]] && continue
1868 if [ -h "/$d" ]; then
1869 inst "/$d" "${prefix}/$d"
1870 else
1871 # shellcheck disable=SC2174
1872 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1873 fi
1874 done
1875 fi
1876
1877 mkdir -p "${initdir}"/lib/dracut
1878
1879 if [[ $kernel_only != yes ]]; then
1880 mkdir -p "${initdir}/etc/cmdline.d"
1881 mkdir -m 0755 "${initdir}"/lib/dracut/hooks
1882 # shellcheck disable=SC2154
1883 for _d in $hookdirs; do
1884 # shellcheck disable=SC2174
1885 mkdir -m 0755 -p "${initdir}/lib/dracut/hooks/$_d"
1886 done
1887 if [[ $EUID == "0" ]] && ! [[ $DRACUT_NO_MKNOD ]]; then
1888 [[ -c ${initdir}/dev/null ]] || mknod "${initdir}"/dev/null c 1 3
1889 [[ -c ${initdir}/dev/kmsg ]] || mknod "${initdir}"/dev/kmsg c 1 11
1890 [[ -c ${initdir}/dev/console ]] || mknod "${initdir}"/dev/console c 5 1
1891 [[ -c ${initdir}/dev/random ]] || mknod "${initdir}"/dev/random c 1 8
1892 [[ -c ${initdir}/dev/urandom ]] || mknod "${initdir}"/dev/urandom c 1 9
1893 fi
1894 fi
1895
1896 _isize=0 #initramfs size
1897 modules_loaded=" "
1898 # source our modules.
1899 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1900 _d_mod=${moddir##*/}
1901 _d_mod=${_d_mod#[0-9][0-9]}
1902 [[ $mods_to_load == *\ $_d_mod\ * ]] || continue
1903 if [[ $show_modules == yes ]]; then
1904 printf "%s\n" "$_d_mod"
1905 else
1906 dinfo "*** Including module: $_d_mod ***"
1907 fi
1908 if [[ $kernel_only == yes ]]; then
1909 module_installkernel "$_d_mod" "$moddir" || {
1910 dfatal "installkernel failed in module $_d_mod"
1911 exit 1
1912 }
1913 else
1914 module_install "$_d_mod" "$moddir"
1915 if [[ $no_kernel != yes ]]; then
1916 module_installkernel "$_d_mod" "$moddir" || {
1917 dfatal "installkernel failed in module $_d_mod"
1918 exit 1
1919 }
1920 fi
1921 fi
1922 mods_to_load=${mods_to_load// $_d_mod /}
1923 modules_loaded+="$_d_mod "
1924
1925 #print the module install size
1926 if [ -n "$printsize" ]; then
1927 _isize_new=$(du -sk "${initdir}" | {
1928 read -r a _
1929 echo -n "$a"
1930 })
1931 _isize_delta=$((_isize_new - _isize))
1932 printf "%s\n" "$_d_mod install size: ${_isize_delta}k"
1933 _isize=$_isize_new
1934 fi
1935 done
1936 unset moddir
1937
1938 for i in $modules_loaded; do
1939 printf "%s\n" "$i" >> "$initdir"/lib/dracut/modules.txt
1940 done
1941
1942 dinfo "*** Including modules done ***"
1943
1944 ## final stuff that has to happen
1945 if [[ $no_kernel != yes ]]; then
1946 if [[ $hostonly_mode == "strict" ]]; then
1947 cp "$DRACUT_KERNEL_MODALIASES" "$initdir"/lib/dracut/hostonly-kernel-modules.txt
1948 fi
1949
1950 if [[ $drivers ]]; then
1951 # shellcheck disable=SC2086
1952 hostonly='' instmods $drivers
1953 fi
1954
1955 if [[ -n ${add_drivers// /} ]]; then
1956 # shellcheck disable=SC2086
1957 hostonly='' instmods -c $add_drivers
1958 fi
1959 if [[ $force_drivers ]]; then
1960 # shellcheck disable=SC2086
1961 hostonly='' instmods -c $force_drivers
1962 rm -f "$initdir"/etc/cmdline.d/20-force_driver.conf
1963 for mod in $force_drivers; do
1964 echo "rd.driver.pre=$mod" >> "$initdir"/etc/cmdline.d/20-force_drivers.conf
1965 done
1966 fi
1967 if [[ $filesystems ]]; then
1968 # shellcheck disable=SC2086
1969 hostonly='' instmods -c $filesystems
1970 fi
1971
1972 dinfo "*** Installing kernel module dependencies ***"
1973 dracut_kernel_post
1974 dinfo "*** Installing kernel module dependencies done ***"
1975
1976 if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
1977 if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] \
1978 && [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
1979 for i in "${initdir}"/etc/cmdline.d/*.conf; do
1980 # We need no initramfs image and do not generate one.
1981 [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
1982 done
1983 fi
1984 fi
1985 fi
1986
1987 if [[ $kernel_only != yes ]]; then
1988 # FIXME: handle legacy item split
1989 # shellcheck disable=SC2068
1990 ((${#install_items[@]} > 0)) && inst_multiple ${install_items[@]}
1991 # shellcheck disable=SC2068
1992 ((${#install_optional_items[@]} > 0)) && inst_multiple -o ${install_optional_items[@]}
1993
1994 if [[ $kernel_cmdline ]] && [[ $uefi != yes ]]; then
1995 printf "%s\n" "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
1996 fi
1997
1998 for line in "${fstab_lines[@]}"; do
1999 read -r -a fstab_field <<< "$line"
2000 if [ -z "${fstab_field[1]}" ]; then
2001 # Determine device and mount options from current system
2002 mountpoint -q "${fstab_field[0]}" || derror "${fstab_field[0]} is not a mount point!"
2003 read -r -a fstab_field < <(findmnt --raw -n --target "${fstab_field[0]}" --output=source,target,fstype,options)
2004 dinfo "Line for ${fstab_field[1]}: ${fstab_field[*]}"
2005 else
2006 # Use default options
2007 [ -z "${fstab_field[3]}" ] && fstab_field[3]="defaults"
2008 fi
2009
2010 # Default options for freq and passno
2011 [ -z "${fstab_field[4]}" ] && fstab_field[4]="0"
2012 [ -z "${fstab_field[5]}" ] && fstab_field[5]="2"
2013
2014 strstr "${fstab_field[2]}" "nfs" && fstab_field[5]="0"
2015 echo "${fstab_field[@]}" >> "${initdir}/etc/fstab"
2016 done
2017
2018 for f in $add_fstab; do
2019 cat "$f" >> "${initdir}/etc/fstab"
2020 done
2021
2022 if [[ $dracutsysrootdir$systemdutildir ]]; then
2023 if [[ -d ${initdir}/$systemdutildir ]]; then
2024 mkdir -p "${initdir}"/etc/conf.d
2025 {
2026 printf "%s\n" "systemdutildir=\"$systemdutildir\""
2027 printf "%s\n" "systemdsystemunitdir=\"$systemdsystemunitdir\""
2028 printf "%s\n" "systemdsystemconfdir=\"$systemdsystemconfdir\""
2029 } > "${initdir}"/etc/conf.d/systemd.conf
2030 fi
2031 fi
2032
2033 if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
2034 dinfo "*** Resolving executable dependencies ***"
2035 # shellcheck disable=SC2086
2036 find "$initdir" -type f -perm /0111 -not -path '*.ko' -print0 \
2037 | xargs -r -0 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R ${DRACUT_FIPS_MODE:+-f} --
2038 dinfo "*** Resolving executable dependencies done ***"
2039 fi
2040
2041 # Now we are done with lazy resolving, always install dependencies
2042 unset DRACUT_RESOLVE_LAZY
2043 export DRACUT_RESOLVE_DEPS=1
2044 fi
2045
2046 for ((i = 0; i < ${#include_src[@]}; i++)); do
2047 src="${include_src[$i]}"
2048 target="${include_target[$i]}"
2049 if [[ $src && $target ]]; then
2050 if [[ -f $src ]]; then
2051 inst "$src" "$target"
2052 elif [[ -d $src ]]; then
2053 ddebug "Including directory: $src"
2054 destdir="${initdir}/${target}"
2055 mkdir -p "$destdir"
2056 # check for preexisting symlinks, so we can cope with the
2057 # symlinks to $prefix
2058 # Objectname is a file or a directory
2059 reset_dotglob="$(shopt -p dotglob)"
2060 shopt -q -s dotglob
2061 for objectname in "$src"/*; do
2062 [[ -e $objectname || -L $objectname ]] || continue
2063 if [[ -d $objectname ]] && [[ ! -L $objectname ]]; then
2064 # objectname is a directory, let's compute the final directory name
2065 object_destdir=${destdir}/${objectname#"$src"/}
2066 if ! [[ -e $object_destdir ]]; then
2067 # shellcheck disable=SC2174
2068 mkdir -m 0755 -p "$object_destdir"
2069 chmod --reference="$objectname" "$object_destdir"
2070 fi
2071 $DRACUT_CP -t "$object_destdir" "$dracutsysrootdir$objectname"/.
2072 else
2073 $DRACUT_CP -t "$destdir" "$dracutsysrootdir$objectname"
2074 fi
2075 done
2076 eval "$reset_dotglob"
2077 elif [[ -e $src ]]; then
2078 derror "$src is neither a directory nor a regular file"
2079 else
2080 derror "$src doesn't exist"
2081 fi
2082 fi
2083 done
2084
2085 if [[ $do_hardlink == yes ]] && command -v hardlink > /dev/null; then
2086 dinfo "*** Hardlinking files ***"
2087 hardlink "$initdir" 2>&1 | ddebug
2088 dinfo "*** Hardlinking files done ***"
2089 fi
2090
2091 # strip binaries
2092 if [[ $do_strip == yes ]]; then
2093 # Prefer strip from elfutils for package size
2094 declare strip_cmd
2095 strip_cmd=$(command -v eu-strip)
2096 [ -z "$strip_cmd" ] && strip_cmd="strip"
2097
2098 for p in $strip_cmd xargs find; do
2099 if ! type -P $p > /dev/null; then
2100 dinfo "Could not find '$p'. Not stripping the initramfs."
2101 do_strip=no
2102 fi
2103 done
2104
2105 if [[ $aggressive_strip == yes ]]; then
2106 # `eu-strip` and `strip` both strips all unneeded parts by default
2107 strip_args=(-p)
2108 else
2109 strip_args=(-g -p)
2110 fi
2111 fi
2112
2113 # cleanup empty ldconfig_paths directories
2114 for d in $(ldconfig_paths); do
2115 rmdir -p --ignore-fail-on-non-empty "$initdir/$d" > /dev/null 2>&1
2116 done
2117
2118 if [[ $early_microcode == yes ]]; then
2119 dinfo "*** Generating early-microcode cpio image ***"
2120 ucode_dir=(amd-ucode intel-ucode)
2121 ucode_dest=(AuthenticAMD.bin GenuineIntel.bin)
2122 _dest_dir="$early_cpio_dir/d/kernel/x86/microcode"
2123 _dest_idx="0 1"
2124 mkdir -p "$_dest_dir"
2125 if [[ $hostonly ]]; then
2126 [[ $(get_cpu_vendor) == "AMD" ]] && _dest_idx="0"
2127 [[ $(get_cpu_vendor) == "Intel" ]] && _dest_idx="1"
2128 fi
2129 for idx in $_dest_idx; do
2130 _fw=${ucode_dir[$idx]}
2131 for _fwdir in $fw_dir; do
2132 if [[ -d $_fwdir && -d $_fwdir/$_fw ]]; then
2133 _src="*"
2134 dinfo "*** Constructing ${ucode_dest[$idx]} ***"
2135 if [[ $hostonly ]]; then
2136 _src=$(get_ucode_file)
2137 [[ $_src ]] || break
2138 [[ -r $_fwdir/$_fw/$_src ]] || _src="${_src}.early"
2139 [[ -r $_fwdir/$_fw/$_src ]] || break
2140 fi
2141
2142 for i in $_fwdir/$_fw/$_src; do
2143 [ -e "$i" ] && break
2144 break 2
2145 done
2146 for i in $_fwdir/$_fw/$_src; do
2147 [[ -e $i ]] || continue
2148 # skip gpg files
2149 str_ends "$i" ".asc" && continue
2150 cat "$i" >> "$_dest_dir/${ucode_dest[$idx]}"
2151 done
2152 create_early_cpio="yes"
2153 fi
2154 done
2155 if [[ ! -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
2156 if cd "$early_cpio_dir/d"; then
2157 for _ucodedir in "${early_microcode_image_dir[@]}"; do
2158 for _ucodename in "${early_microcode_image_name[@]}"; do
2159 [[ -e "$_ucodedir/$_ucodename" ]] \
2160 && cpio --extract --file "$_ucodedir/$_ucodename" --quiet \
2161 "kernel/x86/microcode/${ucode_dest[$idx]}"
2162 if [[ -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
2163 dinfo "*** Using microcode found in '$_ucodedir/$_ucodename' ***"
2164 create_early_cpio="yes"
2165 break 2
2166 fi
2167 done
2168 done
2169 fi
2170 fi
2171 done
2172 fi
2173
2174 if [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; then
2175 dinfo "*** Packaging ACPI tables to override BIOS provided ones ***"
2176 _dest_dir="$early_cpio_dir/d/kernel/firmware/acpi"
2177 mkdir -p "$_dest_dir"
2178 for table in "$acpi_table_dir"/*.aml; do
2179 dinfo " Adding ACPI table: $table"
2180 $DRACUT_CP "$table" "$_dest_dir"
2181 create_early_cpio="yes"
2182 done
2183 fi
2184
2185 dinfo "*** Store current command line parameters ***"
2186 if ! (echo "$PARMS_TO_STORE" > "$initdir"/lib/dracut/build-parameter.txt); then
2187 dfatal "Could not store the current command line parameters"
2188 exit 1
2189 fi
2190
2191 if [[ $hostonly_cmdline == "yes" ]]; then
2192 unset _stored_cmdline
2193 if [[ -d $initdir/etc/cmdline.d ]]; then
2194 dinfo "Stored kernel commandline:"
2195 for conf in "$initdir"/etc/cmdline.d/*.conf; do
2196 [ -e "$conf" ] || continue
2197 dinfo "$(< "$conf")"
2198 _stored_cmdline=1
2199 done
2200 fi
2201 if ! [[ $_stored_cmdline ]]; then
2202 dinfo "No dracut internal kernel commandline stored in the initramfs"
2203 fi
2204 fi
2205
2206 if [[ $kernel_only != yes ]]; then
2207 # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so
2208 for _dir in $libdirs; do
2209 for _f in "$dracutsysrootdir$_dir/libpthread.so"*; do
2210 [[ -e $_f ]] || continue
2211 inst_libdir_file "libgcc_s.so*"
2212 break 2
2213 done
2214 done
2215
2216 # FIPS workaround for Fedora/RHEL: libcrypto needs libssl when FIPS is enabled
2217 if [[ $DRACUT_FIPS_MODE ]]; then
2218 for _dir in $libdirs; do
2219 for _f in "$dracutsysrootdir$_dir/libcrypto.so"*; do
2220 [[ -e $_f ]] || continue
2221 inst_libdir_file -o "libssl.so*"
2222 break 2
2223 done
2224 done
2225 fi
2226 fi
2227
2228 if [[ $kernel_only != yes ]]; then
2229 # make sure that library links are correct and up to date
2230 build_ld_cache
2231 fi
2232
2233 if dracut_module_included "squash"; then
2234 readonly squash_dir="$initdir/squash/root"
2235 readonly squash_img="$initdir/squash-root.img"
2236 mkdir -p "$squash_dir"
2237 dinfo "*** Install squash loader ***"
2238 DRACUT_SQUASH_POST_INST=1 module_install "squash"
2239 fi
2240
2241 if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
2242 # stripping files negates (dedup) benefits of using reflink
2243 [[ -n $enhanced_cpio ]] && ddebug "strip is enabled alongside cpio reflink"
2244 dinfo "*** Stripping files ***"
2245 find "$initdir" -type f \
2246 -executable -not -path '*/lib/modules/*.ko' -print0 \
2247 | xargs -r -0 $strip_cmd "${strip_args[@]}" 2> /dev/null
2248
2249 # strip kernel modules, but do not touch signed modules
2250 find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
2251 | while read -r -d $'\0' f || [ -n "$f" ]; do
2252 SIG=$(tail -c 28 "$f" | tr -d '\000')
2253 [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
2254 done | xargs -r -0 $strip_cmd "${strip_args[@]}"
2255 dinfo "*** Stripping files done ***"
2256 fi
2257
2258 if dracut_module_included "squash"; then
2259 dinfo "*** Squashing the files inside the initramfs ***"
2260 declare squash_compress_arg
2261 # shellcheck disable=SC2086
2262 if [[ $squash_compress ]]; then
2263 if ! mksquashfs /dev/null "$DRACUT_TMPDIR"/.squash-test.img -no-progress -comp $squash_compress &> /dev/null; then
2264 dwarn "mksquashfs doesn't support compressor '$squash_compress', failing back to default compressor."
2265 else
2266 squash_compress_arg="$squash_compress"
2267 fi
2268 fi
2269
2270 # shellcheck disable=SC2086
2271 if ! mksquashfs "$squash_dir" "$squash_img" \
2272 -no-xattrs -no-exports -noappend -no-recovery -always-use-fragments \
2273 -no-progress ${squash_compress_arg:+-comp $squash_compress_arg} 1> /dev/null; then
2274 dfatal "Failed making squash image"
2275 exit 1
2276 fi
2277
2278 rm -rf "$squash_dir"
2279 dinfo "*** Squashing the files inside the initramfs done ***"
2280
2281 # Skip initramfs compress
2282 compress="cat"
2283 fi
2284
2285 dinfo "*** Creating image file '$outfile' ***"
2286
2287 if [[ $uefi == yes ]]; then
2288 readonly uefi_outdir="$DRACUT_TMPDIR/uefi"
2289 mkdir -p "$uefi_outdir"
2290 fi
2291
2292 if [[ $DRACUT_REPRODUCIBLE ]]; then
2293 find "$initdir" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
2294 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
2295
2296 if [[ "$(cpio --help)" == *--reproducible* ]]; then
2297 CPIO_REPRODUCIBLE=1
2298 else
2299 dinfo "cpio does not support '--reproducible'. Resulting image will not be reproducible."
2300 fi
2301 fi
2302
2303 [[ $EUID != 0 ]] && cpio_owner="0:0"
2304
2305 if [[ $create_early_cpio == yes ]]; then
2306 echo 1 > "$early_cpio_dir/d/early_cpio"
2307
2308 if [[ $DRACUT_REPRODUCIBLE ]]; then
2309 find "$early_cpio_dir/d" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
2310 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
2311 fi
2312
2313 # The microcode blob is _before_ the initramfs blob, not after
2314 if [[ -n $enhanced_cpio ]]; then
2315 if ! (
2316 umask 077
2317 cd "$early_cpio_dir/d"
2318 find . -print0 | sort -z \
2319 | $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2320 --mtime 0 --data-align "$cpio_align" --truncate-existing \
2321 "${DRACUT_TMPDIR}/initramfs.img"
2322 ); then
2323 dfatal "dracut-cpio: creation of $outfile failed"
2324 exit 1
2325 fi
2326 else
2327 if ! (
2328 umask 077
2329 cd "$early_cpio_dir/d"
2330 find . -print0 | sort -z \
2331 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
2332 ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
2333 ); then
2334 dfatal "Creation of $outfile failed"
2335 exit 1
2336 fi
2337 fi
2338 fi
2339
2340 if check_kernel_config CONFIG_RD_ZSTD; then
2341 DRACUT_KERNEL_RD_ZSTD=yes
2342 else
2343 DRACUT_KERNEL_RD_ZSTD=
2344 fi
2345
2346 if [[ $compress == $DRACUT_COMPRESS_ZSTD* && ! $DRACUT_KERNEL_RD_ZSTD ]]; then
2347 dwarn "Kernel has no zstd support compiled in."
2348 compress=
2349 fi
2350
2351 if [[ $compress && $compress != cat ]]; then
2352 if ! command -v "${compress%% *}" &> /dev/null; then
2353 derror "Cannot execute compression command '$compress', falling back to default"
2354 compress=
2355 fi
2356 fi
2357
2358 if ! [[ $compress ]]; then
2359 # check all known compressors, if none specified
2360 for i in $DRACUT_COMPRESS_PIGZ $DRACUT_COMPRESS_GZIP $DRACUT_COMPRESS_LZ4 $DRACUT_COMPRESS_LZOP $DRACUT_COMPRESS_ZSTD $DRACUT_COMPRESS_LZMA $DRACUT_COMPRESS_XZ $DRACUT_COMPRESS_LBZIP2 $DRACUT_COMPRESS_BZIP2 $DRACUT_COMPRESS_CAT; do
2361 [[ $i != "$DRACUT_COMPRESS_ZSTD" || $DRACUT_KERNEL_RD_ZSTD ]] || continue
2362 command -v "$i" &> /dev/null || continue
2363 compress="$i"
2364 break
2365 done
2366 if [[ $compress == cat ]]; then
2367 dwarn "No compression tool available. Initramfs image is going to be big."
2368 else
2369 dinfo "Using auto-determined compression method '$compress'"
2370 fi
2371 fi
2372
2373 # choose the right arguments for the compressor
2374 case $compress in
2375 bzip2 | lbzip2)
2376 if [[ $compress == lbzip2 ]] || command -v "$DRACUT_COMPRESS_LBZIP2" &> /dev/null; then
2377 compress="$DRACUT_COMPRESS_LBZIP2 -9"
2378 else
2379 compress="$DRACUT_COMPRESS_BZIP2 -9"
2380 fi
2381 ;;
2382 lzma)
2383 compress="$DRACUT_COMPRESS_LZMA -9 -T0"
2384 ;;
2385 xz)
2386 compress="$DRACUT_COMPRESS_XZ --check=crc32 --lzma2=dict=1MiB -T0"
2387 ;;
2388 gzip | pigz)
2389 if [[ $compress == pigz ]] || command -v "$DRACUT_COMPRESS_PIGZ" &> /dev/null; then
2390 compress="$DRACUT_COMPRESS_PIGZ -9 -n -T -R"
2391 elif command -v gzip &> /dev/null && $DRACUT_COMPRESS_GZIP --help 2>&1 | grep -q rsyncable; then
2392 compress="$DRACUT_COMPRESS_GZIP -n -9 --rsyncable"
2393 else
2394 compress="$DRACUT_COMPRESS_GZIP -n -9"
2395 fi
2396 ;;
2397 lzo | lzop)
2398 compress="$DRACUT_COMPRESS_LZOP -9"
2399 ;;
2400 lz4)
2401 compress="$DRACUT_COMPRESS_LZ4 -l -9"
2402 ;;
2403 zstd)
2404 compress="$DRACUT_COMPRESS_ZSTD -15 -q -T0"
2405 ;;
2406 esac
2407
2408 if [[ -n $enhanced_cpio ]]; then
2409 if [[ $compress == "cat" ]]; then
2410 # dracut-cpio appends by default, so any ucode remains
2411 cpio_outfile="${DRACUT_TMPDIR}/initramfs.img"
2412 else
2413 ddebug "$compress compression enabled alongside cpio reflink"
2414 # dracut-cpio doesn't output to stdout, so stage for compression
2415 cpio_outfile="${DRACUT_TMPDIR}/initramfs.img.uncompressed"
2416 fi
2417
2418 if ! (
2419 umask 077
2420 cd "$initdir"
2421 find . -print0 | sort -z \
2422 | $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2423 --mtime 0 --data-align "$cpio_align" "$cpio_outfile" || exit 1
2424 [[ $compress == "cat" ]] && exit 0
2425 $compress < "$cpio_outfile" >> "${DRACUT_TMPDIR}/initramfs.img" \
2426 && rm "$cpio_outfile"
2427 ); then
2428 dfatal "dracut-cpio: creation of $outfile failed"
2429 exit 1
2430 fi
2431 unset cpio_outfile
2432 else
2433 if ! (
2434 umask 077
2435 cd "$initdir"
2436 find . -print0 | sort -z \
2437 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2438 | $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2439 ); then
2440 dfatal "Creation of $outfile failed"
2441 exit 1
2442 fi
2443 fi
2444
2445 # shellcheck disable=SC2154
2446 if ((maxloglvl >= 5)) && ((verbosity_mod_l >= 0)); then
2447 if [[ $allowlocal ]]; then
2448 "$dracutbasedir/lsinitrd.sh" "${DRACUT_TMPDIR}/initramfs.img" | ddebug
2449 else
2450 lsinitrd "${DRACUT_TMPDIR}/initramfs.img" | ddebug
2451 fi
2452 fi
2453
2454 umask 077
2455
2456 if [[ $uefi == yes ]]; then
2457 if [[ $kernel_cmdline ]]; then
2458 echo -n "$kernel_cmdline" > "$uefi_outdir/cmdline.txt"
2459 elif [[ $hostonly_cmdline == yes ]]; then
2460 if [ -d "$initdir/etc/cmdline.d" ]; then
2461 for conf in "$initdir"/etc/cmdline.d/*.conf; do
2462 [ -e "$conf" ] || continue
2463 printf "%s " "$(< "$conf")" >> "$uefi_outdir/cmdline.txt"
2464 done
2465 elif [ -e "/proc/cmdline" ]; then
2466 printf "%s " "$(< "/proc/cmdline")" > "$uefi_outdir/cmdline.txt"
2467 fi
2468 fi
2469
2470 offs=$(objdump -h "$uefi_stub" 2> /dev/null | awk 'NF==7 {size=strtonum("0x"$3);\
2471 offset=strtonum("0x"$4)} END {print size + offset}')
2472 if [[ $offs -eq 0 ]]; then
2473 dfatal "Failed to get the size of $uefi_stub to create UEFI image file"
2474 exit 1
2475 fi
2476 align=$(pe_get_section_align "$uefi_stub")
2477 if [[ $? -eq 1 ]]; then
2478 dfatal "Failed to get the SectionAlignment of the stub PE header to create the UEFI image file"
2479 exit 1
2480 fi
2481 offs=$((offs + "$align" - offs % "$align"))
2482 [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
2483 [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
2484 [[ -s $uefi_osrelease ]] \
2485 && uefi_osrelease_offs=${offs} \
2486 && offs=$((offs + $(stat -Lc%s "$uefi_osrelease"))) \
2487 && offs=$((offs + "$align" - offs % "$align"))
2488
2489 if [[ $kernel_cmdline ]] || [[ $hostonly_cmdline == yes && -e "${uefi_outdir}/cmdline.txt" ]]; then
2490 echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
2491 dinfo "Using UEFI kernel cmdline:"
2492 dinfo "$(tr -d '\000' < "$uefi_outdir/cmdline.txt")"
2493 uefi_cmdline="${uefi_outdir}/cmdline.txt"
2494 uefi_cmdline_offs=${offs}
2495 offs=$((offs + $(stat -Lc%s "$uefi_cmdline")))
2496 offs=$((offs + "$align" - offs % "$align"))
2497 else
2498 unset uefi_cmdline
2499 fi
2500
2501 if [[ -s ${dracutsysrootdir}${uefi_splash_image} ]]; then
2502 uefi_splash_image="${dracutsysrootdir}${uefi_splash_image}"
2503 uefi_splash_offs=${offs}
2504 offs=$((offs + $(stat -Lc%s "$uefi_splash_image")))
2505 offs=$((offs + "$align" - offs % "$align"))
2506 else
2507 unset uefi_splash_image
2508 fi
2509
2510 uefi_linux_offs="${offs}"
2511 offs=$((offs + $(stat -Lc%s "$kernel_image")))
2512 offs=$((offs + "$align" - offs % "$align"))
2513 uefi_initrd_offs="${offs}"
2514
2515 base_image=$(pe_get_image_base "$uefi_stub")
2516 if [[ $? -eq 1 ]]; then
2517 dfatal "Failed to get ImageBase data of $uefi_stub to create UEFI image file"
2518 exit 1
2519 fi
2520
2521 if objcopy \
2522 ${uefi_osrelease:+--add-section .osrel="$uefi_osrelease" --change-section-vma .osrel=$(printf 0x%x "$uefi_osrelease_offs")} \
2523 ${uefi_cmdline:+--add-section .cmdline="$uefi_cmdline" --change-section-vma .cmdline=$(printf 0x%x "$uefi_cmdline_offs")} \
2524 ${uefi_splash_image:+--add-section .splash="$uefi_splash_image" --change-section-vma .splash=$(printf 0x%x "$uefi_splash_offs")} \
2525 --add-section .linux="$kernel_image" --change-section-vma .linux="$(printf 0x%x "$uefi_linux_offs")" \
2526 --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd="$(printf 0x%x "$uefi_initrd_offs")" \
2527 --image-base="$(printf 0x%x "$base_image")" \
2528 "$uefi_stub" "${uefi_outdir}/linux.efi"; then
2529 if [[ -n ${uefi_secureboot_key} && -n ${uefi_secureboot_cert} ]]; then
2530 if sbsign \
2531 ${uefi_secureboot_engine:+--engine "$uefi_secureboot_engine"} \
2532 --key "${uefi_secureboot_key}" \
2533 --cert "${uefi_secureboot_cert}" \
2534 --output "$outfile" "${uefi_outdir}/linux.efi" \
2535 && sbverify --cert "${uefi_secureboot_cert}" "$outfile" > /dev/null 2>&1; then
2536 dinfo "*** Creating signed UEFI image file '$outfile' done ***"
2537 else
2538 rm -f -- "$outfile"
2539 dfatal "*** Creating signed UEFI image file '$outfile' failed ***"
2540 exit 1
2541 fi
2542 else
2543 if cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
2544 dinfo "*** Creating UEFI image file '$outfile' done ***"
2545 else
2546 rm -f -- "$outfile"
2547 dfatal "Creation of $outfile failed"
2548 exit 1
2549 fi
2550 fi
2551 else
2552 rm -f -- "$outfile"
2553 dfatal "*** Creating UEFI image file '$outfile' failed ***"
2554 exit 1
2555 fi
2556 else
2557 if cp --reflink=auto "${DRACUT_TMPDIR}/initramfs.img" "$outfile"; then
2558 dinfo "*** Creating initramfs image file '$outfile' done ***"
2559 else
2560 rm -f -- "$outfile"
2561 dfatal "Creation of $outfile failed"
2562 exit 1
2563 fi
2564 fi
2565
2566 btrfs_uuid() {
2567 btrfs filesystem show "$1" | sed -n '1s/^.*uuid: //p'
2568 }
2569
2570 freeze_ok_for_btrfs() {
2571 local mnt uuid1 uuid2
2572 # If the output file is on btrfs, we need to make sure that it's
2573 # not on a subvolume of the same file system as the root FS.
2574 # Otherwise, fsfreeze() might freeze the entire system.
2575 # This is most conveniently checked by comparing the FS uuid.
2576
2577 [[ "$(stat -f -c %T -- "/")" == "btrfs" ]] || return 0
2578 mnt=$(stat -c %m -- "$1")
2579 uuid1=$(btrfs_uuid "$mnt")
2580 uuid2=$(btrfs_uuid "/")
2581 [[ $uuid1 && $uuid2 && $uuid1 != "$uuid2" ]]
2582 }
2583
2584 freeze_ok_for_fstype() {
2585 local outfile=$1
2586 local fstype
2587
2588 [[ "$(stat -c %m -- "$outfile")" == "/" ]] && return 1
2589 fstype=$(stat -f -c %T -- "$outfile")
2590 case $fstype in
2591 msdos)
2592 return 1
2593 ;;
2594 zfs)
2595 return 1
2596 ;;
2597 btrfs)
2598 freeze_ok_for_btrfs "$outfile"
2599 ;;
2600 *)
2601 return 0
2602 ;;
2603 esac
2604 }
2605
2606 # We sync/fsfreeze only if we're operating on a live booted system.
2607 # It's possible for e.g. `kernel` to be installed as an RPM BuildRequires or equivalent,
2608 # and there's no reason to sync, and *definitely* no reason to fsfreeze.
2609 # Another case where this happens is rpm-ostree, which performs its own sync/fsfreeze
2610 # globally. See e.g. https://github.com/ostreedev/ostree/commit/8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0
2611 if [[ -d $dracutsysrootdir/run/systemd/system ]]; then
2612 if ! sync "$outfile" 2> /dev/null; then
2613 dinfo "sync operation on newly created initramfs $outfile failed"
2614 exit 1
2615 fi
2616
2617 # use fsfreeze only if we're not writing to /
2618 if [[ "$(stat -c %m -- "$outfile")" != "/" ]] && freeze_ok_for_fstype "$outfile"; then
2619 FSFROZEN="$(dirname "$outfile")"
2620 if ! (fsfreeze -f "${FSFROZEN}" 2> /dev/null && fsfreeze -u "${FSFROZEN}" 2> /dev/null); then
2621 dwarn "Could not fsfreeze $(dirname "$outfile")"
2622 fi
2623 unset FSFROZEN
2624 fi
2625 fi
2626
2627 exit 0