]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
iscsi: always popd, even if there is no iscsi device
[thirdparty/dracut.git] / dracut.sh
1 #!/bin/bash -p
2 #
3 # Generator script for a dracut initramfs
4 # Tries to retain some degree of compatibility with the command line
5 # of the various mkinitrd implementations out there
6 #
7
8 # Copyright 2005-2013 Red Hat, Inc. All rights reserved.
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #
23
24 # store for logging
25
26 unset BASH_ENV
27
28 # Verify bash version, current minimum is 4
29 if (( BASH_VERSINFO[0] < 4 )); then
30 printf -- 'You need at least Bash 4 to use dracut, sorry.' >&2
31 exit 1
32 fi
33
34 dracut_args=( "$@" )
35 readonly dracut_cmd="$(readlink -f $0)"
36
37 set -o pipefail
38
39 usage() {
40 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
41 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
42 . $dracutbasedir/dracut-version.sh
43 fi
44
45 # 80x25 linebreak here ^
46 cat << EOF
47 Usage: $dracut_cmd [OPTION]... [<initramfs> [<kernel-version>]]
48
49 Version: $DRACUT_VERSION
50
51 Creates initial ramdisk images for preloading modules
52
53 -h, --help Display all options
54
55 If a [LIST] has multiple arguments, then you have to put these in quotes.
56
57 For example:
58
59 # dracut --add-drivers "module1 module2" ...
60
61 EOF
62 }
63
64 long_usage() {
65 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
66 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
67 . $dracutbasedir/dracut-version.sh
68 fi
69
70 # 80x25 linebreak here ^
71 cat << EOF
72 Usage: $dracut_cmd [OPTION]... [<initramfs> [<kernel-version>]]
73
74 Version: $DRACUT_VERSION
75
76 Creates initial ramdisk images for preloading modules
77
78 --kver [VERSION] Set kernel version to [VERSION].
79 -f, --force Overwrite existing initramfs file.
80 -a, --add [LIST] Add a space-separated list of dracut modules.
81 --rebuild Append arguments to those of existing image and rebuild
82 -m, --modules [LIST] Specify a space-separated list of dracut modules to
83 call when building the initramfs. Modules are located
84 in /usr/lib/dracut/modules.d.
85 -o, --omit [LIST] Omit a space-separated list of dracut modules.
86 --force-add [LIST] Force to add a space-separated list of dracut modules
87 to the default set of modules, when -H is specified.
88 -d, --drivers [LIST] Specify a space-separated list of kernel modules to
89 exclusively include in the initramfs.
90 --add-drivers [LIST] Specify a space-separated list of kernel
91 modules to add to the initramfs.
92 --force-drivers [LIST] Specify a space-separated list of kernel
93 modules to add to the initramfs and make sure they
94 are tried to be loaded via modprobe same as passing
95 rd.driver.pre=DRIVER kernel parameter.
96 --omit-drivers [LIST] Specify a space-separated list of kernel
97 modules not to add to the initramfs.
98 --filesystems [LIST] Specify a space-separated list of kernel filesystem
99 modules to exclusively include in the generic
100 initramfs.
101 -k, --kmoddir [DIR] Specify the directory, where to look for kernel
102 modules
103 --fwdir [DIR] Specify additional directories, where to look for
104 firmwares, separated by :
105 --kernel-only Only install kernel drivers and firmware files
106 --no-kernel Do not install kernel drivers and firmware files
107 --print-cmdline Print the kernel command line for the given disk layout
108 --early-microcode Combine early microcode with ramdisk
109 --no-early-microcode Do not combine early microcode with ramdisk
110 --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
111 --strip Strip binaries in the initramfs
112 --nostrip Do not strip binaries in the initramfs
113 --hardlink Hardlink files in the initramfs
114 --nohardlink Do not hardlink files in the initramfs
115 --prefix [DIR] Prefix initramfs files with [DIR]
116 --noprefix Do not prefix initramfs files
117 --mdadmconf Include local /etc/mdadm.conf
118 --nomdadmconf Do not include local /etc/mdadm.conf
119 --lvmconf Include local /etc/lvm/lvm.conf
120 --nolvmconf Do not include local /etc/lvm/lvm.conf
121 --fscks [LIST] Add a space-separated list of fsck helpers.
122 --nofscks Inhibit installation of any fsck helpers.
123 --ro-mnt Mount / and /usr read-only by default.
124 -h, --help This message
125 --debug Output debug information of the build process
126 --profile Output profile information of the build process
127 -L, --stdlog [0-6] Specify logging level (to standard error)
128 0 - suppress any messages
129 1 - only fatal errors
130 2 - all errors
131 3 - warnings
132 4 - info
133 5 - debug info (here starts lots of output)
134 6 - trace info (and even more)
135 -v, --verbose Increase verbosity level
136 -q, --quiet Decrease verbosity level
137 -c, --conf [FILE] Specify configuration file to use.
138 Default: /etc/dracut.conf
139 --confdir [DIR] Specify configuration directory to use *.conf files
140 from. Default: /etc/dracut.conf.d
141 --tmpdir [DIR] Temporary directory to be used instead of default
142 /var/tmp.
143 -l, --local Local mode. Use modules from the current working
144 directory instead of the system-wide installed in
145 /usr/lib/dracut/modules.d.
146 Useful when running dracut from a git checkout.
147 -H, --hostonly Host-Only mode: Install only what is needed for
148 booting the local host instead of a generic host.
149 -N, --no-hostonly Disables Host-Only mode
150 --hostonly-mode <mode>
151 Specify the hostonly mode to use. <mode> could be
152 one of "sloppy" or "strict". "sloppy" mode is used
153 by default.
154 In "sloppy" hostonly mode, extra drivers and modules
155 will be installed, so minor hardware change won't make
156 the image unbootable (eg. changed keyboard), and the
157 image is still portable among similar hosts.
158 With "strict" mode enabled, anything not necessary
159 for booting the local host in its current state will
160 not be included, and modules may do some extra job
161 to save more space. Minor change of hardware or
162 environment could make the image unbootable.
163 DO NOT use "strict" mode unless you know what you
164 are doing.
165 --hostonly-cmdline Store kernel command line arguments needed
166 in the initramfs
167 --no-hostonly-cmdline Do not store kernel command line arguments needed
168 in the initramfs
169 --no-hostonly-default-device
170 Do not generate implicit host devices like root,
171 swap, fstab, etc. Use "--mount" or "--add-device"
172 to explicitly add devices as needed.
173 --hostonly-i18n Install only needed keyboard and font files according
174 to the host configuration (default).
175 --no-hostonly-i18n Install all keyboard and font files available.
176 --persistent-policy [POLICY]
177 Use [POLICY] to address disks and partitions.
178 POLICY can be any directory name found in /dev/disk.
179 E.g. "by-uuid", "by-label"
180 --fstab Use /etc/fstab to determine the root device.
181 --add-fstab [FILE] Add file to the initramfs fstab
182 --mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
183 Mount device [DEV] on mountpoint [MP] with filesystem
184 [FSTYPE] and options [FSOPTS] in the initramfs
185 --mount "[MP]" Same as above, but [DEV], [FSTYPE] and [FSOPTS] are
186 determined by looking at the current mounts.
187 --add-device "[DEV]" Bring up [DEV] in initramfs
188 -i, --include [SOURCE] [TARGET]
189 Include the files in the SOURCE directory into the
190 Target directory in the final initramfs.
191 If SOURCE is a file, it will be installed to TARGET
192 in the final initramfs.
193 -I, --install [LIST] Install the space separated list of files into the
194 initramfs.
195 --install-optional [LIST] Install the space separated list of files into the
196 initramfs, if they exist.
197 --gzip Compress the generated initramfs using gzip.
198 This will be done by default, unless another
199 compression option or --no-compress is passed.
200 --bzip2 Compress the generated initramfs using bzip2.
201 Make sure your kernel has bzip2 decompression support
202 compiled in, otherwise you will not be able to boot.
203 --lzma Compress the generated initramfs using lzma.
204 Make sure your kernel has lzma support compiled in,
205 otherwise you will not be able to boot.
206 --xz Compress the generated initramfs using xz.
207 Make sure that your kernel has xz support compiled
208 in, otherwise you will not be able to boot.
209 --lzo Compress the generated initramfs using lzop.
210 Make sure that your kernel has lzo support compiled
211 in, otherwise you will not be able to boot.
212 --lz4 Compress the generated initramfs using lz4.
213 Make sure that your kernel has lz4 support compiled
214 in, otherwise you will not be able to boot.
215 --zstd Compress the generated initramfs using Zstandard.
216 Make sure that your kernel has zstd support compiled
217 in, otherwise you will not be able to boot.
218 --compress [COMPRESSION] Compress the generated initramfs with the
219 passed compression program. Make sure your kernel
220 knows how to decompress the generated initramfs,
221 otherwise you will not be able to boot.
222 --no-compress Do not compress the generated initramfs. This will
223 override any other compression options.
224 --list-modules List all available dracut modules.
225 -M, --show-modules Print included module's name to standard output during
226 build.
227 --keep Keep the temporary initramfs for debugging purposes
228 --printsize Print out the module install size
229 --sshkey [SSHKEY] Add ssh key to initramfs (use with ssh-client module)
230 --logfile [FILE] Logfile to use (overrides configuration setting)
231 --reproducible Create reproducible images
232 --no-reproducible Do not create reproducible images
233 --loginstall [DIR] Log all files installed from the host to [DIR]
234 --uefi Create an UEFI executable with the kernel cmdline and
235 kernel combined
236 --uefi-stub [FILE] Use the UEFI stub [FILE] to create an UEFI executable
237 --kernel-image [FILE] location of the kernel image
238
239 If [LIST] has multiple arguments, then you have to put these in quotes.
240
241 For example:
242
243 # dracut --add-drivers "module1 module2" ...
244
245 EOF
246 }
247
248 # Fills up host_devs stack variable and makes sure there are no duplicates
249 push_host_devs() {
250 local _dev
251 for _dev in "$@"; do
252 [[ " ${host_devs[@]} " == *" $_dev "* ]] && return
253 host_devs+=( "$_dev" )
254 done
255 }
256
257 # Little helper function for reading args from the commandline.
258 # it automatically handles -a b and -a=b variants, and returns 1 if
259 # we need to shift $3.
260 read_arg() {
261 # $1 = arg name
262 # $2 = arg value
263 # $3 = arg parameter
264 local rematch='^[^=]*=(.*)$'
265 if [[ $2 =~ $rematch ]]; then
266 read "$1" <<< "${BASH_REMATCH[1]}"
267 else
268 read "$1" <<< "$3"
269 # There is no way to shift our callers args, so
270 # return 1 to indicate they should do it instead.
271 return 1
272 fi
273 }
274
275 dropindirs_sort()
276 {
277 local suffix=$1; shift
278 local -a files
279 local f d
280
281 for d in "$@"; do
282 for i in "$d/"*"$suffix"; do
283 if [[ -e "$i" ]]; then
284 printf "%s\n" "${i##*/}"
285 fi
286 done
287 done | sort -Vu | {
288 readarray -t files
289
290 for f in "${files[@]}"; do
291 for d in "$@"; do
292 if [[ -e "$d/$f" ]]; then
293 printf "%s\n" "$d/$f"
294 continue 2
295 fi
296 done
297 done
298 }
299 }
300
301 rearrange_params()
302 {
303 # Workaround -i, --include taking 2 arguments
304 newat=()
305 for i in "$@"; do
306 if [[ $i == "-i" ]] || [[ $i == "--include" ]]; then
307 newat+=("++include") # Replace --include by ++include
308 else
309 newat+=("$i")
310 fi
311 done
312 set -- "${newat[@]}" # Set new $@
313
314 TEMP=$(unset POSIXLY_CORRECT; getopt \
315 -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
316 --long kver: \
317 --long add: \
318 --long force-add: \
319 --long add-drivers: \
320 --long force-drivers: \
321 --long omit-drivers: \
322 --long modules: \
323 --long omit: \
324 --long drivers: \
325 --long filesystems: \
326 --long install: \
327 --long install-optional: \
328 --long fwdir: \
329 --long libdirs: \
330 --long fscks: \
331 --long add-fstab: \
332 --long mount: \
333 --long device: \
334 --long add-device: \
335 --long nofscks \
336 --long ro-mnt \
337 --long kmoddir: \
338 --long conf: \
339 --long confdir: \
340 --long tmpdir: \
341 --long stdlog: \
342 --long compress: \
343 --long prefix: \
344 --long rebuild: \
345 --long force \
346 --long kernel-only \
347 --long no-kernel \
348 --long print-cmdline \
349 --long kernel-cmdline: \
350 --long strip \
351 --long nostrip \
352 --long hardlink \
353 --long nohardlink \
354 --long noprefix \
355 --long mdadmconf \
356 --long nomdadmconf \
357 --long lvmconf \
358 --long nolvmconf \
359 --long debug \
360 --long profile \
361 --long sshkey: \
362 --long logfile: \
363 --long verbose \
364 --long quiet \
365 --long local \
366 --long hostonly \
367 --long host-only \
368 --long no-hostonly \
369 --long no-host-only \
370 --long hostonly-mode: \
371 --long hostonly-cmdline \
372 --long no-hostonly-cmdline \
373 --long no-hostonly-default-device \
374 --long persistent-policy: \
375 --long fstab \
376 --long help \
377 --long bzip2 \
378 --long lzma \
379 --long xz \
380 --long lzo \
381 --long lz4 \
382 --long zstd \
383 --long no-compress \
384 --long gzip \
385 --long list-modules \
386 --long show-modules \
387 --long keep \
388 --long printsize \
389 --long regenerate-all \
390 --long noimageifnotneeded \
391 --long early-microcode \
392 --long no-early-microcode \
393 --long reproducible \
394 --long no-reproducible \
395 --long loginstall: \
396 --long uefi \
397 --long uefi-stub: \
398 --long kernel-image: \
399 --long no-hostonly-i18n \
400 --long hostonly-i18n \
401 --long no-machineid \
402 -- "$@")
403
404 if (( $? != 0 )); then
405 usage
406 exit 1
407 fi
408 }
409
410 verbosity_mod_l=0
411 unset kernel
412 unset outfile
413
414 rearrange_params "$@"
415 eval set -- "$TEMP"
416
417 # parse command line args to check if '--rebuild' option is present
418 unset append_args_l
419 unset rebuild_file
420 while :
421 do
422 if [ "$1" == "--" ]; then
423 shift; break
424 fi
425 if [ "$1" == "--rebuild" ]; then
426 append_args_l="yes"
427 rebuild_file=$2
428 if [ ! -e $rebuild_file ]; then
429 echo "Image file '$rebuild_file', for rebuild, does not exist!"
430 exit 1
431 fi
432 abs_rebuild_file=$(readlink -f "$rebuild_file") && rebuild_file="$abs_rebuild_file"
433 shift; continue
434 fi
435 shift
436 done
437
438 # get output file name and kernel version from command line arguments
439 while (($# > 0)); do
440 case ${1%%=*} in
441 ++include)
442 shift 2;;
443 *)
444 if ! [[ ${outfile+x} ]]; then
445 outfile=$1
446 elif ! [[ ${kernel+x} ]]; then
447 kernel=$1
448 else
449 printf "\nUnknown arguments: %s\n\n" "$*" >&2
450 usage; exit 1;
451 fi
452 ;;
453 esac
454 shift
455 done
456
457 # extract input image file provided with rebuild option to get previous parameters, if any
458 if [[ $append_args_l == "yes" ]]; then
459 unset rebuild_param
460
461 # determine resultant file
462 if ! [[ $outfile ]]; then
463 outfile=$rebuild_file
464 fi
465
466 if ! rebuild_param=$(lsinitrd $rebuild_file '*lib/dracut/build-parameter.txt'); then
467 echo "Image '$rebuild_file' has no rebuild information stored"
468 exit 1
469 fi
470
471 # prepend previous parameters to current command line args
472 if [[ $rebuild_param ]]; then
473 TEMP="$rebuild_param $TEMP"
474 eval set -- "$TEMP"
475 rearrange_params "$@"
476 fi
477 fi
478
479 unset PARMS_TO_STORE
480 PARMS_TO_STORE=""
481
482 eval set -- "$TEMP"
483
484 while :; do
485 if [ $1 != "--" ] && [ $1 != "--rebuild" ]; then
486 PARMS_TO_STORE+=" $1";
487 fi
488 case $1 in
489 --kver) kernel="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
490 -a|--add) add_dracutmodules_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
491 --force-add) force_add_dracutmodules_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
492 --add-drivers) add_drivers_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
493 --force-drivers) force_drivers_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
494 --omit-drivers) omit_drivers_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
495 -m|--modules) dracutmodules_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
496 -o|--omit) omit_dracutmodules_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
497 -d|--drivers) drivers_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
498 --filesystems) filesystems_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
499 -I|--install) install_items_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
500 --install-optional) install_optional_items_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
501 --fwdir) fw_dir_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
502 --libdirs) libdirs_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
503 --fscks) fscks_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
504 --add-fstab) add_fstab_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
505 --mount) fstab_lines+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
506 --add-device|--device) add_device_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
507 --kernel-cmdline) kernel_cmdline_l+=("$2"); PARMS_TO_STORE+=" '$2'"; shift;;
508 --nofscks) nofscks_l="yes";;
509 --ro-mnt) ro_mnt_l="yes";;
510 -k|--kmoddir) drivers_dir_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
511 -c|--conf) conffile="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
512 --confdir) confdir="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
513 --tmpdir) tmpdir_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
514 -L|--stdlog) stdloglvl_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
515 --compress) compress_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
516 --prefix) prefix_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
517 --loginstall) loginstall_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
518 --rebuild) if [ $rebuild_file == $outfile ]; then
519 force=yes
520 fi
521 shift
522 ;;
523 -f|--force) force=yes;;
524 --kernel-only) kernel_only="yes"; no_kernel="no";;
525 --no-kernel) kernel_only="no"; no_kernel="yes";;
526 --print-cmdline)
527 print_cmdline="yes"; hostonly_l="yes"; kernel_only="yes"; no_kernel="yes";;
528 --early-microcode)
529 early_microcode_l="yes";;
530 --no-early-microcode)
531 early_microcode_l="no";;
532 --strip) do_strip_l="yes";;
533 --nostrip) do_strip_l="no";;
534 --hardlink) do_hardlink_l="yes";;
535 --nohardlink) do_hardlink_l="no";;
536 --noprefix) prefix_l="/";;
537 --mdadmconf) mdadmconf_l="yes";;
538 --nomdadmconf) mdadmconf_l="no";;
539 --lvmconf) lvmconf_l="yes";;
540 --nolvmconf) lvmconf_l="no";;
541 --debug) debug="yes";;
542 --profile) profile="yes";;
543 --sshkey) sshkey="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
544 --logfile) logfile_l="$2"; shift;;
545 -v|--verbose) ((verbosity_mod_l++));;
546 -q|--quiet) ((verbosity_mod_l--));;
547 -l|--local)
548 allowlocal="yes"
549 [[ -f "$(readlink -f "${0%/*}")/dracut-init.sh" ]] \
550 && dracutbasedir="$(readlink -f "${0%/*}")"
551 ;;
552 -H|--hostonly|--host-only)
553 hostonly_l="yes" ;;
554 -N|--no-hostonly|--no-host-only)
555 hostonly_l="no" ;;
556 --hostonly-mode)
557 hostonly_mode_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
558 --hostonly-cmdline)
559 hostonly_cmdline_l="yes" ;;
560 --hostonly-i18n)
561 i18n_install_all_l="no" ;;
562 --no-hostonly-i18n)
563 i18n_install_all_l="yes" ;;
564 --no-hostonly-cmdline)
565 hostonly_cmdline_l="no" ;;
566 --no-hostonly-default-device)
567 hostonly_default_device="no" ;;
568 --persistent-policy)
569 persistent_policy_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
570 --fstab) use_fstab_l="yes" ;;
571 -h|--help) long_usage; exit 1 ;;
572 -i|--include) include_src+=("$2"); PARMS_TO_STORE+=" '$2'";
573 shift;;
574 --bzip2) compress_l="bzip2";;
575 --lzma) compress_l="lzma";;
576 --xz) compress_l="xz";;
577 --lzo) compress_l="lzo";;
578 --lz4) compress_l="lz4";;
579 --zstd) compress_l="zstd";;
580 --no-compress) _no_compress_l="cat";;
581 --gzip) compress_l="gzip";;
582 --list-modules) do_list="yes";;
583 -M|--show-modules)
584 show_modules_l="yes"
585 ;;
586 --keep) keep="yes";;
587 --printsize) printsize="yes";;
588 --regenerate-all) regenerate_all="yes";;
589 --noimageifnotneeded) noimageifnotneeded="yes";;
590 --reproducible) reproducible_l="yes";;
591 --no-reproducible) reproducible_l="no";;
592 --uefi) uefi="yes";;
593 --uefi-stub)
594 uefi_stub_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
595 --kernel-image)
596 kernel_image_l="$2"; PARMS_TO_STORE+=" '$2'"; shift;;
597 --no-machineid)
598 machine_id_l="no";;
599 --) shift; break;;
600
601 *) # should not even reach this point
602 printf "\n!Unknown option: '%s'\n\n" "$1" >&2; usage; exit 1;;
603 esac
604 shift
605 done
606
607 # getopt cannot handle multiple arguments, so just handle "-I,--include"
608 # the old fashioned way
609
610 while (($# > 0)); do
611 if [ "${1%%=*}" == "++include" ]; then
612 include_src+=("$2")
613 include_target+=("$3")
614 PARMS_TO_STORE+=" --include '$2' '$3'"
615 shift 2
616 fi
617 shift
618 done
619
620 if [[ $regenerate_all == "yes" ]]; then
621 ret=0
622 if [[ $kernel ]]; then
623 printf -- "--regenerate-all cannot be called with a kernel version\n" >&2
624 exit 1
625 fi
626
627 if [[ $outfile ]]; then
628 printf -- "--regenerate-all cannot be called with a image file\n" >&2
629 exit 1
630 fi
631
632 ((len=${#dracut_args[@]}))
633 for ((i=0; i < len; i++)); do
634 [[ ${dracut_args[$i]} == "--regenerate-all" ]] && \
635 unset dracut_args[$i]
636 done
637
638 cd /lib/modules
639 for i in *; do
640 [[ -f $i/modules.dep ]] || [[ -f $i/modules.dep.bin ]] || continue
641 "$dracut_cmd" --kver="$i" "${dracut_args[@]}"
642 ((ret+=$?))
643 done
644 exit $ret
645 fi
646
647 if ! [[ $kernel ]]; then
648 kernel=$(uname -r)
649 fi
650
651 export LC_ALL=C
652 export LANG=C
653 unset LC_MESSAGES
654 unset LC_CTYPE
655 unset LD_LIBRARY_PATH
656 unset LD_PRELOAD
657 unset GREP_OPTIONS
658
659 export DRACUT_LOG_LEVEL=warning
660 [[ $debug ]] && {
661 export DRACUT_LOG_LEVEL=debug
662 export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
663 set -x
664 }
665
666 [[ $profile ]] && {
667 export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
668 set -x
669 debug=yes
670 }
671
672 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
673
674 # if we were not passed a config file, try the default one
675 if [[ ! -f $conffile ]]; then
676 if [[ $allowlocal ]]; then
677 conffile="$dracutbasedir/dracut.conf"
678 else
679 conffile="/etc/dracut.conf"
680 fi
681 fi
682
683 if [[ ! -d $confdir ]]; then
684 if [[ $allowlocal ]]; then
685 confdir="$dracutbasedir/dracut.conf.d"
686 else
687 confdir="/etc/dracut.conf.d"
688 fi
689 fi
690
691 # source our config file
692 [[ -f $conffile ]] && . "$conffile"
693
694 # source our config dir
695 for f in $(dropindirs_sort ".conf" "$confdir" "$dracutbasedir/dracut.conf.d"); do
696 [[ -e $f ]] && . "$f"
697 done
698
699 DRACUT_PATH=${DRACUT_PATH:-/sbin /bin /usr/sbin /usr/bin}
700
701 for i in $DRACUT_PATH; do
702 rl=$i
703 if [ -L "$i" ]; then
704 rl=$(readlink -f $i)
705 fi
706 if [[ "$NPATH" != *:$rl* ]] ; then
707 NPATH+=":$rl"
708 fi
709 done
710 export PATH="${NPATH#:}"
711 unset NPATH
712
713 # these options add to the stuff in the config file
714 (( ${#add_dracutmodules_l[@]} )) && add_dracutmodules+=" ${add_dracutmodules_l[@]} "
715 (( ${#force_add_dracutmodules_l[@]} )) && force_add_dracutmodules+=" ${force_add_dracutmodules_l[@]} "
716 (( ${#fscks_l[@]} )) && fscks+=" ${fscks_l[@]} "
717 (( ${#add_fstab_l[@]} )) && add_fstab+=" ${add_fstab_l[@]} "
718 (( ${#fstab_lines_l[@]} )) && fstab_lines+=( "${fstab_lines_l[@]}" )
719 (( ${#install_items_l[@]} )) && install_items+=" ${install_items_l[@]} "
720 (( ${#install_optional_items_l[@]} )) && install_optional_items+=" ${install_optional_items_l[@]} "
721
722 # these options override the stuff in the config file
723 (( ${#dracutmodules_l[@]} )) && dracutmodules="${dracutmodules_l[@]}"
724 (( ${#omit_dracutmodules_l[@]} )) && omit_dracutmodules="${omit_dracutmodules_l[@]}"
725 (( ${#filesystems_l[@]} )) && filesystems="${filesystems_l[@]}"
726 (( ${#fw_dir_l[@]} )) && fw_dir="${fw_dir_l[@]}"
727 (( ${#libdirs_l[@]} ))&& libdirs="${libdirs_l[@]}"
728
729 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
730 [[ ! $stdloglvl ]] && stdloglvl=4
731 stdloglvl=$((stdloglvl + verbosity_mod_l))
732 ((stdloglvl > 6)) && stdloglvl=6
733 ((stdloglvl < 0)) && stdloglvl=0
734
735 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
736 [[ $do_strip_l ]] && do_strip=$do_strip_l
737 [[ $do_strip ]] || do_strip=yes
738 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
739 [[ $do_hardlink ]] || do_hardlink=yes
740 [[ $prefix_l ]] && prefix=$prefix_l
741 [[ $prefix = "/" ]] && unset prefix
742 [[ $hostonly_l ]] && hostonly=$hostonly_l
743 [[ $hostonly_cmdline_l ]] && hostonly_cmdline=$hostonly_cmdline_l
744 [[ $hostonly_mode_l ]] && hostonly_mode=$hostonly_mode_l
745 [[ "$hostonly" == "yes" ]] && ! [[ $hostonly_cmdline ]] && hostonly_cmdline="yes"
746 [[ $i18n_install_all_l ]] && i18n_install_all=$i18n_install_all_l
747 [[ $persistent_policy_l ]] && persistent_policy=$persistent_policy_l
748 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
749 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
750 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
751 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
752 [[ $fw_dir ]] || fw_dir="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
753 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
754 [[ $tmpdir ]] || tmpdir=/var/tmp
755 [[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
756 [[ $compress_l ]] && compress=$compress_l
757 [[ $show_modules_l ]] && show_modules=$show_modules_l
758 [[ $nofscks_l ]] && nofscks="yes"
759 [[ $ro_mnt_l ]] && ro_mnt="yes"
760 [[ $early_microcode_l ]] && early_microcode=$early_microcode_l
761 [[ $early_microcode ]] || early_microcode=yes
762 [[ $logfile_l ]] && logfile="$logfile_l"
763 [[ $reproducible_l ]] && reproducible="$reproducible_l"
764 [[ $loginstall_l ]] && loginstall="$loginstall_l"
765 [[ $uefi_stub_l ]] && uefi_stub="$uefi_stub_l"
766 [[ $kernel_image_l ]] && kernel_image="$kernel_image_l"
767 [[ $machine_id_l ]] && machine_id="$machine_id_l"
768
769 if ! [[ $outfile ]]; then
770 if [[ $machine_id != "no" ]]; then
771 [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id
772 fi
773
774 if [[ $uefi == "yes" ]]; then
775 BUILD_ID=$(cat /etc/os-release /usr/lib/os-release \
776 | while read -r line || [[ $line ]]; do \
777 [[ $line =~ BUILD_ID\=* ]] && eval "$line" && echo "$BUILD_ID" && break; \
778 done)
779 if [[ -d /efi ]] && mountpoint -q /efi; then
780 efidir=/efi
781 else
782 efidir=/boot/EFI
783 if [[ -d /boot/efi/EFI ]] && mountpoint -q /boot/efi; then
784 efidir=/boot/efi/EFI
785 fi
786 fi
787 mkdir -p "$efidir/Linux"
788 outfile="$efidir/Linux/linux-$kernel${MACHINE_ID:+-${MACHINE_ID}}${BUILD_ID:+-${BUILD_ID}}.efi"
789 else
790 if [[ -e "/boot/vmlinuz-$kernel" ]]; then
791 outfile="/boot/initramfs-$kernel.img"
792 elif [[ $MACHINE_ID ]] && ( [[ -d /boot/${MACHINE_ID} ]] || [[ -L /boot/${MACHINE_ID} ]] ); then
793 outfile="/boot/${MACHINE_ID}/$kernel/initrd"
794 else
795 outfile="/boot/initramfs-$kernel.img"
796 fi
797 fi
798 fi
799
800 # eliminate IFS hackery when messing with fw_dir
801 export DRACUT_FIRMWARE_PATH=${fw_dir// /:}
802 fw_dir=${fw_dir//:/ }
803
804 # check for logfile and try to create one if it doesn't exist
805 if [[ -n "$logfile" ]];then
806 if [[ ! -f "$logfile" ]];then
807 touch "$logfile"
808 if [ ! $? -eq 0 ] ;then
809 printf "%s\n" "dracut: touch $logfile failed." >&2
810 fi
811 fi
812 fi
813
814 # handle compression options.
815 if [[ $_no_compress_l = "cat" ]]; then
816 compress="cat"
817 fi
818
819 if ! [[ $compress ]]; then
820 # check all known compressors, if none specified
821 for i in pigz gzip lz4 lzop zstd lzma xz lbzip2 bzip2 cat; do
822 command -v "$i" &>/dev/null || continue
823 compress="$i"
824 break
825 done
826 if [[ $compress = cat ]]; then
827 printf "%s\n" "dracut: no compression tool available. Initramfs image is going to be big." >&2
828 fi
829 fi
830
831 # choose the right arguments for the compressor
832 case $compress in
833 bzip2|lbzip2)
834 if [[ "$compress" = lbzip2 ]] || command -v lbzip2 &>/dev/null; then
835 compress="lbzip2 -9"
836 else
837 compress="bzip2 -9"
838 fi
839 ;;
840 lzma)
841 compress="lzma -9 -T0"
842 ;;
843 xz)
844 compress="xz --check=crc32 --lzma2=dict=1MiB -T0"
845 ;;
846 gzip|pigz)
847 if [[ "$compress" = pigz ]] || command -v pigz &>/dev/null; then
848 compress="pigz -9 -n -T -R"
849 elif command -v gzip &>/dev/null && gzip --help 2>&1 | grep -q rsyncable; then
850 compress="gzip -n -9 --rsyncable"
851 else
852 compress="gzip -n -9"
853 fi
854 ;;
855 lzo|lzop)
856 compress="lzop -9"
857 ;;
858 lz4)
859 compress="lz4 -l -9"
860 ;;
861 zstd)
862 compress="zstd -15 -q -T0"
863 ;;
864 esac
865
866 [[ $hostonly = yes ]] && hostonly="-h"
867 [[ $hostonly != "-h" ]] && unset hostonly
868
869 case $hostonly_mode in
870 '')
871 [[ $hostonly ]] && hostonly_mode="sloppy" ;;
872 sloppy|strict)
873 if [[ ! $hostonly ]]; then
874 unset hostonly_mode
875 fi
876 ;;
877 *)
878 printf "%s\n" "dracut: Invalid hostonly mode '$hostonly_mode'." >&2
879 exit 1
880 esac
881
882 [[ $reproducible == yes ]] && DRACUT_REPRODUCIBLE=1
883
884 readonly TMPDIR="$(realpath -e "$tmpdir")"
885 [ -d "$TMPDIR" ] || {
886 printf "%s\n" "dracut: Invalid tmpdir '$tmpdir'." >&2
887 exit 1
888 }
889 readonly DRACUT_TMPDIR="$(mktemp -p "$TMPDIR/" -d -t dracut.XXXXXX)"
890 [ -d "$DRACUT_TMPDIR" ] || {
891 printf "%s\n" "dracut: mktemp -p '$TMPDIR/' -d -t dracut.XXXXXX failed." >&2
892 exit 1
893 }
894
895 # clean up after ourselves no matter how we die.
896 trap '
897 ret=$?;
898 [[ $keep ]] && echo "Not removing $DRACUT_TMPDIR." >&2 || { [[ $DRACUT_TMPDIR ]] && rm -rf -- "$DRACUT_TMPDIR"; };
899 exit $ret;
900 ' EXIT
901
902 # clean up after ourselves no matter how we die.
903 trap 'exit 1;' SIGINT
904
905 readonly initdir="${DRACUT_TMPDIR}/initramfs"
906 mkdir "$initdir"
907
908 if [[ $early_microcode = yes ]] || ( [[ $acpi_override = yes ]] && [[ -d $acpi_table_dir ]] ); then
909 readonly early_cpio_dir="${DRACUT_TMPDIR}/earlycpio"
910 mkdir "$early_cpio_dir"
911 fi
912
913 export DRACUT_RESOLVE_LAZY="1"
914
915 if [[ $print_cmdline ]]; then
916 stdloglvl=0
917 sysloglvl=0
918 fileloglvl=0
919 kmsgloglvl=0
920 fi
921
922 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
923 . $dracutbasedir/dracut-version.sh
924 fi
925
926 if [[ -f $dracutbasedir/dracut-init.sh ]]; then
927 . $dracutbasedir/dracut-init.sh
928 else
929 printf "%s\n" "dracut: Cannot find $dracutbasedir/dracut-init.sh." >&2
930 printf "%s\n" "dracut: Are you running from a git checkout?" >&2
931 printf "%s\n" "dracut: Try passing -l as an argument to $dracut_cmd" >&2
932 exit 1
933 fi
934
935 if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
936 printf "%s\n" "dracut: Cannot find module directory $srcmods" >&2
937 printf "%s\n" "dracut: and --no-kernel was not specified" >&2
938 exit 1
939 fi
940
941 if ! [[ $print_cmdline ]]; then
942 inst /bin/sh
943 if ! $DRACUT_INSTALL ${initdir:+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
944 unset DRACUT_RESOLVE_LAZY
945 export DRACUT_RESOLVE_DEPS=1
946 fi
947 rm -fr -- ${initdir}/*
948 fi
949
950 dracutfunctions=$dracutbasedir/dracut-functions.sh
951 export dracutfunctions
952
953 (( ${#drivers_l[@]} )) && drivers="${drivers_l[@]}"
954 drivers=${drivers/-/_}
955
956 (( ${#add_drivers_l[@]} )) && add_drivers+=" ${add_drivers_l[@]} "
957 add_drivers=${add_drivers/-/_}
958
959 (( ${#force_drivers_l[@]} )) && force_drivers+=" ${force_drivers_l[@]} "
960 force_drivers=${force_drivers/-/_}
961
962 (( ${#omit_drivers_l[@]} )) && omit_drivers+=" ${omit_drivers_l[@]} "
963 omit_drivers=${omit_drivers/-/_}
964
965 (( ${#kernel_cmdline_l[@]} )) && kernel_cmdline+=" ${kernel_cmdline_l[@]} "
966
967 omit_drivers_corrected=""
968 for d in $omit_drivers; do
969 [[ " $drivers $add_drivers " == *\ $d\ * ]] && continue
970 [[ " $drivers $force_drivers " == *\ $d\ * ]] && continue
971 omit_drivers_corrected+="$d|"
972 done
973 omit_drivers="${omit_drivers_corrected%|}"
974 unset omit_drivers_corrected
975
976 # prepare args for logging
977 for ((i=0; i < ${#dracut_args[@]}; i++)); do
978 [[ "${dracut_args[$i]}" == *\ * ]] && \
979 dracut_args[$i]="\"${dracut_args[$i]}\""
980 #" keep vim happy
981 done
982
983 dinfo "Executing: $dracut_cmd ${dracut_args[@]}"
984
985 [[ $do_list = yes ]] && {
986 for mod in $dracutbasedir/modules.d/*; do
987 [[ -d $mod ]] || continue;
988 [[ -e $mod/install || -e $mod/installkernel || \
989 -e $mod/module-setup.sh ]] || continue
990 printf "%s\n" "${mod##*/??}"
991 done
992 exit 0
993 }
994
995 # This is kinda legacy -- eventually it should go away.
996 case $dracutmodules in
997 ""|auto) dracutmodules="all" ;;
998 esac
999
1000 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
1001
1002 if [[ $no_kernel != yes ]] && [[ -d $srcmods ]]; then
1003 if ! [[ -f $srcmods/modules.dep ]]; then
1004 if [[ -n "$(find "$srcmods" -name '*.ko*')" ]]; then
1005 dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
1006 exit 1
1007 else
1008 dwarn "$srcmods/modules.dep is missing. Did you run depmod?"
1009 fi
1010 elif ! ( command -v gzip &>/dev/null && command -v xz &>/dev/null); then
1011 read _mod < $srcmods/modules.dep
1012 _mod=${_mod%%:*}
1013 if [[ -f $srcmods/"$_mod" ]]; then
1014 # Check, if kernel modules are compressed, and if we can uncompress them
1015 case "$_mod" in
1016 *.ko.gz) kcompress=gzip;;
1017 *.ko.xz) kcompress=xz;;
1018 esac
1019 if [[ $kcompress ]]; then
1020 if ! command -v "$kcompress" &>/dev/null; then
1021 dfatal "Kernel modules are compressed with $kcompress, but $kcompress is not available."
1022 exit 1
1023 fi
1024 fi
1025 fi
1026 fi
1027 fi
1028
1029 if [[ ! $print_cmdline ]]; then
1030 if [[ -f $outfile && ! $force ]]; then
1031 dfatal "Will not override existing initramfs ($outfile) without --force"
1032 exit 1
1033 fi
1034
1035 outdir=${outfile%/*}
1036 [[ $outdir ]] || outdir="/"
1037
1038 if [[ ! -d "$outdir" ]]; then
1039 dfatal "Can't write to $outdir: Directory $outdir does not exist or is not accessible."
1040 exit 1
1041 elif [[ ! -w "$outdir" ]]; then
1042 dfatal "No permission to write to $outdir."
1043 exit 1
1044 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
1045 dfatal "No permission to write $outfile."
1046 exit 1
1047 fi
1048
1049 if [[ $loginstall ]]; then
1050 if ! mkdir -p "$loginstall"; then
1051 dfatal "Could not create directory to log installed files to '$loginstall'."
1052 exit 1
1053 fi
1054 loginstall=$(readlink -f "$loginstall")
1055 fi
1056
1057 if [[ $uefi = yes ]]; then
1058 if ! command -v objcopy &>/dev/null; then
1059 dfatal "Need 'objcopy' to create a UEFI executable"
1060 exit 1
1061 fi
1062 unset EFI_MACHINE_TYPE_NAME
1063 case $(arch) in
1064 x86_64)
1065 EFI_MACHINE_TYPE_NAME=x64;;
1066 ia32)
1067 EFI_MACHINE_TYPE_NAME=ia32;;
1068 *)
1069 dfatal "Architecture '$(arch)' not supported to create a UEFI executable"
1070 exit 1
1071 ;;
1072 esac
1073
1074 if ! [[ -s $uefi_stub ]]; then
1075 for uefi_stub in \
1076 "${systemdutildir}/boot/efi/linux${EFI_MACHINE_TYPE_NAME}.efi.stub" \
1077 "/usr/lib/gummiboot/linux${EFI_MACHINE_TYPE_NAME}.efi.stub"; do
1078 [[ -s $uefi_stub ]] || continue
1079 break
1080 done
1081 fi
1082 if ! [[ -s $uefi_stub ]]; then
1083 dfatal "Can't find a uefi stub '$uefi_stub' to create a UEFI executable"
1084 exit 1
1085 fi
1086
1087 if ! [[ $kernel_image ]]; then
1088 for kernel_image in "/lib/modules/$kernel/vmlinuz" "/boot/vmlinuz-$kernel"; do
1089 [[ -s "$kernel_image" ]] || continue
1090 break
1091 done
1092 fi
1093 if ! [[ -s $kernel_image ]]; then
1094 dfatal "Can't find a kernel image '$kernel_image' to create a UEFI executable"
1095 exit 1
1096 fi
1097 fi
1098 fi
1099
1100 if [[ $acpi_override = yes ]] && ! ( check_kernel_config CONFIG_ACPI_TABLE_UPGRADE || check_kernel_config CONFIG_ACPI_INITRD_TABLE_OVERRIDE ); then
1101 dwarn "Disabling ACPI override, because kernel does not support it. CONFIG_ACPI_INITRD_TABLE_OVERRIDE!=y or CONFIG_ACPI_TABLE_UPGRADE!=y"
1102 unset acpi_override
1103 fi
1104
1105 if [[ $early_microcode = yes ]]; then
1106 if [[ $hostonly ]]; then
1107 [[ $(get_cpu_vendor) == "AMD" ]] \
1108 && ! check_kernel_config CONFIG_MICROCODE_AMD \
1109 && unset early_microcode
1110 [[ $(get_cpu_vendor) == "Intel" ]] \
1111 && ! check_kernel_config CONFIG_MICROCODE_INTEL \
1112 && unset early_microcode
1113 else
1114 ! check_kernel_config CONFIG_MICROCODE_AMD \
1115 && ! check_kernel_config CONFIG_MICROCODE_INTEL \
1116 && unset early_microcode
1117 fi
1118 [[ $early_microcode != yes ]] \
1119 && dwarn "Disabling early microcode, because kernel does not support it. CONFIG_MICROCODE_[AMD|INTEL]!=y"
1120 fi
1121
1122 # Need to be able to have non-root users read stuff (rpcbind etc)
1123 chmod 755 "$initdir"
1124
1125 if [[ $hostonly ]]; then
1126 for i in /sys /proc /run /dev; do
1127 if ! findmnt --target "$i" &>/dev/null; then
1128 dwarning "Turning off host-only mode: '$i' is not mounted!"
1129 unset hostonly
1130 fi
1131 done
1132 fi
1133
1134 declare -A host_fs_types
1135
1136 for line in "${fstab_lines[@]}"; do
1137 set -- $line
1138 dev="$1"
1139 #dev mp fs fsopts
1140 case "$dev" in
1141 UUID=*)
1142 dev=$(blkid -l -t UUID=${dev#UUID=} -o device)
1143 ;;
1144 LABEL=*)
1145 dev=$(blkid -l -t LABEL=${dev#LABEL=} -o device)
1146 ;;
1147 PARTUUID=*)
1148 dev=$(blkid -l -t PARTUUID=${dev#PARTUUID=} -o device)
1149 ;;
1150 PARTLABEL=*)
1151 dev=$(blkid -l -t PARTLABEL=${dev#PARTLABEL=} -o device)
1152 ;;
1153 esac
1154 [ -z "$dev" ] && dwarn "Bad fstab entry $@" && continue
1155 if [[ "$3" == btrfs ]]; then
1156 for i in $(btrfs_devs "$2"); do
1157 push_host_devs "$i"
1158 done
1159 fi
1160 push_host_devs "$dev"
1161 host_fs_types["$dev"]="$3"
1162 done
1163
1164 for f in $add_fstab; do
1165 [[ -e $f ]] || continue
1166 while read dev rest || [ -n "$dev" ]; do
1167 push_host_devs "$dev"
1168 done < "$f"
1169 done
1170
1171 for dev in $add_device; do
1172 push_host_devs "$dev"
1173 done
1174
1175 if (( ${#add_device_l[@]} )); then
1176 add_device+=" ${add_device_l[@]} "
1177 push_host_devs "${add_device_l[@]}"
1178 fi
1179
1180 if [[ $hostonly ]] && [[ "$hostonly_default_device" != "no" ]]; then
1181 # in hostonly mode, determine all devices, which have to be accessed
1182 # and examine them for filesystem types
1183
1184 for mp in \
1185 "/" \
1186 "/etc" \
1187 "/bin" \
1188 "/sbin" \
1189 "/lib" \
1190 "/lib64" \
1191 "/usr" \
1192 "/usr/bin" \
1193 "/usr/sbin" \
1194 "/usr/lib" \
1195 "/usr/lib64" \
1196 "/boot" \
1197 "/boot/efi" \
1198 "/boot/zipl" \
1199 ;
1200 do
1201 mp=$(readlink -f "$mp")
1202 mountpoint "$mp" >/dev/null 2>&1 || continue
1203 _dev=$(find_block_device "$mp")
1204 _bdev=$(readlink -f "/dev/block/$_dev")
1205 [[ -b $_bdev ]] && _dev=$_bdev
1206 [[ "$mp" == "/" ]] && root_devs+=("$_dev")
1207 push_host_devs "$_dev"
1208 if [[ $(find_mp_fstype "$mp") == btrfs ]]; then
1209 for i in $(btrfs_devs "$mp"); do
1210 [[ "$mp" == "/" ]] && root_devs+=("$i")
1211 push_host_devs "$i"
1212 done
1213 fi
1214 done
1215
1216 if [[ -f /proc/swaps ]] && [[ -f /etc/fstab ]]; then
1217 while read dev type rest || [ -n "$dev" ]; do
1218 [[ -b $dev ]] || continue
1219 [[ "$type" == "partition" ]] || continue
1220
1221 while read _d _m _t _o _r || [ -n "$_d" ]; do
1222 [[ "$_d" == \#* ]] && continue
1223 [[ $_d ]] || continue
1224 [[ $_t != "swap" ]] && continue
1225 [[ $_m != "swap" ]] && [[ $_m != "none" ]] && continue
1226 [[ "$_o" == *noauto* ]] && continue
1227 _d=$(expand_persistent_dev "$_d")
1228 [[ "$_d" -ef "$dev" ]] || continue
1229
1230 if [[ -f /etc/crypttab ]]; then
1231 while read _mapper _a _p _o || [ -n "$_mapper" ]; do
1232 [[ $_mapper = \#* ]] && continue
1233 [[ "$_d" -ef /dev/mapper/"$_mapper" ]] || continue
1234 [[ "$_o" ]] || _o="$_p"
1235 # skip entries with password files
1236 [[ "$_p" == /* ]] && [[ -f $_p ]] && continue 2
1237 # skip mkswap swap
1238 [[ $_o == *swap* ]] && continue 2
1239 done < /etc/crypttab
1240 fi
1241
1242 _dev="$(readlink -f "$dev")"
1243 push_host_devs "$_dev"
1244 swap_devs+=("$_dev")
1245 break
1246 done < /etc/fstab
1247 done < /proc/swaps
1248 fi
1249
1250 # collect all "x-initrd.mount" entries from /etc/fstab
1251 if [[ -f /etc/fstab ]]; then
1252 while read _d _m _t _o _r || [ -n "$_d" ]; do
1253 [[ "$_d" == \#* ]] && continue
1254 [[ $_d ]] || continue
1255 [[ "$_o" != *x-initrd.mount* ]] && continue
1256 _dev=$(expand_persistent_dev "$_d")
1257 _dev="$(readlink -f "$_dev")"
1258 [[ -b $_dev ]] || continue
1259
1260 push_host_devs "$_dev"
1261 if [[ "$_t" == btrfs ]]; then
1262 for i in $(btrfs_devs "$_m"); do
1263 push_host_devs "$i"
1264 done
1265 fi
1266 done < /etc/fstab
1267 fi
1268 fi
1269
1270 unset m
1271 unset rest
1272
1273 _get_fs_type() {
1274 [[ $1 ]] || return
1275 if [[ -b /dev/block/$1 ]]; then
1276 ID_FS_TYPE=$(get_fs_env "/dev/block/$1") && host_fs_types["$(readlink -f "/dev/block/$1")"]="$ID_FS_TYPE"
1277 return 1
1278 fi
1279 if [[ -b $1 ]]; then
1280 ID_FS_TYPE=$(get_fs_env "$1") && host_fs_types["$(readlink -f "$1")"]="$ID_FS_TYPE"
1281 return 1
1282 fi
1283 if fstype=$(find_dev_fstype "$1"); then
1284 host_fs_types["$1"]="$fstype"
1285 return 1
1286 fi
1287 return 1
1288 }
1289
1290 for dev in "${host_devs[@]}"; do
1291 _get_fs_type "$dev"
1292 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1293 done
1294
1295 for dev in "${!host_fs_types[@]}"; do
1296 [[ ${host_fs_types[$dev]} = "reiserfs" ]] || [[ ${host_fs_types[$dev]} = "xfs" ]] || continue
1297 rootopts=$(find_dev_fsopts "$dev")
1298 if [[ ${host_fs_types[$dev]} = "reiserfs" ]]; then
1299 journaldev=$(fs_get_option $rootopts "jdev")
1300 elif [[ ${host_fs_types[$dev]} = "xfs" ]]; then
1301 journaldev=$(fs_get_option $rootopts "logdev")
1302 fi
1303 if [[ $journaldev ]]; then
1304 dev="$(readlink -f "$dev")"
1305 push_host_devs "$dev"
1306 _get_fs_type "$dev"
1307 check_block_and_slaves_all _get_fs_type "$(get_maj_min "$dev")"
1308 fi
1309 done
1310
1311 [[ -d $udevdir ]] \
1312 || udevdir="$(pkg-config udev --variable=udevdir 2>/dev/null)"
1313 if ! [[ -d "$udevdir" ]]; then
1314 [[ -e /lib/udev/collect ]] && udevdir=/lib/udev
1315 [[ -e /usr/lib/udev/collect ]] && udevdir=/usr/lib/udev
1316 fi
1317
1318 [[ -d $systemdutildir ]] \
1319 || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
1320
1321 if ! [[ -d "$systemdutildir" ]]; then
1322 [[ -e /lib/systemd/systemd-udevd ]] && systemdutildir=/lib/systemd
1323 [[ -e /usr/lib/systemd/systemd-udevd ]] && systemdutildir=/usr/lib/systemd
1324 fi
1325
1326 [[ -d $systemdsystemunitdir ]] \
1327 || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
1328
1329 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
1330
1331 [[ -d $systemdsystemconfdir ]] \
1332 || systemdsystemconfdir=$(pkg-config systemd --variable=systemdsystemconfdir 2>/dev/null)
1333
1334 [[ -d "$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
1335
1336 [[ -d $tmpfilesdir ]] \
1337 || tmpfilesdir=$(pkg-config systemd --variable=tmpfilesdir 2>/dev/null)
1338
1339 if ! [[ -d "$tmpfilesdir" ]]; then
1340 [[ -d /lib/tmpfiles.d ]] && tmpfilesdir=/lib/tmpfiles.d
1341 [[ -d /usr/lib/tmpfiles.d ]] && tmpfilesdir=/usr/lib/tmpfiles.d
1342 fi
1343
1344 export initdir dracutbasedir \
1345 dracutmodules force_add_dracutmodules add_dracutmodules omit_dracutmodules \
1346 mods_to_load \
1347 fw_dir drivers_dir debug no_kernel kernel_only \
1348 omit_drivers mdadmconf lvmconf root_devs \
1349 use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
1350 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
1351 debug host_fs_types host_devs swap_devs sshkey add_fstab \
1352 DRACUT_VERSION udevdir prefix filesystems drivers \
1353 systemdutildir systemdsystemunitdir systemdsystemconfdir \
1354 hostonly_cmdline loginstall \
1355 tmpfilesdir
1356
1357 mods_to_load=""
1358 # check all our modules to see if they should be sourced.
1359 # This builds a list of modules that we will install next.
1360 for_each_module_dir check_module
1361 for_each_module_dir check_mount
1362
1363 dracut_module_included "fips" && export DRACUT_FIPS_MODE=1
1364
1365 do_print_cmdline()
1366 {
1367 local -A _mods_to_print
1368 for i in $modules_loaded $mods_to_load; do
1369 _mods_to_print[$i]=1
1370 done
1371
1372 # source our modules.
1373 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1374 _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
1375 [[ ${_mods_to_print[$_d_mod]} ]] || continue
1376 module_cmdline "$_d_mod"
1377 done
1378 unset moddir
1379 }
1380
1381 if [[ $print_cmdline ]]; then
1382 do_print_cmdline
1383 printf "\n"
1384 exit 0
1385 fi
1386
1387 # Create some directory structure first
1388 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
1389
1390 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
1391 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
1392
1393 if [[ $prefix ]]; then
1394 for d in bin etc lib sbin tmp usr var $libdirs; do
1395 [[ "$d" == */* ]] && continue
1396 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
1397 done
1398 fi
1399
1400 if [[ $kernel_only != yes ]]; then
1401 for d in usr/bin usr/sbin bin etc lib sbin tmp usr var var/tmp $libdirs; do
1402 [[ -e "${initdir}${prefix}/$d" ]] && continue
1403 if [ -L "/$d" ]; then
1404 inst_symlink "/$d" "${prefix}/$d"
1405 else
1406 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1407 fi
1408 done
1409
1410 for d in dev proc sys sysroot root run; do
1411 if [ -L "/$d" ]; then
1412 inst_symlink "/$d"
1413 else
1414 mkdir -m 0755 -p "$initdir/$d"
1415 fi
1416 done
1417
1418 ln -sfn ../run "$initdir/var/run"
1419 ln -sfn ../run/lock "$initdir/var/lock"
1420 else
1421 for d in lib "$libdir"; do
1422 [[ -e "${initdir}${prefix}/$d" ]] && continue
1423 if [ -h "/$d" ]; then
1424 inst "/$d" "${prefix}/$d"
1425 else
1426 mkdir -m 0755 -p "${initdir}${prefix}/$d"
1427 fi
1428 done
1429 fi
1430
1431 if [[ $kernel_only != yes ]]; then
1432 mkdir -p "${initdir}/etc/cmdline.d"
1433 for _d in $hookdirs; do
1434 mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
1435 done
1436 if [[ "$EUID" = "0" ]]; then
1437 [ -c ${initdir}/dev/null ] || mknod ${initdir}/dev/null c 1 3
1438 [ -c ${initdir}/dev/kmsg ] || mknod ${initdir}/dev/kmsg c 1 11
1439 [ -c ${initdir}/dev/console ] || mknod ${initdir}/dev/console c 5 1
1440 [ -c ${initdir}/dev/random ] || mknod ${initdir}/dev/random c 1 8
1441 [ -c ${initdir}/dev/urandom ] || mknod ${initdir}/dev/urandom c 1 9
1442 fi
1443 fi
1444
1445 _isize=0 #initramfs size
1446 modules_loaded=" "
1447 # source our modules.
1448 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
1449 _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
1450 [[ "$mods_to_load" == *\ $_d_mod\ * ]] || continue
1451 if [[ $show_modules = yes ]]; then
1452 printf "%s\n" "$_d_mod"
1453 else
1454 dinfo "*** Including module: $_d_mod ***"
1455 fi
1456 if [[ $kernel_only == yes ]]; then
1457 module_installkernel "$_d_mod" || {
1458 dfatal "installkernel failed in module $_d_mod"
1459 exit 1
1460 }
1461 else
1462 module_install "$_d_mod"
1463 if [[ $no_kernel != yes ]]; then
1464 module_installkernel "$_d_mod" || {
1465 dfatal "installkernel failed in module $_d_mod"
1466 exit 1
1467 }
1468 fi
1469 fi
1470 mods_to_load=${mods_to_load// $_d_mod /}
1471 modules_loaded+="$_d_mod "
1472
1473 #print the module install size
1474 if [ -n "$printsize" ]; then
1475 _isize_new=$(du -sk ${initdir}|cut -f1)
1476 _isize_delta=$((_isize_new - _isize))
1477 printf "%s\n" "$_d_mod install size: ${_isize_delta}k"
1478 _isize=$_isize_new
1479 fi
1480 done
1481 unset moddir
1482
1483 for i in $modules_loaded; do
1484 mkdir -p $initdir/lib/dracut
1485 printf "%s\n" "$i" >> $initdir/lib/dracut/modules.txt
1486 done
1487
1488 dinfo "*** Including modules done ***"
1489
1490 ## final stuff that has to happen
1491 if [[ $no_kernel != yes ]]; then
1492 if [[ $hostonly ]]; then
1493 echo "$(get_loaded_kernel_modules)" > $initdir/lib/dracut/loaded-kernel-modules.txt
1494 fi
1495
1496 if [[ $drivers ]]; then
1497 hostonly='' instmods $drivers
1498 fi
1499
1500 if [[ -n "${add_drivers// }" ]]; then
1501 hostonly='' instmods -c $add_drivers
1502 fi
1503 if [[ $force_drivers ]]; then
1504 hostonly='' instmods -c $force_drivers
1505 rm -f $initdir/etc/cmdline.d/20-force_driver.conf
1506 for mod in $force_drivers; do
1507 echo "rd.driver.pre=$mod" >>$initdir/etc/cmdline.d/20-force_drivers.conf
1508 done
1509 fi
1510 if [[ $filesystems ]]; then
1511 hostonly='' instmods -c $filesystems
1512 fi
1513
1514 dinfo "*** Installing kernel module dependencies ***"
1515 dracut_kernel_post
1516 dinfo "*** Installing kernel module dependencies done ***"
1517
1518 if [[ $noimageifnotneeded == yes ]] && [[ $hostonly ]]; then
1519 if [[ ! -f "$initdir/lib/dracut/need-initqueue" ]] && \
1520 [[ -f ${initdir}/lib/modules/$kernel/modules.dep && ! -s ${initdir}/lib/modules/$kernel/modules.dep ]]; then
1521 for i in ${initdir}/etc/cmdline.d/*.conf; do
1522 # We need no initramfs image and do not generate one.
1523 [[ $i == "${initdir}/etc/cmdline.d/*.conf" ]] && exit 0
1524 done
1525 fi
1526 fi
1527 fi
1528
1529 if [[ $kernel_only != yes ]]; then
1530 (( ${#install_items[@]} > 0 )) && inst_multiple ${install_items[@]}
1531 (( ${#install_optional_items[@]} > 0 )) && inst_multiple -o ${install_optional_items[@]}
1532
1533 [[ $kernel_cmdline ]] && printf "%s\n" "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
1534
1535 for line in "${fstab_lines[@]}"; do
1536 line=($line)
1537
1538 if [ -z "${line[1]}" ]; then
1539 # Determine device and mount options from current system
1540 mountpoint -q "${line[0]}" || derror "${line[0]} is not a mount point!"
1541 line=($(findmnt --raw -n --target "${line[0]}" --output=source,target,fstype,options))
1542 dinfo "Line for ${line[1]}: ${line[@]}"
1543 else
1544 # Use default options
1545 [ -z "${line[3]}" ] && line[3]="defaults"
1546 fi
1547
1548 # Default options for freq and passno
1549 [ -z "${line[4]}" ] && line[4]="0"
1550 [ -z "${line[5]}" ] && line[5]="2"
1551
1552 strstr "${line[2]}" "nfs" && line[5]="0"
1553 echo "${line[@]}" >> "${initdir}/etc/fstab"
1554 done
1555
1556 for f in $add_fstab; do
1557 cat "$f" >> "${initdir}/etc/fstab"
1558 done
1559
1560 if [[ $systemdutildir ]]; then
1561 if [ -d ${initdir}/$systemdutildir ]; then
1562 mkdir -p ${initdir}/etc/conf.d
1563 {
1564 printf "%s\n" "systemdutildir=\"$systemdutildir\""
1565 printf "%s\n" "systemdsystemunitdir=\"$systemdsystemunitdir\""
1566 printf "%s\n" "systemdsystemconfdir=\"$systemdsystemconfdir\""
1567 } > ${initdir}/etc/conf.d/systemd.conf
1568 fi
1569 fi
1570
1571 if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
1572 dinfo "*** Resolving executable dependencies ***"
1573 find "$initdir" -type f -perm /0111 -not -path '*.ko' -print0 \
1574 | xargs -r -0 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -R ${DRACUT_FIPS_MODE:+-f} --
1575 dinfo "*** Resolving executable dependencies done ***"
1576 fi
1577
1578 # Now we are done with lazy resolving, always install dependencies
1579 unset DRACUT_RESOLVE_LAZY
1580 export DRACUT_RESOLVE_DEPS=1
1581
1582 # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so
1583 for _dir in $libdirs; do
1584 for _f in "$_dir/libpthread.so"*; do
1585 [[ -e "$_f" ]] || continue
1586 inst_libdir_file "libgcc_s.so*"
1587 break 2
1588 done
1589 done
1590 fi
1591
1592 for ((i=0; i < ${#include_src[@]}; i++)); do
1593 src="${include_src[$i]}"
1594 target="${include_target[$i]}"
1595 if [[ $src && $target ]]; then
1596 if [[ -f $src ]]; then
1597 inst $src $target
1598 else
1599 ddebug "Including directory: $src"
1600 destdir="${initdir}/${target}"
1601 mkdir -p "$destdir"
1602 # check for preexisting symlinks, so we can cope with the
1603 # symlinks to $prefix
1604 # Objectname is a file or a directory
1605 for objectname in "$src"/*; do
1606 [[ -e "$objectname" || -h "$objectname" ]] || continue
1607 if [[ -d "$objectname" ]]; then
1608 # objectname is a directory, let's compute the final directory name
1609 object_destdir=${destdir}/${objectname#$src/}
1610 if ! [[ -e "$object_destdir" ]]; then
1611 mkdir -m 0755 -p "$object_destdir"
1612 chmod --reference="$objectname" "$object_destdir"
1613 fi
1614 $DRACUT_CP -t "$object_destdir" "$objectname"/*
1615 else
1616 $DRACUT_CP -t "$destdir" "$objectname"
1617 fi
1618 done
1619 fi
1620 fi
1621 done
1622
1623 if [[ $kernel_only != yes ]]; then
1624 # make sure that library links are correct and up to date
1625 for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
1626 [[ -f $f ]] && inst_simple "$f"
1627 done
1628 if ! ldconfig -r "$initdir"; then
1629 if [[ $EUID = 0 ]]; then
1630 derror "ldconfig exited ungracefully"
1631 else
1632 derror "ldconfig might need uid=0 (root) for chroot()"
1633 fi
1634 fi
1635 fi
1636
1637 if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
1638 dinfo "*** Hardlinking files ***"
1639 hardlink "$initdir" 2>&1
1640 dinfo "*** Hardlinking files done ***"
1641 fi
1642
1643 # strip binaries
1644 if [[ $do_strip = yes ]] ; then
1645 # Prefer strip from elfutils for package size
1646 declare strip_cmd=$(command -v eu-strip)
1647 test -z "$strip_cmd" && strip_cmd="strip"
1648
1649 for p in $strip_cmd xargs find; do
1650 if ! type -P $p >/dev/null; then
1651 dinfo "Could not find '$p'. Not stripping the initramfs."
1652 do_strip=no
1653 fi
1654 done
1655 fi
1656
1657 # cleanup empty ldconfig_paths directories
1658 for d in $(ldconfig_paths); do
1659 rmdir -p --ignore-fail-on-non-empty "$initdir/$d" >/dev/null 2>&1
1660 done
1661
1662 if [[ $do_strip = yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
1663 dinfo "*** Stripping files ***"
1664 find "$initdir" -type f \
1665 -executable -not -path '*/lib/modules/*.ko' -print0 \
1666 | xargs -r -0 $strip_cmd -g -p 2>/dev/null
1667
1668 # strip kernel modules, but do not touch signed modules
1669 find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
1670 | while read -r -d $'\0' f || [ -n "$f" ]; do
1671 SIG=$(tail -c 28 "$f" | tr -d '\000')
1672 [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
1673 done | xargs -r -0 $strip_cmd -g -p
1674
1675 dinfo "*** Stripping files done ***"
1676 fi
1677 if [[ $early_microcode = yes ]]; then
1678 dinfo "*** Generating early-microcode cpio image ***"
1679 ucode_dir=(amd-ucode intel-ucode)
1680 ucode_dest=(AuthenticAMD.bin GenuineIntel.bin)
1681 _dest_dir="$early_cpio_dir/d/kernel/x86/microcode"
1682 _dest_idx="0 1"
1683 mkdir -p $_dest_dir
1684 if [[ $hostonly ]]; then
1685 [[ $(get_cpu_vendor) == "AMD" ]] && _dest_idx="0"
1686 [[ $(get_cpu_vendor) == "Intel" ]] && _dest_idx="1"
1687 fi
1688 for idx in $_dest_idx; do
1689 _fw=${ucode_dir[$idx]}
1690 for _fwdir in $fw_dir; do
1691 if [[ -d $_fwdir && -d $_fwdir/$_fw ]]; then
1692 _src="*"
1693 dinfo "*** Constructing ${ucode_dest[$idx]} ***"
1694 if [[ $hostonly ]]; then
1695 _src=$(get_ucode_file)
1696 [[ $_src ]] || break
1697 [[ -r $_fwdir/$_fw/$_src ]] || break
1698 fi
1699
1700 for i in $_fwdir/$_fw/$_src; do
1701 [ -e "$i" ] && break
1702 break 2
1703 done
1704 for i in $_fwdir/$_fw/$_src; do
1705 [[ -e "$i" ]] || continue
1706 # skip gpg files
1707 str_ends "$i" ".asc" && continue
1708 cat "$i" >> $_dest_dir/${ucode_dest[$idx]}
1709 done
1710 create_early_cpio="yes"
1711 fi
1712 done
1713 done
1714 fi
1715
1716 if [[ $acpi_override = yes ]] && [[ -d $acpi_table_dir ]]; then
1717 dinfo "*** Packaging ACPI tables to override BIOS provided ones ***"
1718 _dest_dir="$early_cpio_dir/d/kernel/firmware/acpi"
1719 mkdir -p $_dest_dir
1720 for table in $acpi_table_dir/*.aml; do
1721 dinfo " Adding ACPI table: $table"
1722 $DRACUT_CP $table $_dest_dir
1723 create_early_cpio="yes"
1724 done
1725 fi
1726
1727 dinfo "*** Store current command line parameters ***"
1728 if ! ( echo $PARMS_TO_STORE > $initdir/lib/dracut/build-parameter.txt ); then
1729 dfatal "Could not store the current command line parameters"
1730 exit 1
1731 fi
1732
1733 if [[ $hostonly_cmdline == "yes" ]] ; then
1734 unset _stored_cmdline
1735 if [ -d $initdir/etc/cmdline.d ];then
1736 dinfo "Stored kernel commandline:"
1737 for conf in $initdir/etc/cmdline.d/*.conf ; do
1738 [ -e "$conf" ] || continue
1739 dinfo "$(< $conf)"
1740 _stored_cmdline=1
1741 done
1742 fi
1743 if ! [[ $_stored_cmdline ]]; then
1744 dinfo "No dracut internal kernel commandline stored in the initramfs"
1745 fi
1746 fi
1747
1748 dinfo "*** Creating image file '$outfile' ***"
1749
1750 if dracut_module_included "squash"; then
1751 if ! check_kernel_config CONFIG_SQUASHFS; then
1752 dfatal "CONFIG_SQUASHFS have to be enabled for dracut squash module to work"
1753 exit 1
1754 fi
1755 if ! check_kernel_config CONFIG_OVERLAY_FS; then
1756 dfatal "CONFIG_OVERLAY_FS have to be enabled for dracut squash module to work"
1757 exit 1
1758 fi
1759 if ! check_kernel_config CONFIG_DEVTMPFS; then
1760 dfatal "CONFIG_DEVTMPFS have to be enabled for dracut squash module to work"
1761 exit 1
1762 fi
1763
1764 readonly squash_dir="${DRACUT_TMPDIR}/squashfs"
1765 readonly squash_img=$initdir/squash/root.img
1766
1767 # Currently only move "usr" "etc" to squashdir
1768 readonly squash_candidate=( "usr" "etc" )
1769
1770 mkdir -m 0755 -p $squash_dir
1771 for folder in "${squash_candidate[@]}"; do
1772 mv $initdir/$folder $squash_dir/$folder
1773 done
1774
1775 # Reinstall required files, because we have moved some important folders to $squash_dir
1776 inst_multiple "echo" "sh" "mount" "modprobe" "mkdir" \
1777 "systemctl" "udevadm" "$systemdutildir/systemd"
1778 hostonly="" instmods "loop" "squashfs" "overlay"
1779
1780 for folder in "${squash_candidate[@]}"; do
1781 # Remove duplicated files in squashfs image, save some more space
1782 [[ ! -d $initdir/$folder/ ]] && continue
1783 for file in $(find $initdir/$folder/ -not -type d);
1784 do
1785 if [[ -e $squash_dir${file#$initdir} ]]; then
1786 mv $squash_dir${file#$initdir} $file
1787 fi
1788 done
1789 done
1790
1791 # Move some files out side of the squash image, including:
1792 # - Files required to boot and mount the squashfs image
1793 # - Files need to be accessible without mounting the squash image
1794 required_in_root() {
1795 local file=$1
1796 local _sqsh_file=$squash_dir/$file
1797 local _init_file=$initdir/$file
1798
1799 if [[ -e $_init_file ]]; then
1800 return
1801 fi
1802
1803 if [[ ! -e $_sqsh_file ]] && [[ ! -L $_sqsh_file ]]; then
1804 derror "$file is required to boot a squashed initramfs but it's not installed!"
1805 return
1806 fi
1807
1808 if [[ ! -d $(dirname $_init_file) ]]; then
1809 required_in_root $(dirname $file)
1810 fi
1811
1812 if [[ -d $_sqsh_file ]]; then
1813 if [[ -L $_sqsh_file ]]; then
1814 cp --preserve=all -P $_sqsh_file $_init_file
1815 else
1816 mkdir $_init_file
1817 fi
1818 else
1819 if [[ -L $_sqsh_file ]]; then
1820 cp --preserve=all -P $_sqsh_file $_init_file
1821 _sqsh_file=$(realpath $_sqsh_file 2>/dev/null)
1822 if [[ -e $_sqsh_file ]] && [[ "$_sqsh_file" == "$squash_dir"* ]]; then
1823 # Relative symlink
1824 required_in_root ${_sqsh_file#$squash_dir/}
1825 return
1826 fi
1827 if [[ -e $squash_dir$_sqsh_file ]]; then
1828 # Absolute symlink
1829 required_in_root ${_sqsh_file#/}
1830 return
1831 fi
1832 required_in_root ${module_spec#$squash_dir/}
1833 else
1834 mv $_sqsh_file $_init_file
1835 fi
1836 fi
1837 }
1838
1839 required_in_root etc/initrd-release
1840
1841 for module_spec in $squash_dir/usr/lib/modules/*/modules.*;
1842 do
1843 required_in_root ${module_spec#$squash_dir/}
1844 done
1845
1846 for dracut_spec in $squash_dir/usr/lib/dracut/*;
1847 do
1848 required_in_root ${dracut_spec#$squash_dir/}
1849 done
1850
1851 mv $initdir/init $initdir/init.stock
1852 ln -s squash/init.sh $initdir/init
1853
1854 mksquashfs $squash_dir $squash_img -comp xz -b 64K -Xdict-size 100% &> /dev/null
1855
1856 if [[ $? != 0 ]]; then
1857 dfatal "dracut: Failed making squash image"
1858 exit 1
1859 fi
1860 fi
1861
1862 if [[ $uefi = yes ]]; then
1863 readonly uefi_outdir="$DRACUT_TMPDIR/uefi"
1864 mkdir "$uefi_outdir"
1865 fi
1866
1867 if [[ $DRACUT_REPRODUCIBLE ]]; then
1868 find "$initdir" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
1869 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
1870
1871 if [[ "$(cpio --help)" == *--reproducible* ]]; then
1872 CPIO_REPRODUCIBLE=1
1873 else
1874 dinfo "cpio does not support '--reproducible'. Resulting image will not be reproducible."
1875 fi
1876 fi
1877
1878 [[ "$EUID" != 0 ]] && cpio_owner_root="-R 0:0"
1879
1880 if [[ $create_early_cpio = yes ]]; then
1881 echo 1 > "$early_cpio_dir/d/early_cpio"
1882
1883 if [[ $DRACUT_REPRODUCIBLE ]]; then
1884 find "$early_cpio_dir/d" -newer "$dracutbasedir/dracut-functions.sh" -print0 \
1885 | xargs -r -0 touch -h -m -c -r "$dracutbasedir/dracut-functions.sh"
1886 fi
1887
1888 # The microcode blob is _before_ the initramfs blob, not after
1889 if ! (
1890 umask 077; cd "$early_cpio_dir/d"
1891 find . -print0 | sort -z \
1892 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null $cpio_owner_root -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
1893 ); then
1894 dfatal "dracut: creation of $outfile failed"
1895 exit 1
1896 fi
1897 fi
1898
1899 if ! (
1900 umask 077; cd "$initdir"
1901 find . -print0 | sort -z \
1902 | cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null $cpio_owner_root -H newc -o --quiet \
1903 | $compress >> "${DRACUT_TMPDIR}/initramfs.img"
1904 ); then
1905 dfatal "dracut: creation of $outfile failed"
1906 exit 1
1907 fi
1908
1909 if (( maxloglvl >= 5 )) && (( verbosity_mod_l >= 0 )); then
1910 if [[ $allowlocal ]]; then
1911 "$dracutbasedir/lsinitrd.sh" "${DRACUT_TMPDIR}/initramfs.img"| ddebug
1912 else
1913 lsinitrd "${DRACUT_TMPDIR}/initramfs.img"| ddebug
1914 fi
1915 fi
1916
1917 umask 077
1918
1919 if [[ $uefi = yes ]]; then
1920 if [[ $kernel_cmdline ]]; then
1921 echo -n "$kernel_cmdline" > "$uefi_outdir/cmdline.txt"
1922 elif [[ $hostonly_cmdline = yes ]] && [ -d $initdir/etc/cmdline.d ];then
1923 for conf in $initdir/etc/cmdline.d/*.conf ; do
1924 [ -e "$conf" ] || continue
1925 printf "%s " "$(< $conf)" >> "$uefi_outdir/cmdline.txt"
1926 done
1927 else
1928 do_print_cmdline > "$uefi_outdir/cmdline.txt"
1929 fi
1930 echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
1931
1932 dinfo "Using UEFI kernel cmdline:"
1933 dinfo $(< "$uefi_outdir/cmdline.txt")
1934
1935 [[ -s /usr/lib/os-release ]] && uefi_osrelease="/usr/lib/os-release"
1936 [[ -s /etc/os-release ]] && uefi_osrelease="/etc/os-release"
1937
1938 if objcopy \
1939 ${uefi_osrelease:+--add-section .osrel=$uefi_osrelease --change-section-vma .osrel=0x20000} \
1940 --add-section .cmdline="${uefi_outdir}/cmdline.txt" --change-section-vma .cmdline=0x30000 \
1941 --add-section .linux="$kernel_image" --change-section-vma .linux=0x40000 \
1942 --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd=0x3000000 \
1943 "$uefi_stub" "${uefi_outdir}/linux.efi" \
1944 && cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
1945 dinfo "*** Creating UEFI image file '$outfile' done ***"
1946 else
1947 rm -f -- "$outfile"
1948 dfatal "*** Creating UEFI image file '$outfile' failed ***"
1949 exit 1
1950 fi
1951 else
1952 if cp --reflink=auto "${DRACUT_TMPDIR}/initramfs.img" "$outfile"; then
1953 dinfo "*** Creating initramfs image file '$outfile' done ***"
1954 else
1955 rm -f -- "$outfile"
1956 dfatal "dracut: creation of $outfile failed"
1957 exit 1
1958 fi
1959 fi
1960
1961 command -v restorecon &>/dev/null && restorecon -- "$outfile"
1962
1963 # We sync/fsfreeze only if we're operating on a live booted system.
1964 # It's possible for e.g. `kernel` to be installed as an RPM BuildRequires or equivalent,
1965 # and there's no reason to sync, and *definitely* no reason to fsfreeze.
1966 # Another case where this happens is rpm-ostree, which performs its own sync/fsfreeze
1967 # globally. See e.g. https://github.com/ostreedev/ostree/commit/8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0
1968 if test -d /run/systemd/system; then
1969 if ! sync "$outfile" 2> /dev/null; then
1970 dinfo "dracut: sync operation on newly created initramfs $outfile failed"
1971 exit 1
1972 fi
1973
1974 # use fsfreeze only if we're not writing to /
1975 if [[ "$(stat -c %m -- "$outfile")" != "/" && "$(stat -f -c %T -- "$outfile")" != "msdos" ]]; then
1976 if ! $(fsfreeze -f $(dirname "$outfile") 2>/dev/null && fsfreeze -u $(dirname "$outfile") 2>/dev/null); then
1977 dinfo "dracut: warning: could not fsfreeze $(dirname "$outfile")"
1978 fi
1979 fi
1980 fi
1981
1982 exit 0