]> git.ipfire.org Git - thirdparty/dracut.git/blob - mkinitrd-suse.sh
mkinitrd-suse: Add SUSE compability wrapper for dracut
[thirdparty/dracut.git] / mkinitrd-suse.sh
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