]>
Commit | Line | Data |
---|---|---|
2b3e22d6 | 1 | #!/bin/bash --norc |
2b3e22d6 | 2 | # |
f18d069d | 3 | # mkinitrd compatibility wrapper for SUSE. |
2b3e22d6 HR |
4 | # |
5 | # Copyright (c) 2013 SUSE Linux Products GmbH. All rights reserved. | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | # | |
20 | ||
21 | boot_dir="/boot" | |
22 | quiet=0 | |
2b3e22d6 HR |
23 | logfile=/var/log/YaST2/mkinitrd.log |
24 | dracut_cmd=dracut | |
25 | ||
26 | error() { echo "$@" >&2; } | |
27 | ||
28 | usage () { | |
29 | [[ $1 = '-n' ]] && cmd=echo || cmd=error | |
30 | ||
31 | $cmd "usage: ${0##*/} [options]" | |
32 | $cmd "" | |
33 | $cmd " Create initial ramdisk images that contain all kernel modules needed" | |
34 | $cmd " in the early boot process, before the root file system becomes" | |
35 | $cmd " available." | |
36 | $cmd " This usually includes SCSI and/or RAID modules, a file system module" | |
37 | $cmd " for the root file system, or a network interface driver module for dhcp." | |
38 | $cmd "" | |
39 | $cmd " options:" | |
40 | $cmd " -f \"feature list\" Features to be enabled when generating initrd." | |
41 | $cmd " Available features are:" | |
42 | $cmd " iscsi, md, multipath, lvm, lvm2," | |
43 | $cmd " ifup, fcoe, dcbd" | |
44 | $cmd " -k \"kernel list\" List of kernel images for which initrd files are" | |
45 | $cmd " created. Defaults to all kernels found in /boot." | |
46 | $cmd " -i \"initrd list\" List of file names for the initrd; position have" | |
47 | $cmd " match to \"kernel list\". Defaults to all kernels" | |
48 | $cmd " found in /boot." | |
49 | $cmd " -b boot_dir Boot directory. Defaults to /boot." | |
50 | $cmd " -t tmp_dir Temporary directory. Defaults to /var/tmp." | |
51 | $cmd " -M map System.map file to use." | |
52 | $cmd " -A Create a so called \"monster initrd\" which" | |
53 | $cmd " includes all features and modules possible." | |
54 | $cmd " -B Do not update bootloader configuration." | |
55 | $cmd " -v Verbose mode." | |
56 | $cmd " -L Disable logging." | |
57 | $cmd " -h This help screen." | |
58 | $cmd " -m \"module list\" Modules to include in initrd. Defaults to the" | |
59 | $cmd " INITRD_MODULES variable in /etc/sysconfig/kernel" | |
60 | $cmd " -u \"DomU module list\" Modules to include in initrd. Defaults to the" | |
61 | $cmd " DOMU_INITRD_MODULES variable in" | |
62 | $cmd " /etc/sysconfig/kernel." | |
63 | $cmd " -d root_device Root device. Defaults to the device from" | |
64 | $cmd " which / is mounted. Overrides the rootdev" | |
f18d069d | 65 | $cmd " environment variable if set." |
2b3e22d6 HR |
66 | $cmd " -j device Journal device" |
67 | $cmd " -D interface Run dhcp on the specified interface." | |
68 | $cmd " -I interface Configure the specified interface statically." | |
552c37e1 | 69 | $cmd " -a acpi_dsdt Obsolete, do not use." |
2b3e22d6 HR |
70 | $cmd " -s size Add splash animation and bootscreen to initrd." |
71 | ||
72 | [[ $1 = '-n' ]] && exit 0 | |
73 | exit 1 | |
74 | } | |
75 | ||
76 | # Little helper function for reading args from the commandline. | |
77 | # it automatically handles -a b and -a=b variants, and returns 1 if | |
78 | # we need to shift $3. | |
79 | read_arg() { | |
80 | # $1 = arg name | |
81 | # $2 = arg value | |
82 | # $3 = arg parameter | |
83 | param="$1" | |
84 | local rematch='^[^=]*=(.*)$' result | |
85 | if [[ $2 =~ $rematch ]]; then | |
86 | read "$param" <<< "${BASH_REMATCH[1]}" | |
87 | else | |
88 | for ((i=3; $i <= $#; i++)); do | |
89 | # Only read next arg if it not an arg itself. | |
90 | if [[ ${@:$i:1} = -* ]];then | |
91 | break | |
92 | fi | |
93 | result="$result ${@:$i:1}" | |
94 | # There is no way to shift our callers args, so | |
95 | # return "no of args" to indicate they should do it instead. | |
96 | done | |
97 | read "$1" <<< "$result" | |
98 | return $(($i - 3)) | |
99 | fi | |
100 | } | |
101 | ||
102 | # Helper functions to calculate ipconfig command line | |
103 | calc_netmask() { | |
104 | local prefix=$1 | |
105 | ||
106 | [ -z "$prefix" ] && return | |
7cf2c217 | 107 | mask=$(( 0xffffffff << (32 - $prefix) )) |
2b3e22d6 HR |
108 | byte1=$(( mask >> 24 )) |
109 | byte2=$(( mask >> 16 )) | |
110 | byte3=$(( mask >> 8 )) | |
111 | byte4=$(( mask & 0xff )) | |
112 | netmask=$(printf "%d.%d.%d.%d" $(( byte1 & 0xff )) $(( byte2 & 0xff )) $(( byte3 & 0xff )) $byte4); | |
113 | ||
114 | echo $netmask | |
115 | } | |
116 | ||
117 | ipconfig() { | |
118 | local interface=$1 | |
119 | local iplink macaddr broadcast gateway ipaddr prefix netmask | |
120 | ||
121 | iplink=$(ip addr show dev $interface | sed -n 's/ *inet \(.*\) brd.*/\1/p') | |
122 | macaddr=$(ip addr show dev $interface | sed -n 's/.*ether \(.*\) brd.*/\1/p') | |
123 | broadcast=$(ip addr show dev $interface | sed -n 's/.*brd \(.*\) scope.*/\1/p') | |
124 | gateway=$(ip route show dev $interface | sed -n 's/default via \([0-9\.]*\).*/\1/p') | |
125 | ||
126 | ipaddr=${iplink%%/*} | |
127 | prefix=${iplink##*/} | |
128 | netmask=$(calc_netmask $prefix) | |
129 | ||
130 | echo "${ipaddr}:${serveraddr}:${gateway}:${netmask}:${hostname}:${interface}:none::${macaddr}" | |
131 | } | |
132 | ||
133 | is_xen_kernel() { | |
134 | local kversion=$1 | |
135 | local root_dir=$2 | |
136 | local cfg | |
137 | ||
138 | for cfg in ${root_dir}/boot/config-$kversion $root_dir/lib/modules/$kversion/build/.config | |
139 | do | |
140 | test -r $cfg || continue | |
141 | grep -q "^CONFIG_XEN=y\$" $cfg | |
142 | return | |
143 | done | |
144 | test $kversion != "${kversion%-xen*}" | |
145 | return | |
146 | } | |
147 | ||
162daf0c | 148 | kernel_version_from_image() { |
4996e53e HH |
149 | local dir="${1%/*}/" |
150 | [[ "$dir" != "$1" ]] || dir="" | |
151 | local kernel_image="$1" kernel_image_gz="${dir}vmlinux-${1#*-}.gz" | |
152 | echo kernel_image_gz="'$kernel_image_gz'" >&2 | |
153 | ||
154 | if get_kernel_version "$kernel_image" 2>/dev/null; then | |
155 | return | |
156 | fi | |
157 | ||
158 | # As a last resort, try vmlinux-$version.gz, which might be around | |
162daf0c TR |
159 | get_kernel_version "$kernel_image_gz" 2>/dev/null |
160 | } | |
2b3e22d6 HR |
161 | |
162 | # Taken over from SUSE mkinitrd | |
163 | default_kernel_images() { | |
164 | local regex kernel_image kernel_version version_version initrd_image | |
165 | local qf='%{NAME}-%{VERSION}-%{RELEASE}\n' | |
166 | ||
167 | case "$(uname -m)" in | |
168 | s390|s390x) | |
169 | regex='image' | |
170 | ;; | |
171 | ppc|ppc64) | |
172 | regex='vmlinux' | |
173 | ;; | |
174 | i386|x86_64) | |
175 | regex='vmlinuz' | |
176 | ;; | |
177 | arm*) | |
178 | regex='[uz]Image' | |
179 | ;; | |
62f939b8 | 180 | aarch64|riscv64) |
2b3e22d6 HR |
181 | regex='Image' |
182 | ;; | |
183 | *) regex='vmlinu.' | |
184 | ;; | |
185 | esac | |
186 | ||
187 | kernel_images="" | |
188 | initrd_images="" | |
189 | for kernel_image in $(ls $boot_dir \ | |
190 | | sed -ne "\|^$regex\(-[0-9.]\+-[0-9]\+-[a-z0-9]\+$\)\?|p" \ | |
191 | | grep -v kdump$ ) ; do | |
192 | ||
193 | # Note that we cannot check the RPM database here -- this | |
194 | # script is itself called from within the binary kernel | |
195 | # packages, and rpm does not allow recursive calls. | |
196 | ||
197 | [ -L "$boot_dir/$kernel_image" ] && continue | |
198 | [ "${kernel_image%%.gz}" != "$kernel_image" ] && continue | |
162daf0c TR |
199 | |
200 | kernel_version=$(kernel_version_from_image \ | |
2b3e22d6 HR |
201 | $boot_dir/$kernel_image 2> /dev/null) |
202 | initrd_image=$(echo $kernel_image | sed -e "s|${regex}|initrd|") | |
203 | if [ "$kernel_image" != "$initrd_image" -a \ | |
204 | -n "$kernel_version" -a \ | |
205 | -d "/lib/modules/$kernel_version" ]; then | |
206 | kernel_images="$kernel_images $boot_dir/$kernel_image" | |
207 | initrd_images="$initrd_images $boot_dir/$initrd_image" | |
208 | fi | |
209 | done | |
210 | for kernel_image in $kernel_images;do | |
211 | kernels="$kernels ${kernel_image#*-}" | |
212 | done | |
213 | for initrd_image in $initrd_images;do | |
214 | targets="$targets $initrd_image" | |
215 | done | |
2b3e22d6 HR |
216 | } |
217 | ||
218 | while (($# > 0)); do | |
219 | case ${1%%=*} in | |
220 | -f) read_arg feature_list "$@" || shift $? | |
221 | # Could be several features | |
222 | ;; | |
223 | -k) # Would be nice to get a list of images here | |
224 | read_arg kernel_images "$@" || shift $? | |
225 | for kernel_image in $kernel_images;do | |
7957bd01 | 226 | [ -L "/boot/$kernel_image" ] && kernel_image="$(readlink "/boot/$kernel_image")" |
2b3e22d6 HR |
227 | kernels="$kernels ${kernel_image#*-}" |
228 | done | |
2b3e22d6 HR |
229 | ;; |
230 | -i) read_arg initrd_images "$@" || shift $? | |
231 | for initrd_image in $initrd_images;do | |
7957bd01 | 232 | [ -L "/boot/$initrd_image" ] && initrd_image="$(readlink "/boot/$initrd_image")" |
2b3e22d6 HR |
233 | # Check if the initrd_image contains a path. |
234 | # if not, then add the default boot_dir | |
235 | dname=`dirname $initrd_image` | |
236 | if [ "$dname" == "." ]; then | |
237 | targets="$targets $boot_dir/$initrd_image"; | |
238 | else | |
239 | targets="$targets $initrd_image"; | |
240 | fi | |
241 | done | |
242 | ;; | |
243 | -b) read_arg boot_dir "$@" || shift $? | |
244 | if [ ! -d $boot_dir ];then | |
245 | error "Boot directory $boot_dir does not exist" | |
246 | exit 1 | |
247 | fi | |
248 | ;; | |
249 | -t) read_arg tmp_dir "$@" || shift $? | |
250 | dracut_args="${dracut_args} --tmpdir $tmp_dir" | |
251 | ;; | |
252 | -M) read_arg map_file "$@" || shift $? | |
253 | ;; | |
39ee4fdf | 254 | -A) dracut_args="${dracut_args} --no-host-only";; |
2b3e22d6 HR |
255 | -B) skip_update_bootloader=1;; |
256 | -v|--verbose) dracut_args="${dracut_args} -v";; | |
257 | -L) logfile=;; | |
258 | -h|--help) usage -n;; | |
259 | -m) read_arg module_list "$@" || shift $? ;; | |
260 | -u) read_arg domu_module_list "$@" || shift $? | |
261 | echo "mkinitrd: DomU modules not yet supported" ;; | |
262 | -d) read_arg rootfs "$@" || shift $? | |
263 | dracut_args="${dracut_args} --filesystems $rootfs" ;; | |
264 | -D) read_arg dhcp_if "$@" || shift $? | |
265 | dracut_cmdline="${dracut_cmdline} ip=${dhcp_if}:dhcp" | |
266 | ;; | |
267 | -I) read_arg static_if "$@" || shift $? | |
268 | dracut_cmdline="${dracut_cmdline} ip=$(ipconfig $static_if)": | |
269 | ;; | |
270 | -a) read_arg acpi_dsdt "$@" || shift $? | |
552c37e1 | 271 | echo "Obsolete -a param, use acpi_table_dir= and acpi_override= variables in /etc/dracut.conf.d/" |
2b3e22d6 HR |
272 | exit 1 |
273 | ;; | |
274 | -s) read_arg boot_splash "$@" || shift $? | |
275 | echo "mkinitrd: boot splash not yet supported" | |
276 | exit 1 | |
277 | ;; | |
278 | -V) echo "mkinitrd: vendor scipts are no longer supported" | |
279 | exit 1;; | |
280 | --dracut) | |
281 | read_arg dracut_cmd "$@" || shift $? ;; | |
282 | --version|-R) | |
283 | echo "mkinitrd: dracut compatibility wrapper" | |
284 | exit 0;; | |
2b3e22d6 HR |
285 | --quiet|-q) quiet=1;; |
286 | *) if [[ ! $targets ]]; then | |
287 | targets=$1 | |
288 | elif [[ ! $kernels ]]; then | |
289 | kernels=$1 | |
290 | else | |
291 | usage | |
292 | fi;; | |
293 | esac | |
294 | shift | |
295 | done | |
296 | ||
297 | [[ $targets && $kernels ]] || default_kernel_images | |
552c37e1 | 298 | if [[ ! $targets || ! $kernels ]];then |
01e60ca4 TR |
299 | error "No kernel found in $boot_dir or bad modules dir in /lib/modules" |
300 | exit 1 | |
552c37e1 | 301 | fi |
2b3e22d6 HR |
302 | |
303 | # We can have several targets/kernels, transform the list to an array | |
304 | targets=( $targets ) | |
305 | [[ $kernels ]] && kernels=( $kernels ) | |
306 | ||
307 | [[ $logfile ]] && dracut_args="${dracut_args} --logfile $logfile" | |
552c37e1 TR |
308 | dracut_args="${dracut_args} --force" |
309 | ||
2b3e22d6 HR |
310 | [[ $dracut_cmdline ]] && dracut_args="${dracut_args} --kernel-cmdline ${dracut_cmdline}" |
311 | [ -z "$(type -p update-bootloader)" ] && skip_update_bootloader=1 | |
312 | ||
313 | # Update defaults from /etc/sysconfig/kernel | |
314 | if [ -f /etc/sysconfig/kernel ] ; then | |
315 | . /etc/sysconfig/kernel | |
316 | fi | |
317 | [[ $module_list ]] || module_list="${INITRD_MODULES}" | |
2b3e22d6 | 318 | [[ $domu_module_list ]] || domu_module_list="${DOMU_INITRD_MODULES}" |
552c37e1 | 319 | shopt -s extglob |
2b3e22d6 | 320 | |
01e60ca4 TR |
321 | failed="" |
322 | ||
2b3e22d6 HR |
323 | for ((i=0 ; $i<${#targets[@]} ; i++)); do |
324 | ||
325 | if [[ $img_vers ]];then | |
326 | target="${targets[$i]}-${kernels[$i]}" | |
327 | else | |
328 | target="${targets[$i]}" | |
329 | fi | |
330 | kernel="${kernels[$i]}" | |
331 | ||
552c37e1 TR |
332 | if is_xen_kernel $kernel $rootfs ; then |
333 | modules_all="${module_list} ${domu_module_list}" | |
334 | else | |
335 | modules_all="${module_list}" | |
336 | fi | |
337 | ||
338 | # Remove leading and trailing spaces needs (set above): shopt -s extglob | |
339 | modules_all=${modules_all%%+([[:space:]])} | |
340 | modules_all=${modules_all##+([[:space:]])} | |
341 | ||
342 | echo "Creating initrd: $target" | |
343 | ||
2b3e22d6 HR |
344 | # Duplicate code: No way found how to redirect output based on $quiet |
345 | if [[ $quiet == 1 ]];then | |
552c37e1 TR |
346 | # Duplicate code: --force-drivers must not be called with empty string |
347 | # -> dracut bug workarounded ugly, because of complex whitespace | |
348 | # expansion magics | |
349 | if [ -n "${modules_all}" ];then | |
350 | $dracut_cmd $dracut_args --force-drivers "${modules_all}" "$target" "$kernel" &>/dev/null | |
01e60ca4 | 351 | [ $? -ne 0 ] && failed="$failed $target" |
552c37e1 | 352 | else |
2b3e22d6 | 353 | $dracut_cmd $dracut_args "$target" "$kernel" &>/dev/null |
01e60ca4 | 354 | [ $? -ne 0 ] && failed="$failed $target" |
552c37e1 | 355 | fi |
2b3e22d6 | 356 | else |
552c37e1 TR |
357 | if [ -n "${modules_all}" ];then |
358 | $dracut_cmd $dracut_args --force-drivers "${modules_all}" "$target" "$kernel" | |
01e60ca4 | 359 | [ $? -ne 0 ] && failed="$failed $target" |
552c37e1 | 360 | else |
2b3e22d6 | 361 | $dracut_cmd $dracut_args "$target" "$kernel" |
01e60ca4 | 362 | [ $? -ne 0 ] && failed="$failed $target" |
552c37e1 | 363 | fi |
2b3e22d6 HR |
364 | fi |
365 | done | |
366 | ||
367 | if [ "$skip_update_bootloader" ] ; then | |
368 | echo 2>&1 "Did not refresh the bootloader. You might need to refresh it manually." | |
369 | else | |
370 | update-bootloader --refresh | |
01e60ca4 TR |
371 | [ $? -ne 0 ] && echo "Updating bootloader failed" && exit 1 |
372 | fi | |
373 | ||
374 | if [ "$failed" != "" ]; then | |
375 | echo "Generating $failed targets failed" | |
376 | exit 1 | |
2b3e22d6 | 377 | fi |
01e60ca4 TR |
378 | |
379 | exit 0 |