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