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 --mdadmconf Include local /etc/mdadm.conf
57 --nomdadmconf Do not include local /etc/mdadm.conf
58 --lvmconf Include local /etc/lvm/lvm.conf
59 --nolvmconf Do not include local /etc/lvm/lvm.conf
60 -h, --help This message
61 --debug Output debug information of the build process
62 -L, --stdlog [0-6] Specify logging level (to standard error)
63 0 - suppress any messages
68 5 - debug info (here starts lots of output)
69 6 - trace info (and even more)
70 -v, --verbose Increase verbosity level (default is info(4))
71 -q, --quiet Decrease verbosity level (default is info(4))
72 -c, --conf [FILE] Specify configuration file to use.
73 Default: /etc/dracut.conf
74 --confdir [DIR] Specify configuration directory to use *.conf files
75 from. Default: /etc/dracut.conf.d
76 -l, --local Local mode. Use modules from the current working
77 directory instead of the system-wide installed in
78 /usr/share/dracut/modules.d.
79 Useful when running dracut from a git checkout.
80 -H, --hostonly Host-Only mode: Install only what is needed for
81 booting the local host instead of a generic host.
82 --fstab Use /etc/fstab to determine the root device.
83 -i, --include [SOURCE] [TARGET]
84 Include the files in the SOURCE directory into the
85 Target directory in the final initramfs.
86 If SOURCE is a file, it will be installed to TARGET
87 in the final initramfs.
88 -I, --install [LIST] Install the space separated list of files into the
90 --gzip Compress the generated initramfs using gzip.
91 This will be done by default, unless another
92 compression option or --no-compress is passed.
93 --bzip2 Compress the generated initramfs using bzip2.
94 Make sure your kernel has bzip2 decompression support
95 compiled in, otherwise you will not be able to boot.
96 --lzma Compress the generated initramfs using lzma.
97 Make sure your kernel has lzma support compiled in,
98 otherwise you will not be able to boot.
99 --xz Compress the generated initramfs using xz.
100 Make sure that your kernel has xz support compiled
101 in, otherwise you will not be able to boot.
102 --compress [COMPRESSION] Compress the generated initramfs with the
103 passed compression program. Make sure your kernel
104 knows how to decompress the generated initramfs,
105 otherwise you will not be able to boot.
106 --no-compress Do not compress the generated initramfs. This will
107 override any other compression options.
108 --list-modules List all available dracut modules.
109 -M, --show-modules Print included module's name to standard output during
115 # push values to a stack
116 # $1 = stack variable
119 # push stack 1 2 "3 4"
121 local __stack
=$1; shift
123 eval ${__stack}'[${#'${__stack}'[@]}]="$i"'
128 # pops the last value from a stack
129 # assigns value to second argument variable
130 # or echo to stdout, if no second argument
131 # $1 = stack variable
132 # $2 = optional variable to store the value
137 local __stack=$1; shift
140 # check for empty stack
141 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
143 eval myresult='${'${__stack}'[${#'${__stack}'[@]}-1]}'
145 if [[ "$__resultvar" ]]; then
146 eval $__resultvar="'$myresult'"
150 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
154 # Little helper function for reading args from the commandline.
155 # it automatically handles -a b and -a=b variants, and returns 1 if
156 # we need to shift $3.
161 local rematch
='^[^=]*=(.*)$'
162 if [[ $2 =~
$rematch ]]; then
163 read "$1" <<< "${BASH_REMATCH[1]}"
166 # There is no way to shift our callers args, so
167 # return 1 to indicate they should do it instead.
172 # Little helper function for reading args from the commandline to a stack.
173 # it automatically handles -a b and -a=b variants, and returns 1 if
174 # we need to shift $3.
179 local rematch
='^[^=]*=(.*)$'
180 if [[ $2 =~
$rematch ]]; then
181 push
"$1" "${BASH_REMATCH[1]}"
184 # There is no way to shift our callers args, so
185 # return 1 to indicate they should do it instead.
194 -a|
--add) push_arg add_dracutmodules_l
"$@" ||
shift;;
195 --add-drivers) push_arg add_drivers_l
"$@" ||
shift;;
196 -m|
--modules) push_arg dracutmodules_l
"$@" ||
shift;;
197 -o|
--omit) push_arg omit_dracutmodules_l
"$@" ||
shift;;
198 -d|
--drivers) push_arg drivers_l
"$@" ||
shift;;
199 --filesystems) push_arg filesystems_l
"$@" ||
shift;;
200 -I|
--install) push_arg install_items
"$@" ||
shift;;
201 --fwdir) push_arg fw_dir_l
"$@" ||
shift;;
202 -k|
--kmoddir) read_arg drivers_dir_l
"$@" ||
shift;;
203 -c|
--conf) read_arg conffile
"$@" ||
shift;;
204 --confdir) read_arg confdir
"$@" ||
shift;;
205 -L|
--stdlog) read_arg stdloglvl_l
"$@" ||
shift;;
206 -I|
--install) read_arg install_items
"$@" ||
shift;;
207 --fwdir) read_arg fw_dir_l
"$@" ||
shift;;
208 --compress) read_arg compress_l
"$@" ||
shift;;
209 -f|
--force) force
=yes;;
210 --kernel-only) kernel_only
="yes"; no_kernel
="no";;
211 --no-kernel) kernel_only
="no"; no_kernel
="yes";;
212 --strip) do_strip_l
="yes";;
213 --nostrip) do_strip_l
="no";;
214 --mdadmconf) mdadmconf_l
="yes";;
215 --nomdadmconf) mdadmconf_l
="no";;
216 --lvmconf) lvmconf_l
="yes";;
217 --nolvmconf) lvmconf_l
="no";;
218 --debug) debug
="yes";;
219 -v|
--verbose) ((verbosity_mod_l
++));;
220 -q|
--quiet) ((verbosity_mod_l--
));;
221 -l|
--local) allowlocal
="yes" ;;
222 -H|
--hostonly) hostonly_l
="yes" ;;
223 --fstab) use_fstab_l
="yes" ;;
224 -h|
--help) usage
; exit 1 ;;
225 -i|
--include) push include_src
"$2"
226 push include_target
"$3"
228 --bzip2) compress_l
="bzip2";;
229 --lzma) compress_l
="lzma";;
230 --xz) compress_l
="xz";;
231 --no-compress) _no_compress_l
="cat";;
232 --gzip) compress_l
="gzip";;
239 -*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage
; exit 1;;
241 if ! [[ ${outfile+x} ]]; then
243 elif ! [[ ${kernel+x} ]]; then
252 if ! [[ $kernel ]]; then
255 [[ $outfile ]] || outfile
="/boot/initramfs-$kernel.img"
257 PATH
=/sbin
:/bin
:/usr
/sbin
:/usr
/bin
261 export PS4
='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
265 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
267 [[ $allowlocal && -f "$(readlink -f ${0%/*})/dracut-functions" ]] && \
268 dracutbasedir
="$(readlink -f ${0%/*})"
270 # if we were not passed a config file, try the default one
271 if [[ ! -f $conffile ]]; then
272 [[ $allowlocal ]] && conffile
="$dracutbasedir/dracut.conf" || \
273 conffile
="/etc/dracut.conf"
276 if [[ ! -d $confdir ]]; then
277 [[ $allowlocal ]] && confdir
="$dracutbasedir/dracut.conf.d" || \
278 confdir
="/etc/dracut.conf.d"
281 # source our config file
282 [[ -f $conffile ]] && .
"$conffile"
284 # source our config dir
285 if [[ $confdir && -d $confdir ]]; then
286 for f
in "$confdir"/*.conf
; do
287 [[ -e $f ]] && .
"$f"
291 # these optins add to the stuff in the config file
292 if (( ${#add_dracutmodules_l[@]} )); then
293 while pop add_dracutmodules_l val
; do
294 add_dracutmodules
+=" $val "
298 if (( ${#add_drivers_l[@]} )); then
299 while pop add_drivers_l val
; do
300 add_drivers
+=" $val "
304 # these options override the stuff in the config file
305 if (( ${#dracutmodules_l[@]} )); then
307 while pop dracutmodules_l val
; do
308 dracutmodules
+="$val "
312 if (( ${#omit_dracutmodules_l[@]} )); then
313 omit_dracutmodules
=''
314 while pop omit_dracutmodules_l val
; do
315 omit_dracutmodules
+="$val "
319 if (( ${#drivers_l[@]} )); then
321 while pop drivers_l val
; do
326 if (( ${#filesystems_l[@]} )); then
328 while pop filesystems_l val
; do
333 if (( ${#fw_dir_l[@]} )); then
335 while pop fw_dir_l val
; do
340 [[ $stdloglvl_l ]] && stdloglvl
=$stdloglvl_l
341 [[ ! $stdloglvl ]] && stdloglvl
=4
342 stdloglvl
=$
((stdloglvl
+ verbosity_mod_l
))
343 ((stdloglvl
> 6)) && stdloglvl
=6
344 ((stdloglvl
< 0)) && stdloglvl
=0
346 [[ $drivers_dir_l ]] && drivers_dir
=$drivers_dir_l
347 [[ $do_strip_l ]] && do_strip
=$do_strip_l
348 [[ $hostonly_l ]] && hostonly
=$hostonly_l
349 [[ $use_fstab_l ]] && use_fstab
=$use_fstab_l
350 [[ $mdadmconf_l ]] && mdadmconf
=$mdadmconf_l
351 [[ $lvmconf_l ]] && lvmconf
=$lvmconf_l
352 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
353 [[ $fw_dir ]] || fw_dir
="/lib/firmware/updates /lib/firmware"
354 [[ $do_strip ]] || do_strip
=no
355 [[ $compress_l ]] && compress=$compress_l
356 [[ $show_modules_l ]] && show_modules
=$show_modules_l
357 # eliminate IFS hackery when messing with fw_dir
358 fw_dir
=${fw_dir//:/ }
360 # handle compression options.
362 bzip2) compress="bzip -9";;
363 lzma
) compress="lzma -9";;
364 xz
) compress="xz --check=crc32 --lzma2=dict=1MiB";;
365 gzip) type pigz
> /dev
/null
2>&1 && compress="pigz -9" || \
368 if [[ $_no_compress_l = "cat" ]]; then
372 [[ $hostonly = yes ]] && hostonly
="-h"
373 [[ $hostonly != "-h" ]] && unset hostonly
374 [[ $compress ]] ||
compress="gzip -9"
376 if [[ -f $dracutbasedir/dracut-functions
]]; then
377 .
$dracutbasedir/dracut-functions
379 echo "Cannot find $dracutbasedir/dracut-functions." >&2
380 echo "Are you running from a git checkout?" >&2
381 echo "Try passing -l as an argument to $0" >&2
385 dracutfunctions
=$dracutbasedir/dracut-functions
386 export dracutfunctions
388 ddebug
"Executing $0 $dracut_args"
390 [[ $do_list = yes ]] && {
391 for mod
in $dracutbasedir/modules.d
/*; do
392 [[ -d $mod ]] ||
continue;
393 [[ -e $mod/install ||
-e $mod/installkernel || \
394 -e $mod/module-setup.sh
]] ||
continue
401 [[ $libdir ]] ||
for libdir
in /lib64
/lib
; do
402 [[ -d $libdir ]] && break
404 dfatal
'No lib directory?!!!'
408 [[ $usrlibdir ]] ||
for usrlibdir
in /usr
/lib64
/usr
/lib
; do
409 [[ -d $usrlibdir ]] && break
410 done || dwarn
'No usr/lib directory!'
412 # This is kinda legacy -- eventually it should go away.
413 case $dracutmodules in
414 ""|auto
) dracutmodules
="all" ;;
417 abs_outfile
=$
(readlink
-f "$outfile") && outfile
="$abs_outfile"
419 srcmods
="/lib/modules/$kernel/"
420 [[ $drivers_dir ]] && {
421 if vercmp $
(modprobe
--version | cut
-d' ' -f3) lt
3.7; then
422 dfatal
'To use --kmoddir option module-init-tools >= 3.7 is required.'
425 srcmods
="$drivers_dir"
429 if [[ -f $outfile && ! $force ]]; then
430 dfatal
"Will not override existing initramfs ($outfile) without --force"
435 [[ $outdir ]] || outdir
="/"
437 if [[ ! -d "$outdir" ]]; then
438 dfatal
"Can't write $outfile: Directory $outdir does not exist."
440 elif [[ ! -w "$outdir" ]]; then
441 dfatal
"No permission to write $outdir."
443 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
444 dfatal
"No permission to write $outfile."
448 [[ $TMPDIR && ! -w $TMPDIR ]] && unset TMPDIR
449 readonly initdir
=$
(mktemp
-d -t initramfs.XXXXXX
)
451 # clean up after ourselves no matter how we die.
452 trap 'ret=$?;rm -rf "$initdir";exit $ret;' EXIT
453 # clean up after ourselves no matter how we die.
454 trap 'exit 1;' SIGINT
456 # Need to be able to have non-root users read stuff (rpcbind etc)
459 export initdir dracutbasedir dracutmodules drivers \
460 fw_dir drivers_dir debug no_kernel kernel_only \
461 add_drivers mdadmconf lvmconf filesystems \
462 use_fstab libdir usrlibdir \
463 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
466 if [[ $kernel_only != yes ]]; then
467 # Create some directory structure first
468 for d
in bin sbin usr
/bin usr
/sbin usr
/lib etc \
469 proc sys sysroot tmp dev
/pts var
/run
; do
474 # check all our modules to see if they should be sourced.
475 # This builds a list of modules that we will install next.
478 # source our modules.
479 for moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
480 mod
=${moddir##*/}; mod
=${mod#[0-9][0-9]}
481 if strstr
"$mods_to_load" " $mod "; then
482 [[ $show_modules = yes ]] && echo "$mod" || \
483 dinfo
"*** Including module: $mod ***"
484 if [[ $kernel_only = yes ]]; then
485 module_installkernel
$mod
488 if [[ $no_kernel != yes ]]; then
489 module_installkernel
$mod
492 mods_to_load
=${mods_to_load// $mod /}
496 dinfo
"*** Including modules done ***"
498 ## final stuff that has to happen
500 # generate module dependencies for the initrd
501 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
502 ! depmod
-a -b "$initdir" $kernel; then
503 dfatal
"\"depmod -a $kernel\" failed."
507 while pop include_src src
&& pop include_target tgt
; do
508 if [[ $src && $tgt ]]; then
509 if [[ -f $src ]]; then
512 ddebug
"Including directory: $src"
513 mkdir
-p "${initdir}/${tgt}"
514 cp -a -t "${initdir}/${tgt}" "$src"/*
519 while pop install_items items
; do
520 for item
in $items; do
521 dracut_install
"$item"
526 # make sure that library links are correct and up to date
527 for f
in /etc
/ld.so.conf
/etc
/ld.so.conf.d
/*; do
528 [[ -e $f ]] && dracut_install
"$f"
530 if ! ldconfig
-r "$initdir"; then
531 if [[ $UID = 0 ]]; then
532 derror
"ldconfig exited ungracefully"
534 derror
"ldconfig might need uid=0 (root) for chroot()"
538 if (($maxloglvl >= 5)); then
539 ddebug
"Listing sizes of included files:"
540 du
-c "$initdir" |
sort -n | ddebug
544 if [[ $do_strip = yes ]] ; then
545 for p
in strip
grep find; do
546 if ! type -P $p >/dev
/null
; then
547 derror
"Could not find '$p'. You should run $0 with '--nostrip'."
553 if [[ $do_strip = yes ]] ; then
554 for f
in $
(find "$initdir" -type f \
555 \
( -perm -0100 -or -perm -0010 -or -perm -0001 \
556 -or -path '*/lib/modules/*.ko' \
) ); do
558 strip
-g "$f" 2>/dev
/null||
:
562 type hardlink
&>/dev
/null
&& {
563 hardlink
"$initdir" 2>&1
566 if ! ( cd "$initdir"; find . |
cpio -R 0:0 -H newc
-o --quiet | \
567 $compress > "$outfile"; ); then
568 dfatal
"dracut: creation of $outfile failed"
572 dinfo
"Wrote $outfile:"
573 dinfo
"$(ls -l "$outfile")"