summaryrefslogtreecommitdiff
path: root/dracut
blob: b43817371a0c2f0ee714451ba0edcf3080d01348 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#!/bin/bash
# 
# Generator script for a dracut initramfs
# Tries to retain some degree of compatibility with the command line
# of the various mkinitrd implementations out there
#

# Copyright 2005-2009 Red Hat, Inc.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


usage() {
#                                                       80x25 linebreak here ^
	echo "Usage: $0 [OPTION]... <initramfs> <kernel-version>
Creates initial ramdisk images for preloading modules

  -f, --force           Overwrite existing initramfs file.
  -m, --modules [LIST]  Specify a space-separated list of dracut modules to
                         call when building the initramfs. Modules are located
                         in /usr/share/dracut/modules.d.
  -o, --omit [LIST]     Omit a space-separated list of dracut modules.
  -a, --add [LIST]      Add a space-separated list of dracut modules.
  -d, --drivers [LIST]  Specify a space-separated list of kernel modules to
                        exclusively include in the initramfs.
  --add-drivers [LIST]  Specify a space-separated list of kernel 
                        modules to add to the initramfs.
  --filesystems [LIST]  Specify a space-separated list of kernel filesystem
                        modules to exclusively include in the generic
                        initramfs.
  -k, --kmoddir [DIR]   Specify the directory, where to look for kernel 
                        modules
  --fwdir [DIR]         Specify additional directories, where to look for 
                        firmwares, separated by :
  --kernel-only         Only install kernel drivers and firmware files
  --no-kernel           Do not install kernel drivers and firmware files
  --strip               Strip binaries in the initramfs (default)
  --nostrip             Do not strip binaries in the initramfs
  --mdadmconf           Include local /etc/mdadm.conf
  --nomdadmconf         Do not include local /etc/mdadm.conf
  --lvmconf             Include local /etc/lvm/lvm.conf
  --nolvmconf             Do not include local /etc/lvm/lvm.conf
  -h, --help            This message
  --debug               Output debug information of the build process
  -v, --verbose         Verbose output during the build process
  -c, --conf [FILE]     Specify configuration file to use.
                         Default: /etc/dracut.conf
  -l, --local           Local mode. Use modules from the current working
                         directory instead of the system-wide installed in
                         /usr/share/dracut/modules.d.
                         Useful when running dracut from a git checkout.
  -H, --hostonly          Host-Only mode: Install only what is needed for
                         booting the local host instead of a generic host.
  -i, --include [SOURCE] [TARGET]
                        Include the files in the SOURCE directory into the
                         Target directory in the final initramfs.
  -I, --install [LIST]  Install the space separated list of files into the
                         initramfs.
"
}

while (($# > 0)); do
    case $1 in
	-f|--force) force=yes;;
	-m|--modules) dracutmodules_l="$2"; shift;;
	-o|--omit) omit_dracutmodules_l="$2"; shift;;
	-a|--add) add_dracutmodules_l="$2"; shift;;
	-d|--drivers) drivers_l="$2"; shift;;
	--add-drivers) add_drivers_l="$2"; shift;;
	--filesystems) filesystems_l="$2"; shift;;
	-k|--kmoddir) drivers_dir_l="$2"; shift;;
	--fwdir) fw_dir_l="$2"; shift;;
	--kernel-only) kernel_only="yes"; no_kernel="no";;
	--no-kernel) kernel_only="no"; no_kernel="yes";;
	--strip) do_strip_l="yes";;
	--nostrip) do_strip_l="no";;
        --mdadmconf) mdadmconf_l="yes";;
        --nomdadmconf) mdadmconf_l="no";;
        --lvmconf) lvmconf_l="yes";;
        --nolvmconf) lvmconf_l="no";;
	-h|--help) usage; exit 1 ;;
	--debug) debug="yes";;
	-v|--verbose) beverbose="yes";;
	-c|--conf) conffile="$2"; shift;;
	-l|--local) allowlocal="yes" ;;
	-H|--hostonly) hostonly_l="yes" ;;
	-i|--include) include_src="$2"; include_target="$3"; shift 2;;
	-I|--install) install_items="$2"; shift;;
	-*) printf "\nUnknown option: %s\n\n" "$1" >&2; usage; exit 1;;
	*) break ;;
    esac
    shift
done

PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH

[[ $debug ]] && { 
    export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
    set -x
}

[[ $dracutbasedir ]] || dracutbasedir=/usr/share/dracut

[[ $allowlocal && -f "$(readlink -f $(dirname $0))/dracut-functions" ]] && dracutbasedir="$(dirname $0)" 

# if we were not passed a config file, try the default one
if [[ ! -f $conffile ]]; then
    [[ $allowlocal ]] || conffile="/etc/dracut.conf"
    [[ $allowlocal ]] && conffile="$dracutbasedir/dracut.conf"
fi

# source our config file
[[ -f $conffile ]] && . "$conffile"

# these options override the stuff in the config file
[[ $dracutmodules_l ]] && dracutmodules=$dracutmodules_l
[[ $omit_dracutmodules_l ]] && omit_dracutmodules=$omit_dracutmodules_l
[[ $add_dracutmodules_l ]] && add_dracutmodules="$add_dracutmodules $add_dracutmodules_l"
[[ $drivers_l ]] && drivers=$drivers_l
[[ $add_drivers_l ]] && add_drivers=$add_drivers_l
[[ $filesystems_l ]] && filesystems=$filesystems_l
[[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
[[ $fw_dir_l ]] && fw_dir=$fw_dir_l
[[ $do_strip_l ]] && do_strip=$do_strip_l
[[ $hostonly_l ]] && hostonly=$hostonly_l
[[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
[[ $lvmconf_l ]] && lvmconf=$lvmconf_l
[[ $dracutbasedir ]] || dracutbasedir=/usr/share/dracut
[[ $fw_dir ]] || fw_dir=/lib/firmware
[[ $do_strip ]] || do_strip=yes
# eliminate IFS hackery when messing with fw_dir
fw_dir=${fw_dir//:/ }

[[ $hostonly = yes ]] && hostonly="-h"
[[ $hostonly != "-h" ]] && unset hostonly

if [[ -f $dracutbasedir/dracut-functions ]]; then
   . $dracutbasedir/dracut-functions
else
   echo "Cannot find $dracutbasedir/dracut-functions. Are you running from a git checkout?"
   echo "Try passing -l as an argument to $0"
   exit 1
fi

dracutfunctions=$dracutbasedir/dracut-functions
export dracutfunctions

# This is kinda legacy -- eventually it should go away.
case $dracutmodules in
    ""|auto) dracutmodules="all" ;;
esac

[[ $2 ]] && kernel=$2 || kernel=$(uname -r)
[[ $1 ]] && outfile=$(readlink -f $1) || outfile="/boot/initramfs-$kernel.img"

srcmods="/lib/modules/$kernel/"
[[ $drivers_dir ]] && srcmods="$drivers_dir"
export srcmods

if [[ -f $outfile && ! $force ]]; then
    echo "Will not override existing initramfs ($outfile) without --force"
    exit 1
fi

if ! [[ -w $(dirname $outfile) ]]; then
    echo "No permission to write $outfile."
    exit 1
fi

hookdirs="cmdline pre-udev pre-trigger netroot pre-mount pre-pivot mount emergency"

[[ -n "$TMPDIR" ]] && ! [[ -w "$TMPDIR" ]] && unset TMPDIR
readonly initdir=$(mktemp -d -t initramfs.XXXXXX)

trap 'ret=$?;rm -rf "$initdir";exit $ret;' EXIT # clean up after ourselves no matter how we die.
trap 'exit 1;' SIGINT # clean up after ourselves no matter how we die.

# Need to be able to have non-root users read stuff (rpcbind etc)
chmod 755 "$initdir"

export initdir hookdirs dracutbasedir dracutmodules drivers \
    fw_dir drivers_dir debug beverbose no_kernel kernel_only \
    add_drivers mdadmconf lvmconf filesystems

if [[ $kernel_only != yes ]]; then
    # Create some directory structure first
    for d in bin sbin usr/bin usr/sbin usr/lib etc proc sys sysroot tmp dev/pts var/run; do 
	inst_dir "/$d"; 
    done
fi

# check all our modules to see if they should be sourced.
# This builds a list of modules that we will install next.
check_modules
  
# source our modules.
for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
    mod=${moddir##*/}; mod=${mod#[0-9][0-9]}
    if strstr "$mods_to_load" " $mod "; then
	if [[ $kernel_only = yes ]]; then
	    [[ -x $moddir/installkernel ]] && . "$moddir/installkernel"
	else
	    . "$moddir/install"
	    if [[ $no_kernel != yes && -x $moddir/installkernel ]]; then
		. "$moddir/installkernel"
	    fi
	fi
	mods_to_load=${mods_to_load// $mod /}
    fi
done
unset moddir

## final stuff that has to happen

# generate module dependencies for the initrd
if [[ -d $initdir/lib/modules/$kernel ]]; then
    if ! depmod -a -b "$initdir" $kernel; then
        derror "\"depmod -a $kernel\" failed."
        exit 1
    fi
fi

# make sure that library links are correct and up to date
ldconfig -n -r "$initdir" /lib* /usr/lib*

if [[ $include_src && $include_target ]]; then
    mkdir -p "$initdir$include_target"
    cp -a -t "$initdir$include_target" "$include_src"/*
fi

for item in $install_items; do
   dracut_install "$item"
done
unset item

[[ $beverbose = yes ]] && (du -c "$initdir" | sort -n)

# strip binaries 
if [[ $do_strip = yes ]] ; then
    for p in strip objdump sed grep find; do 
	if ! which $p >/dev/null 2>&1; then
	    derror "Could not find '$p'. You should run $0 with '--nostrip'."
	    do_strip=no
	fi
    done
fi

if [[ $do_strip = yes ]] ; then
    for f in $(find "$initdir" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 -or -path '/lib/modules/*.ko' \) -exec file {} \; | 
	grep -v ' shared object,' | 
	sed -n -e 's/^\(.*\):[ 	]*ELF.*, not stripped/\1/p'); do
	dinfo "Stripping $f"
	strip -g "$f" || :
        #
        # FIXME: only strip -g for now
        #
	#strip -g --strip-unneeded "$f" || :
	#note="-R .note"
	#if objdump -h $f | grep '^[ 	]*[0-9]*[ 	]*.note[ 	]' -A 1 | \
	#    grep -q ALLOC; then
	#    note=
	#fi
	#strip -R .comment $note "$f" || :
    done
fi

( cd "$initdir"; find . |cpio -R 0:0 -H newc -o --quiet |gzip -9 > "$outfile"; ) 
if [ $? -ne 0 ]; then
    derror "dracut: creation of $outfile failed"
    exit 1
fi 

[[ $beverbose = yes ]] && ls -lh "$outfile"

exit 0