| 4 |
- |
1 |
#! /bin/sh
|
|
|
2 |
### BEGIN INIT INFO
|
|
|
3 |
# Provides: kdump
|
|
|
4 |
# Default-Start: 3 4 5
|
|
|
5 |
# Default-Stop: 0 1 6
|
| 34 |
- |
6 |
# Require-Start: $network $local_fs $remote_fs
|
| 4 |
- |
7 |
# Short-Description: start and stop kdump crash recovery service
|
|
|
8 |
# Description: The kdump init script provides the support necessary for
|
|
|
9 |
# loading a kdump kernel into memory at system bootup time,
|
|
|
10 |
# and for copying away a vmcore at system panic time.
|
|
|
11 |
### END INIT INFO
|
|
|
12 |
# Copyright 2005 Red Hat, Inc.
|
|
|
13 |
#
|
|
|
14 |
# Author: Jeff Moyer <jmoyer@redhat.com>
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
# Source function library.
|
|
|
18 |
. /etc/init.d/functions
|
|
|
19 |
|
|
|
20 |
KEXEC=/sbin/kexec
|
|
|
21 |
|
|
|
22 |
# Will be different for ia64, for example. For now, that architecture isn't
|
|
|
23 |
# supported. Code needs to be added here when we do.
|
|
|
24 |
BOOTDIR="/boot"
|
|
|
25 |
|
|
|
26 |
KDUMP_KERNELVER=""
|
|
|
27 |
KDUMP_COMMANDLINE=""
|
|
|
28 |
KDUMP_IDE_NOPROBE_COMMANDLINE=""
|
|
|
29 |
KEXEC_ARGS=""
|
|
|
30 |
KDUMP_CONFIG_FILE="/etc/kdump.conf"
|
|
|
31 |
MEM_RESERVED=""
|
|
|
32 |
MKDUMPRD_ARGS=""
|
|
|
33 |
CLUSTER_CONFIG_FILE="/etc/cluster/cluster.conf"
|
|
|
34 |
FENCE_KDUMP_CONFIG="/etc/sysconfig/fence_kdump"
|
|
|
35 |
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
|
| 58 |
- |
36 |
#kdump shall be the default dump mode
|
|
|
37 |
DEFAULT_DUMP_MODE="kdump"
|
| 4 |
- |
38 |
|
|
|
39 |
LOGGER="/usr/bin/logger -p info -t kdump"
|
|
|
40 |
|
|
|
41 |
standard_kexec_args="-p"
|
|
|
42 |
|
|
|
43 |
if [ -f /etc/sysconfig/kdump ]; then
|
|
|
44 |
. /etc/sysconfig/kdump
|
|
|
45 |
fi
|
|
|
46 |
|
|
|
47 |
function single_instance_lock()
|
|
|
48 |
{
|
|
|
49 |
exec 9>/var/lock/kdump
|
|
|
50 |
flock 9
|
|
|
51 |
}
|
|
|
52 |
|
| 58 |
- |
53 |
determine_dump_mode()
|
|
|
54 |
{
|
|
|
55 |
# Check if firmware-assisted dump is enabled
|
|
|
56 |
# if yes, set the dump mode as fadump and source
|
|
|
57 |
# fadump related functions
|
|
|
58 |
fadump_enabled_sys_node="/sys/kernel/fadump_enabled"
|
|
|
59 |
if [ -f $fadump_enabled_sys_node ]; then
|
|
|
60 |
rc=`cat $fadump_enabled_sys_node`
|
|
|
61 |
if [ $rc -eq 1 ]; then
|
|
|
62 |
echo "kdump: dump mode is fadump"
|
|
|
63 |
DEFAULT_DUMP_MODE="fadump"
|
|
|
64 |
. /etc/init.d/fadump-functions
|
|
|
65 |
fi
|
|
|
66 |
fi
|
|
|
67 |
}
|
|
|
68 |
|
| 4 |
- |
69 |
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]
|
|
|
70 |
# Remove a list of kernel parameters from a given kernel cmdline and print the result.
|
|
|
71 |
# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.
|
|
|
72 |
function remove_cmdline_param()
|
|
|
73 |
{
|
|
|
74 |
local cmdline=$1
|
|
|
75 |
shift
|
|
|
76 |
|
|
|
77 |
for arg in $@; do
|
|
|
78 |
cmdline=`echo $cmdline | \
|
|
|
79 |
sed -e "s/\b$arg=[^ ]*\b//g" \
|
|
|
80 |
-e "s/\b$arg\b//g"`
|
|
|
81 |
done
|
|
|
82 |
echo $cmdline
|
|
|
83 |
}
|
|
|
84 |
|
|
|
85 |
|
|
|
86 |
function in_xen_pv_guest()
|
|
|
87 |
{
|
|
|
88 |
grep -q 'xen-percpu-virq *timer0' /proc/interrupts
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
function in_xen_hvm_guest()
|
|
|
92 |
{
|
|
|
93 |
grep -q "xen" /sys/hypervisor/type >& /dev/null && ! grep -q 'xen-percpu-virq *timer0' /proc/interrupts
|
|
|
94 |
}
|
|
|
95 |
|
|
|
96 |
function check_xen_hvm_nopv_premkdumprd()
|
|
|
97 |
{
|
|
|
98 |
if in_xen_hvm_guest; then
|
|
|
99 |
if grep -q "xen_.*front" /proc/modules; then
|
|
|
100 |
return 1
|
|
|
101 |
fi
|
|
|
102 |
fi
|
|
|
103 |
}
|
|
|
104 |
|
|
|
105 |
function save_kernel_logs()
|
|
|
106 |
{
|
|
|
107 |
local _path=$1
|
|
|
108 |
|
|
|
109 |
mkdir -p $_path
|
|
|
110 |
|
|
|
111 |
if [ ! -f /sbin/vmcore-dmesg ];then
|
|
|
112 |
$LOGGER "Skipping saving vmcore-dmesg.txt. File /sbin/vmcore-dmesg is not present"
|
|
|
113 |
return;
|
|
|
114 |
fi
|
|
|
115 |
|
|
|
116 |
echo "kdump: saving vmcore-dmesg.txt to $_path"
|
|
|
117 |
$LOGGER "saving vmcore-dmesg.txt to $_path"
|
|
|
118 |
/sbin/vmcore-dmesg /proc/vmcore > $_path/vmcore-dmesg-incomplete.txt
|
|
|
119 |
if [ $? == 0 ]; then
|
|
|
120 |
mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
|
|
|
121 |
echo "kdump: saved vmcore-dmesg.txt to $_path"
|
|
|
122 |
$LOGGER "saved vmcore-dmesg.txt to $_path"
|
|
|
123 |
else
|
|
|
124 |
echo "kdump: failed to save vmcore-dmesg.txt to $_path"
|
|
|
125 |
$LOGGER "failed to save vmcore-dmesg.txt to $_path"
|
|
|
126 |
fi
|
|
|
127 |
|
|
|
128 |
}
|
|
|
129 |
|
| 5 |
- |
130 |
#
|
|
|
131 |
# This function returns the "initial apicid" of the
|
|
|
132 |
# boot cpu (cpu 0) if present.
|
|
|
133 |
#
|
|
|
134 |
function get_bootcpu_initial_apicid()
|
|
|
135 |
{
|
|
|
136 |
awk ' \
|
|
|
137 |
BEGIN { CPU = "-1"; } \
|
|
|
138 |
$1=="processor" && $2==":" { CPU = $NF; } \
|
|
|
139 |
CPU=="0" && /initial apicid/ { print $NF; } \
|
|
|
140 |
' \
|
|
|
141 |
/proc/cpuinfo
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
#
|
|
|
145 |
# This function appends argument "$2=$3" to string ($1) if not already present.
|
|
|
146 |
#
|
|
|
147 |
function append_cmdline()
|
|
|
148 |
{
|
|
|
149 |
local cmdline=$1
|
|
|
150 |
local newstr=${cmdline/$2/""}
|
|
|
151 |
|
|
|
152 |
# unchanged str implies argument wasn't there
|
|
|
153 |
if [ "$cmdline" == "$newstr" ]; then
|
|
|
154 |
cmdline="${cmdline} ${2}=${3}"
|
|
|
155 |
fi
|
|
|
156 |
|
|
|
157 |
echo $cmdline
|
|
|
158 |
}
|
|
|
159 |
|
|
|
160 |
# This function performs a series of edits on the command line
|
|
|
161 |
function prepare_cmdline()
|
|
|
162 |
{
|
|
|
163 |
local cmdline;
|
|
|
164 |
if [ -z "$KDUMP_COMMANDLINE" ]; then
|
|
|
165 |
cmdline=`cat /proc/cmdline`
|
|
|
166 |
else
|
|
|
167 |
cmdline=${KDUMP_COMMANDLINE}
|
|
|
168 |
fi
|
|
|
169 |
cmdline=`remove_cmdline_param "$cmdline" crashkernel mem hugepages hugepagesz`
|
|
|
170 |
cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
|
|
|
171 |
avoid_cdrom_drive
|
|
|
172 |
KDUMP_COMMANDLINE="${KDUMP_COMMANDLINE} ${KDUMP_IDE_NOPROBE_COMMANDLINE}"
|
|
|
173 |
|
|
|
174 |
local id=`get_bootcpu_initial_apicid`
|
|
|
175 |
if [ ! -z ${id} ] ; then
|
|
|
176 |
cmdline=`append_cmdline "${cmdline}" disable_cpu_apicid ${id}`
|
|
|
177 |
fi
|
|
|
178 |
|
|
|
179 |
echo $cmdline
|
|
|
180 |
}
|
|
|
181 |
|
| 4 |
- |
182 |
function save_core()
|
|
|
183 |
{
|
|
|
184 |
local kdump_path
|
|
|
185 |
kdump_path=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`
|
|
|
186 |
if [ -z "$kdump_path" ]; then
|
|
|
187 |
coredir="/var/crash/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"
|
|
|
188 |
else
|
|
|
189 |
coredir="${kdump_path}/127.0.0.1-`date +"%Y-%m-%d-%H:%M"`"
|
|
|
190 |
fi
|
|
|
191 |
|
|
|
192 |
mkdir -p $coredir
|
|
|
193 |
save_kernel_logs "${coredir}"
|
|
|
194 |
/usr/sbin/makedumpfile -c --message-level 1 -d 31 /proc/vmcore $coredir/vmcore-incomplete
|
|
|
195 |
if [ $? == 0 ]; then
|
|
|
196 |
mv $coredir/vmcore-incomplete $coredir/vmcore
|
|
|
197 |
$LOGGER "saved a vmcore to $coredir"
|
|
|
198 |
else
|
|
|
199 |
$LOGGER "failed to save a vmcore to $coredir"
|
|
|
200 |
fi
|
|
|
201 |
}
|
|
|
202 |
|
| 58 |
- |
203 |
function check_kdump_config()
|
| 4 |
- |
204 |
{
|
|
|
205 |
local modified_files=""
|
|
|
206 |
local force_rebuild=0
|
| 58 |
- |
207 |
MKDUMPRD="/sbin/mkdumprd -d -f $MKDUMPRD_ARGS"
|
| 4 |
- |
208 |
|
|
|
209 |
force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE | cut -d' ' -f2`
|
|
|
210 |
if [ -n "$force_rebuild" ] && [ "$force_rebuild" -ne 0 ]
|
|
|
211 |
then
|
|
|
212 |
modified_files="force_rebuild"
|
|
|
213 |
fi
|
|
|
214 |
|
|
|
215 |
if [ -z "$KDUMP_KERNELVER" ]; then
|
|
|
216 |
local running_kernel=`uname -r`
|
|
|
217 |
|
|
|
218 |
kdump_kver=`echo $running_kernel | sed 's/smp//g'`
|
|
|
219 |
else
|
|
|
220 |
kdump_kver=$KDUMP_KERNELVER
|
|
|
221 |
fi
|
|
|
222 |
|
|
|
223 |
kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
|
|
|
224 |
kdump_initrd="${KDUMP_BOOTDIR}/initrd-${kdump_kver}kdump.img"
|
|
|
225 |
|
|
|
226 |
if [ ! -f $kdump_kernel ]; then
|
|
|
227 |
echo -n "No kdump kernel image found."; warning; echo
|
|
|
228 |
echo "Tried to locate ${kdump_kernel}"
|
|
|
229 |
return 0
|
|
|
230 |
fi
|
|
|
231 |
|
|
|
232 |
if [ ! -f $kdump_initrd ]; then
|
|
|
233 |
echo -n "No kdump initial ramdisk found."; warning; echo
|
|
|
234 |
if ! check_xen_hvm_nopv_premkdumprd; then
|
|
|
235 |
echo "hvm guest with pv drivers is not supported."
|
|
|
236 |
exit 1
|
|
|
237 |
fi
|
|
|
238 |
|
|
|
239 |
echo "Rebuilding $kdump_initrd"
|
|
|
240 |
$MKDUMPRD $kdump_initrd $kdump_kver
|
|
|
241 |
if [ $? != 0 ]; then
|
|
|
242 |
echo "Failed to run mkdumprd"
|
|
|
243 |
$LOGGER "mkdumprd: failed to make kdump initrd"
|
| 58 |
- |
244 |
rm -f $kdump_initrd
|
| 4 |
- |
245 |
exit 1
|
|
|
246 |
fi
|
|
|
247 |
return 0
|
|
|
248 |
fi
|
|
|
249 |
|
|
|
250 |
if [ -z "$modified_files" ]
|
|
|
251 |
then
|
|
|
252 |
#check to see if config file or kdump post has been modified
|
|
|
253 |
#since last build of the image file
|
|
|
254 |
image_time=`stat -c "%Y" $kdump_initrd`
|
|
|
255 |
EXTRA_FILES=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2`
|
|
|
256 |
CHECK_FILE=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2`
|
|
|
257 |
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
|
|
|
258 |
CHECK_FILE=`grep ^extra_modules $KDUMP_CONFIG_FILE | cut -d\ -f2-`
|
|
|
259 |
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
|
|
|
260 |
CHECK_FILE=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
|
|
|
261 |
EXTRA_FILES="$EXTRA_FILES $CHECK_FILE"
|
|
|
262 |
FORCE_REBUILD=`grep ^extra_modules $KDUMP_CONFIG_FILE`
|
|
|
263 |
files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_FILES"
|
|
|
264 |
|
| 9 |
- |
265 |
# changes in CLUSTER_CONFIG_FILE should be monitored only if fence_kdump
|
|
|
266 |
# is not configured using fence_kdump_nodes option in /etc/kdump.conf
|
|
|
267 |
# and fence_kdump is configured in Pacemaker cluster
|
|
|
268 |
if ! grep -q ^fence_kdump_nodes /etc/kdump.conf \
|
|
|
269 |
&& [ -f "$CLUSTER_CONFIG_FILE" ] \
|
|
|
270 |
&& grep -q fence_kdump "$CLUSTER_CONFIG_FILE"
|
| 4 |
- |
271 |
then
|
|
|
272 |
files="$files $CLUSTER_CONFIG_FILE"
|
|
|
273 |
if [ -f "$FENCE_KDUMP_CONFIG" ]; then
|
|
|
274 |
files="$files $FENCE_KDUMP_CONFIG"
|
|
|
275 |
fi
|
|
|
276 |
fi
|
|
|
277 |
|
|
|
278 |
for file in $files; do
|
|
|
279 |
time_stamp=0
|
|
|
280 |
if [ -f "$file" ]; then
|
|
|
281 |
time_stamp=`stat -c "%Y" $file`
|
|
|
282 |
else
|
|
|
283 |
modified_files="$modified_files $file"
|
|
|
284 |
continue
|
|
|
285 |
fi
|
|
|
286 |
if [ "$time_stamp" -gt "$image_time" ]; then
|
|
|
287 |
modified_files="$modified_files $file"
|
|
|
288 |
fi
|
|
|
289 |
done
|
|
|
290 |
fi
|
|
|
291 |
|
|
|
292 |
if [ -n "$FORCE_REBUILD" -a "$modified_files"!=" " ]
|
|
|
293 |
then
|
|
|
294 |
modified_files="force_rebuild"
|
|
|
295 |
fi
|
|
|
296 |
|
|
|
297 |
if [ -n "$modified_files" -a "$modified_files"!=" " ]; then
|
|
|
298 |
if [ "$modified_files" != "force_rebuild" ]
|
|
|
299 |
then
|
|
|
300 |
echo "Detected change(s) the following file(s):"
|
|
|
301 |
echo -n " "; echo "$modified_files" | sed 's/\s/\n /g'
|
|
|
302 |
fi
|
|
|
303 |
|
|
|
304 |
if ! check_xen_hvm_nopv_premkdumprd; then
|
|
|
305 |
echo "hvm guest with pv drivers is not supported."
|
|
|
306 |
exit 1
|
|
|
307 |
fi
|
|
|
308 |
|
|
|
309 |
echo "Rebuilding $kdump_initrd"
|
|
|
310 |
$MKDUMPRD $kdump_initrd $kdump_kver
|
|
|
311 |
if [ $? != 0 ]; then
|
|
|
312 |
echo "Failed to run mkdumprd"
|
|
|
313 |
$LOGGER "mkdumprd: failed to make kdump initrd"
|
| 58 |
- |
314 |
rm -f $kdump_initrd
|
| 4 |
- |
315 |
return 1
|
|
|
316 |
fi
|
|
|
317 |
fi
|
|
|
318 |
|
|
|
319 |
#double check the xen_*front modules are not included for xen hvm
|
|
|
320 |
if in_xen_hvm_guest; then
|
|
|
321 |
if $(lsinitrd $kdump_initrd|grep -q "xen_.*front.ko"); then
|
|
|
322 |
echo "Found xen pv drivers in kdump initrd"
|
|
|
323 |
exit 1
|
|
|
324 |
fi
|
|
|
325 |
fi
|
|
|
326 |
return 0
|
|
|
327 |
}
|
|
|
328 |
|
| 58 |
- |
329 |
function check_config()
|
|
|
330 |
{
|
|
|
331 |
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
|
|
332 |
check_fadump_config
|
|
|
333 |
else
|
|
|
334 |
check_kdump_config
|
|
|
335 |
fi
|
|
|
336 |
|
|
|
337 |
return $?
|
|
|
338 |
}
|
|
|
339 |
|
| 4 |
- |
340 |
# This function check iomem and determines if we have more than
|
|
|
341 |
# 4GB of ram available. Returns 1 if we do, 0 if we dont
|
|
|
342 |
function need_64bit_headers()
|
|
|
343 |
{
|
|
|
344 |
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
|
|
|
345 |
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
|
|
|
346 |
}
|
|
|
347 |
|
|
|
348 |
function avoid_cdrom_drive()
|
|
|
349 |
{
|
|
|
350 |
local DRIVE=""
|
|
|
351 |
local MEDIA=""
|
|
|
352 |
local IDE_DRIVES=(`echo hd{a,b,c,d}`)
|
|
|
353 |
local COUNTER="0"
|
|
|
354 |
|
|
|
355 |
for DRIVE in ${IDE_DRIVES[@]}
|
|
|
356 |
do
|
|
|
357 |
if ! $(echo "$KDUMP_COMMANDLINE" |grep -q "$DRIVE=");then
|
|
|
358 |
if [ -f /proc/ide/$DRIVE/media ];then
|
|
|
359 |
MEDIA=$(cat /proc/ide/$DRIVE/media)
|
|
|
360 |
if [ x"$MEDIA" == x"cdrom" ]; then
|
|
|
361 |
KDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=cdrom"
|
|
|
362 |
COUNTER=$(($COUNTER+1))
|
|
|
363 |
fi
|
|
|
364 |
fi
|
|
|
365 |
else
|
|
|
366 |
KDUMP_IDE_NOPROBE_COMMANDLINE="$KDUMP_IDE_NOPROBE_COMMANDLINE $DRIVE=noprobe"
|
|
|
367 |
fi
|
|
|
368 |
done
|
|
|
369 |
# We don't find cdrom drive.
|
|
|
370 |
if [ $COUNTER -eq 0 ]; then
|
|
|
371 |
KDUMP_IDE_NOPROBE_COMMANDLINE=""
|
|
|
372 |
fi
|
|
|
373 |
}
|
|
|
374 |
|
|
|
375 |
function check_kernel_parameter()
|
|
|
376 |
{
|
|
|
377 |
if [ -z "$KDUMP_COMMANDLINE" ]
|
|
|
378 |
then
|
|
|
379 |
KDUMP_COMMANDLINE=`cat /proc/cmdline`
|
|
|
380 |
fi
|
|
|
381 |
|
|
|
382 |
MEM_RESERVED=`cat /sys/kernel/kexec_crash_size`
|
|
|
383 |
|
|
|
384 |
if [ $MEM_RESERVED -eq 0 ]
|
|
|
385 |
then
|
|
|
386 |
return 1
|
|
|
387 |
else
|
|
|
388 |
return 0
|
|
|
389 |
fi
|
|
|
390 |
}
|
|
|
391 |
|
| 58 |
- |
392 |
# Load the kdump kernel specified in /etc/sysconfig/kdump
|
| 4 |
- |
393 |
# If none is specified, try to load a kdump kernel with the same version
|
|
|
394 |
# as the currently running kernel.
|
|
|
395 |
function load_kdump()
|
|
|
396 |
{
|
|
|
397 |
ARCH=`uname -m`
|
|
|
398 |
|
|
|
399 |
# Get the approx amount of ram the kernel is using in Kb
|
|
|
400 |
KMEMINUSE=`awk '/Slab:.*/ {print $2}' /proc/meminfo`
|
|
|
401 |
# Convert the reserved ram amount to Kb
|
|
|
402 |
MEM_RESERVED=`dc -e"$MEM_RESERVED 1024 / p"`
|
|
|
403 |
|
|
|
404 |
# Take 70% of the reserved value rounding up to the nearest integer
|
|
|
405 |
MEM_RESERVED=`dc -e"$MEM_RESERVED .7 * 10 * 10 / p"`
|
|
|
406 |
|
|
|
407 |
#On x86, we are using nr_cpus=1, so the following check is not necessary.
|
|
|
408 |
if [ "$ARCH" != "i686" -a "$ARCH" != "i386" -a "$ARCH" != "x86_64" ]
|
|
|
409 |
then
|
|
|
410 |
#Check if the KMEMINUSE is greater than MEM_RESERVED
|
|
|
411 |
# This indicates that the currently runnign kernel is using
|
|
|
412 |
# 70% of the amount of memory that we have reserved for kdump
|
|
|
413 |
# we should issue a warning here indicating that the user may
|
|
|
414 |
# want to increase the amount of reserved ram on the system
|
|
|
415 |
if [ $KMEMINUSE -gt $MEM_RESERVED ]
|
|
|
416 |
then
|
|
|
417 |
echo -n "Your running kernel is using more than 70% of the amount of space you reserved for kdump, you should consider increasing your crashkernel reservation"
|
|
|
418 |
warning
|
|
|
419 |
echo
|
|
|
420 |
fi
|
|
|
421 |
fi
|
|
|
422 |
|
|
|
423 |
if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
|
|
|
424 |
then
|
|
|
425 |
|
|
|
426 |
need_64bit_headers
|
|
|
427 |
if [ $? == 1 ]
|
|
|
428 |
then
|
|
|
429 |
FOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf32-core-headers`
|
|
|
430 |
if [ -n "$FOUND_ELF_ARGS" ]
|
|
|
431 |
then
|
|
|
432 |
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
|
|
|
433 |
warning
|
|
|
434 |
echo
|
|
|
435 |
else
|
|
|
436 |
KEXEC_ARGS="$KEXEC_ARGS --elf64-core-headers"
|
|
|
437 |
fi
|
|
|
438 |
else
|
|
|
439 |
FOUND_ELF_ARGS=`echo $KEXEC_ARGS | grep elf64-core-headers`
|
|
|
440 |
if [ -z "$FOUND_ELF_ARGS" ]
|
|
|
441 |
then
|
|
|
442 |
KEXEC_ARGS="$KEXEC_ARGS --elf32-core-headers"
|
|
|
443 |
fi
|
|
|
444 |
fi
|
|
|
445 |
fi
|
|
|
446 |
|
|
|
447 |
if [ -f /sys/firmware/efi/systab ]
|
|
|
448 |
then
|
|
|
449 |
if grep -q '^ACPI20=' /sys/firmware/efi/systab
|
|
|
450 |
then
|
|
|
451 |
acpi_addr=$(awk -F'=' '/^ACPI20=/ {print $2}' /sys/firmware/efi/systab)
|
|
|
452 |
else
|
|
|
453 |
acpi_addr=$(awk -F'=' '/^ACPI=/ {print $2}' /sys/firmware/efi/systab)
|
|
|
454 |
fi
|
|
|
455 |
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE noefi acpi_rsdp=$acpi_addr"
|
| 97 |
- |
456 |
|
|
|
457 |
smbios_addr=$(awk -F'=' '/^SMBIOS=/ {print $2}' /sys/firmware/efi/systab)
|
|
|
458 |
if [ -n "$smbios_addr" ]; then
|
|
|
459 |
KDUMP_COMMANDLINE="$KDUMP_COMMANDLINE efi_smbios_addr=$smbios_addr"
|
|
|
460 |
fi
|
| 4 |
- |
461 |
fi
|
|
|
462 |
|
|
|
463 |
if echo "$KDUMP_COMMANDLINE_APPEND" | grep -q nr_cpus;
|
|
|
464 |
then
|
|
|
465 |
ver=`uname -r`
|
|
|
466 |
maj=`echo $ver | cut -d'-' -f1`
|
|
|
467 |
min=`echo $ver | cut -d'-' -f2`
|
|
|
468 |
min=${min%%.*}
|
|
|
469 |
if [ "$maj" = "2.6.32" ] && [ $min -lt 171 ]
|
|
|
470 |
then
|
|
|
471 |
echo "Your kernel is old, please use maxcpus=1 instead of nr_cpus=1"
|
|
|
472 |
return 1
|
|
|
473 |
fi
|
|
|
474 |
fi
|
|
|
475 |
|
| 5 |
- |
476 |
KDUMP_COMMANDLINE=`prepare_cmdline`
|
|
|
477 |
|
| 4 |
- |
478 |
if ! grep -q /sys/kernel/debug /proc/mounts;
|
|
|
479 |
then
|
|
|
480 |
mount -t debugfs debug /sys/kernel/debug
|
|
|
481 |
MNTDEBUG=/sys/kernel/debug
|
|
|
482 |
fi
|
| 5 |
- |
483 |
|
| 4 |
- |
484 |
$KEXEC $KEXEC_ARGS $standard_kexec_args \
|
|
|
485 |
--command-line="$KDUMP_COMMANDLINE" \
|
|
|
486 |
--initrd=$kdump_initrd $kdump_kernel 2>/dev/null
|
|
|
487 |
if [ $? == 0 ]; then
|
|
|
488 |
umount $MNTDEBUG 2>/dev/null
|
|
|
489 |
$LOGGER "kexec: loaded kdump kernel"
|
|
|
490 |
return 0
|
|
|
491 |
else
|
|
|
492 |
umount $MNTDEBUG 2>/dev/null
|
|
|
493 |
$LOGGER "kexec: failed to load kdump kernel"
|
|
|
494 |
return 1
|
|
|
495 |
fi
|
|
|
496 |
}
|
|
|
497 |
|
|
|
498 |
function propagate_ssh_key()
|
|
|
499 |
{
|
|
|
500 |
while read config_opt config_val; do
|
|
|
501 |
case "$config_opt" in
|
|
|
502 |
sshkey)
|
|
|
503 |
SSH_KEY_LOCATION="$config_val"
|
|
|
504 |
;;
|
|
|
505 |
*)
|
|
|
506 |
;;
|
|
|
507 |
esac
|
|
|
508 |
done < $KDUMP_CONFIG_FILE
|
|
|
509 |
|
|
|
510 |
local KEYFILE=$SSH_KEY_LOCATION
|
|
|
511 |
local errmsg="Failed to propagate ssh key"
|
|
|
512 |
|
|
|
513 |
#make sure they've configured kdump.conf for ssh dumps
|
|
|
514 |
local SSH_TARGET=`awk '/^\ *net.*@.*$/ {print $0}' $KDUMP_CONFIG_FILE`
|
|
|
515 |
[ -z "$SSH_TARGET" ] && SSH_TARGET=`awk '/^\ *ssh.*@.*$/ {print $0}' $KDUMP_CONFIG_FILE`
|
|
|
516 |
if [ -z "$SSH_TARGET" ]; then
|
|
|
517 |
echo "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate"
|
|
|
518 |
$LOGGER "$errmsg, no ssh config specified in $KDUMP_CONFIG_FILE"
|
|
|
519 |
exit 1
|
|
|
520 |
fi
|
|
|
521 |
|
|
|
522 |
#Check to see if we already created key, if not, create it.
|
|
|
523 |
if [ -f $KEYFILE ]; then
|
|
|
524 |
echo "Using existing keys..."
|
|
|
525 |
else
|
|
|
526 |
echo -n "Generating new ssh keys... "
|
|
|
527 |
/usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/null
|
|
|
528 |
echo "done."
|
|
|
529 |
fi
|
|
|
530 |
|
|
|
531 |
#now find the target ssh user and server to contact.
|
|
|
532 |
SSH_USER=`echo $SSH_TARGET | cut -d\ -f2 | cut -d@ -f1`
|
|
|
533 |
SSH_SERVER=`echo $SSH_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'`
|
|
|
534 |
|
|
|
535 |
#now send the found key to the found server
|
|
|
536 |
ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER &>/dev/null
|
|
|
537 |
RET=$?
|
|
|
538 |
if [ $RET == 0 ]; then
|
|
|
539 |
echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER
|
|
|
540 |
$LOGGER "propagated ssh key (ssh server: $SSH_SERVER)"
|
|
|
541 |
return 0
|
|
|
542 |
else
|
|
|
543 |
echo $KEYFILE failed in transfer to $SSH_SERVER
|
|
|
544 |
$LOGGER "$errmsg, unable to transfer $KEYFILE to $SSH_SERVER"
|
|
|
545 |
exit 1
|
|
|
546 |
fi
|
|
|
547 |
|
|
|
548 |
}
|
|
|
549 |
|
|
|
550 |
function status()
|
|
|
551 |
{
|
| 58 |
- |
552 |
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
|
|
553 |
check_current_fadump_status
|
|
|
554 |
return $?
|
|
|
555 |
fi
|
|
|
556 |
|
| 4 |
- |
557 |
if [ ! -e /sys/kernel/kexec_crash_loaded ]
|
|
|
558 |
then
|
|
|
559 |
return 2
|
|
|
560 |
fi
|
|
|
561 |
|
|
|
562 |
if in_xen_pv_guest; then
|
|
|
563 |
return 2
|
|
|
564 |
elif in_xen_hvm_guest && ! grep -q -e xen_emul_unplug=never -e xen_emul_unplug=unnecessary /proc/cmdline; then
|
|
|
565 |
echo 'kdump only supported on xen hvm guests booted with xen_emul_unplug=never or xen_emul_unplug=unnecessary'
|
|
|
566 |
return 2
|
|
|
567 |
fi
|
|
|
568 |
|
|
|
569 |
rc=`cat /sys/kernel/kexec_crash_loaded`
|
|
|
570 |
if [ $rc == 1 ]; then
|
|
|
571 |
return 0
|
|
|
572 |
else
|
|
|
573 |
return 1
|
|
|
574 |
fi
|
|
|
575 |
}
|
|
|
576 |
|
|
|
577 |
function save_raw()
|
|
|
578 |
{
|
|
|
579 |
local raw_part=$(awk '$1 ~ /^raw$/ { print $2; }' $KDUMP_CONFIG_FILE)
|
|
|
580 |
local kdump_dir
|
|
|
581 |
if [ "$raw_part" ]; then
|
|
|
582 |
[ -b "$raw_part" ] || {
|
|
|
583 |
echo "raw partition $raw_part not found"
|
|
|
584 |
return 1
|
|
|
585 |
}
|
|
|
586 |
kdump_dir=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`
|
|
|
587 |
if [ -z "${kdump_dir}" ]; then
|
|
|
588 |
coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"
|
|
|
589 |
else
|
|
|
590 |
coredir="${kdump_dir}/`date +"%Y-%m-%d-%H:%M"`"
|
|
|
591 |
fi
|
|
|
592 |
mkdir -p "$coredir"
|
|
|
593 |
[ -d "$coredir" ] || {
|
|
|
594 |
echo "failed to create $coredir"
|
|
|
595 |
return 1
|
|
|
596 |
}
|
|
|
597 |
if makedumpfile -R $coredir/vmcore <$raw_part >/dev/null 2>&1; then
|
|
|
598 |
# dump found
|
|
|
599 |
echo "Dump saved to $coredir/vmcore"
|
|
|
600 |
# wipe makedumpfile header
|
|
|
601 |
dd if=/dev/zero of=$raw_part bs=1b count=1 2>/dev/null
|
|
|
602 |
else
|
|
|
603 |
rm -rf "$coredir"
|
|
|
604 |
fi
|
|
|
605 |
fi
|
|
|
606 |
return 0
|
|
|
607 |
}
|
|
|
608 |
|
|
|
609 |
get_save_path() {
|
|
|
610 |
local _save_path=$(grep "^path" /etc/kdump.conf|awk '{print $2}')
|
|
|
611 |
if [ -z "$_save_path" ]; then
|
|
|
612 |
_save_path="/var/crash"
|
|
|
613 |
fi
|
|
|
614 |
|
|
|
615 |
echo $_save_path
|
|
|
616 |
}
|
|
|
617 |
|
|
|
618 |
is_dump_target_configured() {
|
|
|
619 |
local _target
|
|
|
620 |
|
| 58 |
- |
621 |
_target=$(egrep "^ext[234]|^xfs|^btrfs|^raw|^ssh|^nfs|^nfs4|^net" /etc/kdump.conf)
|
| 4 |
- |
622 |
|
|
|
623 |
[ -n "$_target" ]
|
|
|
624 |
}
|
|
|
625 |
|
|
|
626 |
local_fs_dump_target()
|
|
|
627 |
{
|
|
|
628 |
local _target
|
|
|
629 |
|
| 58 |
- |
630 |
_target=$(egrep "^ext[234]|^xfs|^btrfs" /etc/kdump.conf)
|
| 4 |
- |
631 |
if [ $? -eq 0 ]; then
|
|
|
632 |
echo $_target|awk '{print $2}'
|
|
|
633 |
fi
|
|
|
634 |
}
|
|
|
635 |
|
|
|
636 |
path_to_be_relabeled() {
|
|
|
637 |
local _path _target _mnt="/" _rmnt
|
|
|
638 |
|
|
|
639 |
if is_dump_target_configured; then
|
|
|
640 |
_target=$(local_fs_dump_target)
|
|
|
641 |
if [[ -n "$_target" ]]; then
|
|
|
642 |
_mnt=$(findmnt -k -f -n -r -o TARGET $_target)
|
|
|
643 |
if [ -z "$_mnt" ]; then
|
|
|
644 |
return
|
|
|
645 |
fi
|
|
|
646 |
else
|
|
|
647 |
return
|
|
|
648 |
fi
|
|
|
649 |
fi
|
|
|
650 |
|
|
|
651 |
_path=$(get_save_path)
|
|
|
652 |
# if $_path is masked by other mount, we will not relabel it.
|
|
|
653 |
# one exception is ! is_dump_target_configure && "$_rmnt" != "$_mnt"
|
|
|
654 |
# for this exception see mkdumprd code about [ -z "$USING_METHOD" ]
|
|
|
655 |
_rmnt=$(df $_mnt/$_path 2>/dev/null | tail -1 | awk '{ print $NF }')
|
|
|
656 |
if [[ "$_rmnt" == "$_mnt" ]] || ! is_dump_target_configured; then
|
|
|
657 |
echo $_mnt/$_path
|
|
|
658 |
fi
|
|
|
659 |
}
|
|
|
660 |
|
|
|
661 |
selinux_relabel()
|
|
|
662 |
{
|
|
|
663 |
local _path _i _attr
|
|
|
664 |
|
|
|
665 |
_path=$(path_to_be_relabeled)
|
|
|
666 |
if [ -z "$_path" ] || ! [ -d "$_path" ] ; then
|
|
|
667 |
return
|
|
|
668 |
fi
|
|
|
669 |
|
|
|
670 |
for _i in $(find $_path); do
|
|
|
671 |
_attr=$(getfattr -m "security.selinux" $_i 2>/dev/null)
|
|
|
672 |
if [ -z "$_attr" ]; then
|
|
|
673 |
restorecon $_i;
|
|
|
674 |
fi
|
|
|
675 |
done
|
|
|
676 |
}
|
|
|
677 |
|
| 58 |
- |
678 |
start_dump()
|
|
|
679 |
{
|
|
|
680 |
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
|
|
681 |
start_fadump
|
|
|
682 |
else
|
|
|
683 |
load_kdump
|
|
|
684 |
fi
|
| 4 |
- |
685 |
|
| 58 |
- |
686 |
return $?
|
|
|
687 |
}
|
|
|
688 |
|
|
|
689 |
|
| 4 |
- |
690 |
# Notes about xen support:
|
|
|
691 |
# pv guests are not supported
|
|
|
692 |
# hvm guests are supported only when you ensure below items:
|
|
|
693 |
# 1. Boot guests with either xen_emul_unplug=never or
|
|
|
694 |
# xen_emul_unplug=unnecessary.
|
|
|
695 |
# 2. While recreating kdump initrd xen_netfront and xen_blkfront modules
|
|
|
696 |
# are not loaded
|
|
|
697 |
function start()
|
|
|
698 |
{
|
|
|
699 |
if sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; then
|
|
|
700 |
selinux_relabel
|
|
|
701 |
fi
|
|
|
702 |
save_raw
|
|
|
703 |
if [ $? -ne 0 ]; then
|
|
|
704 |
echo -n "Starting kdump:"; failure; echo
|
|
|
705 |
$LOGGER "failed to start up"
|
|
|
706 |
return 1
|
|
|
707 |
fi
|
|
|
708 |
status
|
|
|
709 |
rc=$?
|
|
|
710 |
if [ $rc == 2 ]; then
|
|
|
711 |
echo -n "Kdump is not supported on this kernel"; failure; echo
|
|
|
712 |
return 1;
|
|
|
713 |
else
|
|
|
714 |
if [ $rc == 0 ]; then
|
|
|
715 |
echo -n "Kdump already running"; success; echo
|
|
|
716 |
return 0
|
|
|
717 |
fi
|
|
|
718 |
fi
|
|
|
719 |
|
| 58 |
- |
720 |
# Kernel parameter check is not required for fadump as 'fadump=on'
|
|
|
721 |
# should have already been passed if dump mode is fadump
|
|
|
722 |
if [ $DEFAULT_DUMP_MODE != "fadump" ]; then
|
|
|
723 |
check_kernel_parameter
|
|
|
724 |
if [ $? != 0 ]; then
|
|
|
725 |
echo -n "Starting kdump:"; failure; echo
|
|
|
726 |
$LOGGER "No crashkernel parameter specified for running kernel"
|
|
|
727 |
return 1
|
|
|
728 |
fi
|
| 4 |
- |
729 |
fi
|
|
|
730 |
|
|
|
731 |
check_config
|
|
|
732 |
if [ $? != 0 ]; then
|
|
|
733 |
echo -n "Starting kdump:"; failure; echo
|
|
|
734 |
$LOGGER "failed to start up, config file incorrect"
|
|
|
735 |
return 1
|
|
|
736 |
fi
|
| 58 |
- |
737 |
|
|
|
738 |
start_dump
|
| 4 |
- |
739 |
if [ $? != 0 ]; then
|
|
|
740 |
echo -n "Starting kdump:"; failure; echo
|
|
|
741 |
$LOGGER "failed to start up"
|
|
|
742 |
return 1
|
|
|
743 |
fi
|
|
|
744 |
|
|
|
745 |
echo -n "Starting kdump:"; success; echo
|
|
|
746 |
$LOGGER "started up"
|
|
|
747 |
}
|
|
|
748 |
|
| 58 |
- |
749 |
stop_kdump()
|
|
|
750 |
{
|
|
|
751 |
$KEXEC -p -u 2>/dev/null
|
|
|
752 |
if [ $? != 0 ]; then
|
|
|
753 |
$LOGGER "kexec: failed to unload kdump kernel"
|
|
|
754 |
return 1
|
|
|
755 |
fi
|
|
|
756 |
|
|
|
757 |
$LOGGER "kexec: unloaded kdump kernel"
|
|
|
758 |
return 0
|
|
|
759 |
}
|
|
|
760 |
|
| 4 |
- |
761 |
function stop()
|
|
|
762 |
{
|
| 58 |
- |
763 |
if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
|
|
|
764 |
stop_fadump
|
| 4 |
- |
765 |
else
|
| 58 |
- |
766 |
stop_kdump
|
|
|
767 |
fi
|
|
|
768 |
|
|
|
769 |
if [ $? != 0 ]; then
|
| 4 |
- |
770 |
echo -n "Stopping kdump:"; failure; echo
|
|
|
771 |
$LOGGER "failed to stop"
|
|
|
772 |
return 1
|
|
|
773 |
fi
|
| 58 |
- |
774 |
|
|
|
775 |
echo -n "Stopping kdump:"; success; echo
|
|
|
776 |
$LOGGER "stopped"
|
|
|
777 |
return 0
|
| 4 |
- |
778 |
}
|
|
|
779 |
|
|
|
780 |
# Other kdump init instances will block in queue, until this one exits.
|
|
|
781 |
single_instance_lock
|
|
|
782 |
|
| 58 |
- |
783 |
# Determine if the dump mode is kdump or fadump
|
|
|
784 |
determine_dump_mode
|
|
|
785 |
|
| 4 |
- |
786 |
case "$1" in
|
|
|
787 |
start)
|
| 58 |
- |
788 |
if [ $DEFAULT_DUMP_MODE == "fadump" ] && is_fadump_save_path
|
|
|
789 |
then
|
|
|
790 |
# fadump: second boot after crash, save vmcore
|
|
|
791 |
save_fadump_core
|
|
|
792 |
if [ $? -eq 0 ]; then
|
|
|
793 |
reboot
|
|
|
794 |
else
|
|
|
795 |
save_fadump_core_on_error
|
|
|
796 |
handle_fadump_default_action
|
|
|
797 |
fi
|
|
|
798 |
elif [ -s /proc/vmcore ]; then
|
| 4 |
- |
799 |
save_core
|
|
|
800 |
reboot
|
|
|
801 |
else
|
|
|
802 |
start
|
|
|
803 |
fi
|
|
|
804 |
;;
|
|
|
805 |
stop)
|
|
|
806 |
stop
|
|
|
807 |
;;
|
|
|
808 |
status)
|
|
|
809 |
EXIT_CODE=0
|
|
|
810 |
status
|
|
|
811 |
case "$?" in
|
|
|
812 |
0)
|
|
|
813 |
echo "Kdump is operational"
|
|
|
814 |
EXIT_CODE=0
|
|
|
815 |
;;
|
|
|
816 |
1)
|
|
|
817 |
echo "Kdump is not operational"
|
|
|
818 |
EXIT_CODE=3
|
|
|
819 |
;;
|
|
|
820 |
2)
|
|
|
821 |
echo "Kdump is unsupported on this kernel"
|
|
|
822 |
EXIT_CODE=3
|
|
|
823 |
;;
|
|
|
824 |
esac
|
|
|
825 |
exit $EXIT_CODE
|
|
|
826 |
;;
|
|
|
827 |
restart)
|
|
|
828 |
stop
|
|
|
829 |
start
|
|
|
830 |
;;
|
|
|
831 |
condrestart)
|
|
|
832 |
EXIT_CODE=1
|
|
|
833 |
status
|
|
|
834 |
case "$?" in
|
|
|
835 |
0)
|
|
|
836 |
stop
|
|
|
837 |
start
|
|
|
838 |
EXIT_CODE=0
|
|
|
839 |
;;
|
|
|
840 |
esac
|
|
|
841 |
exit $EXIT_CODE
|
|
|
842 |
;;
|
|
|
843 |
propagate)
|
|
|
844 |
propagate_ssh_key
|
|
|
845 |
;;
|
|
|
846 |
*)
|
|
|
847 |
echo $"Usage: $0 {start|stop|status|restart|propagate}"
|
|
|
848 |
exit 1
|
|
|
849 |
esac
|
|
|
850 |
|
|
|
851 |
exit $?
|