]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
fix(dracut.sh): kmoddir does not handle trailing /
[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 [[ -f "$dracutsysrootdir"/etc/machine-id ]]; then
1091 read -r MACHINE_ID < "$dracutsysrootdir"/etc/machine-id
1092 else
1093 MACHINE_ID="Default"
1094 fi
1095 fi
1096
1097 if [[ $uefi == "yes" ]]; then
1098 # shellcheck disable=SC2154
1099 if [[ -n $uefi_secureboot_key && -z $uefi_secureboot_cert ]] || [[ -z $uefi_secureboot_key && -n $uefi_secureboot_cert ]]; then
1100 printf "%s\n" "dracut[F]: Need 'uefi_secureboot_key' and 'uefi_secureboot_cert' both to be set." >&2
1101 exit 1
1102 fi
1103
1104 if [[ -n $uefi_secureboot_key && -n $uefi_secureboot_cert ]] && ! command -v sbsign &> /dev/null; then
1105 printf "%s\n" "dracut[F]: Need 'sbsign' to create a signed UEFI executable." >&2
1106 exit 1
1107 fi
1108
1109 BUILD_ID=$(cat "$dracutsysrootdir"/etc/os-release "$dracutsysrootdir"/usr/lib/os-release \
1110 | while read -r line || [[ $line ]]; do
1111 [[ $line =~ BUILD_ID\=* ]] && eval "$line" && echo "$BUILD_ID" && break
1112 done)
1113 if [[ -z $dracutsysrootdir ]]; then
1114 if [[ -d /efi ]] && mountpoint -q /efi; then
1115 efidir=/efi/EFI
1116 else
1117 efidir=/boot/EFI
1118 if [[ -d /boot/efi/EFI ]]; then
1119 efidir=/boot/efi/EFI
1120 fi
1121 fi
1122 else
1123 efidir=/boot/EFI
1124 if [[ -d $dracutsysrootdir/boot/efi/EFI ]]; then
1125 efidir=/boot/efi/EFI
1126 fi
1127 fi
1128 mkdir -p "$dracutsysrootdir$efidir/Linux"
1129 outfile="$dracutsysrootdir$efidir/Linux/linux-$kernel${MACHINE_ID:+-${MACHINE_ID}}${BUILD_ID:+-${BUILD_ID}}.efi"
1130 else
1131 if [[ -d "$dracutsysrootdir"/efi/loader/entries || -L "$dracutsysrootdir"/efi/loader/entries ]] \
1132 && [[ $MACHINE_ID ]] \
1133 && [[ -d "$dracutsysrootdir"/efi/${MACHINE_ID} || -L "$dracutsysrootdir"/efi/${MACHINE_ID} ]]; then
1134 outfile="$dracutsysrootdir/efi/${MACHINE_ID}/${kernel}/initrd"
1135 elif [[ -d "$dracutsysrootdir"/boot/loader/entries || -L "$dracutsysrootdir"/boot/loader/entries ]] \
1136 && [[ $MACHINE_ID ]] \
1137 && [[ -d "$dracutsysrootdir"/boot/${MACHINE_ID} || -L "$dracutsysrootdir"/boot/${MACHINE_ID} ]]; then
1138 outfile="$dracutsysrootdir/boot/${MACHINE_ID}/${kernel}/initrd"
1139 elif [[ -d "$dracutsysrootdir"/boot/efi/loader/entries || -L "$dracutsysrootdir"/boot/efi/loader/entries ]] \
1140 && [[ $MACHINE_ID ]] \
1141 && [[ -d "$dracutsysrootdir"/boot/efi/${MACHINE_ID} || -L "$dracutsysrootdir"/boot/efi/${MACHINE_ID} ]]; then
1142 outfile="$dracutsysrootdir/boot/efi/${MACHINE_ID}/${kernel}/initrd"
1143 elif [[ -f "$dracutsysrootdir"/lib/modules/${kernel}/initrd ]]; then
1144 outfile="$dracutsysrootdir/lib/modules/${kernel}/initrd"
1145 elif [[ -e $dracutsysrootdir/boot/vmlinuz-${kernel} ]]; then
1146 outfile="$dracutsysrootdir/boot/initramfs-${kernel}.img"
1147 elif [[ -z $dracutsysrootdir ]] \
1148 && [[ $MACHINE_ID ]] \
1149 && mountpoint -q /efi; then
1150 outfile="/efi/${MACHINE_ID}/${kernel}/initrd"
1151 elif [[ -z $dracutsysrootdir ]] \
1152 && [[ $MACHINE_ID ]] \
1153 && mountpoint -q /boot/efi; then
1154 outfile="/boot/efi/${MACHINE_ID}/${kernel}/initrd"
1155 else
1156 outfile="$dracutsysrootdir/boot/initramfs-${kernel}.img"
1157 fi
1158 fi
1159 fi
1160
1161 # eliminate IFS hackery when messing with fw_dir
1162 export DRACUT_FIRMWARE_PATH=${fw_dir// /:}
1163 fw_dir=${fw_dir//:/ }
1164
1165 # check for logfile and try to create one if it doesn't exist
1166 if [[ -n $logfile ]]; then
1167 if [[ ! -f $logfile ]]; then
1168 if touch "$logfile"; then
1169 printf "%s\n" "dracut[W]: touch $logfile failed." >&2
1170 fi
1171 fi
1172 fi
1173
1174 # handle compression options.
1175 DRACUT_COMPRESS_BZIP2=${DRACUT_COMPRESS_BZIP2:-bzip2}
1176 DRACUT_COMPRESS_LBZIP2=${DRACUT_COMPRESS_LBZIP2:-lbzip2}
1177 DRACUT_COMPRESS_LZMA=${DRACUT_COMPRESS_LZMA:-lzma}
1178 DRACUT_COMPRESS_XZ=${DRACUT_COMPRESS_XZ:-xz}
1179 DRACUT_COMPRESS_GZIP=${DRACUT_COMPRESS_GZIP:-gzip}
1180 DRACUT_COMPRESS_PIGZ=${DRACUT_COMPRESS_PIGZ:-pigz}
1181 DRACUT_COMPRESS_LZOP=${DRACUT_COMPRESS_LZOP:-lzop}
1182 DRACUT_COMPRESS_ZSTD=${DRACUT_COMPRESS_ZSTD:-zstd}
1183 DRACUT_COMPRESS_LZ4=${DRACUT_COMPRESS_LZ4:-lz4}
1184 DRACUT_COMPRESS_CAT=${DRACUT_COMPRESS_CAT:-cat}
1185
1186 if [[ $_no_compress_l == "$DRACUT_COMPRESS_CAT" ]]; then
1187 compress="$DRACUT_COMPRESS_CAT"
1188 fi
1189
1190 [[ $hostonly == yes ]] && hostonly="-h"
1191 [[ $hostonly != "-h" ]] && unset hostonly
1192
1193 case $hostonly_mode in
1194 '')
1195 [[ $hostonly ]] && hostonly_mode="sloppy"
1196 ;;
1197 sloppy | strict)
1198 if [[ ! $hostonly ]]; then
1199 unset hostonly_mode
1200 fi
1201 ;;
1202 *)
1203 printf "%s\n" "dracut[F]: Invalid hostonly mode '$hostonly_mode'." >&2
1204 exit 1
1205 ;;
1206 esac
1207
1208 [[ $reproducible == yes ]] && DRACUT_REPRODUCIBLE=1
1209
1210 if [[ -z $DRACUT_KMODDIR_OVERRIDE && -n $drivers_dir ]]; then
1211 drivers_basename="${drivers_dir##*/}"
1212 if [[ -n $drivers_basename && $drivers_basename != "$kernel" ]]; then
1213 printf "%s\n" "dracut[F]: The provided directory where to look for kernel modules ($drivers_basename)" >&2
1214 printf "%s\n" "dracut[F]: does not match the kernel version set for the initramfs ($kernel)." >&2
1215 printf "%s\n" "dracut[F]: Set DRACUT_KMODDIR_OVERRIDE=1 to ignore this check." >&2
1216 exit 1
1217 fi
1218 drivers_dirname="${drivers_dir%/*}/"
1219 if [[ ! $drivers_dirname =~ .*/lib/modules/$ ]]; then
1220 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
1221 printf "%s\n" "dracut[F]: or modules may not be placed in the correct location inside the initramfs." >&2
1222 printf "%s\n" "dracut[F]: was given: ${drivers_dir}" >&2
1223 printf "%s\n" "dracut[F]: expected: ${drivers_dirname}lib/modules/${kernel}" >&2
1224 printf "%s\n" "dracut[F]: Please move your modules into the correct directory structure and pass the new location," >&2
1225 printf "%s\n" "dracut[F]: or set DRACUT_KMODDIR_OVERRIDE=1 to ignore this check." >&2
1226 exit 1
1227 fi
1228 fi
1229
1230 # shellcheck disable=SC2155
1231 readonly TMPDIR="$(realpath -e "$tmpdir")"
1232 [ -d "$TMPDIR" ] || {
1233 printf "%s\n" "dracut[F]: Invalid tmpdir '$tmpdir'." >&2
1234 exit 1
1235 }
1236
1237 if findmnt --raw -n --target "$tmpdir" --output=options | grep -q noexec; then
1238 [[ $debug == yes ]] && printf "%s\n" "dracut[D]: Tmpdir '$tmpdir' is mounted with 'noexec'." >&2
1239 noexec=1
1240 fi
1241
1242 # shellcheck disable=SC2155
1243 readonly DRACUT_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t dracut.XXXXXX)"
1244 [ -d "$DRACUT_TMPDIR" ] || {
1245 printf "%s\n" "dracut[F]: mktemp -p '$TMPDIR/' -d -t dracut.XXXXXX failed." >&2
1246 exit 1
1247 }
1248
1249 # Cache file used to optimize get_maj_min()
1250 declare -x -r get_maj_min_cache_file="${DRACUT_TMPDIR}/majmin_cache"
1251 : > "$get_maj_min_cache_file"
1252
1253 # clean up after ourselves no matter how we die.
1254 trap '
1255 ret=$?;
1256 [[ $keep ]] && echo "Not removing $DRACUT_TMPDIR." >&2 || { [[ $DRACUT_TMPDIR ]] && rm -rf -- "$DRACUT_TMPDIR"; };
1257 if [[ ${FSFROZEN} ]]; then
1258 fsfreeze -u "${FSFROZEN}"
1259 fi
1260 exit $ret;
1261 ' EXIT
1262
1263 # clean up after ourselves no matter how we die.
1264 trap 'exit 1;' SIGINT
1265
1266 readonly initdir="${DRACUT_TMPDIR}/initramfs"
1267 mkdir -p "$initdir"
1268
1269 # shellcheck disable=SC2154
1270 if [[ $early_microcode == yes ]] || { [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; }; then
1271 readonly early_cpio_dir="${DRACUT_TMPDIR}/earlycpio"
1272 mkdir "$early_cpio_dir"
1273 fi
1274
1275 [[ "$dracutsysrootdir" ]] || [[ "$noexec" ]] || export DRACUT_RESOLVE_LAZY="1"
1276
1277 if [[ $print_cmdline ]]; then
1278 stdloglvl=0
1279 sysloglvl=0
1280 fileloglvl=0
1281 kmsgloglvl=0
1282 fi
1283
1284 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
1285 # shellcheck source=./dracut-version.sh
1286 . "$dracutbasedir"/dracut-version.sh
1287 fi
1288
1289 if systemd-detect-virt -c &> /dev/null; then
1290 export DRACUT_NO_MKNOD=1 DRACUT_NO_XATTR=1
1291 if [[ $hostonly ]]; then
1292 printf "%s\n" "dracut[W]: Running in hostonly mode in a container!" >&2
1293 fi
1294 fi
1295
1296 if [[ -f $dracutbasedir/dracut-init.sh ]]; then
1297 # shellcheck source=./dracut-init.sh
1298 . "$dracutbasedir"/dracut-init.sh
1299 else
1300 printf "%s\n" "dracut[F]: Cannot find $dracutbasedir/dracut-init.sh." >&2
1301 printf "%s\n" "dracut[F]: Are you running from a git checkout?" >&2
1302 printf "%s\n" "dracut[F]: Try passing -l as an argument to $dracut_cmd" >&2
1303 exit 1
1304 fi
1305
1306 if [[ $persistent_policy == "mapper" ]]; then
1307 unset persistent_policy
1308 elif [[ -n $persistent_policy && ! -d "/dev/disk/${persistent_policy}" ]]; then
1309 dwarn "Invalid persistent policy, your system does not have a /dev/disk/${persistent_policy} directory."
1310 unset persistent_policy
1311 fi
1312
1313 if [[ $enhanced_cpio == "yes" ]]; then
1314 enhanced_cpio="$dracutbasedir/dracut-cpio"
1315 if [[ -x $enhanced_cpio ]]; then
1316 # align based on statfs optimal transfer size
1317 cpio_align=$(stat --file-system -c "%s" -- "$initdir")
1318 else
1319 dinfo "--enhanced-cpio ignored due to lack of dracut-cpio"
1320 unset enhanced_cpio
1321 fi
1322 else
1323 unset enhanced_cpio
1324 fi
1325
1326 # shellcheck disable=SC2154
1327 if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
1328 dfatal "Cannot find module directory $srcmods"
1329 dfatal "and --no-kernel was not specified"
1330 exit 1
1331 fi
1332
1333 if ! [[ $print_cmdline ]]; then
1334 inst "$DRACUT_TESTBIN"
1335 if ! $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R "$DRACUT_TESTBIN" &> /dev/null; then
1336 unset DRACUT_RESOLVE_LAZY
1337 export DRACUT_RESOLVE_DEPS=1
1338 fi
1339 rm -fr -- "${initdir:?}"/*
1340 fi
1341
1342 dracutfunctions=$dracutbasedir/dracut-functions.sh
1343 export dracutfunctions
1344
1345 ((${#drivers_l[@]})) && drivers="${drivers_l[*]}"
1346 drivers=${drivers/-/_}
1347
1348 ((${#add_drivers_l[@]})) && add_drivers+=" ${add_drivers_l[*]} "
1349 add_drivers=${add_drivers/-/_}
1350
1351 ((${#force_drivers_l[@]})) && force_drivers+=" ${force_drivers_l[*]} "
1352 force_drivers=${force_drivers/-/_}
1353
1354 ((${#omit_drivers_l[@]})) && omit_drivers+=" ${omit_drivers_l[*]} "
1355 omit_drivers=${omit_drivers/-/_}
1356
1357 ((${#kernel_cmdline_l[@]})) && kernel_cmdline+=" ${kernel_cmdline_l[*]} "
1358
1359 omit_drivers_corrected=""
1360 for d in $omit_drivers; do
1361 [[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
1362 [[ " $drivers $force_drivers " == *\ $d\ * ]] && continue
1363 omit_drivers_corrected+="^$d$|"
1364 done
1365 omit_drivers="${omit_drivers_corrected%|}"
1366 unset omit_drivers_corrected
1367
1368 # prepare args for logging
1369 for ((i = 0; i < ${#dracut_args[@]}; i++)); do
1370 [[ ${dracut_args[$i]} == *\ * ]] \
1371 && dracut_args[$i]="\"${dracut_args[$i]}\""
1372 #" keep vim happy
1373 done
1374
1375 dinfo "Executing: $dracut_cmd ${dracut_args[*]}"
1376
1377 [[ $do_list == yes ]] && {
1378 for mod in "$dracutbasedir"/modules.d/*; do
1379 [[ -d $mod ]] || continue
1380 [[ -e $mod/install || -e $mod/installkernel || -e $mod/module-setup.sh ]] || continue
1381 printf "%s\n" "${mod##*/??}"
1382 done
1383 exit 0
1384 }
1385
1386 # This is kinda legacy -- eventually it should go away.
1387 case $dracutmodules in
1388 "" | auto) dracutmodules="all" ;;
1389 esac
1390
1391 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
1392
1393 # Helper function to set global variables
1394 # set_global_var <pkg_config> <var> <value[:check_file]> [<value[:check_file]>] ...
1395 set_global_var() {
1396 local _pkgconfig="$1"
1397 local _var="$2"
1398 [[ -z ${!_var} || ! -d ${dracutsysrootdir}${!_var} ]] \
1399 && export "$_var"="$(pkg-config "$_pkgconfig" --variable="$_var" 2> /dev/null)"
1400 if [[ -z ${!_var} || ! -d ${dracutsysrootdir}${!_var} ]]; then
1401 shift 2
1402 if (($# == 1)); then
1403 export "$_var"="$1"
1404 else
1405 local _val
1406 for _val in "$@"; do
1407 _check=${_val##*:}
1408 _val=${_val%:*}
1409 [[ -e ${dracutsysrootdir}${_check} ]] && export "$_var"="$_val"
1410 done
1411 fi
1412 fi
1413 }
1414
1415 # dbus global variables
1416 set_global_var "dbus" "dbus" "/usr/share/dbus-1"
1417 set_global_var "dbus" "dbusconfdir" "/etc/dbus-1"
1418 set_global_var "dbus" "dbusinterfaces" "${dbus}/interfaces"
1419 set_global_var "dbus" "dbusinterfacesconfdir" "${dbusconfdir}/interfaces"
1420 set_global_var "dbus" "dbusservices" "${dbus}/services"
1421 set_global_var "dbus" "dbusservicesconfdir" "${dbusconfdir}/services"
1422 set_global_var "dbus" "dbussession" "${dbus}/session.d"
1423 set_global_var "dbus" "dbussessionconfdir" "${dbusconfdir}/session.d"
1424 set_global_var "dbus" "dbussystem" "${dbus}/system.d"
1425 set_global_var "dbus" "dbussystemconfdir" "${dbusconfdir}/system.d"
1426 set_global_var "dbus" "dbussystemservices" "${dbus}/system-services"
1427 set_global_var "dbus" "dbussystemservicesconfdir" "${dbusconfdir}/system-services"
1428
1429 # udev global variables
1430 set_global_var "udev" "udevdir" "/lib/udev:/lib/udev/ata_id" "/usr/lib/udev:/usr/lib/udev/ata_id"
1431 set_global_var "udev" "udevconfdir" "/etc/udev"
1432 set_global_var "udev" "udevrulesdir" "${udevdir}/rules.d"
1433 set_global_var "udev" "udevrulesconfdir" "${udevconfdir}/rules.d"
1434
1435 # systemd global variables
1436 set_global_var "systemd" "systemdutildir" "/lib/systemd:/lib/systemd/systemd-udevd" "/usr/lib/systemd:/usr/lib/systemd/systemd-udevd"
1437 set_global_var "systemd" "systemdutilconfdir" "/etc/systemd"
1438 set_global_var "systemd" "environment" "/usr/lib/environment.d"
1439 set_global_var "systemd" "environmentconfdir" "/etc/environment.d"
1440 set_global_var "systemd" "modulesload" "/usr/lib/modules-load.d"
1441 set_global_var "systemd" "modulesloadconfdir" "/etc/modules-load.d"
1442 set_global_var "systemd" "sysctld" "/usr/lib/sysctl.d"
1443 set_global_var "systemd" "sysctlconfdir" "/etc/sysctl.d"
1444 set_global_var "systemd" "systemdcatalog" "${systemdutildir}/catalog"
1445 set_global_var "systemd" "systemdnetwork" "${systemdutildir}/network"
1446 set_global_var "systemd" "systemdnetworkconfdir" "${systemdutilconfdir}/network"
1447 set_global_var "systemd" "systemdntpunits" "${systemdutildir}/ntp-units.d"
1448 set_global_var "systemd" "systemdntpunitsconfdir" "${systemdutilconfdir}/ntp-units.d"
1449 set_global_var "systemd" "systemdportable" "${systemdutildir}/portable"
1450 set_global_var "systemd" "systemdportableconfdir" "${systemdutilconfdir}/portable"
1451 set_global_var "systemd" "systemdsystemunitdir" "${systemdutildir}/system"
1452 set_global_var "systemd" "systemdsystemconfdir" "${systemdutilconfdir}/system"
1453 set_global_var "systemd" "systemduser" "${systemdutildir}/user"
1454 set_global_var "systemd" "systemduserconfdir" "${systemdutilconfdir}/user"
1455 set_global_var "systemd" "sysusers" "/usr/lib/sysusers.d"
1456 set_global_var "systemd" "sysusersconfdir" "/etc/sysusers.d"
1457 set_global_var "systemd" "tmpfilesdir" "/lib/tmpfiles.d" "/usr/lib/tmpfiles.d"
1458 set_global_var "systemd" "tmpfilesconfdir" "/etc/tmpfiles.d"
1459
1460 # libkmod global variables
1461 set_global_var "libkmod" "depmodd" "/usr/lib/depmod.d"
1462 set_global_var "libkmod" "depmodconfdir" "/etc/depmod.d"
1463
1464 if [[ $no_kernel != yes ]] && [[ -d $srcmods ]]; then
1465 if ! [[ -f $srcmods/modules.dep ]]; then
1466 if [[ -n "$(find "$srcmods" -name '*.ko*')" ]]; then
1467 dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
1468 exit 1
1469 else
1470 dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
1471 fi
1472 fi
1473 fi
1474
1475 if [[ ! $print_cmdline ]]; then
1476 if [[ -f $outfile && ! $force ]]; then
1477 dfatal "Will not override existing initramfs ($outfile) without --force"
1478 exit 1
1479 fi
1480
1481 outdir=${outfile%/*}
1482 [[ $outdir ]] || outdir="/"
1483
1484 if [[ ! -d $outdir ]]; then
1485 dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
1486 exit 1
1487 elif [[ ! -w $outdir ]]; then
1488 dfatal "No permission to write to $outdir."
1489 exit 1
1490 elif [[ -f $outfile && ! -w $outfile ]]; then
1491 dfatal "No permission to write $outfile."
1492 exit 1
1493 fi
1494
1495 if [[ $loginstall ]]; then
1496 if ! mkdir -p "$loginstall"; then
1497 dfatal "Could not create directory to log installed files to '$loginstall'."
1498 exit 1
1499 fi
1500 loginstall=$(readlink -f "$loginstall")
1501 fi
1502
1503 if [[ $uefi == yes ]]; then
1504 if ! command -v objcopy &> /dev/null; then
1505 dfatal "Need 'objcopy' to create a UEFI executable"
1506 exit 1
1507 fi
1508 unset EFI_MACHINE_TYPE_NAME
1509 EFI_SECTION_VMA_INITRD=0x3000000
1510 case "${DRACUT_ARCH:-$(uname -m)}" in
1511 x86_64)
1512 EFI_MACHINE_TYPE_NAME=x64
1513 ;;
1514 i?86)
1515 EFI_MACHINE_TYPE_NAME=ia32
1516 ;;
1517 aarch64)
1518 EFI_MACHINE_TYPE_NAME=aa64
1519 # aarch64 kernels are uncompressed and thus larger, so we need a bigger gap between vma sections
1520 EFI_SECTION_VMA_INITRD=0x4000000
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${systemdutildir}/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 | dinfo
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 if [[ $kernel_cmdline ]] || [[ $hostonly_cmdline == yes && -e "${uefi_outdir}/cmdline.txt" ]]; then
2471 echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
2472 dinfo "Using UEFI kernel cmdline:"
2473 dinfo "$(tr -d '\000' < "$uefi_outdir/cmdline.txt")"
2474 uefi_cmdline="${uefi_outdir}/cmdline.txt"
2475 else
2476 unset uefi_cmdline
2477 fi
2478
2479 [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
2480 [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
2481 if [[ -s ${dracutsysrootdir}${uefi_splash_image} ]]; then
2482 uefi_splash_image="${dracutsysrootdir}${uefi_splash_image}"
2483 else
2484 unset uefi_splash_image
2485 fi
2486
2487 if objcopy \
2488 ${uefi_osrelease:+--add-section .osrel="$uefi_osrelease" --change-section-vma .osrel=0x20000} \
2489 ${uefi_cmdline:+--add-section .cmdline="$uefi_cmdline" --change-section-vma .cmdline=0x30000} \
2490 ${uefi_splash_image:+--add-section .splash="$uefi_splash_image" --change-section-vma .splash=0x40000} \
2491 --add-section .linux="$kernel_image" --change-section-vma .linux=0x2000000 \
2492 --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd="${EFI_SECTION_VMA_INITRD}" \
2493 "$uefi_stub" "${uefi_outdir}/linux.efi"; then
2494 if [[ -n ${uefi_secureboot_key} && -n ${uefi_secureboot_cert} ]]; then
2495 if sbsign \
2496 ${uefi_secureboot_engine:+--engine "$uefi_secureboot_engine"} \
2497 --key "${uefi_secureboot_key}" \
2498 --cert "${uefi_secureboot_cert}" \
2499 --output "$outfile" "${uefi_outdir}/linux.efi" \
2500 && sbverify --cert "${uefi_secureboot_cert}" "$outfile" > /dev/null 2>&1; then
2501 dinfo "*** Creating signed UEFI image file '$outfile' done ***"
2502 else
2503 rm -f -- "$outfile"
2504 dfatal "*** Creating signed UEFI image file '$outfile' failed ***"
2505 exit 1
2506 fi
2507 else
2508 if cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
2509 dinfo "*** Creating UEFI image file '$outfile' done ***"
2510 else
2511 rm -f -- "$outfile"
2512 dfatal "Creation of $outfile failed"
2513 exit 1
2514 fi
2515 fi
2516 else
2517 rm -f -- "$outfile"
2518 dfatal "*** Creating UEFI image file '$outfile' failed ***"
2519 exit 1
2520 fi
2521 else
2522 if cp --reflink=auto "${DRACUT_TMPDIR}/initramfs.img" "$outfile"; then
2523 dinfo "*** Creating initramfs image file '$outfile' done ***"
2524 else
2525 rm -f -- "$outfile"
2526 dfatal "Creation of $outfile failed"
2527 exit 1
2528 fi
2529 fi
2530
2531 btrfs_uuid() {
2532 btrfs filesystem show "$1" | sed -n '1s/^.*uuid: //p'
2533 }
2534
2535 freeze_ok_for_btrfs() {
2536 local mnt uuid1 uuid2
2537 # If the output file is on btrfs, we need to make sure that it's
2538 # not on a subvolume of the same file system as the root FS.
2539 # Otherwise, fsfreeze() might freeze the entire system.
2540 # This is most conveniently checked by comparing the FS uuid.
2541
2542 [[ "$(stat -f -c %T -- "/")" == "btrfs" ]] || return 0
2543 mnt=$(stat -c %m -- "$1")
2544 uuid1=$(btrfs_uuid "$mnt")
2545 uuid2=$(btrfs_uuid "/")
2546 [[ $uuid1 && $uuid2 && $uuid1 != "$uuid2" ]]
2547 }
2548
2549 freeze_ok_for_fstype() {
2550 local outfile=$1
2551 local fstype
2552
2553 [[ "$(stat -c %m -- "$outfile")" == "/" ]] && return 1
2554 fstype=$(stat -f -c %T -- "$outfile")
2555 case $fstype in
2556 msdos)
2557 return 1
2558 ;;
2559 zfs)
2560 return 1
2561 ;;
2562 btrfs)
2563 freeze_ok_for_btrfs "$outfile"
2564 ;;
2565 *)
2566 return 0
2567 ;;
2568 esac
2569 }
2570
2571 # We sync/fsfreeze only if we're operating on a live booted system.
2572 # It's possible for e.g. `kernel` to be installed as an RPM BuildRequires or equivalent,
2573 # and there's no reason to sync, and *definitely* no reason to fsfreeze.
2574 # Another case where this happens is rpm-ostree, which performs its own sync/fsfreeze
2575 # globally. See e.g. https://github.com/ostreedev/ostree/commit/8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0
2576 if [[ -d $dracutsysrootdir/run/systemd/system ]]; then
2577 if ! sync "$outfile" 2> /dev/null; then
2578 dinfo "sync operation on newly created initramfs $outfile failed"
2579 exit 1
2580 fi
2581
2582 # use fsfreeze only if we're not writing to /
2583 if [[ "$(stat -c %m -- "$outfile")" != "/" ]] && freeze_ok_for_fstype "$outfile"; then
2584 FSFROZEN="$(dirname "$outfile")"
2585 if ! (fsfreeze -f "${FSFROZEN}" 2> /dev/null && fsfreeze -u "${FSFROZEN}" 2> /dev/null); then
2586 dwarn "Could not fsfreeze $(dirname "$outfile")"
2587 fi
2588 unset FSFROZEN
2589 fi
2590 fi
2591
2592 exit 0