]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
e0abdb3b050800fbfb70f4fd533f403f9d476e79
[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" ]]; then
1565 check_kernel_config CONFIG_MICROCODE_AMD || unset early_microcode
1566 elif [[ $(get_cpu_vendor) == "Intel" ]]; then
1567 check_kernel_config CONFIG_MICROCODE_INTEL || unset early_microcode
1568 else
1569 unset early_microcode
1570 fi
1571 else
1572 ! check_kernel_config CONFIG_MICROCODE_AMD \
1573 && ! check_kernel_config CONFIG_MICROCODE_INTEL \
1574 && unset early_microcode
1575 fi
1576 # Do not complain on non-x86 architectures as it makes no sense
1577 case "${DRACUT_ARCH:-$(uname -m)}" in
1578 x86_64 | i?86)
1579 [[ $early_microcode != yes ]] \
1580 && dwarn "Disabling early microcode, because kernel does not support it. CONFIG_MICROCODE_[AMD|INTEL]!=y"
1581 ;;
1582 *) ;;
1583 esac
1584 fi
1585
1586 # Need to be able to have non-root users read stuff (rpcbind etc)
1587 chmod 755 "$initdir"
1588
1589 if [[ $hostonly ]]; then
1590 for i in /sys /proc /run /dev; do
1591 if ! findmnt --target "$i" &> /dev/null; then
1592 dwarning "Turning off host-only mode: '$i' is not mounted!"
1593 unset hostonly
1594 fi
1595 done
1596 fi
1597
1598 declare -A host_fs_types
1599
1600 for line in "${fstab_lines[@]}"; do
1601 # shellcheck disable=SC2086
1602 set -- $line
1603 dev="$1"
1604 #dev mp fs fsopts
1605 case "$dev" in
1606 UUID=*)
1607 dev=$(blkid -l -t "UUID=${dev#UUID=}" -o device)
1608 ;;
1609 LABEL=*)
1610 dev=$(blkid -l -t "LABEL=${dev#LABEL=}" -o device)
1611 ;;
1612 PARTUUID=*)
1613 dev=$(blkid -l -t "PARTUUID=${dev#PARTUUID=}" -o device)
1614 ;;
1615 PARTLABEL=*)
1616 dev=$(blkid -l -t "PARTLABEL=${dev#PARTLABEL=}" -o device)
1617 ;;
1618 esac
1619 [ -z "$dev" ] && dwarn "Bad fstab entry $*" && continue
1620 if [[ $3 == btrfs ]]; then
1621 for mp in $(findmnt --source "$1" -o TARGET -n); do
1622 for i in $(btrfs_devs "$mp"); do
1623 push_host_devs "$i"
1624 done
1625 done
1626 elif [[ $3 == zfs ]]; then
1627 for mp in $(zfs_devs "$1"); do
1628 push_host_devs "$mp"
1629 done
1630 fi
1631 push_host_devs "$dev"
1632 host_fs_types["$dev"]="$3"
1633 done
1634
1635 for f in $add_fstab; do
1636 [[ -e $f ]] || continue
1637 while read -r dev rest || [ -n "$dev" ]; do
1638 push_host_devs "$dev"
1639 done < "$f"
1640 done
1641
1642 for dev in $add_device; do
1643 push_host_devs "$dev"
1644 done
1645
1646 if ((${#add_device_l[@]})); then
1647 add_device+=" ${add_device_l[*]} "
1648 push_host_devs "${add_device_l[@]}"
1649 fi
1650
1651 if [[ $hostonly ]] && [[ $hostonly_default_device != "no" ]]; then
1652 # in hostonly mode, determine all devices, which have to be accessed
1653 # and examine them for filesystem types
1654
1655 for mp in \
1656 "/" \
1657 "/etc" \
1658 "/bin" \
1659 "/sbin" \
1660 "/lib" \
1661 "/lib64" \
1662 "/usr" \
1663 "/usr/bin" \
1664 "/usr/sbin" \
1665 "/usr/lib" \
1666 "/usr/lib64" \
1667 "/boot" \
1668 "/boot/efi" \
1669 "/boot/zipl"; do
1670 mp=$(readlink -f "$dracutsysrootdir$mp")
1671 mountpoint "$mp" > /dev/null 2>&1 || continue
1672 _dev=$(find_block_device "$mp")
1673 _bdev=$(readlink -f "/dev/block/$_dev")
1674 [[ -b $_bdev ]] && _dev=$_bdev
1675 [[ $mp == "/" ]] && root_devs+=("$_dev")
1676 push_host_devs "$_dev"
1677 if [[ $(find_mp_fstype "$mp") == btrfs ]]; then
1678 for i in $(btrfs_devs "$mp"); do
1679 [[ $mp == "/" ]] && root_devs+=("$i")
1680 push_host_devs "$i"
1681 done
1682 elif [[ $(find_mp_fstype "$mp") == zfs ]]; then
1683 for i in $(zfs_devs "$(findmnt -n -o SOURCE "$mp")"); do
1684 [[ $mp == "/" ]] && root_devs+=("$i")
1685 push_host_devs "$i"
1686 done
1687 fi
1688
1689 done
1690
1691 # TODO - with sysroot, /proc/swaps is not relevant
1692 if [[ -f /proc/swaps ]] && [[ -f $dracutsysrootdir/etc/fstab ]]; then
1693 while read -r dev type rest || [ -n "$dev" ]; do
1694 [[ -b $dev ]] || continue
1695 [[ $type == "partition" ]] || continue
1696
1697 while read -r _d _m _t _o _ || [ -n "$_d" ]; do
1698 [[ $_d == \#* ]] && continue
1699 [[ $_d ]] || continue
1700 [[ $_t != "swap" ]] && continue
1701 [[ $_m != "swap" ]] && [[ $_m != "none" ]] && continue
1702 [[ $_o == *noauto* ]] && continue
1703 _d=$(expand_persistent_dev "$_d")
1704 [[ $_d -ef $dev ]] || continue
1705
1706 if [[ -f $dracutsysrootdir/etc/crypttab ]]; then
1707 while read -r _mapper _ _p _o || [ -n "$_mapper" ]; do
1708 [[ $_mapper == \#* ]] && continue
1709 [[ $_d -ef /dev/mapper/"$_mapper" ]] || continue
1710 [[ "$_o" ]] || _o="$_p"
1711 # skip entries with password files
1712 [[ $_p == /* ]] && [[ -f $_p ]] && continue 2
1713 # skip mkswap swap
1714 [[ $_o == *swap* ]] && continue 2
1715 done < "$dracutsysrootdir"/etc/crypttab
1716 fi
1717
1718 _dev="$(readlink -f "$dev")"
1719 push_host_devs "$_dev"
1720 swap_devs+=("$_dev")
1721 break
1722 done < "$dracutsysrootdir"/etc/fstab
1723 done < /proc/swaps
1724 fi
1725
1726 # collect all "x-initrd.mount" entries from /etc/fstab
1727 if [[ -f $dracutsysrootdir/etc/fstab ]]; then
1728 while read -r _d _m _t _o _ || [ -n "$_d" ]; do
1729 [[ $_d == \#* ]] && continue
1730 [[ $_d ]] || continue
1731 [[ $_o != *x-initrd.mount* ]] && continue
1732 _dev=$(expand_persistent_dev "$_d")
1733 _dev="$(readlink -f "$_dev")"
1734 [[ -b $_dev ]] || continue
1735
1736 push_host_devs "$_dev"
1737 if [[ $_t == btrfs ]]; then
1738 for i in $(btrfs_devs "$_m"); do
1739 push_host_devs "$i"
1740 done
1741 elif [[ $_t == zfs ]]; then
1742 for i in $(zfs_devs "$_d"); do
1743 push_host_devs "$i"
1744 done
1745 fi
1746 done < "$dracutsysrootdir"/etc/fstab
1747 fi
1748 fi
1749
1750 unset m
1751 unset rest
1752
1753 _get_fs_type() {
1754 [[ $1 ]] || return
1755 if [[ -b /dev/block/$1 ]]; then
1756 ID_FS_TYPE=$(get_fs_env "/dev/block/$1") && host_fs_types["$(readlink -f "/dev/block/$1")"]="$ID_FS_TYPE"
1757 return 1
1758 fi
1759 if [[ -b $1 ]]; then
1760 ID_FS_TYPE=$(get_fs_env "$1") && host_fs_types["$(readlink -f "$1")"]="$ID_FS_TYPE"
1761 return 1
1762 fi
1763 if fstype=$(find_dev_fstype "$1"); then
1764 host_fs_types["$1"]="$fstype"
1765 return 1
1766 fi
1767 return 1
1768 }
1769
1770 for dev in "${host_devs[@]}"; do
1771 _get_fs_type "$dev"
1772 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1773 done
1774
1775 for dev in "${!host_fs_types[@]}"; do
1776 [[ ${host_fs_types[$dev]} == "reiserfs" ]] || [[ ${host_fs_types[$dev]} == "xfs" ]] || continue
1777 rootopts=$(find_dev_fsopts "$dev")
1778 if [[ ${host_fs_types[$dev]} == "reiserfs" ]]; then
1779 journaldev=$(fs_get_option "$rootopts" "jdev")
1780 elif [[ ${host_fs_types[$dev]} == "xfs" ]]; then
1781 journaldev=$(fs_get_option "$rootopts" "logdev")
1782 fi
1783 if [[ $journaldev ]]; then
1784 dev="$(readlink -f "$dev")"
1785 push_host_devs "$dev"
1786 _get_fs_type "$dev"
1787 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1788 fi
1789 done
1790
1791 export initdir dracutbasedir \
1792 dracutmodules force_add_dracutmodules add_dracutmodules omit_dracutmodules \
1793 mods_to_load \
1794 fw_dir drivers_dir debug no_kernel kernel_only \
1795 omit_drivers mdadmconf lvmconf root_devs \
1796 use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
1797 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
1798 host_fs_types host_devs swap_devs sshkey add_fstab \
1799 DRACUT_VERSION \
1800 prefix filesystems drivers \
1801 hostonly_cmdline loginstall
1802
1803 mods_to_load=""
1804 # check all our modules to see if they should be sourced.
1805 # This builds a list of modules that we will install next.
1806 for_each_module_dir check_module
1807 for_each_module_dir check_mount
1808
1809 dracut_module_included "fips" && export DRACUT_FIPS_MODE=1
1810
1811 do_print_cmdline() {
1812 local -A _mods_to_print
1813 for i in $modules_loaded $mods_to_load; do
1814 _mods_to_print[$i]=1
1815 done
1816
1817 # source our modules.
1818 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1819 _d_mod=${moddir##*/}
1820 _d_mod=${_d_mod#[0-9][0-9]}
1821 [[ ${_mods_to_print[$_d_mod]} ]] || continue
1822 module_cmdline "$_d_mod" "$moddir"
1823 done
1824 unset moddir
1825 }
1826
1827 if [[ $print_cmdline ]]; then
1828 do_print_cmdline
1829 printf "\n"
1830 exit 0
1831 fi
1832
1833 # Create some directory structure first
1834 # shellcheck disable=SC2174
1835 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
1836
1837 # shellcheck disable=SC2174
1838 [[ -L $dracutsysrootdir/lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
1839 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
1840
1841 if [[ $prefix ]]; then
1842 for d in bin etc lib sbin tmp usr var $libdirs; do
1843 d=${d#/}
1844 [[ $d == */* ]] && continue
1845 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
1846 done
1847 fi
1848
1849 if [[ $kernel_only != yes ]]; then
1850 for d in usr usr/bin usr/sbin bin etc lib sbin tmp var var/tmp $libdirs; do
1851 d=${d#/}
1852 [[ -e "${initdir}${prefix}/$d" ]] && continue
1853 if [ -L "/$d" ]; then
1854 inst_symlink "/$d" "${prefix}/$d"
1855 else
1856 # shellcheck disable=SC2174
1857 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1858 fi
1859 done
1860
1861 for d in dev proc sys sysroot root run; do
1862 if [ -L "/$d" ]; then
1863 inst_symlink "/$d"
1864 else
1865 # shellcheck disable=SC2174
1866 mkdir -m 0755 -p "$initdir/$d"
1867 fi
1868 done
1869
1870 ln -sfn ../run "$initdir/var/run"
1871 ln -sfn ../run/lock "$initdir/var/lock"
1872 else
1873 for d in lib "$libdirs"; do
1874 [[ -e "${initdir}${prefix}/$d" ]] && continue
1875 if [ -h "/$d" ]; then
1876 inst "/$d" "${prefix}/$d"
1877 else
1878 # shellcheck disable=SC2174
1879 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1880 fi
1881 done
1882 fi
1883
1884 mkdir -p "${initdir}"/lib/dracut
1885
1886 if [[ $kernel_only != yes ]]; then
1887 mkdir -p "${initdir}/etc/cmdline.d"
1888 mkdir -m 0755 "${initdir}"/lib/dracut/hooks
1889 for _d in $hookdirs; do
1890 # shellcheck disable=SC2174
1891 mkdir -m 0755 -p "${initdir}/lib/dracut/hooks/$_d"
1892 done
1893 if [[ $EUID == "0" ]] && ! [[ $DRACUT_NO_MKNOD ]]; then
1894 [[ -c ${initdir}/dev/null ]] || mknod "${initdir}"/dev/null c 1 3
1895 [[ -c ${initdir}/dev/kmsg ]] || mknod "${initdir}"/dev/kmsg c 1 11
1896 [[ -c ${initdir}/dev/console ]] || mknod "${initdir}"/dev/console c 5 1
1897 [[ -c ${initdir}/dev/random ]] || mknod "${initdir}"/dev/random c 1 8
1898 [[ -c ${initdir}/dev/urandom ]] || mknod "${initdir}"/dev/urandom c 1 9
1899 fi
1900 fi
1901
1902 _isize=0 #initramfs size
1903 modules_loaded=" "
1904 # source our modules.
1905 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1906 _d_mod=${moddir##*/}
1907 _d_mod=${_d_mod#[0-9][0-9]}
1908 [[ $mods_to_load == *\ $_d_mod\ * ]] || continue
1909 if [[ $show_modules == yes ]]; then
1910 printf "%s\n" "$_d_mod"
1911 else
1912 dinfo "*** Including module: $_d_mod ***"
1913 fi
1914 if [[ $kernel_only == yes ]]; then
1915 module_installkernel "$_d_mod" "$moddir" || {
1916 dfatal "installkernel failed in module $_d_mod"
1917 exit 1
1918 }
1919 else
1920 module_install "$_d_mod" "$moddir"
1921 if [[ $no_kernel != yes ]]; then
1922 module_installkernel "$_d_mod" "$moddir" || {
1923 dfatal "installkernel failed in module $_d_mod"
1924 exit 1
1925 }
1926 fi
1927 fi
1928 mods_to_load=${mods_to_load// $_d_mod /}
1929 modules_loaded+="$_d_mod "
1930
1931 #print the module install size
1932 if [ -n "$printsize" ]; then
1933 _isize_new=$(du -sk "${initdir}" | {
1934 read -r a _
1935 echo -n "$a"
1936 })
1937 _isize_delta=$((_isize_new - _isize))
1938 printf "%s\n" "$_d_mod install size: ${_isize_delta}k"
1939 _isize=$_isize_new
1940 fi
1941 done
1942 unset moddir
1943
1944 for i in $modules_loaded; do
1945 printf "%s\n" "$i" >> "$initdir"/lib/dracut/modules.txt
1946 done
1947
1948 dinfo "*** Including modules done ***"
1949
1950 ## final stuff that has to happen
1951 if [[ $no_kernel != yes ]]; then
1952 if [[ $hostonly_mode == "strict" ]]; then
1953 cp "$DRACUT_KERNEL_MODALIASES" "$initdir"/lib/dracut/hostonly-kernel-modules.txt
1954 fi
1955
1956 if [[ $drivers ]]; then
1957 # shellcheck disable=SC2086
1958 hostonly='' instmods $drivers
1959 fi
1960
1961 if [[ -n ${add_drivers// /} ]]; then
1962 # shellcheck disable=SC2086
1963 hostonly='' instmods -c $add_drivers
1964 fi
1965 if [[ $force_drivers ]]; then
1966 # shellcheck disable=SC2086
1967 hostonly='' instmods -c $force_drivers
1968 rm -f "$initdir"/etc/cmdline.d/20-force_driver.conf
1969 for mod in $force_drivers; do
1970 echo "rd.driver.pre=$mod" >> "$initdir"/etc/cmdline.d/20-force_drivers.conf
1971 done
1972 fi
1973 if [[ $filesystems ]]; then
1974 # shellcheck disable=SC2086
1975 hostonly='' instmods -c $filesystems
1976 fi
1977
1978 dinfo "*** Installing kernel module dependencies ***"
1979 dracut_kernel_post
1980 dinfo "*** Installing kernel module dependencies done ***"
1981
1982 if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
1983 if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] \
1984 && [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
1985 for i in "${initdir}"/etc/cmdline.d/*.conf; do
1986 # We need no initramfs image and do not generate one.
1987 [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
1988 done
1989 fi
1990 fi
1991 fi
1992
1993 if [[ $kernel_only != yes ]]; then
1994 # FIXME: handle legacy item split
1995 # shellcheck disable=SC2068
1996 ((${#install_items[@]} > 0)) && inst_multiple ${install_items[@]}
1997 # shellcheck disable=SC2068
1998 ((${#install_optional_items[@]} > 0)) && inst_multiple -o ${install_optional_items[@]}
1999
2000 if [[ $kernel_cmdline ]] && [[ $uefi != yes ]]; then
2001 printf "%s\n" "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
2002 fi
2003
2004 for line in "${fstab_lines[@]}"; do
2005 read -r -a fstab_field <<< "$line"
2006 if [ -z "${fstab_field[1]}" ]; then
2007 # Determine device and mount options from current system
2008 mountpoint -q "${fstab_field[0]}" || derror "${fstab_field[0]} is not a mount point!"
2009 read -r -a fstab_field < <(findmnt --raw -n --target "${fstab_field[0]}" --output=source,target,fstype,options)
2010 dinfo "Line for ${fstab_field[1]}: ${fstab_field[*]}"
2011 else
2012 # Use default options
2013 [ -z "${fstab_field[3]}" ] && fstab_field[3]="defaults"
2014 fi
2015
2016 # Default options for freq and passno
2017 [ -z "${fstab_field[4]}" ] && fstab_field[4]="0"
2018 [ -z "${fstab_field[5]}" ] && fstab_field[5]="2"
2019
2020 strstr "${fstab_field[2]}" "nfs" && fstab_field[5]="0"
2021 echo "${fstab_field[@]}" >> "${initdir}/etc/fstab"
2022 done
2023
2024 for f in $add_fstab; do
2025 cat "$f" >> "${initdir}/etc/fstab"
2026 done
2027
2028 if [[ $dracutsysrootdir$systemdutildir ]]; then
2029 if [[ -d ${initdir}/$systemdutildir ]]; then
2030 mkdir -p "${initdir}"/etc/conf.d
2031 {
2032 printf "%s\n" "systemdutildir=\"$systemdutildir\""
2033 printf "%s\n" "systemdsystemunitdir=\"$systemdsystemunitdir\""
2034 printf "%s\n" "systemdsystemconfdir=\"$systemdsystemconfdir\""
2035 } > "${initdir}"/etc/conf.d/systemd.conf
2036 fi
2037 fi
2038
2039 if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
2040 dinfo "*** Resolving executable dependencies ***"
2041 # shellcheck disable=SC2086
2042 find "$initdir" -type f -perm /0111 -not -path '*.ko' -print0 \
2043 | xargs -r -0 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R ${DRACUT_FIPS_MODE:+-f} --
2044 # shellcheck disable=SC2181
2045 if (($? == 0)); then
2046 dinfo "*** Resolving executable dependencies done ***"
2047 else
2048 dfatal "Resolving executable dependencies failed"
2049 exit 1
2050 fi
2051 fi
2052
2053 # Now we are done with lazy resolving, always install dependencies
2054 unset DRACUT_RESOLVE_LAZY
2055 export DRACUT_RESOLVE_DEPS=1
2056 fi
2057
2058 for ((i = 0; i < ${#include_src[@]}; i++)); do
2059 src="${include_src[$i]}"
2060 target="${include_target[$i]}"
2061 if [[ $src && $target ]]; then
2062 if [[ -f $src ]]; then
2063 inst "$src" "$target"
2064 elif [[ -d $src ]]; then
2065 ddebug "Including directory: $src"
2066 destdir="${initdir}/${target}"
2067 mkdir -p "$destdir"
2068 # check for preexisting symlinks, so we can cope with the
2069 # symlinks to $prefix
2070 # Objectname is a file or a directory
2071 reset_dotglob="$(shopt -p dotglob)"
2072 shopt -q -s dotglob
2073 for objectname in "$src"/*; do
2074 [[ -e $objectname || -L $objectname ]] || continue
2075 if [[ -d $objectname ]] && [[ ! -L $objectname ]]; then
2076 # objectname is a directory, let's compute the final directory name
2077 object_destdir=${destdir}/${objectname#"$src"/}
2078 if ! [[ -e $object_destdir ]]; then
2079 # shellcheck disable=SC2174
2080 mkdir -m 0755 -p "$object_destdir"
2081 chmod --reference="$objectname" "$object_destdir"
2082 fi
2083 $DRACUT_CP -t "$object_destdir" "$dracutsysrootdir$objectname"/.
2084 else
2085 $DRACUT_CP -t "$destdir" "$dracutsysrootdir$objectname"
2086 fi
2087 done
2088 eval "$reset_dotglob"
2089 elif [[ -e $src ]]; then
2090 derror "$src is neither a directory nor a regular file"
2091 else
2092 derror "$src doesn't exist"
2093 fi
2094 fi
2095 done
2096
2097 if [[ $do_hardlink == yes ]] && command -v hardlink > /dev/null; then
2098 dinfo "*** Hardlinking files ***"
2099 hardlink "$initdir" 2>&1 | ddebug
2100 dinfo "*** Hardlinking files done ***"
2101 fi
2102
2103 # strip binaries
2104 if [[ $do_strip == yes ]]; then
2105 # Prefer strip from elfutils for package size
2106 declare strip_cmd
2107 strip_cmd=$(command -v eu-strip)
2108 [ -z "$strip_cmd" ] && strip_cmd="strip"
2109
2110 for p in $strip_cmd xargs find; do
2111 if ! type -P $p > /dev/null; then
2112 dinfo "Could not find '$p'. Not stripping the initramfs."
2113 do_strip=no
2114 fi
2115 done
2116
2117 if [[ $aggressive_strip == yes ]]; then
2118 # `eu-strip` and `strip` both strips all unneeded parts by default
2119 strip_args=(-p)
2120 else
2121 strip_args=(-g -p)
2122 fi
2123 fi
2124
2125 # cleanup empty ldconfig_paths directories
2126 for d in $(ldconfig_paths); do
2127 rmdir -p --ignore-fail-on-non-empty "$initdir/$d" > /dev/null 2>&1
2128 done
2129
2130 if [[ $early_microcode == yes ]]; then
2131 dinfo "*** Generating early-microcode cpio image ***"
2132 ucode_dir=(amd-ucode intel-ucode)
2133 ucode_dest=(AuthenticAMD.bin GenuineIntel.bin)
2134 _dest_dir="$early_cpio_dir/d/kernel/x86/microcode"
2135 _dest_idx="0 1"
2136 mkdir -p "$_dest_dir"
2137 if [[ $hostonly ]]; then
2138 [[ $(get_cpu_vendor) == "AMD" ]] && _dest_idx="0"
2139 [[ $(get_cpu_vendor) == "Intel" ]] && _dest_idx="1"
2140 fi
2141 for idx in $_dest_idx; do
2142 _fw=${ucode_dir[$idx]}
2143 for _fwdir in $fw_dir; do
2144 if [[ -d $_fwdir && -d $_fwdir/$_fw ]]; then
2145 _src="*"
2146 dinfo "*** Constructing ${ucode_dest[$idx]} ***"
2147 if [[ $hostonly ]]; then
2148 _src=$(get_ucode_file)
2149 [[ $_src ]] || break
2150 [[ -r $_fwdir/$_fw/$_src ]] || _src="${_src}.early"
2151 [[ -r $_fwdir/$_fw/$_src ]] || break
2152 fi
2153
2154 for i in $_fwdir/$_fw/$_src; do
2155 [ -e "$i" ] && break
2156 break 2
2157 done
2158 for i in $_fwdir/$_fw/$_src; do
2159 [[ -e $i ]] || continue
2160 # skip gpg files
2161 str_ends "$i" ".asc" && continue
2162 cat "$i" >> "$_dest_dir/${ucode_dest[$idx]}"
2163 done
2164 create_early_cpio="yes"
2165 fi
2166 done
2167 if [[ ! -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
2168 if cd "$early_cpio_dir/d"; then
2169 for _ucodedir in "${early_microcode_image_dir[@]}"; do
2170 for _ucodename in "${early_microcode_image_name[@]}"; do
2171 [[ -e "$_ucodedir/$_ucodename" ]] \
2172 && cpio --extract --file "$_ucodedir/$_ucodename" --quiet \
2173 "kernel/x86/microcode/${ucode_dest[$idx]}"
2174 if [[ -e "$_dest_dir/${ucode_dest[$idx]}" ]]; then
2175 dinfo "*** Using microcode found in '$_ucodedir/$_ucodename' ***"
2176 create_early_cpio="yes"
2177 break 2
2178 fi
2179 done
2180 done
2181 fi
2182 fi
2183 done
2184 fi
2185
2186 if [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; then
2187 dinfo "*** Packaging ACPI tables to override BIOS provided ones ***"
2188 _dest_dir="$early_cpio_dir/d/kernel/firmware/acpi"
2189 mkdir -p "$_dest_dir"
2190 for table in "$acpi_table_dir"/*.aml; do
2191 dinfo " Adding ACPI table: $table"
2192 $DRACUT_CP "$table" "$_dest_dir"
2193 create_early_cpio="yes"
2194 done
2195 fi
2196
2197 dinfo "*** Store current command line parameters ***"
2198 if ! (echo "$PARMS_TO_STORE" > "$initdir"/lib/dracut/build-parameter.txt); then
2199 dfatal "Could not store the current command line parameters"
2200 exit 1
2201 fi
2202
2203 if [[ $hostonly_cmdline == "yes" ]]; then
2204 unset _stored_cmdline
2205 if [[ -d $initdir/etc/cmdline.d ]]; then
2206 dinfo "Stored kernel commandline:"
2207 for conf in "$initdir"/etc/cmdline.d/*.conf; do
2208 [ -e "$conf" ] || continue
2209 dinfo "$(< "$conf")"
2210 _stored_cmdline=1
2211 done
2212 fi
2213 if ! [[ $_stored_cmdline ]]; then
2214 dinfo "No dracut internal kernel commandline stored in the initramfs"
2215 fi
2216 fi
2217
2218 if [[ $kernel_only != yes ]]; then
2219 # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so
2220 for _dir in $libdirs; do
2221 for _f in "$dracutsysrootdir$_dir/libpthread.so"*; do
2222 [[ -e $_f ]] || continue
2223 inst_libdir_file "libgcc_s.so*"
2224 break 2
2225 done
2226 done
2227
2228 # FIPS workaround for Fedora/RHEL: libcrypto needs libssl when FIPS is enabled
2229 if [[ $DRACUT_FIPS_MODE ]]; then
2230 for _dir in $libdirs; do
2231 for _f in "$dracutsysrootdir$_dir/libcrypto.so"*; do
2232 [[ -e $_f ]] || continue
2233 inst_libdir_file -o "libssl.so*"
2234 break 2
2235 done
2236 done
2237 fi
2238 fi
2239
2240 if [[ $kernel_only != yes ]]; then
2241 # make sure that library links are correct and up to date
2242 build_ld_cache
2243 fi
2244
2245 if dracut_module_included "squash"; then
2246 readonly squash_dir="$initdir/squash/root"
2247 readonly squash_img="$initdir/squash-root.img"
2248 mkdir -p "$squash_dir"
2249 dinfo "*** Install squash loader ***"
2250 DRACUT_SQUASH_POST_INST=1 module_install "squash"
2251 fi
2252
2253 if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
2254 # stripping files negates (dedup) benefits of using reflink
2255 [[ -n $enhanced_cpio ]] && ddebug "strip is enabled alongside cpio reflink"
2256 dinfo "*** Stripping files ***"
2257 find "$initdir" -type f \
2258 -executable -not -path '*/lib/modules/*.ko' -print0 \
2259 | xargs -r -0 $strip_cmd "${strip_args[@]}" 2> /dev/null
2260
2261 # strip kernel modules, but do not touch signed modules
2262 find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
2263 | while read -r -d $'\0' f || [ -n "$f" ]; do
2264 SIG=$(tail -c 28 "$f" | tr -d '\000')
2265 [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
2266 done | xargs -r -0 $strip_cmd "${strip_args[@]}"
2267 dinfo "*** Stripping files done ***"
2268 fi
2269
2270 if dracut_module_included "squash"; then
2271 dinfo "*** Squashing the files inside the initramfs ***"
2272 declare squash_compress_arg
2273 # shellcheck disable=SC2086
2274 if [[ $squash_compress ]]; then
2275 if ! mksquashfs /dev/null "$DRACUT_TMPDIR"/.squash-test.img -no-progress -comp $squash_compress &> /dev/null; then
2276 dwarn "mksquashfs doesn't support compressor '$squash_compress', failing back to default compressor."
2277 else
2278 squash_compress_arg="$squash_compress"
2279 fi
2280 fi
2281
2282 # shellcheck disable=SC2086
2283 if ! mksquashfs "$squash_dir" "$squash_img" \
2284 -no-xattrs -no-exports -noappend -no-recovery -always-use-fragments \
2285 -no-progress ${squash_compress_arg:+-comp $squash_compress_arg} 1> /dev/null; then
2286 dfatal "Failed making squash image"
2287 exit 1
2288 fi
2289
2290 rm -rf "$squash_dir"
2291 dinfo "*** Squashing the files inside the initramfs done ***"
2292
2293 # Skip initramfs compress
2294 compress="cat"
2295 fi
2296
2297 dinfo "*** Creating image file '$outfile' ***"
2298
2299 if [[ $uefi == yes ]]; then
2300 readonly uefi_outdir="$DRACUT_TMPDIR/uefi"
2301 mkdir -p "$uefi_outdir"
2302 fi
2303
2304 if [[ $DRACUT_REPRODUCIBLE ]]; then
2305 find "$initdir" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
2306 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
2307
2308 if [[ "$(cpio --help)" == *--reproducible* ]]; then
2309 CPIO_REPRODUCIBLE=1
2310 else
2311 dinfo "cpio does not support '--reproducible'. Resulting image will not be reproducible."
2312 fi
2313 fi
2314
2315 [[ $EUID != 0 ]] && cpio_owner="0:0"
2316
2317 if [[ $create_early_cpio == yes ]]; then
2318 echo 1 > "$early_cpio_dir/d/early_cpio"
2319
2320 if [[ $DRACUT_REPRODUCIBLE ]]; then
2321 find "$early_cpio_dir/d" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
2322 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
2323 fi
2324
2325 # The microcode blob is _before_ the initramfs blob, not after
2326 if [[ -n $enhanced_cpio ]]; then
2327 if ! (
2328 umask 077
2329 cd "$early_cpio_dir/d"
2330 find . -print0 | sort -z \
2331 | $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2332 --mtime 0 --data-align "$cpio_align" --truncate-existing \
2333 "${DRACUT_TMPDIR}/initramfs.img"
2334 ); then
2335 dfatal "dracut-cpio: creation of $outfile failed"
2336 exit 1
2337 fi
2338 else
2339 if ! (
2340 umask 077
2341 cd "$early_cpio_dir/d"
2342 find . -print0 | sort -z \
2343 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
2344 ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
2345 ); then
2346 dfatal "Creation of $outfile failed"
2347 exit 1
2348 fi
2349 fi
2350 fi
2351
2352 if check_kernel_config CONFIG_RD_ZSTD; then
2353 DRACUT_KERNEL_RD_ZSTD=yes
2354 else
2355 DRACUT_KERNEL_RD_ZSTD=
2356 fi
2357
2358 if [[ $compress == $DRACUT_COMPRESS_ZSTD* && ! $DRACUT_KERNEL_RD_ZSTD ]]; then
2359 dwarn "Kernel has no zstd support compiled in."
2360 compress=
2361 fi
2362
2363 if [[ $compress && $compress != cat ]]; then
2364 if ! command -v "${compress%% *}" &> /dev/null; then
2365 derror "Cannot execute compression command '$compress', falling back to default"
2366 compress=
2367 fi
2368 fi
2369
2370 if ! [[ $compress ]]; then
2371 # check all known compressors, if none specified
2372 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
2373 [[ $i != "$DRACUT_COMPRESS_ZSTD" || $DRACUT_KERNEL_RD_ZSTD ]] || continue
2374 command -v "$i" &> /dev/null || continue
2375 compress="$i"
2376 break
2377 done
2378 if [[ $compress == cat ]]; then
2379 dwarn "No compression tool available. Initramfs image is going to be big."
2380 else
2381 dinfo "Using auto-determined compression method '$compress'"
2382 fi
2383 fi
2384
2385 # choose the right arguments for the compressor
2386 case $compress in
2387 bzip2 | lbzip2)
2388 if [[ $compress == lbzip2 ]] || command -v "$DRACUT_COMPRESS_LBZIP2" &> /dev/null; then
2389 compress="$DRACUT_COMPRESS_LBZIP2 -9"
2390 else
2391 compress="$DRACUT_COMPRESS_BZIP2 -9"
2392 fi
2393 ;;
2394 lzma)
2395 compress="$DRACUT_COMPRESS_LZMA -9 -T0"
2396 ;;
2397 xz)
2398 compress="$DRACUT_COMPRESS_XZ --check=crc32 --lzma2=dict=1MiB -T0"
2399 ;;
2400 gzip | pigz)
2401 if [[ $compress == pigz ]] || command -v "$DRACUT_COMPRESS_PIGZ" &> /dev/null; then
2402 compress="$DRACUT_COMPRESS_PIGZ -9 -n -T -R"
2403 elif command -v gzip &> /dev/null && $DRACUT_COMPRESS_GZIP --help 2>&1 | grep -q rsyncable; then
2404 compress="$DRACUT_COMPRESS_GZIP -n -9 --rsyncable"
2405 else
2406 compress="$DRACUT_COMPRESS_GZIP -n -9"
2407 fi
2408 ;;
2409 lzo | lzop)
2410 compress="$DRACUT_COMPRESS_LZOP -9"
2411 ;;
2412 lz4)
2413 compress="$DRACUT_COMPRESS_LZ4 -l -9"
2414 ;;
2415 zstd)
2416 compress="$DRACUT_COMPRESS_ZSTD -15 -q -T0"
2417 ;;
2418 esac
2419
2420 if [[ -n $enhanced_cpio ]]; then
2421 if [[ $compress == "cat" ]]; then
2422 # dracut-cpio appends by default, so any ucode remains
2423 cpio_outfile="${DRACUT_TMPDIR}/initramfs.img"
2424 else
2425 ddebug "$compress compression enabled alongside cpio reflink"
2426 # dracut-cpio doesn't output to stdout, so stage for compression
2427 cpio_outfile="${DRACUT_TMPDIR}/initramfs.img.uncompressed"
2428 fi
2429
2430 if ! (
2431 umask 077
2432 cd "$initdir"
2433 find . -print0 | sort -z \
2434 | $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2435 --mtime 0 --data-align "$cpio_align" "$cpio_outfile" || exit 1
2436 [[ $compress == "cat" ]] && exit 0
2437 $compress < "$cpio_outfile" >> "${DRACUT_TMPDIR}/initramfs.img" \
2438 && rm "$cpio_outfile"
2439 ); then
2440 dfatal "dracut-cpio: creation of $outfile failed"
2441 exit 1
2442 fi
2443 unset cpio_outfile
2444 else
2445 if ! (
2446 umask 077
2447 cd "$initdir"
2448 find . -print0 | sort -z \
2449 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2450 | $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2451 ); then
2452 dfatal "Creation of $outfile failed"
2453 exit 1
2454 fi
2455 fi
2456
2457 if ((maxloglvl >= 5)) && ((verbosity_mod_l >= 0)); then
2458 if [[ $allowlocal ]]; then
2459 "$dracutbasedir/lsinitrd.sh" "${DRACUT_TMPDIR}/initramfs.img" | ddebug
2460 else
2461 lsinitrd "${DRACUT_TMPDIR}/initramfs.img" | ddebug
2462 fi
2463 fi
2464
2465 umask 077
2466
2467 SBAT_DEFAULT="sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md"
2468 sbat_out=$uefi_outdir/uki.sbat
2469
2470 clean_sbat_string() {
2471 local inp=$1
2472 local temp=$uefi_outdir/temp.sbat
2473 sed "/${SBAT_DEFAULT//\//\\/}/d" "$inp" > "$temp"
2474 [[ -s $temp ]] && cat "$temp" >> "$sbat_out"
2475 rm "$temp"
2476 }
2477
2478 get_sbat_string() {
2479 local inp=$1
2480 local out=$uefi_outdir/$2
2481 objcopy -O binary --only-section=.sbat "$inp" "$out"
2482 clean_sbat_string "$out"
2483 }
2484
2485 if [[ $uefi == yes ]]; then
2486 if [[ $kernel_cmdline ]]; then
2487 echo -n "$kernel_cmdline" > "$uefi_outdir/cmdline.txt"
2488 elif [[ $hostonly_cmdline == yes ]]; then
2489 if [ -d "$initdir/etc/cmdline.d" ]; then
2490 for conf in "$initdir"/etc/cmdline.d/*.conf; do
2491 [ -e "$conf" ] || continue
2492 printf "%s " "$(< "$conf")" >> "$uefi_outdir/cmdline.txt"
2493 done
2494 elif [ -e "/proc/cmdline" ]; then
2495 printf "%s " "$(< "/proc/cmdline")" > "$uefi_outdir/cmdline.txt"
2496 fi
2497 fi
2498
2499 offs=$(objdump -h "$uefi_stub" 2> /dev/null | gawk 'NF==7 {size=strtonum("0x"$3);
2500 offset=strtonum("0x"$4)} END {print size + offset}')
2501 if [[ $offs -eq 0 ]]; then
2502 dfatal "Failed to get the size of $uefi_stub to create UEFI image file"
2503 exit 1
2504 fi
2505 align=$(pe_get_section_align "$uefi_stub")
2506 if [[ $? -eq 1 ]]; then
2507 dfatal "Failed to get the SectionAlignment of the stub PE header to create the UEFI image file"
2508 exit 1
2509 fi
2510 offs=$((offs + "$align" - offs % "$align"))
2511 [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
2512 [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
2513 [[ -s $uefi_osrelease ]] \
2514 && uefi_osrelease_offs=${offs} \
2515 && offs=$((offs + $(stat -Lc%s "$uefi_osrelease"))) \
2516 && offs=$((offs + "$align" - offs % "$align"))
2517
2518 if [[ $kernel_cmdline ]] || [[ $hostonly_cmdline == yes && -e "${uefi_outdir}/cmdline.txt" ]]; then
2519 echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
2520 dinfo "Using UEFI kernel cmdline:"
2521 dinfo "$(tr -d '\000' < "$uefi_outdir/cmdline.txt")"
2522 uefi_cmdline="${uefi_outdir}/cmdline.txt"
2523 uefi_cmdline_offs=${offs}
2524 offs=$((offs + $(stat -Lc%s "$uefi_cmdline")))
2525 offs=$((offs + "$align" - offs % "$align"))
2526 else
2527 unset uefi_cmdline
2528 fi
2529
2530 if [[ -s ${dracutsysrootdir}${uefi_splash_image} ]]; then
2531 uefi_splash_image="${dracutsysrootdir}${uefi_splash_image}"
2532 uefi_splash_offs=${offs}
2533 offs=$((offs + $(stat -Lc%s "$uefi_splash_image")))
2534 offs=$((offs + "$align" - offs % "$align"))
2535 else
2536 unset uefi_splash_image
2537 fi
2538
2539 echo "$SBAT_DEFAULT" > "$sbat_out"
2540 if [[ -n $sbat ]]; then
2541 echo "$sbat" | sed "/${SBAT_DEFAULT//\//\\/}/d" >> "$sbat_out"
2542 fi
2543 get_sbat_string "$kernel_image" kernel.sbat
2544 get_sbat_string "$uefi_stub" stub.sbat
2545
2546 uefi_sbat_offs="${offs}"
2547 offs=$((offs + $(stat -Lc%s "$sbat_out")))
2548 offs=$((offs + "$align" - offs % "$align"))
2549 uefi_linux_offs="${offs}"
2550 offs=$((offs + $(stat -Lc%s "$kernel_image")))
2551 offs=$((offs + "$align" - offs % "$align"))
2552 uefi_initrd_offs="${offs}"
2553
2554 base_image=$(pe_get_image_base "$uefi_stub")
2555 if [[ $? -eq 1 ]]; then
2556 dfatal "Failed to get ImageBase data of $uefi_stub to create UEFI image file"
2557 exit 1
2558 fi
2559
2560 tmp_uefi_stub=$uefi_outdir/elf.stub
2561 cp "$uefi_stub" "$tmp_uefi_stub"
2562 objcopy --remove-section .sbat "$tmp_uefi_stub" &> /dev/null
2563
2564 if objcopy \
2565 ${uefi_osrelease:+--add-section .osrel="$uefi_osrelease" --change-section-vma .osrel=$(printf 0x%x "$uefi_osrelease_offs")} \
2566 ${uefi_cmdline:+--add-section .cmdline="$uefi_cmdline" --change-section-vma .cmdline=$(printf 0x%x "$uefi_cmdline_offs")} \
2567 ${uefi_splash_image:+--add-section .splash="$uefi_splash_image" --change-section-vma .splash=$(printf 0x%x "$uefi_splash_offs")} \
2568 --add-section .sbat="$sbat_out" --change-section-vma .sbat="$(printf 0x%x "$uefi_sbat_offs")" \
2569 --add-section .linux="$kernel_image" --change-section-vma .linux="$(printf 0x%x "$uefi_linux_offs")" \
2570 --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd="$(printf 0x%x "$uefi_initrd_offs")" \
2571 --image-base="$(printf 0x%x "$base_image")" \
2572 "$tmp_uefi_stub" "${uefi_outdir}/linux.efi"; then
2573 if [[ -n ${uefi_secureboot_key} && -n ${uefi_secureboot_cert} ]]; then
2574 if sbsign \
2575 ${uefi_secureboot_engine:+--engine "$uefi_secureboot_engine"} \
2576 --key "${uefi_secureboot_key}" \
2577 --cert "${uefi_secureboot_cert}" \
2578 --output "$outfile" "${uefi_outdir}/linux.efi" \
2579 && sbverify --cert "${uefi_secureboot_cert}" "$outfile" > /dev/null 2>&1; then
2580 dinfo "*** Creating signed UEFI image file '$outfile' done ***"
2581 else
2582 rm -f -- "$outfile"
2583 dfatal "*** Creating signed UEFI image file '$outfile' failed ***"
2584 exit 1
2585 fi
2586 else
2587 if cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
2588 dinfo "*** Creating UEFI image file '$outfile' done ***"
2589 else
2590 rm -f -- "$outfile"
2591 dfatal "Creation of $outfile failed"
2592 exit 1
2593 fi
2594 fi
2595 else
2596 rm -f -- "$outfile"
2597 dfatal "*** Creating UEFI image file '$outfile' failed ***"
2598 exit 1
2599 fi
2600 else
2601 if cp --reflink=auto "${DRACUT_TMPDIR}/initramfs.img" "$outfile"; then
2602 dinfo "*** Creating initramfs image file '$outfile' done ***"
2603 else
2604 rm -f -- "$outfile"
2605 dfatal "Creation of $outfile failed"
2606 exit 1
2607 fi
2608 fi
2609
2610 btrfs_uuid() {
2611 btrfs filesystem show "$1" | sed -n '1s/^.*uuid: //p'
2612 }
2613
2614 freeze_ok_for_btrfs() {
2615 local mnt uuid1 uuid2
2616 # If the output file is on btrfs, we need to make sure that it's
2617 # not on a subvolume of the same file system as the root FS.
2618 # Otherwise, fsfreeze() might freeze the entire system.
2619 # This is most conveniently checked by comparing the FS uuid.
2620
2621 [[ "$(stat -f -c %T -- "/")" == "btrfs" ]] || return 0
2622 mnt=$(stat -c %m -- "$1")
2623 uuid1=$(btrfs_uuid "$mnt")
2624 uuid2=$(btrfs_uuid "/")
2625 [[ $uuid1 && $uuid2 && $uuid1 != "$uuid2" ]]
2626 }
2627
2628 freeze_ok_for_fstype() {
2629 local outfile=$1
2630 local fstype
2631
2632 [[ "$(stat -c %m -- "$outfile")" == "/" ]] && return 1
2633 fstype=$(stat -f -c %T -- "$outfile")
2634 case $fstype in
2635 msdos)
2636 return 1
2637 ;;
2638 zfs)
2639 return 1
2640 ;;
2641 tmpfs)
2642 return 1
2643 ;;
2644 btrfs)
2645 freeze_ok_for_btrfs "$outfile"
2646 ;;
2647 *)
2648 return 0
2649 ;;
2650 esac
2651 }
2652
2653 # We sync/fsfreeze only if we're operating on a live booted system.
2654 # It's possible for e.g. `kernel` to be installed as an RPM BuildRequires or equivalent,
2655 # and there's no reason to sync, and *definitely* no reason to fsfreeze.
2656 # Another case where this happens is rpm-ostree, which performs its own sync/fsfreeze
2657 # globally. See e.g. https://github.com/ostreedev/ostree/commit/8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0
2658 if [[ -d $dracutsysrootdir/run/systemd/system ]]; then
2659 if ! sync "$outfile" 2> /dev/null; then
2660 dinfo "sync operation on newly created initramfs $outfile failed"
2661 exit 1
2662 fi
2663
2664 # use fsfreeze only if we're not writing to /
2665 if [[ "$(stat -c %m -- "$outfile")" != "/" ]] && freeze_ok_for_fstype "$outfile"; then
2666 FSFROZEN="$(dirname "$outfile")"
2667 if ! (fsfreeze -f "${FSFROZEN}" 2> /dev/null && fsfreeze -u "${FSFROZEN}" 2> /dev/null); then
2668 dwarn "Could not fsfreeze $(dirname "$outfile")"
2669 fi
2670 unset FSFROZEN
2671 fi
2672 fi
2673
2674 exit 0