2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
5 # Generator script for a dracut initramfs
6 # Tries to retain some degree of compatibility with the command line
7 # of the various mkinitrd implementations out there
10 # Copyright 2005-2010 Red Hat, Inc. All rights reserved.
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program. If not, see <http://www.gnu.org/licenses/>.
30 # 80x25 linebreak here ^
32 Usage: $0 [OPTION]... <initramfs> <kernel-version>
33 Creates initial ramdisk images for preloading modules
35 -f, --force Overwrite existing initramfs file.
36 -m, --modules [LIST] Specify a space-separated list of dracut modules to
37 call when building the initramfs. Modules are located
38 in /usr/share/dracut/modules.d.
39 -o, --omit [LIST] Omit a space-separated list of dracut modules.
40 -a, --add [LIST] Add a space-separated list of dracut modules.
41 -d, --drivers [LIST] Specify a space-separated list of kernel modules to
42 exclusively include in the initramfs.
43 --add-drivers [LIST] Specify a space-separated list of kernel
44 modules to add to the initramfs.
45 --filesystems [LIST] Specify a space-separated list of kernel filesystem
46 modules to exclusively include in the generic
48 -k, --kmoddir [DIR] Specify the directory, where to look for kernel
50 --fwdir [DIR] Specify additional directories, where to look for
51 firmwares, separated by :
52 --kernel-only Only install kernel drivers and firmware files
53 --no-kernel Do not install kernel drivers and firmware files
54 --strip Strip binaries in the initramfs
55 --nostrip Do not strip binaries in the initramfs (default)
56 --prefix [DIR] Prefix initramfs files with [DIR]
57 --noprefix Do not prefix initramfs files (default)
58 --mdadmconf Include local /etc/mdadm.conf
59 --nomdadmconf Do not include local /etc/mdadm.conf
60 --lvmconf Include local /etc/lvm/lvm.conf
61 --nolvmconf Do not include local /etc/lvm/lvm.conf
62 -h, --help This message
63 --debug Output debug information of the build process
64 -L, --stdlog [0-6] Specify logging level (to standard error)
65 0 - suppress any messages
70 5 - debug info (here starts lots of output)
71 6 - trace info (and even more)
72 -v, --verbose Increase verbosity level (default is info(4))
73 -q, --quiet Decrease verbosity level (default is info(4))
74 -c, --conf [FILE] Specify configuration file to use.
75 Default: /etc/dracut.conf
76 --confdir [DIR] Specify configuration directory to use *.conf files
77 from. Default: /etc/dracut.conf.d
78 -l, --local Local mode. Use modules from the current working
79 directory instead of the system-wide installed in
80 /usr/share/dracut/modules.d.
81 Useful when running dracut from a git checkout.
82 -H, --hostonly Host-Only mode: Install only what is needed for
83 booting the local host instead of a generic host.
84 --fstab Use /etc/fstab to determine the root device.
85 -i, --include [SOURCE] [TARGET]
86 Include the files in the SOURCE directory into the
87 Target directory in the final initramfs.
88 If SOURCE is a file, it will be installed to TARGET
89 in the final initramfs.
90 -I, --install [LIST] Install the space separated list of files into the
92 --gzip Compress the generated initramfs using gzip.
93 This will be done by default, unless another
94 compression option or --no-compress is passed.
95 --bzip2 Compress the generated initramfs using bzip2.
96 Make sure your kernel has bzip2 decompression support
97 compiled in, otherwise you will not be able to boot.
98 --lzma Compress the generated initramfs using lzma.
99 Make sure your kernel has lzma support compiled in,
100 otherwise you will not be able to boot.
101 --xz Compress the generated initramfs using xz.
102 Make sure that your kernel has xz support compiled
103 in, otherwise you will not be able to boot.
104 --compress [COMPRESSION] Compress the generated initramfs with the
105 passed compression program. Make sure your kernel
106 knows how to decompress the generated initramfs,
107 otherwise you will not be able to boot.
108 --no-compress Do not compress the generated initramfs. This will
109 override any other compression options.
110 --list-modules List all available dracut modules.
111 -M, --show-modules Print included module's name to standard output during
117 # push values to a stack
118 # $1 = stack variable
121 # push stack 1 2 "3 4"
123 local __stack
=$1; shift
125 eval ${__stack}'[${#'${__stack}'[@]}]="$i"'
130 # pops the last value from a stack
131 # assigns value to second argument variable
132 # or echo to stdout, if no second argument
133 # $1 = stack variable
134 # $2 = optional variable to store the value
139 local __stack=$1; shift
142 # check for empty stack
143 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
145 eval myresult='${'${__stack}'[${#'${__stack}'[@]}-1]}'
147 if [[ "$__resultvar" ]]; then
148 eval $__resultvar="'$myresult'"
152 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
156 # Little helper function for reading args from the commandline.
157 # it automatically handles -a b and -a=b variants, and returns 1 if
158 # we need to shift $3.
163 local rematch
='^[^=]*=(.*)$'
164 if [[ $2 =~
$rematch ]]; then
165 read "$1" <<< "${BASH_REMATCH[1]}"
168 # There is no way to shift our callers args, so
169 # return 1 to indicate they should do it instead.
174 # Little helper function for reading args from the commandline to a stack.
175 # it automatically handles -a b and -a=b variants, and returns 1 if
176 # we need to shift $3.
181 local rematch
='^[^=]*=(.*)$'
182 if [[ $2 =~
$rematch ]]; then
183 push
"$1" "${BASH_REMATCH[1]}"
186 # There is no way to shift our callers args, so
187 # return 1 to indicate they should do it instead.
196 -a|
--add) push_arg add_dracutmodules_l
"$@" ||
shift;;
197 --add-drivers) push_arg add_drivers_l
"$@" ||
shift;;
198 -m|
--modules) push_arg dracutmodules_l
"$@" ||
shift;;
199 -o|
--omit) push_arg omit_dracutmodules_l
"$@" ||
shift;;
200 -d|
--drivers) push_arg drivers_l
"$@" ||
shift;;
201 --filesystems) push_arg filesystems_l
"$@" ||
shift;;
202 -I|
--install) push_arg install_items
"$@" ||
shift;;
203 --fwdir) push_arg fw_dir_l
"$@" ||
shift;;
204 -k|
--kmoddir) read_arg drivers_dir_l
"$@" ||
shift;;
205 -c|
--conf) read_arg conffile
"$@" ||
shift;;
206 --confdir) read_arg confdir
"$@" ||
shift;;
207 -L|
--stdlog) read_arg stdloglvl_l
"$@" ||
shift;;
208 -I|
--install) read_arg install_items
"$@" ||
shift;;
209 --fwdir) read_arg fw_dir_l
"$@" ||
shift;;
210 --compress) read_arg compress_l
"$@" ||
shift;;
211 --prefix) read_arg prefix_l
"$@" ||
shift;;
212 -f|
--force) force
=yes;;
213 --kernel-only) kernel_only
="yes"; no_kernel
="no";;
214 --no-kernel) kernel_only
="no"; no_kernel
="yes";;
215 --strip) do_strip_l
="yes";;
216 --nostrip) do_strip_l
="no";;
217 --noprefix) prefix_l
="/";;
218 --mdadmconf) mdadmconf_l
="yes";;
219 --nomdadmconf) mdadmconf_l
="no";;
220 --lvmconf) lvmconf_l
="yes";;
221 --nolvmconf) lvmconf_l
="no";;
222 --debug) debug
="yes";;
223 -v|
--verbose) ((verbosity_mod_l
++));;
224 -q|
--quiet) ((verbosity_mod_l--
));;
225 -l|
--local) allowlocal
="yes" ;;
226 -H|
--hostonly) hostonly_l
="yes" ;;
227 --fstab) use_fstab_l
="yes" ;;
228 -h|
--help) usage
; exit 1 ;;
229 -i|
--include) push include_src
"$2"
230 push include_target
"$3"
232 --bzip2) compress_l
="bzip2";;
233 --lzma) compress_l
="lzma";;
234 --xz) compress_l
="xz";;
235 --no-compress) _no_compress_l
="cat";;
236 --gzip) compress_l
="gzip";;
243 -*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage
; exit 1;;
245 if ! [[ ${outfile+x} ]]; then
247 elif ! [[ ${kernel+x} ]]; then
256 if ! [[ $kernel ]]; then
259 [[ $outfile ]] || outfile
="/boot/initramfs-$kernel.img"
261 PATH
=/sbin
:/bin
:/usr
/sbin
:/usr
/bin
265 export PS4
='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
269 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
271 [[ $allowlocal && -f "$(readlink -f ${0%/*})/dracut-functions" ]] && \
272 dracutbasedir
="$(readlink -f ${0%/*})"
274 # if we were not passed a config file, try the default one
275 if [[ ! -f $conffile ]]; then
276 [[ $allowlocal ]] && conffile
="$dracutbasedir/dracut.conf" || \
277 conffile
="/etc/dracut.conf"
280 if [[ ! -d $confdir ]]; then
281 [[ $allowlocal ]] && confdir
="$dracutbasedir/dracut.conf.d" || \
282 confdir
="/etc/dracut.conf.d"
285 # source our config file
286 [[ -f $conffile ]] && .
"$conffile"
288 # source our config dir
289 if [[ $confdir && -d $confdir ]]; then
290 for f
in "$confdir"/*.conf
; do
291 [[ -e $f ]] && .
"$f"
295 # these optins add to the stuff in the config file
296 if (( ${#add_dracutmodules_l[@]} )); then
297 while pop add_dracutmodules_l val
; do
298 add_dracutmodules
+=" $val "
302 if (( ${#add_drivers_l[@]} )); then
303 while pop add_drivers_l val
; do
304 add_drivers
+=" $val "
308 # these options override the stuff in the config file
309 if (( ${#dracutmodules_l[@]} )); then
311 while pop dracutmodules_l val
; do
312 dracutmodules
+="$val "
316 if (( ${#omit_dracutmodules_l[@]} )); then
317 omit_dracutmodules
=''
318 while pop omit_dracutmodules_l val
; do
319 omit_dracutmodules
+="$val "
323 if (( ${#drivers_l[@]} )); then
325 while pop drivers_l val
; do
330 if (( ${#filesystems_l[@]} )); then
332 while pop filesystems_l val
; do
337 if (( ${#fw_dir_l[@]} )); then
339 while pop fw_dir_l val
; do
344 [[ $stdloglvl_l ]] && stdloglvl
=$stdloglvl_l
345 [[ ! $stdloglvl ]] && stdloglvl
=4
346 stdloglvl
=$
((stdloglvl
+ verbosity_mod_l
))
347 ((stdloglvl
> 6)) && stdloglvl
=6
348 ((stdloglvl
< 0)) && stdloglvl
=0
350 [[ $drivers_dir_l ]] && drivers_dir
=$drivers_dir_l
351 [[ $do_strip_l ]] && do_strip
=$do_strip_l
352 [[ $prefix_l ]] && prefix
=$prefix_l
353 [[ $prefix = "/" ]] && unset prefix
354 [[ $hostonly_l ]] && hostonly
=$hostonly_l
355 [[ $use_fstab_l ]] && use_fstab
=$use_fstab_l
356 [[ $mdadmconf_l ]] && mdadmconf
=$mdadmconf_l
357 [[ $lvmconf_l ]] && lvmconf
=$lvmconf_l
358 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
359 [[ $fw_dir ]] || fw_dir
="/lib/firmware/updates /lib/firmware"
360 [[ $do_strip ]] || do_strip
=no
361 [[ $compress_l ]] && compress=$compress_l
362 [[ $show_modules_l ]] && show_modules
=$show_modules_l
363 # eliminate IFS hackery when messing with fw_dir
364 fw_dir
=${fw_dir//:/ }
366 # handle compression options.
368 bzip2) compress="bzip -9";;
369 lzma
) compress="lzma -9";;
370 xz
) compress="xz --check=crc32 --lzma2=dict=1MiB";;
371 gzip) type pigz
> /dev
/null
2>&1 && compress="pigz -9" || \
374 if [[ $_no_compress_l = "cat" ]]; then
378 [[ $hostonly = yes ]] && hostonly
="-h"
379 [[ $hostonly != "-h" ]] && unset hostonly
380 [[ $compress ]] ||
compress="gzip -9"
382 if [[ -f $dracutbasedir/dracut-functions
]]; then
383 .
$dracutbasedir/dracut-functions
385 echo "Cannot find $dracutbasedir/dracut-functions." >&2
386 echo "Are you running from a git checkout?" >&2
387 echo "Try passing -l as an argument to $0" >&2
391 dracutfunctions
=$dracutbasedir/dracut-functions
392 export dracutfunctions
394 ddebug
"Executing $0 $dracut_args"
396 [[ $do_list = yes ]] && {
397 for mod
in $dracutbasedir/modules.d
/*; do
398 [[ -d $mod ]] ||
continue;
399 [[ -e $mod/install ||
-e $mod/installkernel || \
400 -e $mod/module-setup.sh
]] ||
continue
407 [[ $libdir ]] ||
for libdir
in /lib64
/lib
; do
408 [[ -d $libdir ]] && break
410 dfatal
'No lib directory?!!!'
414 [[ $usrlibdir ]] ||
for usrlibdir
in /usr
/lib64
/usr
/lib
; do
415 [[ -d $usrlibdir ]] && break
416 done || dwarn
'No usr/lib directory!'
418 # This is kinda legacy -- eventually it should go away.
419 case $dracutmodules in
420 ""|auto
) dracutmodules
="all" ;;
423 abs_outfile
=$
(readlink
-f "$outfile") && outfile
="$abs_outfile"
425 srcmods
="/lib/modules/$kernel/"
426 [[ $drivers_dir ]] && {
427 if vercmp $
(modprobe
--version | cut
-d' ' -f3) lt
3.7; then
428 dfatal
'To use --kmoddir option module-init-tools >= 3.7 is required.'
431 srcmods
="$drivers_dir"
435 if [[ -f $outfile && ! $force ]]; then
436 dfatal
"Will not override existing initramfs ($outfile) without --force"
441 [[ $outdir ]] || outdir
="/"
443 if [[ ! -d "$outdir" ]]; then
444 dfatal
"Can't write $outfile: Directory $outdir does not exist."
446 elif [[ ! -w "$outdir" ]]; then
447 dfatal
"No permission to write $outdir."
449 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
450 dfatal
"No permission to write $outfile."
454 readonly TMPDIR
=/var
/tmp
455 readonly initdir
=$
(mktemp
--tmpdir=/var
/tmp
/ -d -t initramfs.XXXXXX
)
457 # clean up after ourselves no matter how we die.
458 trap 'ret=$?;rm -rf "$initdir";exit $ret;' EXIT
459 # clean up after ourselves no matter how we die.
460 trap 'exit 1;' SIGINT
462 # Need to be able to have non-root users read stuff (rpcbind etc)
465 export initdir dracutbasedir dracutmodules drivers \
466 fw_dir drivers_dir debug no_kernel kernel_only \
467 add_drivers mdadmconf lvmconf filesystems \
468 use_fstab libdir usrlibdir \
469 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
472 # Create some directory structure first
473 [[ $prefix ]] && mkdir
-m 0755 -p "${initdir}${prefix}"
475 mkdir
-m 0755 -p "${initdir}${prefix}/lib"
476 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
478 if [[ $kernel_only != yes ]]; then
479 for d
in bin etc lib
"$libdir" sbin tmp usr var
; do
480 [[ -e "${initdir}${prefix}/$d" ]] && continue
481 mkdir
-m 0755 -p "${initdir}${prefix}/$d"
482 [[ $prefix ]] && ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
485 for d
in proc sys sysroot root run run
/lock run
/initramfs
; do
486 mkdir
-m 0755 -p "$initdir/$d";
489 ln -sfn /run
"$initdir/var/run"
490 ln -sfn /run
/lock
"$initdir/var/lock"
493 # check all our modules to see if they should be sourced.
494 # This builds a list of modules that we will install next.
497 # source our modules.
498 for moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
499 _d_mod
=${moddir##*/}; _d_mod
=${_d_mod#[0-9][0-9]}
500 if strstr
"$mods_to_load" " $_d_mod "; then
501 [[ $show_modules = yes ]] && echo "$_d_mod" || \
502 dinfo
"*** Including module: $_d_mod ***"
503 if [[ $kernel_only = yes ]]; then
504 module_installkernel
$_d_mod
506 module_install
$_d_mod
507 if [[ $no_kernel != yes ]]; then
508 module_installkernel
$_d_mod
511 mods_to_load
=${mods_to_load// $_d_mod /}
512 modules_loaded
+="$_d_mod "
516 dinfo
"*** Including modules done ***"
518 ## final stuff that has to happen
520 # generate module dependencies for the initrd
521 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
522 ! depmod
-a -b "$initdir" $kernel; then
523 dfatal
"\"depmod -a $kernel\" failed."
527 while pop include_src src
&& pop include_target tgt
; do
528 if [[ $src && $tgt ]]; then
529 if [[ -f $src ]]; then
532 ddebug
"Including directory: $src"
533 mkdir
-p "${initdir}/${tgt}"
534 # check for preexisting symlinks, so we can cope with the
535 # symlinks to $prefix
536 for i
in "$src"/*; do
537 [[ -e "$i" ||
-h "$i" ]] ||
continue
538 s
=${initdir}/${tgt}/${i#$src/}
539 if [[ -d "$i" ]]; then
540 if ! [[ -e "$s" ]]; then
541 mkdir
-m 0755 -p "$s"
542 chmod --reference="$i" "$s"
553 while pop install_items items
; do
554 for item
in $items; do
555 dracut_install
"$item"
561 if [[ $kernel_only != yes ]]; then
562 # make sure that library links are correct and up to date
563 for f
in /etc
/ld.so.conf
/etc
/ld.so.conf.d
/*; do
564 [[ -e $f ]] && dracut_install
"$f"
566 if ! ldconfig
-r "$initdir"; then
567 if [[ $UID = 0 ]]; then
568 derror
"ldconfig exited ungracefully"
570 derror
"ldconfig might need uid=0 (root) for chroot()"
575 if (($maxloglvl >= 5)); then
576 ddebug
"Listing sizes of included files:"
577 du
-c "$initdir" |
sort -n | ddebug
581 if [[ $do_strip = yes ]] ; then
582 for p
in strip
grep find; do
583 if ! type -P $p >/dev
/null
; then
584 derror
"Could not find '$p'. You should run $0 with '--nostrip'."
590 if [[ $do_strip = yes ]] ; then
591 for f
in $
(find "$initdir" -type f \
592 \
( -perm -0100 -or -perm -0010 -or -perm -0001 \
593 -or -path '*/lib/modules/*.ko' \
) ); do
595 strip
-g "$f" 2>/dev
/null||
:
599 type hardlink
&>/dev
/null
&& {
600 hardlink
"$initdir" 2>&1
603 if strstr
"$modules_loaded" " fips " && command -v prelink
>/dev
/null
; then
604 for i
in $initdir/bin
/* \
607 $initdir/usr
/sbin
/*; do
608 [ -x $i ] && prelink
-u $i &>/dev
/null
612 if ! ( cd "$initdir"; find . |
cpio -R 0:0 -H newc
-o --quiet | \
613 $compress > "$outfile"; ); then
614 dfatal
"dracut: creation of $outfile failed"
618 dinfo
"Wrote $outfile:"
619 dinfo
"$(ls -l "$outfile")"