-
Notifications
You must be signed in to change notification settings - Fork 0
/
install
executable file
·336 lines (304 loc) · 10.7 KB
/
install
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#!/bin/sh
#
# Check/Download/Compile the latest Linux kernel from https://www.kernel.org.
# If checking in GUI, show notification balloon if a new kernel is available.
#
# Usage: kernel-update [moniker] [-c]
#
# moniker: stable, mainline, longterm, linux-next, etc.
# -c: just check if new version is available, don't update
#
# dependencies: wget bc bison flex lz4c libncurses5-dev
# optional: notify-send, for kernel check GUI notification support
#
# (cloux@rote.ch)
###########################################################
# Linux kernel branch
MONIKER=stable
# How to run kernel configuration:
# "ask" - use config from previous kernel, ask user for new symbols
# empty (default) - use config from previous kernel, and apply defaults for
# new symbols. Fully automated, for unattended upgrades.
#CONFIGTYPE=ask
CONFIGTYPE=
# Number of simultaneous compilation jobs.
# If not set, detect and use all CPU cores.
JOBS=
# Compilation log will go into: /usr/src/kernel-VERSION/$LOGFILE
LOGFILE=compile.log
# Delete obsolete kernels, keep only the currently used and the new one.
# Remove kernel sources, keep only headers required to compile kernel modules.
# This makes kernel headers available for sharing.
#CLEANUP=y
CLEANUP=n
# Pack kernel modules into an archive in /boot for sharing.
# Useful when combined with a webserver and 'sin pull kernel' command.
#SHARE=y
SHARE=n
###########################################################
exec 2>&1
# use configuration files to override the defaults above
MODULE_PATH=$(realpath "${0%/*}" 2>/dev/null)
[ -r "$MODULE_PATH/conf" ] && . "$MODULE_PATH/conf"
[ -r /etc/default/kernel-update ] && . /etc/default/kernel-update
# parse parameters
CHECK=""
for PARAM in "$@"; do
if [ "$PARAM" = "-c" ]; then
CHECK="Y"
else
MONIKER="$PARAM"
fi
done
# We need to be root to install new kernel
if [ $(id -u) -ne 0 ] && [ "$CHECK" != "Y" ]; then
printf 'Need to be root!\n'
exit 1
fi
#
# check and try to install dependencies
#
APTINST="$(command -v aptitude)"
[ "$APTINST" ] || APTINST="$(command -v apt-get)"
export DEBIAN_FRONTEND=noninteractive
if [ -z "$(command -v wget)" ] || [ -z "$(command -v bc)" ] || \
[ -z "$(command -v bison)" ] || [ -z "$(command -v flex)" ] || \
[ -z "$(command -v lz4c)" ] || [ -z "$(command -v jq)" ]; then \
if [ "$APTINST" ]; then
$APTINST --assume-yes -o Dpkg::Use-Pty=0 update
$APTINST --assume-yes -o Dpkg::Use-Pty=0 install \
wget bc bison flex libssl-dev libelf-dev lz4 jq
fi
fi
for DEP in wget bc bison flex lz4c jq; do
if ! command -v "$DEP" >/dev/null; then
printf 'ERROR: Please install "%s" to continue.\n' "$DEP"
exit 1
fi
done
# PATH needs /usr/sbin for update-grub to work
printf '%s' "$PATH" | grep -q '/usr/sbin' || export PATH=$PATH:/usr/sbin
#
# Get information about the latest kernel on kernel.org
#
printf 'Current kernel: %s\n' "$(uname -r)"
printf 'Latest %s kernel: ' "$MONIKER"
# JSON file with current kernel information.
RELEASES_LINK=https://www.kernel.org/releases.json
RELEASES_FILE="$(printf %s "$RELEASES_LINK" | grep -o '[^/]*$')"
cd /tmp || exit 1
if ! wget -q -N -4 "$RELEASES_LINK"; then
printf 'ERROR: Link %s not available!\n' "$RELEASES_LINK"
exit 1
fi
# select MONIKER json
KERNEL_JSON="$(jq -c '.releases | map(select(.moniker == "'$MONIKER'"))[0]' "$RELEASES_FILE")"
rm "$RELEASES_FILE"
if [ -z "$KERNEL_JSON" ]; then
printf 'ERROR: Moniker "%s" not found.\n' "$MONIKER"
exit 1
fi
KERNEL_LINK=$(printf '%s' "$KERNEL_JSON" | jq -r '.source')
KERNEL_DATE=$(printf '%s' "$KERNEL_JSON" | jq -r '.released.isodate?')
# Work around weird version numbering differences:
# The numbering scheme in the JSON might differ from vmlinuz-XY kernel
# file name when 0's are involved, like "4.0.0", but "4.0-rc1" :/
KERNEL_VERSION=$(printf '%s' "$KERNEL_JSON" | jq -r '.version' | sed 's/-/.0-/')
[ $(printf '%s' "$KERNEL_VERSION" | grep -o '\.' | wc -l) -eq 1 ] && KERNEL_VERSION=$KERNEL_VERSION.0
KERNEL_VERSION=$(printf '%s' "$KERNEL_VERSION" | sed 's/\.0\.0-/.0-/')
printf '%s (%s)\n' "$KERNEL_VERSION" "$KERNEL_DATE"
if [ -e "/boot/vmlinuz-$KERNEL_VERSION" ]; then
printf 'We already have that one.\n'
exit
fi
#
# If checking, notify the user and exit
#
if [ "$CHECK" ]; then
printf 'This is a new kernel, you may update.\n'
# show notification balloon in GUI environment
if [ "$(command -v notify-send)" ]; then
export DISPLAY=$(who | grep $(id -un) | grep -o '[(].*[)]$' | grep -o '[^()]*')
notify-send --expire-time=30000 \
--icon=/usr/share/icons/gnome/48x48/status/software-update-available.png \
"New $MONIKER kernel $KERNEL_VERSION found" 2>/dev/null
fi
exit
fi
#
# Download new kernel
#
cd /usr/src || exit 1
KERNEL_FILE=$(printf '%s' "$KERNEL_LINK" | grep -o '[^/]*$')
if [ ! -e "$KERNEL_FILE" ]; then
printf '\nDownloading ...\n'
wget -4 --progress=dot:giga "$KERNEL_LINK"
if [ $? -ne 0 ]; then
printf 'ERROR: kernel download failed.\n'
exit 1
fi
fi
#
# Check free space in /usr/src
#
FREE_MB=$(df --block-size=M --output=avail /usr/src | grep -o '[0-9]*')
# rough estimate how much do we need
KERNEL_SIZE_MB=$(du --block-size=M "$KERNEL_FILE" | grep -o '^[0-9]*')
NEEDED_MB=$(printf '22 * %s\n' "$KERNEL_SIZE_MB" | bc)
if [ $NEEDED_MB -gt $FREE_MB ]; then
printf 'ERROR: not enough free space in /usr/src\n'
printf 'You should have at least %s GB free to continue.\n' "$(printf 'scale=1; %s/1000\n' "$NEEDED_MB" | bc)"
exit 1
fi
#
# Unpack
#
printf 'Unpacking ...\n'
tar xJf "$KERNEL_FILE"
if [ $? -ne 0 ]; then
printf 'ERROR: Unpacking /usr/src/%s Failed!\n' "$KERNEL_FILE"
exit 1
fi
rm -f "$KERNEL_FILE"
KERNEL_DIR=$(printf '%s' "$KERNEL_FILE" | grep -Po '.*(?=.tar)')
if [ ! -d "$KERNEL_DIR" ]; then
printf 'ERROR: Kernel path /usr/src/%s not found!\n' "$KERNEL_DIR"
exit 1
fi
cd "$KERNEL_DIR"
#
# Configure (see CONFIGTYPE variable)
#
printf '\nConfigure '
# clean up logfile variable
LOGFILE=${LOGFILE##*/}
[ "$LOGFILE" ] || LOGFILE=compile.log
if [ "$CONFIGTYPE" = "ask" ]; then
# use same configuration as previous kernel, ask user for new symbols
printf '"%s" ...\n' "$CONFIGTYPE"
make oldconfig
elif [ "$CONFIGTYPE" = "menu" ]; then
# same as "old", then run ncurses configuration tool for additional changes
# WARNING: do NOT use this from Simple Installer (https://github.com/cloux/sin)
printf '"%s" ...\n' "$CONFIGTYPE"
make oldconfig; sleep 2
make menuconfig
else
# by default, run automatic unattended update: use previous kernel config,
# and apply default values for new symbols
printf '"unattended" ...\n'
make olddefconfig
fi
#
# Define compiler threads (see JOBS variable)
#
[ $JOBS -gt 0 ] 2>/dev/null
[ $? -ne 0 ] && JOBS=0
[ $JOBS -gt 0 ] || JOBS=$(nproc --all 2>/dev/null)
#
# Compile
#
printf 'Logfile: %s\n' "/usr/src/$KERNEL_DIR/$LOGFILE"
printf 'Compile using %s threads ...' "$JOBS"
START=$(date +%s.%N)
nice -n 1 make -j $JOBS >"/usr/src/$KERNEL_DIR/$LOGFILE" 2>&1
END=$(date +%s.%N)
printf 'DONE\n'
#
# Install
#
if [ -s vmlinux ]; then
printf '\nInstall modules ...'
make modules_install >>"/usr/src/$KERNEL_DIR/$LOGFILE"
printf 'DONE\n'
# Do not generate initrd if the feature is disabled in the kernel.
# See /etc/kernel/postinst.d/initramfs-tools hook script
(grep -iq 'BLK_DEV_INITRD *= *y' .config) || export INITRD=No
printf '\nInstall kernel ...\n'
make install
printf '\nCompilation FINISHED after [s.ms]: '
else
tail -n 15 "/usr/src/$KERNEL_DIR/$LOGFILE"
printf '\nCompilation FAILED after [s.ms]: '
fi
printf 'scale=3; (%s - %s)/1\n' "$END" "$START" | bc
[ -e "/boot/vmlinuz-$KERNEL_VERSION" ] || exit 1
#
# Delete obsolete kernels (see CLEANUP variable)
#
OLD_KERNELS=""
CUR_KERNEL=$(uname -r)
if [ "$CLEANUP" = "y" ] && [ -f "/boot/vmlinuz-$CUR_KERNEL" ]; then
printf '\nKernel cleanup ...\n'
printf 'Current active kernel: %s\n' "$CUR_KERNEL"
printf ' New updated kernel: %s\n' "$KERNEL_VERSION"
OLD_KERNELS=$(find /boot -maxdepth 1 -type f -name "vmlinuz*" ! -name "*$CUR_KERNEL" ! -name "*$KERNEL_VERSION" ! -name "*memtest*" -printf '%f ')
OLD_KERNELS=$(printf '%s' "$OLD_KERNELS" | sed 's/vmlinuz-//g')
printf ' Obsolete kernels: '
if [ "$OLD_KERNELS" ]; then
printf '%s\n' "$OLD_KERNELS"
printf 'Deleting obsolete kernels ...'
find /boot -maxdepth 1 -type f ! -name "*$CUR_KERNEL" ! -name "*$KERNEL_VERSION" ! -name "*memtest*" -delete
printf 'OK\nDeleting obsolete modules in /lib/modules ...'
for OLD_KERNEL in $OLD_KERNELS; do
[ -d "/lib/modules/$OLD_KERNEL" ] && rm -rf "/lib/modules/$OLD_KERNEL"
done
printf 'OK\nDeleting obsolete sources in /usr/src ...'
for OLD_KERNEL in $OLD_KERNELS; do
KERNELSRC_DIR=$(printf '%s' "$OLD_KERNEL" | sed 's/\.0$//')
[ -d "/usr/src/linux-$KERNELSRC_DIR" ] && rm -rf "/usr/src/linux-$KERNELSRC_DIR"
done
printf 'OK\n'
/usr/sbin/update-grub
else
printf 'none\n'
fi
elif [ "$CLEANUP" = "y" ]; then
printf 'WARNING: unable to determine current kernel, skipping /boot cleanup.\n'
fi
#
# Clean up source, keep only headers (see CLEANUP variable).
# Force this if the free space left is less than the size of this kernel.
#
cd "/usr/src/$KERNEL_DIR"
FREE_SPACE_MB=$(df --block-size=M --output=avail /usr/src | grep -o '[0-9]*')
KERNEL_SRC_MB=$(du --summarize --block-size=M . | grep -o '^[0-9]*')
[ $KERNEL_SRC_MB -gt $FREE_SPACE_MB ] && \
printf 'WARNING: Low on disk space: %s MB\n' "$FREE_SPACE_MB"
if [ "$CLEANUP" = "y" ] || [ $KERNEL_SRC_MB -gt $FREE_SPACE_MB ]; then
printf 'Deleting sources, keep headers ...\n'
cp -f -t /tmp .config Module.symvers
make distclean
mv -f /tmp/.config .
make modules_prepare >>"/usr/src/$KERNEL_DIR/$LOGFILE" 2>&1
mv -f /tmp/Module.symvers .
find -mindepth 1 -maxdepth 1 ! -name 'arch' ! -name 'include' ! -name 'scripts' \
! -name 'tools' ! -name 'Makefile' ! -name 'Kbuild' ! -name 'Kconfig' \
! -name '.config' ! -name 'Module.symvers' ! -name 'LICENSES' ! -name 'COPYING' \
-exec rm -rf '{}' \;
ln -s "/boot/System.map-$KERNEL_VERSION" System.map
cd arch && find -mindepth 1 -maxdepth 1 -type d ! -name 'x86' -exec rm -rf '{}' \;
cd ..
cd tools && rm -rf perf/ testing/
cd arch && find -mindepth 1 -maxdepth 1 -type d ! -name 'x86' -exec rm -rf '{}' \;
fi
#
# Pack kernel modules and headers into /boot (see SHARE variable)
#
# the /boot path can be shared with other systems that need the same kernel, see 'kernel-pull-binary.sh'
if [ "$SHARE" = "y" ]; then
# pack modules
cd /lib/modules
printf '\nPack modules into /boot for sharing ...'
tar czf "/boot/modules-$KERNEL_VERSION.tgz" "$KERNEL_VERSION" && printf 'OK\n'
# pack headers only if the source directory is cleaned up
if [ "$CLEANUP" = "y" ]; then
printf 'Pack headers into /boot for sharing ...'
cd /usr/src
tar czf "/boot/headers-$KERNEL_VERSION.tgz" "$KERNEL_DIR" && printf 'OK\n'
fi
# mark the latest available version into /boot/latest
printf '%s' "$KERNEL_VERSION" > /boot/latest
fi
printf '\nDONE\n'
exit