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