]> git.ipfire.org Git - thirdparty/dracut.git/blob - dracut.sh
469f40872074807c71588e627f988c3eaa89d5f8
[thirdparty/dracut.git] / dracut.sh
1 #!/bin/bash
2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
4 #
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
8 #
9
10 # Copyright 2005-2010 Red Hat, Inc. All rights reserved.
11 #
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.
16 #
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.
21 #
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/>.
24 #
25
26 # store for logging
27 dracut_args=( "$@" )
28
29 set -o pipefail
30
31 usage() {
32 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
33 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
34 . $dracutbasedir/dracut-version.sh
35 fi
36
37 # 80x25 linebreak here ^
38 cat << EOF
39 Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
40
41 Version: $DRACUT_VERSION
42
43 Creates initial ramdisk images for preloading modules
44
45 -h, --help Display all options
46
47 If a [LIST] has multiple arguments, then you have to put these in quotes.
48
49 For example:
50
51 # dracut --add-drivers "module1 module2" ...
52
53 EOF
54 }
55
56 long_usage() {
57 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
58 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
59 . $dracutbasedir/dracut-version.sh
60 fi
61
62 # 80x25 linebreak here ^
63 cat << EOF
64 Usage: $0 [OPTION]... [<initramfs> [<kernel-version>]]
65
66 Version: $DRACUT_VERSION
67
68 Creates initial ramdisk images for preloading modules
69
70 --kver [VERSION] Set kernel version to [VERSION].
71 -f, --force Overwrite existing initramfs file.
72 -m, --modules [LIST] Specify a space-separated list of dracut modules to
73 call when building the initramfs. Modules are located
74 in /usr/lib/dracut/modules.d.
75 -o, --omit [LIST] Omit a space-separated list of dracut modules.
76 -a, --add [LIST] Add a space-separated list of dracut modules.
77 -d, --drivers [LIST] Specify a space-separated list of kernel modules to
78 exclusively include in the initramfs.
79 --add-drivers [LIST] Specify a space-separated list of kernel
80 modules to add to the initramfs.
81 --omit-drivers [LIST] Specify a space-separated list of kernel
82 modules not to add to the initramfs.
83 --filesystems [LIST] Specify a space-separated list of kernel filesystem
84 modules to exclusively include in the generic
85 initramfs.
86 -k, --kmoddir [DIR] Specify the directory, where to look for kernel
87 modules
88 --fwdir [DIR] Specify additional directories, where to look for
89 firmwares, separated by :
90 --kernel-only Only install kernel drivers and firmware files
91 --no-kernel Do not install kernel drivers and firmware files
92 --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
93 --strip Strip binaries in the initramfs (default)
94 --nostrip Do not strip binaries in the initramfs
95 --hardlink Hardlink files in the initramfs (default)
96 --nohardlink Do not hardlink files in the initramfs
97 --prefix [DIR] Prefix initramfs files with [DIR]
98 --noprefix Do not prefix initramfs files (default)
99 --mdadmconf Include local /etc/mdadm.conf
100 --nomdadmconf Do not include local /etc/mdadm.conf
101 --lvmconf Include local /etc/lvm/lvm.conf
102 --nolvmconf Do not include local /etc/lvm/lvm.conf
103 --fscks [LIST] Add a space-separated list of fsck helpers.
104 --nofscks Inhibit installation of any fsck helpers.
105 --ro-mnt Mount / and /usr read-only by default.
106 -h, --help This message
107 --debug Output debug information of the build process
108 --profile Output profile information of the build process
109 -L, --stdlog [0-6] Specify logging level (to standard error)
110 0 - suppress any messages
111 1 - only fatal errors
112 2 - all errors
113 3 - warnings
114 4 - info (default)
115 5 - debug info (here starts lots of output)
116 6 - trace info (and even more)
117 -v, --verbose Increase verbosity level (default is info(4))
118 -q, --quiet Decrease verbosity level (default is info(4))
119 -c, --conf [FILE] Specify configuration file to use.
120 Default: /etc/dracut.conf
121 --confdir [DIR] Specify configuration directory to use *.conf files
122 from. Default: /etc/dracut.conf.d
123 --tmpdir [DIR] Temporary directory to be used instead of default
124 /var/tmp.
125 -l, --local Local mode. Use modules from the current working
126 directory instead of the system-wide installed in
127 /usr/lib/dracut/modules.d.
128 Useful when running dracut from a git checkout.
129 -H, --hostonly Host-Only mode: Install only what is needed for
130 booting the local host instead of a generic host.
131 -N, --no-hostonly Disables Host-Only mode
132 --fstab Use /etc/fstab to determine the root device.
133 --add-fstab [FILE] Add file to the initramfs fstab
134 --mount "[DEV] [MP] [FSTYPE] [FSOPTS]"
135 Mount device [DEV] on mountpoint [MP] with filesystem
136 [FSTYPE] and options [FSOPTS] in the initramfs
137 --device "[DEV]" Bring up [DEV] in initramfs
138 -i, --include [SOURCE] [TARGET]
139 Include the files in the SOURCE directory into the
140 Target directory in the final initramfs.
141 If SOURCE is a file, it will be installed to TARGET
142 in the final initramfs.
143 -I, --install [LIST] Install the space separated list of files into the
144 initramfs.
145 --gzip Compress the generated initramfs using gzip.
146 This will be done by default, unless another
147 compression option or --no-compress is passed.
148 --bzip2 Compress the generated initramfs using bzip2.
149 Make sure your kernel has bzip2 decompression support
150 compiled in, otherwise you will not be able to boot.
151 --lzma Compress the generated initramfs using lzma.
152 Make sure your kernel has lzma support compiled in,
153 otherwise you will not be able to boot.
154 --xz Compress the generated initramfs using xz.
155 Make sure that your kernel has xz support compiled
156 in, otherwise you will not be able to boot.
157 --compress [COMPRESSION] Compress the generated initramfs with the
158 passed compression program. Make sure your kernel
159 knows how to decompress the generated initramfs,
160 otherwise you will not be able to boot.
161 --no-compress Do not compress the generated initramfs. This will
162 override any other compression options.
163 --list-modules List all available dracut modules.
164 -M, --show-modules Print included module's name to standard output during
165 build.
166 --keep Keep the temporary initramfs for debugging purposes
167 --printsize Print out the module install size
168 --sshkey [SSHKEY] Add ssh key to initramfs (use with ssh-client module)
169
170 If [LIST] has multiple arguments, then you have to put these in quotes.
171
172 For example:
173
174 # dracut --add-drivers "module1 module2" ...
175
176 EOF
177 }
178
179 # function push()
180 # push values to a stack
181 # $1 = stack variable
182 # $2.. values
183 # example:
184 # push stack 1 2 "3 4"
185 push() {
186 local _i
187 local __stack=$1; shift
188 for _i in "$@"; do
189 eval ${__stack}'[${#'${__stack}'[@]}]="$_i"'
190 done
191 }
192
193 # function pop()
194 # pops the last value from a stack
195 # assigns value to second argument variable
196 # or echo to stdout, if no second argument
197 # $1 = stack variable
198 # $2 = optional variable to store the value
199 # example:
200 # pop stack val
201 # val=$(pop stack)
202 pop() {
203 local __stack=$1; shift
204 local __resultvar=$1
205 local _value;
206 # check for empty stack
207 eval '[[ ${#'${__stack}'[@]} -eq 0 ]] && return 1'
208
209 eval _value='${'${__stack}'[${#'${__stack}'[@]}-1]}'
210
211 if [[ "$__resultvar" ]]; then
212 eval $__resultvar="'$_value'"
213 else
214 echo "$_value"
215 fi
216 eval unset ${__stack}'[${#'${__stack}'[@]}-1]'
217 return 0
218 }
219
220 # Little helper function for reading args from the commandline.
221 # it automatically handles -a b and -a=b variants, and returns 1 if
222 # we need to shift $3.
223 read_arg() {
224 # $1 = arg name
225 # $2 = arg value
226 # $3 = arg parameter
227 local rematch='^[^=]*=(.*)$'
228 if [[ $2 =~ $rematch ]]; then
229 read "$1" <<< "${BASH_REMATCH[1]}"
230 else
231 read "$1" <<< "$3"
232 # There is no way to shift our callers args, so
233 # return 1 to indicate they should do it instead.
234 return 1
235 fi
236 }
237
238 verbosity_mod_l=0
239 unset kernel
240 unset outfile
241
242 # Workaround -i, --include taking 2 arguments
243 set -- "${@/--include/++include}"
244
245 # This prevents any long argument ending with "-i"
246 # -i, like --opt-i but I think we can just prevent that
247 set -- "${@/%-i/++include}"
248
249 TEMP=$(unset POSIXLY_CORRECT; getopt \
250 -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
251 --long kver: \
252 --long add: \
253 --long force-add: \
254 --long add-drivers: \
255 --long omit-drivers: \
256 --long modules: \
257 --long omit: \
258 --long drivers: \
259 --long filesystems: \
260 --long install: \
261 --long fwdir: \
262 --long libdirs: \
263 --long fscks: \
264 --long add-fstab: \
265 --long mount: \
266 --long device: \
267 --long nofscks: \
268 --long ro-mnt \
269 --long kmoddir: \
270 --long conf: \
271 --long confdir: \
272 --long tmpdir: \
273 --long stdlog: \
274 --long compress: \
275 --long prefix: \
276 --long force \
277 --long kernel-only \
278 --long no-kernel \
279 --long kernel-cmdline: \
280 --long strip \
281 --long nostrip \
282 --long hardlink \
283 --long nohardlink \
284 --long noprefix \
285 --long mdadmconf \
286 --long nomdadmconf \
287 --long lvmconf \
288 --long nolvmconf \
289 --long debug \
290 --long profile \
291 --long sshkey: \
292 --long verbose \
293 --long quiet \
294 --long local \
295 --long hostonly \
296 --long no-hostonly \
297 --long fstab \
298 --long help \
299 --long bzip2 \
300 --long lzma \
301 --long xz \
302 --long no-compress \
303 --long gzip \
304 --long list-modules \
305 --long show-modules \
306 --long keep \
307 --long printsize \
308 -- "$@")
309
310 if (( $? != 0 )); then
311 usage
312 exit 1
313 fi
314
315 eval set -- "$TEMP"
316
317 while :; do
318 case $1 in
319 --kver) kernel="$2"; shift;;
320 -a|--add) push add_dracutmodules_l "$2"; shift;;
321 --force-add) push force_add_dracutmodules_l "$2"; shift;;
322 --add-drivers) push add_drivers_l "$2"; shift;;
323 --omit-drivers) push omit_drivers_l "$2"; shift;;
324 -m|--modules) push dracutmodules_l "$2"; shift;;
325 -o|--omit) push omit_dracutmodules_l "$2"; shift;;
326 -d|--drivers) push drivers_l "$2"; shift;;
327 --filesystems) push filesystems_l "$2"; shift;;
328 -I|--install) push install_items_l "$2"; shift;;
329 --fwdir) push fw_dir_l "$2"; shift;;
330 --libdirs) push libdirs_l "$2"; shift;;
331 --fscks) push fscks_l "$2"; shift;;
332 --add-fstab) push add_fstab_l "$2"; shift;;
333 --mount) push fstab_lines "$2"; shift;;
334 --device) push host_devs "$2"; shift;;
335 --kernel-cmdline) push kernel_cmdline_l "$2"; shift;;
336 --nofscks) nofscks_l="yes";;
337 --ro-mnt) ro_mnt_l="yes";;
338 -k|--kmoddir) drivers_dir_l="$2"; shift;;
339 -c|--conf) conffile="$2"; shift;;
340 --confdir) confdir="$2"; shift;;
341 --tmpdir) tmpdir_l="$2"; shift;;
342 -L|--stdlog) stdloglvl_l="$2"; shift;;
343 --compress) compress_l="$2"; shift;;
344 --prefix) prefix_l="$2"; shift;;
345 -f|--force) force=yes;;
346 --kernel-only) kernel_only="yes"; no_kernel="no";;
347 --no-kernel) kernel_only="no"; no_kernel="yes";;
348 --strip) do_strip_l="yes";;
349 --nostrip) do_strip_l="no";;
350 --hardlink) do_hardlink_l="yes";;
351 --nohardlink) do_hardlink_l="no";;
352 --noprefix) prefix_l="/";;
353 --mdadmconf) mdadmconf_l="yes";;
354 --nomdadmconf) mdadmconf_l="no";;
355 --lvmconf) lvmconf_l="yes";;
356 --nolvmconf) lvmconf_l="no";;
357 --debug) debug="yes";;
358 --profile) profile="yes";;
359 --sshkey) sshkey="$2"; shift;;
360 -v|--verbose) ((verbosity_mod_l++));;
361 -q|--quiet) ((verbosity_mod_l--));;
362 -l|--local)
363 allowlocal="yes"
364 [[ -f "$(readlink -f ${0%/*})/dracut-functions.sh" ]] \
365 && dracutbasedir="$(readlink -f ${0%/*})"
366 ;;
367 -H|--hostonly) hostonly_l="yes" ;;
368 -N|--no-hostonly) hostonly_l="no" ;;
369 --fstab) use_fstab_l="yes" ;;
370 -h|--help) long_usage; exit 1 ;;
371 -i|--include) push include_src "$2"
372 shift;;
373 --bzip2) compress_l="bzip2";;
374 --lzma) compress_l="lzma";;
375 --xz) compress_l="xz";;
376 --no-compress) _no_compress_l="cat";;
377 --gzip) compress_l="gzip";;
378 --list-modules) do_list="yes";;
379 -M|--show-modules)
380 show_modules_l="yes"
381 ;;
382 --keep) keep="yes";;
383 --printsize) printsize="yes";;
384
385 --) shift; break;;
386
387 *) # should not even reach this point
388 printf "\n!Unknown option: '%s'\n\n" "$1" >&2; usage; exit 1;;
389 esac
390 shift
391 done
392
393 # getopt cannot handle multiple arguments, so just handle "-I,--include"
394 # the old fashioned way
395
396 while (($# > 0)); do
397 case ${1%%=*} in
398 ++include) push include_src "$2"
399 push include_target "$3"
400 shift 2;;
401 *)
402 if ! [[ ${outfile+x} ]]; then
403 outfile=$1
404 elif ! [[ ${kernel+x} ]]; then
405 kernel=$1
406 else
407 printf "\nUnknown arguments: %s\n\n" "$*" >&2
408 usage; exit 1;
409 fi
410 ;;
411 esac
412 shift
413 done
414
415 if ! [[ $kernel ]]; then
416 kernel=$(uname -r)
417 fi
418
419 if ! [[ $outfile ]]; then
420 outfile="/boot/initramfs-$kernel.img"
421 fi
422
423 for i in /usr/sbin /sbin /usr/bin /bin; do
424 rl=$i
425 if [ -L "$i" ]; then
426 rl=$(readlink -f $i)
427 fi
428 if [[ "$NPATH" != "*:$rl*" ]] ; then
429 NPATH+=":$rl"
430 fi
431 done
432 export PATH="${NPATH#:}"
433 unset NPATH
434 unset LD_LIBRARY_PATH
435 unset GREP_OPTIONS
436
437 export DRACUT_LOG_LEVEL=warning
438 [[ $debug ]] && {
439 export DRACUT_LOG_LEVEL=debug
440 export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
441 set -x
442 }
443
444 [[ $profile ]] && {
445 export PS4='+ $(date "+%s.%N") ${BASH_SOURCE}@${LINENO}: ';
446 set -x
447 debug=yes
448 }
449
450 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
451
452 # if we were not passed a config file, try the default one
453 if [[ ! -f $conffile ]]; then
454 [[ $allowlocal ]] && conffile="$dracutbasedir/dracut.conf" || \
455 conffile="/etc/dracut.conf"
456 fi
457
458 if [[ ! -d $confdir ]]; then
459 [[ $allowlocal ]] && confdir="$dracutbasedir/dracut.conf.d" || \
460 confdir="/etc/dracut.conf.d"
461 fi
462
463 # source our config file
464 [[ -f $conffile ]] && . "$conffile"
465
466 # source our config dir
467 if [[ $confdir && -d $confdir ]]; then
468 for f in "$confdir"/*.conf; do
469 [[ -e $f ]] && . "$f"
470 done
471 fi
472
473 # these optins add to the stuff in the config file
474 if (( ${#add_dracutmodules_l[@]} )); then
475 while pop add_dracutmodules_l val; do
476 add_dracutmodules+=" $val "
477 done
478 fi
479
480 if (( ${#force_add_dracutmodules_l[@]} )); then
481 while pop force_add_dracutmodules_l val; do
482 force_add_dracutmodules+=" $val "
483 done
484 fi
485
486 if (( ${#fscks_l[@]} )); then
487 while pop fscks_l val; do
488 fscks+=" $val "
489 done
490 fi
491
492 if (( ${#add_fstab_l[@]} )); then
493 while pop add_fstab_l val; do
494 add_fstab+=" $val "
495 done
496 fi
497
498 if (( ${#fstab_lines_l[@]} )); then
499 while pop fstab_lines_l val; do
500 push fstab_lines $val
501 done
502 fi
503
504 if (( ${#install_items_l[@]} )); then
505 while pop install_items_l val; do
506 install_items+=" $val "
507 done
508 fi
509
510 # these options override the stuff in the config file
511 if (( ${#dracutmodules_l[@]} )); then
512 dracutmodules=''
513 while pop dracutmodules_l val; do
514 dracutmodules+="$val "
515 done
516 fi
517
518 if (( ${#omit_dracutmodules_l[@]} )); then
519 omit_dracutmodules=''
520 while pop omit_dracutmodules_l val; do
521 omit_dracutmodules+="$val "
522 done
523 fi
524
525 if (( ${#filesystems_l[@]} )); then
526 filesystems=''
527 while pop filesystems_l val; do
528 filesystems+="$val "
529 done
530 fi
531
532 if (( ${#fw_dir_l[@]} )); then
533 fw_dir=''
534 while pop fw_dir_l val; do
535 fw_dir+="$val "
536 done
537 fi
538
539 if (( ${#libdirs_l[@]} )); then
540 libdirs=''
541 while pop libdirs_l val; do
542 libdirs+="$val "
543 done
544 fi
545
546 [[ $stdloglvl_l ]] && stdloglvl=$stdloglvl_l
547 [[ ! $stdloglvl ]] && stdloglvl=4
548 stdloglvl=$((stdloglvl + verbosity_mod_l))
549 ((stdloglvl > 6)) && stdloglvl=6
550 ((stdloglvl < 0)) && stdloglvl=0
551
552 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
553 [[ $do_strip_l ]] && do_strip=$do_strip_l
554 [[ $do_strip ]] || do_strip=yes
555 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
556 [[ $do_hardlink ]] || do_hardlink=yes
557 [[ $prefix_l ]] && prefix=$prefix_l
558 [[ $prefix = "/" ]] && unset prefix
559 [[ $hostonly_l ]] && hostonly=$hostonly_l
560 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
561 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
562 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
563 [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
564 [[ $fw_dir ]] || fw_dir="/lib/firmware/updates /lib/firmware"
565 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
566 [[ $tmpdir ]] || tmpdir=/var/tmp
567 [[ $compress_l ]] && compress=$compress_l
568 [[ $show_modules_l ]] && show_modules=$show_modules_l
569 [[ $nofscks_l ]] && nofscks="yes"
570 [[ $ro_mnt_l ]] && ro_mnt="yes"
571 # eliminate IFS hackery when messing with fw_dir
572 fw_dir=${fw_dir//:/ }
573
574 # handle compression options.
575 [[ $compress ]] || compress="gzip"
576 case $compress in
577 bzip2) compress="bzip2 -9";;
578 lzma) compress="lzma -9";;
579 xz) compress="xz --check=crc32 --lzma2=dict=1MiB";;
580 gzip) command -v pigz > /dev/null 2>&1 && compress="pigz -9" || \
581 compress="gzip -9";;
582 esac
583 if [[ $_no_compress_l = "cat" ]]; then
584 compress="cat"
585 fi
586
587 [[ $hostonly = yes ]] && hostonly="-h"
588 [[ $hostonly != "-h" ]] && unset hostonly
589
590 readonly TMPDIR="$tmpdir"
591 readonly initdir=$(mktemp --tmpdir="$TMPDIR/" -d -t initramfs.XXXXXX)
592 [ -d "$initdir" ] || {
593 echo "dracut: mktemp --tmpdir=\"$TMPDIR/\" -d -t initramfs.XXXXXX failed." >&2
594 exit 1
595 }
596
597 export DRACUT_KERNEL_LAZY="1"
598 export DRACUT_RESOLVE_LAZY="1"
599
600 if [[ -f $dracutbasedir/dracut-functions.sh ]]; then
601 . $dracutbasedir/dracut-functions.sh
602 else
603 echo "dracut: Cannot find $dracutbasedir/dracut-functions.sh." >&2
604 echo "dracut: Are you running from a git checkout?" >&2
605 echo "dracut: Try passing -l as an argument to $0" >&2
606 exit 1
607 fi
608
609 inst /bin/sh
610 if ! $DRACUT_INSTALL ${initdir+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
611 unset DRACUT_RESOLVE_LAZY
612 export DRACUT_RESOLVE_DEPS=1
613 fi
614 rm -fr ${initdir}/*
615
616 if [[ -f $dracutbasedir/dracut-version.sh ]]; then
617 . $dracutbasedir/dracut-version.sh
618 fi
619
620 # Verify bash version, current minimum is 3.1
621 if (( ${BASH_VERSINFO[0]} < 3 ||
622 ( ${BASH_VERSINFO[0]} == 3 && ${BASH_VERSINFO[1]} < 1 ) )); then
623 dfatal 'You need at least Bash 3.1 to use dracut, sorry.'
624 exit 1
625 fi
626
627 dracutfunctions=$dracutbasedir/dracut-functions.sh
628 export dracutfunctions
629
630 if (( ${#drivers_l[@]} )); then
631 drivers=''
632 while pop drivers_l val; do
633 drivers+="$val "
634 done
635 fi
636 drivers=${drivers/-/_}
637
638 if (( ${#add_drivers_l[@]} )); then
639 while pop add_drivers_l val; do
640 add_drivers+=" $val "
641 done
642 fi
643 add_drivers=${add_drivers/-/_}
644
645 if (( ${#omit_drivers_l[@]} )); then
646 while pop omit_drivers_l val; do
647 omit_drivers+=" $val "
648 done
649 fi
650 omit_drivers=${omit_drivers/-/_}
651
652 if (( ${#kernel_cmdline_l[@]} )); then
653 while pop kernel_cmdline_l val; do
654 kernel_cmdline+=" $val "
655 done
656 fi
657
658 omit_drivers_corrected=""
659 for d in $omit_drivers; do
660 strstr " $drivers $add_drivers " " $d " && continue
661 omit_drivers_corrected+="$d|"
662 done
663 omit_drivers="${omit_drivers_corrected%|}"
664 unset omit_drivers_corrected
665
666 # prepare args for logging
667 for ((i=0; i < ${#dracut_args[@]}; i++)); do
668 strstr "${dracut_args[$i]}" " " && \
669 dracut_args[$i]="\"${dracut_args[$i]}\""
670 #" keep vim happy
671 done
672 ddebug "Executing: $0 ${dracut_args[@]}"
673
674 [[ $do_list = yes ]] && {
675 for mod in $dracutbasedir/modules.d/*; do
676 [[ -d $mod ]] || continue;
677 [[ -e $mod/install || -e $mod/installkernel || \
678 -e $mod/module-setup.sh ]] || continue
679 echo ${mod##*/??}
680 done
681 exit 0
682 }
683
684 # This is kinda legacy -- eventually it should go away.
685 case $dracutmodules in
686 ""|auto) dracutmodules="all" ;;
687 esac
688
689 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
690
691 [[ -f $srcmods/modules.dep ]] || {
692 dfatal "$srcmods/modules.dep is missing. Did you run depmod?"
693 exit 1
694 }
695
696 if [[ -f $outfile && ! $force ]]; then
697 dfatal "Will not override existing initramfs ($outfile) without --force"
698 exit 1
699 fi
700
701 outdir=${outfile%/*}
702 [[ $outdir ]] || outdir="/"
703
704 if [[ ! -d "$outdir" ]]; then
705 dfatal "Can't write $outfile: Directory $outdir does not exist."
706 exit 1
707 elif [[ ! -w "$outdir" ]]; then
708 dfatal "No permission to write to $outdir."
709 exit 1
710 elif [[ -f "$outfile" && ! -w "$outfile" ]]; then
711 dfatal "No permission to write $outfile."
712 exit 1
713 fi
714
715 # clean up after ourselves no matter how we die.
716 trap 'ret=$?;[[ $keep ]] && echo "Not removing $initdir." >&2 || rm -rf "$initdir";exit $ret;' EXIT
717 # clean up after ourselves no matter how we die.
718 trap 'exit 1;' SIGINT
719
720 # Need to be able to have non-root users read stuff (rpcbind etc)
721 chmod 755 "$initdir"
722
723 for line in "${fstab_lines[@]}"; do
724 set -- $line
725 #dev mp fs fsopts
726 push host_devs "$1"
727 push host_fs_types "$1|$3"
728 done
729
730 for f in $add_fstab; do
731 [ -e $f ] || continue
732 while read dev rest; do
733 push host_devs $dev
734 done < $f
735 done
736
737 if [[ $hostonly ]]; then
738 # in hostonly mode, determine all devices, which have to be accessed
739 # and examine them for filesystem types
740
741 push host_mp \
742 "/" \
743 "/etc" \
744 "/usr" \
745 "/usr/bin" \
746 "/usr/sbin" \
747 "/usr/lib" \
748 "/usr/lib64" \
749 "/boot"
750
751 for mp in "${host_mp[@]}"; do
752 mountpoint "$mp" >/dev/null 2>&1 || continue
753 push host_devs $(readlink -f "/dev/block/$(find_block_device "$mp")")
754 done
755 fi
756
757 _get_fs_type() (
758 [[ $1 ]] || return
759 if [[ -b $1 ]] && get_fs_env $1; then
760 echo "$(readlink -f $1)|$ID_FS_TYPE"
761 return 1
762 fi
763 if [[ -b /dev/block/$1 ]] && get_fs_env /dev/block/$1; then
764 echo "$(readlink -f /dev/block/$1)|$ID_FS_TYPE"
765 return 1
766 fi
767 if fstype=$(find_dev_fstype $1); then
768 echo "$1|$fstype"
769 return 1
770 fi
771 return 1
772 )
773
774 for dev in "${host_devs[@]}"; do
775 unset fs_type
776 for fstype in $(_get_fs_type $dev) \
777 $(check_block_and_slaves _get_fs_type $(get_maj_min $dev)); do
778 if ! strstr " ${host_fs_types[*]} " " $fstype ";then
779 push host_fs_types "$fstype"
780 fi
781 done
782 done
783
784 [[ -d $udevdir ]] \
785 || udevdir=$(pkg-config udev --variable=udevdir 2>/dev/null)
786 if ! [[ -d "$udevdir" ]]; then
787 [[ -d /lib/udev ]] && udevdir=/lib/udev
788 [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
789 fi
790
791 [[ -d $systemdutildir ]] \
792 || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
793 [[ -d $systemdsystemunitdir ]] \
794 || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
795
796 if ! [[ -d "$systemdutildir" ]]; then
797 [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
798 [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
799 fi
800 [[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
801
802 export initdir dracutbasedir dracutmodules \
803 fw_dir drivers_dir debug no_kernel kernel_only \
804 omit_drivers mdadmconf lvmconf \
805 use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
806 stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
807 debug host_fs_types host_devs sshkey add_fstab \
808 DRACUT_VERSION udevdir systemdutildir systemdsystemunitdir \
809 prefix filesystems drivers
810
811 # Create some directory structure first
812 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
813
814 [[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
815 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
816
817 if [[ $prefix ]]; then
818 for d in bin etc lib sbin tmp usr var $libdirs; do
819 strstr "$d" "/" && continue
820 ln -sfn "${prefix#/}/${d#/}" "$initdir/$d"
821 done
822 fi
823
824 if [[ $kernel_only != yes ]]; then
825 for d in usr/bin usr/sbin bin etc lib sbin tmp usr var var/log $libdirs; do
826 [[ -e "${initdir}${prefix}/$d" ]] && continue
827 if [ -L "/$d" ]; then
828 inst_symlink "/$d" "${prefix}/$d"
829 else
830 mkdir -m 0755 -p "${initdir}${prefix}/$d"
831 fi
832 done
833
834 for d in dev proc sys sysroot root run run/lock run/initramfs; do
835 if [ -L "/$d" ]; then
836 inst_symlink "/$d"
837 else
838 mkdir -m 0755 -p "$initdir/$d"
839 fi
840 done
841
842 ln -sfn ../run "$initdir/var/run"
843 ln -sfn ../run/lock "$initdir/var/lock"
844 else
845 for d in lib "$libdir"; do
846 [[ -e "${initdir}${prefix}/$d" ]] && continue
847 if [ -h "/$d" ]; then
848 inst "/$d" "${prefix}/$d"
849 else
850 mkdir -m 0755 -p "${initdir}${prefix}/$d"
851 fi
852 done
853 fi
854
855 if [[ $kernel_only != yes ]]; then
856 mkdir -p "${initdir}/etc/cmdline.d"
857 for _d in $hookdirs; do
858 mkdir -m 0755 -p ${initdir}/lib/dracut/hooks/$_d
859 done
860 if [[ "$UID" = "0" ]]; then
861 [ -c ${initdir}/dev/null ] || mknod ${initdir}/dev/null c 1 3
862 [ -c ${initdir}/dev/kmsg ] || mknod ${initdir}/dev/kmsg c 1 11
863 [ -c ${initdir}/dev/console ] || mknod ${initdir}/dev/console c 5 1
864 fi
865 fi
866
867 mods_to_load=""
868 # check all our modules to see if they should be sourced.
869 # This builds a list of modules that we will install next.
870 for_each_module_dir check_module
871 for_each_module_dir check_mount
872
873 strstr "$mods_to_load" "fips" && export DRACUT_FIPS_MODE=1
874
875 _isize=0 #initramfs size
876 modules_loaded=" "
877 # source our modules.
878 for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
879 _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
880 if strstr "$mods_to_load" " $_d_mod "; then
881 [[ $show_modules = yes ]] && echo "$_d_mod" || \
882 dinfo "*** Including module: $_d_mod ***"
883 if [[ $kernel_only = yes ]]; then
884 module_installkernel $_d_mod || {
885 dfatal "installkernel failed in module $_d_mod"
886 exit 1
887 }
888 else
889 module_install $_d_mod
890 if [[ $no_kernel != yes ]]; then
891 module_installkernel $_d_mod || {
892 dfatal "installkernel failed in module $_d_mod"
893 exit 1
894 }
895 fi
896 fi
897 mods_to_load=${mods_to_load// $_d_mod /}
898 modules_loaded+="$_d_mod "
899
900 #print the module install size
901 if [ -n "$printsize" ]; then
902 _isize_new=$(du -sk ${initdir}|cut -f1)
903 _isize_delta=$(($_isize_new - $_isize))
904 echo "$_d_mod install size: ${_isize_delta}k"
905 _isize=$_isize_new
906 fi
907 fi
908 done
909 unset moddir
910
911 for i in $modules_loaded; do
912 mkdir -p $initdir/lib/dracut
913 echo "$i" >> $initdir/lib/dracut/modules.txt
914 done
915
916 dinfo "*** Including modules done ***"
917
918 ## final stuff that has to happen
919 if [[ $no_kernel != yes ]]; then
920
921 if [[ $drivers ]]; then
922 hostonly='' instmods $drivers
923 fi
924
925 if [[ $add_drivers ]]; then
926 hostonly='' instmods -c $add_drivers
927 fi
928 if [[ $filesystems ]]; then
929 hostonly='' instmods -c $filesystems
930 fi
931
932 dinfo "*** Installing kernel module dependencies and firmware ***"
933 dracut_kernel_post
934 dinfo "*** Installing kernel module dependencies and firmware done ***"
935 fi
936
937 if [[ $kernel_only != yes ]]; then
938 (( ${#install_items[@]} > 0 )) && dracut_install ${install_items[@]}
939
940 [[ $kernel_cmdline ]] && echo "$kernel_cmdline" >> "${initdir}/etc/cmdline.d/01-default.conf"
941
942 while pop fstab_lines line; do
943 echo "$line 0 0" >> "${initdir}/etc/fstab"
944 done
945
946 for f in $add_fstab; do
947 cat $f >> "${initdir}/etc/fstab"
948 done
949
950 if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
951 dinfo "*** Resolving executable dependencies ***"
952 find "$initdir" -type f \
953 '(' -perm -0100 -or -perm -0010 -or -perm -0001 ')' \
954 -not -path '*.ko' -print0 \
955 | xargs -r -0 $DRACUT_INSTALL ${initdir+-D "$initdir"} -R ${DRACUT_FIPS_MODE+-H}
956 dinfo "*** Resolving executable dependencies done***"
957 fi
958 fi
959
960 while pop include_src src && pop include_target tgt; do
961 if [[ $src && $tgt ]]; then
962 if [[ -f $src ]]; then
963 inst $src $tgt
964 else
965 ddebug "Including directory: $src"
966 mkdir -p "${initdir}/${tgt}"
967 # check for preexisting symlinks, so we can cope with the
968 # symlinks to $prefix
969 for i in "$src"/*; do
970 [[ -e "$i" || -h "$i" ]] || continue
971 s=${initdir}/${tgt}/${i#$src/}
972 if [[ -d "$i" ]]; then
973 if ! [[ -e "$s" ]]; then
974 mkdir -m 0755 -p "$s"
975 chmod --reference="$i" "$s"
976 fi
977 cp --reflink=auto --sparse=auto -fa -t "$s" "$i"/*
978 else
979 cp --reflink=auto --sparse=auto -fa -t "$s" "$i"
980 fi
981 done
982 fi
983 fi
984 done
985
986 if [[ $kernel_only != yes ]]; then
987 # make sure that library links are correct and up to date
988 for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
989 [[ -f $f ]] && inst_simple "$f"
990 done
991 if ! ldconfig -r "$initdir"; then
992 if [[ $UID = 0 ]]; then
993 derror "ldconfig exited ungracefully"
994 else
995 derror "ldconfig might need uid=0 (root) for chroot()"
996 fi
997 fi
998 fi
999
1000 if (($maxloglvl >= 5)); then
1001 ddebug "Listing sizes of included files:"
1002 du -c "$initdir" | sort -n | ddebug
1003 fi
1004
1005 PRELINK_BIN=$(command -v prelink)
1006 if [[ $UID = 0 ]] && [[ $PRELINK_BIN ]]; then
1007 if [[ $DRACUT_FIPS_MODE ]]; then
1008 dinfo "*** Pre-unlinking files ***"
1009 dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf /etc/prelink.cache
1010 chroot "$initdir" $PRELINK_BIN -u -a
1011 rm -f "$initdir"/$PRELINK_BIN
1012 rm -fr "$initdir"/etc/prelink.*
1013 dinfo "*** Pre-unlinking files done ***"
1014 else
1015 dinfo "*** Pre-linking files ***"
1016 dracut_install -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf
1017 chroot "$initdir" $PRELINK_BIN -a
1018 rm -f "$initdir"/$PRELINK_BIN
1019 rm -fr "$initdir"/etc/prelink.*
1020 dinfo "*** Pre-linking files done ***"
1021 fi
1022 fi
1023
1024 if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
1025 dinfo "*** Hardlinking files ***"
1026 hardlink "$initdir" 2>&1
1027 dinfo "*** Hardlinking files done ***"
1028 fi
1029
1030 # strip binaries
1031 if [[ $do_strip = yes ]] ; then
1032 for p in strip xargs find; do
1033 if ! type -P $p >/dev/null; then
1034 dwarn "Could not find '$p'. Not stripping the initramfs."
1035 do_strip=no
1036 fi
1037 done
1038 fi
1039
1040 if [[ $do_strip = yes ]] ; then
1041 dinfo "*** Stripping files ***"
1042 if [[ $DRACUT_FIPS_MODE ]]; then
1043 find "$initdir" -type f \
1044 -executable -not -path '*/lib/modules/*.ko' -print0 \
1045 | while read -r -d $'\0' f; do
1046 if ! [[ -e "${f%/*}/.${f##*/}.hmac" ]] \
1047 && ! [[ -e "/lib/fipscheck/${f##*/}.hmac" ]] \
1048 && ! [[ -e "/lib64/fipscheck/${f##*/}.hmac" ]]; then
1049 echo -n "$f"; echo -n -e "\000"
1050 fi
1051 done | xargs -r -0 strip -g 2>/dev/null
1052 else
1053 find "$initdir" -type f \
1054 -executable -not -path '*/lib/modules/*.ko' -print0 \
1055 | xargs -r -0 strip -g 2>/dev/null
1056 fi
1057
1058 # strip kernel modules, but do not touch signed modules
1059 find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
1060 | while read -r -d $'\0' f; do
1061 SIG=$(tail -c 28 "$f")
1062 [[ $SIG == '~Module signature appended~' ]] || { echo -n "$f"; echo -n -e "\000"; }
1063 done | xargs -r -0 strip -g
1064
1065 dinfo "*** Stripping files done ***"
1066 fi
1067
1068 rm -f "$outfile"
1069 dinfo "*** Creating image file ***"
1070 if ! ( umask 077; cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet| \
1071 $compress > "$outfile"; ); then
1072 dfatal "dracut: creation of $outfile failed"
1073 exit 1
1074 fi
1075 dinfo "*** Creating image file done ***"
1076
1077 dinfo "Wrote $outfile:"
1078 dinfo "$(ls -l "$outfile")"
1079
1080 exit 0