Subversion Repositories configs

Rev

Rev 97 | Details | Compare with Previous | Last modification | View Log | RSS feed

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