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 Verbose output during the build process (info level)
71 -q, --quiet Display only errors and fatal errors during build
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 --no-compress Do not compress the generated initramfs. This will
100 override any other compression options.
101 --list-modules List all available dracut modules.
106 # push values to a stack
107 # $1 = stack variable
110 # push stack 1 2 "3 4"
112 local __stack
=$1; shift
114 eval ${__stack}'[${#'${__stack}'[@]}]="$i"'
119 # pops the last value from a stack
120 # assigns value to second argument variable
121 # or echo to stdout, if no second argument
122 # $1 = stack variable
123 # $2 = optional variable to store the value
128 local __stack=$1; shift
131 # check for empty stack
132 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
134 eval myresult='${'${__stack}'[${#'${__stack}'[@]}-1]}'
136 if [[ "$__resultvar" ]]; then
137 eval $__resultvar="'$myresult'"
141 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
145 # Little helper function for reading args from the commandline.
146 # it automatically handles -a b and -a=b variants, and returns 1 if
147 # we need to shift $3.
152 local rematch
='^[^=]*=(.*)$'
153 if [[ $2 =~
$rematch ]]; then
154 read "$1" <<< "${BASH_REMATCH[1]}"
157 # There is no way to shift our callers args, so
158 # return 1 to indicate they should do it instead.
163 # Little helper function for reading args from the commandline to a stack.
164 # it automatically handles -a b and -a=b variants, and returns 1 if
165 # we need to shift $3.
170 local rematch
='^[^=]*=(.*)$'
171 if [[ $2 =~
$rematch ]]; then
172 push
"$1" "${BASH_REMATCH[1]}"
175 # There is no way to shift our callers args, so
176 # return 1 to indicate they should do it instead.
186 -a|
--add) push_arg add_dracutmodules_l
"$@" ||
shift;;
187 --add-drivers) push_arg add_drivers_l
"$@" ||
shift;;
188 -m|
--modules) push_arg dracutmodules_l
"$@" ||
shift;;
189 -o|
--omit) push_arg omit_dracutmodules_l
"$@" ||
shift;;
190 -d|
--drivers) push_arg drivers_l
"$@" ||
shift;;
191 --filesystems) push_arg filesystems_l
"$@" ||
shift;;
192 -I|
--install) push_arg install_items
"$@" ||
shift;;
193 --fwdir) push_arg fw_dir_l
"$@" ||
shift;;
194 -k|
--kmoddir) read_arg drivers_dir_l
"$@" ||
shift;;
195 -c|
--conf) read_arg conffile
"$@" ||
shift;;
196 --confdir) read_arg confdir
"$@" ||
shift;;
197 -L|
--stdlog) read_arg stdloglvl_l
"$@" ||
shift;;
198 -f|
--force) force
=yes;;
199 --kernel-only) kernel_only
="yes"; no_kernel
="no";;
200 --no-kernel) kernel_only
="no"; no_kernel
="yes";;
201 --strip) do_strip_l
="yes";;
202 --nostrip) do_strip_l
="no";;
203 --mdadmconf) mdadmconf_l
="yes";;
204 --nomdadmconf) mdadmconf_l
="no";;
205 --lvmconf) lvmconf_l
="yes";;
206 --nolvmconf) lvmconf_l
="no";;
207 --debug) debug
="yes";;
208 -v|
--verbose) beverbose
="yes";;
209 -q|
--quiet) bequiet
="yes";;
210 -l|
--local) allowlocal
="yes" ;;
211 -H|
--hostonly) hostonly_l
="yes" ;;
212 --fstab) use_fstab_l
="yes" ;;
213 -h|
--help) usage
; exit 1 ;;
214 -i|
--include) push include_src
"$2"; push include_target
"$3"; shift 2;;
215 --bzip2) [[ $compress != cat ]] && compress="bzip2 -9";;
216 --lzma) [[ $compress != cat ]] && compress="lzma -9";;
217 --xz) [[ $compress != cat ]] && compress="xz -9";;
218 --no-compress) compress="cat";;
219 --gzip) if [[ $compress != cat ]]; then
220 type pigz
> /dev
/null
2>&1 && compress="pigz -9" || \
226 -*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage
; exit 1;;
228 if ! [[ $outfile ]]; then
230 elif [[ $kernel = "unset" ]]; then
239 if ! [[ $kernel ]] ||
[[ $kernel = "unset" ]]; then
242 [[ $outfile ]] || outfile
="/boot/initramfs-$kernel.img"
244 PATH
=/sbin
:/bin
:/usr
/sbin
:/usr
/bin
248 export PS4
='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
252 # For compatibility with -v behaviour. Set to info level.
253 [[ $beverbose ]] && (( $stdloglvl_l < 4 )) && stdloglvl_l
=4
255 # When quiet, display only errors and fatal errors.
256 [[ $bequiet ]] && (( $stdloglvl_l > 2 )) && stdloglvl_l
=2
258 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
260 [[ $allowlocal && -f "$(readlink -f ${0%/*})/dracut-functions" ]] && \
261 dracutbasedir
="${0%/*}"
263 # if we were not passed a config file, try the default one
264 if [[ ! -f $conffile ]]; then
265 [[ $allowlocal ]] && conffile
="$dracutbasedir/dracut.conf" || \
266 conffile
="/etc/dracut.conf"
269 if [[ ! -d $confdir ]]; then
270 [[ $allowlocal ]] && confdir
="$dracutbasedir/dracut.conf.d" || \
271 confdir
="/etc/dracut.conf.d"
274 # source our config file
275 [[ -f $conffile ]] && .
"$conffile"
277 # source our config dir
278 if [[ $confdir && -d $confdir ]]; then
279 for f
in "$confdir"/*.conf
; do
280 [[ -e $f ]] && .
"$f"
284 # these optins add to the stuff in the config file
285 if [[ ${#add_dracutmodules_l[@]} ]]; then
286 while pop add_dracutmodules_l val
; do
287 add_dracutmodules
+=" $val "
291 if [[ ${#add_drivers_l[@]} ]]; then
292 while pop add_drivers_l val
; do
293 add_drivers
+=" $val "
297 # these options override the stuff in the config file
298 if [[ ${#dracutmodules_l[@]} ]]; then
300 while pop dracutmodules_l val
; do
301 dracutmodules
+="$val "
305 if [[ ${#omit_dracutmodules_l[@]} ]]; then
306 omit_dracutmodules
=''
307 while pop omit_dracutmodules_l val
; do
308 omit_dracutmodules
+="$val "
312 if [[ ${#drivers_l[@]} ]]; then
314 while pop drivers_l val
; do
319 if [[ ${#filesystems_l[@]} ]]; then
321 while pop filesystems_l val
; do
326 if [[ ${#fw_dir_l[@]} ]]; then
328 while pop fw_dir_l val
; do
333 [[ $stdloglvl_l ]] && stdloglvl
=$stdloglvl_l
334 [[ $drivers_dir_l ]] && drivers_dir
=$drivers_dir_l
335 [[ $do_strip_l ]] && do_strip
=$do_strip_l
336 [[ $hostonly_l ]] && hostonly
=$hostonly_l
337 [[ $use_fstab_l ]] && use_fstab
=$use_fstab_l
338 [[ $mdadmconf_l ]] && mdadmconf
=$mdadmconf_l
339 [[ $lvmconf_l ]] && lvmconf
=$lvmconf_l
340 [[ $dracutbasedir ]] || dracutbasedir
=/usr
/share
/dracut
341 [[ $fw_dir ]] || fw_dir
=/lib
/firmware
342 [[ $do_strip ]] || do_strip
=no
343 # eliminate IFS hackery when messing with fw_dir
344 fw_dir
=${fw_dir//:/ }
346 [[ $hostonly = yes ]] && hostonly
="-h"
347 [[ $hostonly != "-h" ]] && unset hostonly
348 [[ $compress ]] ||
compress="gzip -9"
350 if [[ -f $dracutbasedir/dracut-functions
]]; then
351 .
$dracutbasedir/dracut-functions
353 echo "Cannot find $dracutbasedir/dracut-functions." >&2
354 echo "Are you running from a git checkout?" >&2
355 echo "Try passing -l as an argument to $0" >&2
359 dracutfunctions
=$dracutbasedir/dracut-functions
360 export dracutfunctions
362 dinfo
"Executing $0 $dracut_args"
364 [[ $do_list = yes ]] && {
365 for mod
in $dracutbasedir/modules.d
/*; do
366 [[ -d $mod ]] ||
continue;
367 [[ -e $mod/install ||
-e $mod/installkernel || \
368 -e $mod/module-setup.sh
]] ||
continue
375 [[ $libdir ]] ||
for libdir
in /lib64
/lib
; do
376 [[ -d $libdir ]] && break
378 derror
'No lib directory?!!!'
381 [[ $usrlibdir ]] ||
for usrlibdir
in /usr
/lib64
/usr
/lib
; do
382 [[ -d $usrlibdir ]] && break
383 done || dwarning
'No usr/lib directory!'
385 # This is kinda legacy -- eventually it should go away.
386 case $dracutmodules in
387 ""|auto
) dracutmodules
="all" ;;
390 abs_outfile
=$
(readlink
-f "$outfile") && outfile
="$abs_outfile"
392 srcmods
="/lib/modules/$kernel/"
393 [[ $drivers_dir ]] && {
394 if vercmp $
(modprobe
--version | cut
-d' ' -f3) lt
3.7; then
395 derror
'To use --kmoddir option module-init-tools >= 3.7 is required.'
398 srcmods
="$drivers_dir"
402 if [[ -f $outfile && ! $force ]]; then
403 derror
"Will not override existing initramfs ($outfile) without --force"
408 if [[ ! -d "$outdir" ]]; then
409 derror
"Can't write $outfile: Directory $outdir does not exist."
411 elif [[ ! -w "$outdir" ]]; then
412 derror
"No permission to write $outdir."
414 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
415 derror
"No permission to write $outfile."
419 hookdirs
="cmdline pre-udev pre-trigger netroot pre-mount"
420 hookdirs
+=" pre-pivot mount emergency"
422 [[ $TMPDIR && ! -w $TMPDIR ]] && unset TMPDIR
423 readonly initdir
=$
(mktemp
-d -t initramfs.XXXXXX
)
425 # clean up after ourselves no matter how we die.
426 trap 'ret=$?;rm -rf "$initdir";exit $ret;' EXIT
427 # clean up after ourselves no matter how we die.
428 trap 'exit 1;' SIGINT
430 # Need to be able to have non-root users read stuff (rpcbind etc)
433 export initdir hookdirs dracutbasedir dracutmodules drivers \
434 fw_dir drivers_dir debug no_kernel kernel_only \
435 add_drivers mdadmconf lvmconf filesystems \
436 use_fstab libdir usrlibdir \
437 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile
439 if [[ $kernel_only != yes ]]; then
440 # Create some directory structure first
441 for d
in bin sbin usr
/bin usr
/sbin usr
/lib etc \
442 proc sys sysroot tmp dev
/pts var
/run
; do
447 # check all our modules to see if they should be sourced.
448 # This builds a list of modules that we will install next.
451 # source our modules.
452 for moddir
in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
453 mod
=${moddir##*/}; mod
=${mod#[0-9][0-9]}
454 if strstr
"$mods_to_load" " $mod "; then
455 dinfo
"*** Sourcing module $mod"
456 if [[ $kernel_only = yes ]]; then
457 module_installkernel
$mod
460 if [[ $no_kernel != yes ]]; then
461 module_installkernel
$mod
464 mods_to_load
=${mods_to_load// $mod /}
469 ## final stuff that has to happen
471 # generate module dependencies for the initrd
472 if [[ -d $initdir/lib
/modules
/$kernel ]] && \
473 ! depmod
-a -b "$initdir" $kernel; then
474 derror
"\"depmod -a $kernel\" failed."
478 while pop include_src src
&& pop include_target tgt
; do
479 if [[ $src && $tgt ]]; then
480 if [[ -f $src ]]; then
483 mkdir
-p "${initdir}/${tgt}"
484 cp -a -t "${initdir}/${tgt}" "$src"/*
489 while pop install_items items
; do
490 for item
in $items; do
491 dracut_install
"$item"
496 # make sure that library links are correct and up to date
497 cp -ar /etc
/ld.so.conf
* "$initdir"/etc
498 ldconfig
-r "$initdir" ||
[[ $UID != "0" ]] && \
499 dinfo
"ldconfig might need uid=0 (root) for chroot()"
501 [[ $beverbose = yes ]] && (du
-c "$initdir" |
sort -n)
504 if [[ $do_strip = yes ]] ; then
505 for p
in strip
grep find; do
506 if ! type -P $p >/dev
/null
; then
507 derror
"Could not find '$p'. You should run $0 with '--nostrip'."
513 if [[ $do_strip = yes ]] ; then
514 for f
in $
(find "$initdir" -type f \
515 \
( -perm -0100 -or -perm -0010 -or -perm -0001 \
516 -or -path '*/lib/modules/*.ko' \
) ); do
518 strip
-g "$f" 2>/dev
/null||
:
522 type hardlink
&>/dev
/null
&& {
523 hardlink
"$initdir" 2>&1
526 if ! ( cd "$initdir"; find . |
cpio -R 0:0 -H newc
-o --quiet | \
527 $compress > "$outfile"; ); then
528 derror
"dracut: creation of $outfile failed"
531 dinfo
"Wrote $outfile"
532 dinfo $
(ls -l "$outfile")