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