summaryrefslogtreecommitdiff
path: root/packages/slugos-init/files/boot/kexec
blob: c5b428cd0777453a89c1ed5e4ca596a95631df29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/sh
#
# Loads the specified kernel and kexecs it.
# 
# The access method and path from which to fetch the kernel
# is specified in "$1" and "$2":
#
# flash      /boot/zImage-ixp4xxbe
# nfs        spike:/home/slug/vmlinuz
# wget       http://devserv/kernels/vmlinuzbe
# wget       ftp://ftpserv/pub/zImage
# /dev/sda1  /kernels/zImage-test
# UUID       /kernels/zImage-test
#
# Command-line options for the new kernel are in "$3".

# Use the standard init path (see /etc/init.d/rcS)
export PATH=/sbin:/bin:/usr/sbin:/usr/bin

# Wait at least a short while for the disks...
if [ ! "$sleep" -gt 0 ] ; then
    sleep=1
fi

# Load the helper functions
. /etc/default/functions
. /etc/default/modulefunctions

leds boot system

if [ -n "$1" -a -n "$2" ] ; then

	method="$1"
	shift
	kpath="$1"
	shift
	if [ -n "$1" ] ; then
	    kcmdline="$1"
	    shift
	fi
	kexec_image=
	need_umount=0
	do_kexec=0

	mount -t proc proc /proc

	case "$method" in

	    flash )
		echo "Loading kexec kernel directly from \"$kpath\"..."
		kexec_image="$kpath"
		;;

	    wget )
		if /boot/network ; then
		    echo "mounting tmpfs partition..."
		    if mount -t tmpfs tmpfs /mnt ; then
			need_umount=1
			echo "Loading kexec kernel using wget \"$kpath\"..."
			wget -P /mnt "$kpath"
			t=`basename "$kpath"`
			kexec_image="/mnt/$t"
		    fi
		fi
		;;

	    nfs )
		if /boot/network ; then
		    echo "Loading kexec kernel using nfs \"$kpath\"..."
		    echo "mounting nfs partition..."
		    if mount -o ro,nolock -t nfs `dirname "$kpath"` /mnt ; then
			need_umount=1
			t=`basename "$kpath"`
			kexec_image="/mnt/$t"
		    fi
		fi
		;;

	    /dev/* )
		echo "Loading kexec kernel using disk \"$kpath\"..."
		loaddiskmods
		sleep "$sleep"
		echo "mounting partition \"$method\"..."
		if mount -o ro "$method" /mnt ; then
		    need_umount=1
		    kexec_image="/mnt/$kpath"
		fi
		;;

	    UUID )
		echo "Loading kexec kernel using disk UUID \"$kpath\"..."
		loaddiskmods
		sleep "$sleep"
		if [ -n "$UUID" ] ; then
		echo "mounting partition UUID \"$UUID\"..."
		    if mount -o ro -U "$UUID" /mnt ; then
			need_umount=1
			kexec_image="/mnt/$kpath"
		    fi
		fi
		;;

	    * )
		echo "Unrecognized method: \"$method\""
		;;

	esac

	if [ -n "$kexec_image" -a -f "$kexec_image" ] ; then
	    if kexec -l "$kexec_image" ; then
		do_kexec=1
	    fi
	else
	    echo "Unable to load \"$kexec_image\""
	fi

	if [ $do_kexec -eq 1 -a -n "$kcmdline" ] ; then
	    echo "Attempting to mount /sys (sysfs)..."
	    if mount -t sysfs sysfs /sys ; then
		echo "Setting command line:"
		echo " \"$kcmdline\""
		echo "$kcmdline" > /sys/kernel/kexec_cmdline
		echo "unmounting /sys..."
		umount /sys
	    else
		do_kexec=0
	    fi
	fi

	if [ $need_umount -eq 1 ] ; then
	    echo "unmounting /mnt..."
	    umount /mnt
	fi

	if [ $do_kexec -eq 1 ] ; then
	    echo "Remounting root as read-only..."
	    mount -o remount,ro /
	    echo "Invoking \"kexec -f -e\" ..."
	    kexec -f -e
	    echo "ERROR!"
	    # We should never return here!  At this point, things are not
	    # too well.  Remount the root as rw, and fallback.
	    echo "Remounting root as read-write..."
	    mount -o remount,rw /
	fi
else
	echo "Usage: $0 flash|nfs|wget|UUID|/dev/<partition> <path-or-URL> [cmdline]"
fi

# fallback - use the flash boot
echo "Falling back to flash boot..."
leds beep -f 1000 -r 2
exec /boot/flash

# fallback to the fallback
leds boot system panic
exec <>/dev/console >&0 2>&0
test -x /bin/sh && exec /bin/sh
exit 1