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 --profile Output profile information of the build process
65 -L, --stdlog [0-6] Specify logging level (to standard error)
66 0 - suppress any messages
71 5 - debug info (here starts lots of output)
72 6 - trace info (and even more)
73 -v, --verbose Increase verbosity level (default is info(4))
74 -q, --quiet Decrease verbosity level (default is info(4))
75 -c, --conf [FILE] Specify configuration file to use.
76 Default: /etc/dracut.conf
77 --confdir [DIR] Specify configuration directory to use *.conf files
78 from. Default: /etc/dracut.conf.d
79 -l, --local Local mode. Use modules from the current working
80 directory instead of the system-wide installed in
81 /usr/share/dracut/modules.d.
82 Useful when running dracut from a git checkout.
83 -H, --hostonly Host-Only mode: Install only what is needed for
84 booting the local host instead of a generic host.
85 --fstab Use /etc/fstab to determine the root device.
86 -i, --include [SOURCE] [TARGET]
87 Include the files in the SOURCE directory into the
88 Target directory in the final initramfs.
89 If SOURCE is a file, it will be installed to TARGET
90 in the final initramfs.
91 -I, --install [LIST] Install the space separated list of files into the
93 --gzip Compress the generated initramfs using gzip.
94 This will be done by default, unless another
95 compression option or --no-compress is passed.
96 --bzip2 Compress the generated initramfs using bzip2.
97 Make sure your kernel has bzip2 decompression support
98 compiled in, otherwise you will not be able to boot.
99 --lzma Compress the generated initramfs using lzma.
100 Make sure your kernel has lzma support compiled in,
101 otherwise you will not be able to boot.
102 --xz Compress the generated initramfs using xz.
103 Make sure that your kernel has xz support compiled
104 in, otherwise you will not be able to boot.
105 --compress [COMPRESSION] Compress the generated initramfs with the
106 passed compression program. Make sure your kernel
107 knows how to decompress the generated initramfs,
108 otherwise you will not be able to boot.
109 --no-compress Do not compress the generated initramfs. This will
110 override any other compression options.
111 --list-modules List all available dracut modules.
112 -M, --show-modules Print included module's name to standard output during
114 --keep Keep the temporary initramfs for debugging purposes
119 # push values to a stack
120 # $1 = stack variable
123 # push stack 1 2 "3 4"
125 local __stack
=$1; shift
127 eval ${__stack}'[${#'${__stack}'[@]}]="$i"'
132 # pops the last value from a stack
133 # assigns value to second argument variable
134 # or echo to stdout, if no second argument
135 # $1 = stack variable
136 # $2 = optional variable to store the value
141 local __stack=$1; shift
144 # check for empty stack
145 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
147 eval myresult='${'${__stack}'[${#'${__stack}'[@]}-1]}'
149 if [[ "$__resultvar" ]]; then
150 eval $__resultvar="'$myresult'"
154 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
158 # Little helper function for reading args from the commandline.
159 # it automatically handles -a b and -a=b variants, and returns 1 if
160 # we need to shift $3.
165 local rematch
='^[^=]*=(.*)$'
166 if [[ $2 =~
$rematch ]]; then
167 read "$1" <<< "${BASH_REMATCH[1]}"
170 # There is no way to shift our callers args, so
171 # return 1 to indicate they should do it instead.
176 # Little helper function for reading args from the commandline to a stack.
177 # it automatically handles -a b and -a=b variants, and returns 1 if
178 # we need to shift $3.
183 local rematch
='^[^=]*=(.*)$'
184 if [[ $2 =~
$rematch ]]; then
185 push
"$1" "${BASH_REMATCH[1]}"
188 # There is no way to shift our callers args, so
189 # return 1 to indicate they should do it instead.
198 -a|
--add) push_arg add_dracutmodules_l
"$@" ||
shift;;
199 --force-add) push_arg force_add_dracutmodules_l
"$@" ||
shift;;
200 --add-drivers) push_arg add_drivers_l
"$@" ||
shift;;
201 -m|
--modules) push_arg dracutmodules_l
"$@" ||
shift;;
202 -o|
--omit) push_arg omit_dracutmodules_l
"$@" ||
shift;;
203 -d|
--drivers) push_arg drivers_l
"$@" ||
shift;;
204 --filesystems) push_arg filesystems_l
"$@" ||
shift;;
205 -I|
--install) push_arg install_items
"$@" ||
shift;;
206 --fwdir) push_arg fw_dir_l
"$@" ||
shift;;
207 -k|
--kmoddir) read_arg drivers_dir_l
"$@" ||
shift;;
208 -c|
--conf) read_arg conffile
"$@" ||
shift;;
209 --confdir) read_arg confdir
"$@" ||
shift;;
210 -L|
--stdlog) read_arg stdloglvl_l
"$@" ||
shift;;
211 -I|
--install) read_arg install_items
"$@" ||
shift;;
212 --fwdir) read_arg fw_dir_l
"$@" ||
shift;;
213 --compress) read_arg compress_l
"$@" ||
shift;;
214 --prefix) read_arg prefix_l
"$@" ||
shift;;
215 -f|
--force) force
=yes;;
216 --kernel-only) kernel_only
="yes"; no_kernel
="no";;
217 --no-kernel) kernel_only
="no"; no_kernel
="yes";;
218 --strip) do_strip_l
="yes";;
219 --nostrip) do_strip_l
="no";;
220 --noprefix) prefix_l
="/";;
221 --mdadmconf) mdadmconf_l
="yes";;
222 --nomdadmconf) mdadmconf_l
="no";;
223 --lvmconf) lvmconf_l
="yes";;
224 --nolvmconf) lvmconf_l
="no";;
225 --debug) debug
="yes";;
226 --profile) profile
="yes";;
227 -v|
--verbose) ((verbosity_mod_l
++));;
228 -q|
--quiet) ((verbosity_mod_l--
));;
229 -l|
--local) allowlocal
="yes" ;;
230 -H|
--hostonly) hostonly_l
="yes" ;;
231 --fstab) use_fstab_l
="yes" ;;
232 -h|
--help) usage
; exit 1 ;;
233 -i|
--include) push include_src
"$2"
234 push include_target
"$3"
236 --bzip2) compress_l
="bzip2";;
237 --lzma) compress_l
="lzma";;
238 --xz) compress_l
="xz";;
239 --no-compress) _no_compress_l
="cat";;
240 --gzip) compress_l
="gzip";;
248 -*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage
; exit 1;;
250 if ! [[ ${outfile+x} ]]; then
252 elif ! [[ ${kernel+x} ]]; then
261 if ! [[ $kernel ]]; then
264 [[ $outfile ]] || outfile
="/boot/initramfs-$kernel.img"
266 PATH
=/sbin
:/bin
:/usr
/sbin
:/usr
/bin
268 unset LD_LIBRARY_PATH
271 export PS4
='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
276 export PS4
='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
281 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
283 [[ $allowlocal && -f "$(readlink -f ${0%/*})/dracut-functions" ]] && \
284 dracutbasedir
="$(readlink -f ${0%/*})"
286 # if we were not passed a config file, try the default one
287 if [[ ! -f $conffile ]]; then
288 [[ $allowlocal ]] && conffile
="$dracutbasedir/dracut.conf" || \
289 conffile
="/etc/dracut.conf"
292 if [[ ! -d $confdir ]]; then
293 [[ $allowlocal ]] && confdir
="$dracutbasedir/dracut.conf.d" || \
294 confdir
="/etc/dracut.conf.d"
297 # source our config file
298 [[ -f $conffile ]] && .
"$conffile"
300 # source our config dir
301 if [[ $confdir && -d $confdir ]]; then
302 for f
in "$confdir"/*.conf
; do
303 [[ -e $f ]] && .
"$f"
307 # these optins add to the stuff in the config file
308 if (( ${#add_dracutmodules_l[@]} )); then
309 while pop add_dracutmodules_l val
; do
310 add_dracutmodules
+=" $val "
314 if (( ${#force_add_dracutmodules_l[@]} )); then
315 while pop force_add_dracutmodules_l val
; do
316 force_add_dracutmodules
+=" $val "
321 if (( ${#add_drivers_l[@]} )); then
322 while pop add_drivers_l val
; do
323 add_drivers
+=" $val "
327 # these options override the stuff in the config file
328 if (( ${#dracutmodules_l[@]} )); then
330 while pop dracutmodules_l val
; do
331 dracutmodules
+="$val "
335 if (( ${#omit_dracutmodules_l[@]} )); then
336 omit_dracutmodules
=''
337 while pop omit_dracutmodules_l val
; do
338 omit_dracutmodules
+="$val "
342 if (( ${#drivers_l[@]} )); then
344 while pop drivers_l val
; do
349 if (( ${#filesystems_l[@]} )); then
351 while pop filesystems_l val
; do
356 if (( ${#fw_dir_l[@]} )); then
358 while pop fw_dir_l val
; do
363 [[ $stdloglvl_l ]] && stdloglvl
=$stdloglvl_l
364 [[ ! $stdloglvl ]] && stdloglvl
=4
365 stdloglvl
=$
((stdloglvl
+ verbosity_mod_l
))
366 ((stdloglvl
> 6)) && stdloglvl
=6
367 ((stdloglvl
< 0)) && stdloglvl
=0
369 [[ $drivers_dir_l ]] && drivers_dir
=$drivers_dir_l
370 [[ $do_strip_l ]] && do_strip
=$do_strip_l
371 [[ $prefix_l ]] && prefix
=$prefix_l
372 [[ $prefix = "/" ]] && unset prefix
373 [[ $hostonly_l ]] && hostonly
=$hostonly_l
374 [[ $use_fstab_l ]] && use_fstab
=$use_fstab_l
375 [[ $mdadmconf_l ]] && mdadmconf
=$mdadmconf_l
376 [[ $lvmconf_l ]] && lvmconf
=$lvmconf_l
377 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
378 [[ $fw_dir ]] || fw_dir
="/lib/firmware/updates /lib/firmware"
379 [[ $do_strip ]] || do_strip
=no
380 [[ $compress_l ]] && compress=$compress_l
381 [[ $show_modules_l ]] && show_modules
=$show_modules_l
382 # eliminate IFS hackery when messing with fw_dir
383 fw_dir
=${fw_dir//:/ }
385 # handle compression options.
386 [[ $compress ]] ||
compress="gzip"
388 bzip2) compress="bzip2 -9";;
389 lzma
) compress="lzma -9";;
390 xz
) compress="xz --check=crc32 --lzma2=dict=1MiB";;
391 gzip) command -v pigz
> /dev
/null
2>&1 && compress="pigz -9" || \
394 if [[ $_no_compress_l = "cat" ]]; then
398 [[ $hostonly = yes ]] && hostonly
="-h"
399 [[ $hostonly != "-h" ]] && unset hostonly
401 if [[ -f $dracutbasedir/dracut-functions
]]; then
402 .
$dracutbasedir/dracut-functions
404 echo "Cannot find $dracutbasedir/dracut-functions." >&2
405 echo "Are you running from a git checkout?" >&2
406 echo "Try passing -l as an argument to $0" >&2
410 dracutfunctions
=$dracutbasedir/dracut-functions
411 export dracutfunctions
413 ddebug
"Executing $0 $dracut_args"
415 [[ $do_list = yes ]] && {
416 for mod
in $dracutbasedir/modules.d
/*; do
417 [[ -d $mod ]] ||
continue;
418 [[ -e $mod/install ||
-e $mod/installkernel || \
419 -e $mod/module-setup.sh
]] ||
continue
426 [[ $libdir ]] ||
for libdir
in /lib64
/lib
; do
427 [[ -d $libdir ]] && break
429 dfatal
'No lib directory?!!!'
433 [[ $usrlibdir ]] ||
for usrlibdir
in /usr
/lib64
/usr
/lib
; do
434 [[ -d $usrlibdir ]] && break
435 done || dwarn
'No usr/lib directory!'
437 # This is kinda legacy -- eventually it should go away.
438 case $dracutmodules in
439 ""|auto
) dracutmodules
="all" ;;
442 abs_outfile
=$
(readlink
-f "$outfile") && outfile
="$abs_outfile"
444 srcmods
="/lib/modules/$kernel/"
445 [[ $drivers_dir ]] && {
446 if vercmp $
(modprobe
--version | cut
-d' ' -f3) lt
3.7; then
447 dfatal
'To use --kmoddir option module-init-tools >= 3.7 is required.'
450 srcmods
="$drivers_dir"
454 if [[ -f $outfile && ! $force ]]; then
455 dfatal
"Will not override existing initramfs ($outfile) without --force"
460 [[ $outdir ]] || outdir
="/"
462 if [[ ! -d "$outdir" ]]; then
463 dfatal
"Can't write $outfile: Directory $outdir does not exist."
465 elif [[ ! -w "$outdir" ]]; then
466 dfatal
"No permission to write $outdir."
468 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
469 dfatal
"No permission to write $outfile."
473 readonly TMPDIR
=/var
/tmp
474 readonly initdir
=$
(mktemp
--tmpdir=/var
/tmp
/ -d -t initramfs.XXXXXX
)
476 # clean up after ourselves no matter how we die.
477 trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
478 # clean up after ourselves no matter how we die.
479 trap 'exit 1;' SIGINT
481 # Need to be able to have non-root users read stuff (rpcbind etc)
484 export initdir dracutbasedir dracutmodules drivers \
485 fw_dir drivers_dir debug no_kernel kernel_only \
486 add_drivers mdadmconf lvmconf filesystems \
487 use_fstab libdir usrlibdir \
488 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
491 # Create some directory structure first
492 [[ $prefix ]] && mkdir
-m 0755 -p "${initdir}${prefix}"
494 [[ -h /lib
]] || mkdir
-m 0755 -p "${initdir}${prefix}/lib"
495 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
497 if [[ $prefix ]]; then
498 for d
in bin etc lib
"$libdir" sbin tmp usr var
; do
499 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
503 if [[ $kernel_only != yes ]]; then
504 for d
in bin etc lib
"$libdir" sbin tmp usr var usr
/bin usr
/sbin
; do
505 [[ -e "${initdir}${prefix}/$d" ]] && continue
506 if [ -h "/$d" ]; then
507 inst
"/$d" "${prefix}/$d"
509 mkdir
-m 0755 -p "${initdir}${prefix}/$d"
513 for d
in proc sys sysroot root run run
/lock run
/initramfs
; do
514 if [ -h "/$d" ]; then
517 mkdir
-m 0755 -p "$initdir/$d"
521 ln -sfn /run
"$initdir/var/run"
522 ln -sfn /run
/lock
"$initdir/var/lock"
524 for d
in lib
"$libdir"; do
525 [[ -e "${initdir}${prefix}/$d" ]] && continue
526 if [ -h "/$d" ]; then
527 inst
"/$d" "${prefix}/$d"
529 mkdir
-m 0755 -p "${initdir}${prefix}/$d"
534 # check all our modules to see if they should be sourced.
535 # This builds a list of modules that we will install next.
538 # source our modules.
539 for moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
540 _d_mod
=${moddir##*/}; _d_mod
=${_d_mod#[0-9][0-9]}
541 if strstr
"$mods_to_load" " $_d_mod "; then
542 [[ $show_modules = yes ]] && echo "$_d_mod" || \
543 dinfo
"*** Including module: $_d_mod ***"
544 if [[ $kernel_only = yes ]]; then
545 module_installkernel
$_d_mod
547 module_install
$_d_mod
548 if [[ $no_kernel != yes ]]; then
549 module_installkernel
$_d_mod
552 mods_to_load
=${mods_to_load// $_d_mod /}
553 modules_loaded
+="$_d_mod "
557 dinfo
"*** Including modules done ***"
559 ## final stuff that has to happen
561 # generate module dependencies for the initrd
562 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
563 ! depmod
-a -b "$initdir" $kernel; then
564 dfatal
"\"depmod -a $kernel\" failed."
568 while pop include_src src
&& pop include_target tgt
; do
569 if [[ $src && $tgt ]]; then
570 if [[ -f $src ]]; then
573 ddebug
"Including directory: $src"
574 mkdir
-p "${initdir}/${tgt}"
575 # check for preexisting symlinks, so we can cope with the
576 # symlinks to $prefix
577 for i
in "$src"/*; do
578 [[ -e "$i" ||
-h "$i" ]] ||
continue
579 s
=${initdir}/${tgt}/${i#$src/}
580 if [[ -d "$i" ]]; then
581 if ! [[ -e "$s" ]]; then
582 mkdir
-m 0755 -p "$s"
583 chmod --reference="$i" "$s"
594 while pop install_items items
; do
595 for item
in $items; do
596 dracut_install
"$item"
602 if [[ $kernel_only != yes ]]; then
603 # make sure that library links are correct and up to date
604 for f
in /etc
/ld.so.conf
/etc
/ld.so.conf.d
/*; do
605 [[ -e $f ]] && inst_simple
"$f"
607 if ! ldconfig
-r "$initdir"; then
608 if [[ $UID = 0 ]]; then
609 derror
"ldconfig exited ungracefully"
611 derror
"ldconfig might need uid=0 (root) for chroot()"
616 if (($maxloglvl >= 5)); then
617 ddebug
"Listing sizes of included files:"
618 du
-c "$initdir" |
sort -n | ddebug
622 if [[ $do_strip = yes ]] ; then
623 for p
in strip
grep find; do
624 if ! type -P $p >/dev
/null
; then
625 derror
"Could not find '$p'. You should run $0 with '--nostrip'."
631 if [[ $do_strip = yes ]] ; then
632 for f
in $
(find "$initdir" -type f \
633 \
( -perm -0100 -or -perm -0010 -or -perm -0001 \
634 -or -path '*/lib/modules/*.ko' \
) ); do
636 strip
-g "$f" 2>/dev
/null||
:
640 type hardlink
&>/dev
/null
&& {
641 hardlink
"$initdir" 2>&1
644 if strstr
"$modules_loaded" " fips " && command -v prelink
>/dev
/null
; then
645 for i
in $initdir/bin
/* \
648 $initdir/usr
/sbin
/*; do
649 [ -x $i ] && prelink
-u $i &>/dev
/null
653 if ! ( cd "$initdir"; find . |
cpio -R 0:0 -H newc
-o --quiet | \
654 $compress > "$outfile"; ); then
655 dfatal
"dracut: creation of $outfile failed"
659 dinfo
"Wrote $outfile:"
660 dinfo
"$(ls -l "$outfile")"