-
Notifications
You must be signed in to change notification settings - Fork 1
/
kexec-multiboot-recovery
138 lines (125 loc) · 3.95 KB
/
kexec-multiboot-recovery
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
#!/bin/sh
### BEGIN INIT INFO
# Version: 1.0.1
# Provides: kexec-multiboot-recovery
# Required-Start: $local_fs
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Kexec kernel check
### END INIT INFO
DRYRUN=false
DEBUG=false
DESC="Kexec kernel validity check...\n"
STARTUP_PATH=""
#STARTUP_PATH=/boot # only for devel, comment out for final test
KEXEC_KERNEL_PATH=/usr/bin/kernel_auto.bin
#Hardcoded partition
do_detect_box() {
MODEL=`cat /proc/device-tree/bolt/board | tr -d '\000' | tr "[A-Z]" "[a-z]"`
echo "- Detected $MODEL"
case $MODEL in
solo4k|uno4k|ultimo4k)
KERNEL=mmcblk0p1
ROOTFS=mmcblk0p4
;;
uno4kse)
KERNEL=mmcblk0p1
ROOTFS=mmcblk0p4
;;
zero4k)
KERNEL=mmcblk0p4
ROOTFS=mmcblk0p7
;;
duo4k|duo4kse)
KERNEL=mmcblk0p6
ROOTFS=mmcblk0p9
;;
*)
echo "ERROR: this box isn't supported yet"
;;
esac
}
do_locate_current_image(){
args=`cat ${STARTUP_PATH}/STARTUP`
for x in ${args};
do
case "$x" in
root=*)
ROOT_DEST="${x#root=}"
;;
kernel=*)
KERNEL_DEST="${x#kernel=}"
;;
esac
done
[ x${DEBUG} = xtrue ] && echo DEBUG:ROOT_DEST=${ROOT_DEST}
[ x${DEBUG} = xtrue ] && echo DEBUG:KERNEL_DEST=${KERNEL_DEST}
#The rootfs in STARTUP slot could be defined as path or as UUID.
#Check if the fs is mounted, if not mount it and identify the mount point to use
ROOT_MOUNT_POINT=""
if echo ${ROOT_DEST} | grep -qi "UUID="; then
DEVICE=$(blkid | sed -n "/${ROOT_DEST#*=}/s/\([^:]\+\):.*/\\1/p")
if [ x${DEVICE} != x ]; then
ROOT_MOUNT_POINT=`grep "^${DEVICE}" /proc/mounts | cut -d " " -f 2`
if [ x${ROOT_MOUNT_POINT} = x ]; then
mkdir -p /tmp/kexec-recovery
eval mount ${ROOT_DEST} /tmp/kexec-recovery
ROOT_MOUNT_POINT=`grep "^${DEVICE}" /proc/mounts | cut -d " " -f 2`
fi
fi
elif echo ${ROOT_DEST} | grep -q "^/dev/mmcblk"; then
ROOT_MOUNT_POINT=${STARTUP_PATH}
else
ROOT_MOUNT_POINT=`grep "^${ROOT_DEST}" /proc/mounts | cut -d " " -f 2`
fi
[ x${DEBUG} = xtrue ] && echo DEBUG:ROOT_DEST=${ROOT_DEST}
[ x${DEBUG} = xtrue ] && echo DEBUG:ROOT_MOUNT_POINT=${ROOT_MOUNT_POINT}
[ x${DEBUG} = xtrue ] && echo DEBUG:KERNEL_DEST=${KERNEL_DEST}
SELECTED_KERNEL_PATH=${ROOT_MOUNT_POINT}/${KERNEL_DEST}
}
do_fix() {
echo "- Backup running kernel into previous selected image"
cmd="dd if=/dev/$KERNEL of=${SELECTED_KERNEL_PATH}"
echo "running: ${cmd}"
[ x${DRYRUN} = xtrue ] && echo "DRYRUN: ${cmd}" || ${cmd}
echo "- Restoring kexec multiboot kernel"
cmd="dd if=/usr/bin/kernel_auto.bin of=/dev/$KERNEL"
echo "running: ${cmd}"
[ x${DRYRUN} = xtrue ] && echo "DRYRUN: ${cmd}" || ${cmd}
cmd="sync; sync; sync"
[ x${DRYRUN} = xtrue ] && echo "DRYRUN: ${cmd}" || eval ${cmd}
cmd="reboot -d -f"
[ x${DRYRUN} = xtrue ] && echo "DRYRUN: ${cmd}" || eval ${cmd}
#/sbin/reboot -d -f
#/sbin/init 6
}
do_check() {
if [ -f ${STARTUP_PATH}/STARTUP -a -f ${STARTUP_PATH}/STARTUP.cpio.gz ]; then
if [ -f /sys/firmware/devicetree/base/chosen/bootargs ]; then
echo "- Kexec kernel works correctly"
else
echo "- Kexec kernel not running... fixing"
do_detect_box
do_locate_current_image
[ x${DEBUG} = xtrue ] && echo DEBUG:SELECTED_KERNEL_PATH:${SELECTED_KERNEL_PATH}
if [ x${SELECTED_KERNEL_PATH} != x ]; then
do_fix
fi
fi
else
echo "- Kexec multiboot not installed.. no fix needed"
fi
}
case "$1" in
start)
echo -n -e "- $DESC"
do_check
echo "done."
;;
*)
echo "Usage: $0 {start}"
exit 1
;;
esac
exit 0