2016-12-24 18:28:21 +09:00
#!/usr/bin/env bash
#
2016-12-25 10:51:41 +09:00
# Auto install latest kernel for TCP BBR
2016-12-24 18:28:21 +09:00
#
# System Required: CentOS 6+, Debian7+, Ubuntu12+
#
2018-01-05 21:16:38 +09:00
# Copyright (C) 2016-2018 Teddysun <i@teddysun.com>
2016-12-24 18:28:21 +09:00
#
2016-12-24 20:36:10 +09:00
# URL: https://teddysun.com/489.html
2016-12-24 18:28:21 +09:00
#
red = '\033[0;31m'
green = '\033[0;32m'
yellow = '\033[0;33m'
plain = '\033[0m'
2017-10-28 12:10:43 +09:00
cur_dir = $( pwd )
2016-12-24 18:28:21 +09:00
[ [ $EUID -ne 0 ] ] && echo -e " ${ red } Error: ${ plain } This script must be run as root! " && exit 1
2018-02-04 22:29:52 +08:00
[ [ -d "/proc/vz" ] ] && echo -e " ${ red } Error: ${ plain } Your VPS is based on OpenVZ, which is not supported. " && exit 1
2016-12-24 18:28:21 +09:00
if [ -f /etc/redhat-release ] ; then
release = "centos"
2016-12-29 16:05:27 +09:00
elif cat /etc/issue | grep -Eqi "debian" ; then
2016-12-24 18:28:21 +09:00
release = "debian"
2016-12-29 16:05:27 +09:00
elif cat /etc/issue | grep -Eqi "ubuntu" ; then
2016-12-24 18:28:21 +09:00
release = "ubuntu"
2016-12-29 16:05:27 +09:00
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat" ; then
2016-12-24 18:28:21 +09:00
release = "centos"
2016-12-29 16:05:27 +09:00
elif cat /proc/version | grep -Eqi "debian" ; then
2016-12-24 18:28:21 +09:00
release = "debian"
2016-12-29 16:05:27 +09:00
elif cat /proc/version | grep -Eqi "ubuntu" ; then
2016-12-24 18:28:21 +09:00
release = "ubuntu"
2016-12-29 16:05:27 +09:00
elif cat /proc/version | grep -Eqi "centos|red hat|redhat" ; then
2016-12-24 18:28:21 +09:00
release = "centos"
2018-01-05 21:16:38 +09:00
else
release = ""
2016-12-24 18:28:21 +09:00
fi
2018-05-12 00:50:19 +09:00
is_digit( ) {
local input = ${ 1 }
if [ [ " $input " = ~ ^[ 0-9] +$ ] ] ; then
return 0
else
return 1
fi
}
2018-12-14 22:36:49 +09:00
is_64bit( ) {
if [ $( getconf WORD_BIT) = '32' ] && [ $( getconf LONG_BIT) = '64' ] ; then
return 0
else
return 1
fi
}
2018-05-12 00:50:19 +09:00
get_valid_valname( ) {
local val = ${ 1 }
local new_val = $( eval echo $val | sed 's/[-.]/_/g' )
echo ${ new_val }
}
get_hint( ) {
local val = ${ 1 }
local new_val = $( get_valid_valname $val )
eval echo " \$hint_ ${ new_val } "
}
#Display Memu
display_menu( ) {
local soft = ${ 1 }
local default = ${ 2 }
eval local arr = ( \$ { ${ soft } _arr[ @] } )
local default_prompt
if [ [ " $default " != "" ] ] ; then
if [ [ " $default " = = "last" ] ] ; then
default = ${# arr [@] }
fi
default_prompt = " (default ${ arr [ $default -1] } ) "
fi
local pick
local hint
local vname
local prompt = " which ${ soft } you'd select ${ default_prompt } : "
while :
do
echo -e " \n------------ ${ soft } setting ------------\n "
for ( ( i = 1; i<= ${# arr [@] } ; i++ ) ) ; do
vname = " $( get_valid_valname ${ arr [ $i -1] } ) "
hint = " $( get_hint $vname ) "
[ [ " $hint " = = "" ] ] && hint = " ${ arr [ $i -1] } "
echo -e " ${ green } ${ i } ${ plain } ) $hint "
done
echo
read -p " ${ prompt } " pick
if [ [ " $pick " = = "" && " $default " != "" ] ] ; then
pick = ${ default }
break
fi
if ! is_digit " $pick " ; then
prompt = "Input error, please input a number"
continue
fi
if [ [ " $pick " -lt 1 || " $pick " -gt ${# arr [@] } ] ] ; then
prompt = " Input error, please input a number between 1 and ${# arr [@] } : "
continue
fi
break
done
eval ${ soft } = ${ arr [ $pick -1] }
vname = " $( get_valid_valname ${ arr [ $pick -1] } ) "
hint = " $( get_hint $vname ) "
[ [ " $hint " = = "" ] ] && hint = " ${ arr [ $pick -1] } "
echo -e " \nyour selection: $hint \n "
}
version_ge( ) {
test " $( echo " $@ " | tr " " "\n" | sort -rV | head -n 1) " = = " $1 "
}
2017-01-21 00:33:25 +09:00
get_latest_version( ) {
2018-12-14 22:36:49 +09:00
latest_version = ( $( wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F'\"v' '/v[4-9]./{print $2}' | cut -d/ -f1 | grep -v - | sort -V) )
2017-01-21 00:33:25 +09:00
2018-05-12 00:50:19 +09:00
[ ${# latest_version [@] } -eq 0 ] && echo -e " ${ red } Error: ${ plain } Get latest kernel version failed. " && exit 1
kernel_arr = ( )
for i in ${ latest_version [@] } ; do
if version_ge $i 4.14; then
kernel_arr += ( $i ) ;
fi
done
2017-01-21 00:33:25 +09:00
2018-05-12 00:50:19 +09:00
display_menu kernel last
2017-02-27 23:39:06 +09:00
2017-01-21 00:33:25 +09:00
if [ [ ` getconf WORD_BIT` = = "32" && ` getconf LONG_BIT` = = "64" ] ] ; then
2018-12-14 22:36:49 +09:00
deb_name = $( wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${ kernel } / | grep "linux-image" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_url = " https://kernel.ubuntu.com/~kernel-ppa/mainline/v ${ kernel } / ${ deb_name } "
2018-05-12 00:50:19 +09:00
deb_kernel_name = " linux-image- ${ kernel } -amd64.deb "
2018-12-14 22:36:49 +09:00
modules_deb_name = $( wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${ kernel } / | grep "linux-modules" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_modules_url = " https://kernel.ubuntu.com/~kernel-ppa/mainline/v ${ kernel } / ${ modules_deb_name } "
2018-05-19 00:31:49 +09:00
deb_kernel_modules_name = " linux-modules- ${ kernel } -amd64.deb "
2017-01-21 00:33:25 +09:00
else
2018-12-14 22:36:49 +09:00
deb_name = $( wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${ kernel } / | grep "linux-image" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_url = " https://kernel.ubuntu.com/~kernel-ppa/mainline/v ${ kernel } / ${ deb_name } "
2018-05-12 00:50:19 +09:00
deb_kernel_name = " linux-image- ${ kernel } -i386.deb "
2018-12-14 22:36:49 +09:00
modules_deb_name = $( wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${ kernel } / | grep "linux-modules" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_modules_url = " https://kernel.ubuntu.com/~kernel-ppa/mainline/v ${ kernel } / ${ modules_deb_name } "
2018-05-19 00:31:49 +09:00
deb_kernel_modules_name = " linux-modules- ${ kernel } -i386.deb "
2017-01-21 00:33:25 +09:00
fi
2018-05-12 00:50:19 +09:00
[ -z ${ deb_name } ] && echo -e " ${ red } Error: ${ plain } Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again. " && exit 1
2017-01-21 00:33:25 +09:00
}
2016-12-24 18:28:21 +09:00
get_opsy( ) {
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}
opsy = $( get_opsy )
arch = $( uname -m )
lbit = $( getconf LONG_BIT )
kern = $( uname -r )
get_char( ) {
SAVEDSTTY = ` stty -g`
stty -echo
stty cbreak
dd if = /dev/tty bs = 1 count = 1 2> /dev/null
stty -raw
stty echo
stty $SAVEDSTTY
}
getversion( ) {
if [ [ -s /etc/redhat-release ] ] ; then
grep -oE "[0-9.]+" /etc/redhat-release
else
grep -oE "[0-9.]+" /etc/issue
fi
}
centosversion( ) {
2018-01-05 21:16:38 +09:00
if [ x" ${ release } " = = x"centos" ] ; then
2016-12-24 18:28:21 +09:00
local code = $1
local version = " $( getversion) "
local main_ver = ${ version %%.* }
if [ " $main_ver " = = " $code " ] ; then
return 0
else
return 1
fi
else
return 1
fi
}
check_bbr_status( ) {
2018-05-12 00:50:19 +09:00
local param = $( sysctl net.ipv4.tcp_congestion_control | awk '{print $3}' )
2018-01-05 21:16:38 +09:00
if [ [ x" ${ param } " = = x"bbr" ] ] ; then
2017-10-28 12:10:43 +09:00
return 0
else
return 1
fi
}
check_kernel_version( ) {
local kernel_version = $( uname -r | cut -d- -f1)
if version_ge ${ kernel_version } 4.9; then
return 0
2016-12-24 18:28:21 +09:00
else
return 1
fi
}
install_elrepo( ) {
2017-02-28 09:38:37 +09:00
2016-12-24 18:28:21 +09:00
if centosversion 5; then
echo -e " ${ red } Error: ${ plain } not supported CentOS 5. "
exit 1
2017-02-28 09:38:37 +09:00
fi
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
if centosversion 6; then
2018-12-14 22:36:49 +09:00
rpm -Uvh https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
2016-12-24 18:28:21 +09:00
elif centosversion 7; then
2018-12-14 22:36:49 +09:00
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
2016-12-24 18:28:21 +09:00
fi
if [ ! -f /etc/yum.repos.d/elrepo.repo ] ; then
2017-02-28 09:38:37 +09:00
echo -e " ${ red } Error: ${ plain } Install elrepo failed, please check it. "
2016-12-24 18:28:21 +09:00
exit 1
fi
}
2017-10-28 12:10:43 +09:00
sysctl_config( ) {
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>& 1
}
2016-12-24 18:28:21 +09:00
install_config( ) {
2018-01-05 21:16:38 +09:00
if [ [ x" ${ release } " = = x"centos" ] ] ; then
2016-12-24 18:28:21 +09:00
if centosversion 6; then
if [ ! -f "/boot/grub/grub.conf" ] ; then
echo -e " ${ red } Error: ${ plain } /boot/grub/grub.conf not found, please check it. "
exit 1
fi
sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
elif centosversion 7; then
if [ ! -f "/boot/grub2/grub.cfg" ] ; then
echo -e " ${ red } Error: ${ plain } /boot/grub2/grub.cfg not found, please check it. "
exit 1
fi
grub2-set-default 0
fi
2018-01-05 21:16:38 +09:00
elif [ [ x" ${ release } " = = x"debian" || x" ${ release } " = = x"ubuntu" ] ] ; then
2017-01-09 11:46:27 +09:00
/usr/sbin/update-grub
2016-12-24 18:28:21 +09:00
fi
2017-10-28 12:10:43 +09:00
}
2016-12-29 16:05:27 +09:00
2017-10-28 12:10:43 +09:00
reboot_os( ) {
echo
echo -e " ${ green } Info: ${ plain } The system needs to reboot. "
read -p "Do you want to restart system? [y/n]" is_reboot
if [ [ ${ is_reboot } = = "y" || ${ is_reboot } = = "Y" ] ] ; then
reboot
else
echo -e " ${ green } Info: ${ plain } Reboot has been canceled... "
exit 0
fi
2016-12-24 18:28:21 +09:00
}
install_bbr( ) {
check_bbr_status
if [ $? -eq 0 ] ; then
echo
2018-06-09 12:29:48 +09:00
echo -e " ${ green } Info: ${ plain } TCP BBR has already been installed. nothing to do... "
2017-10-28 12:10:43 +09:00
exit 0
fi
check_kernel_version
if [ $? -eq 0 ] ; then
echo
echo -e " ${ green } Info: ${ plain } Your kernel version is greater than 4.9, directly setting TCP BBR... "
sysctl_config
echo -e " ${ green } Info: ${ plain } Setting TCP BBR completed... "
exit 0
2016-12-24 18:28:21 +09:00
fi
2018-01-05 21:16:38 +09:00
if [ [ x" ${ release } " = = x"centos" ] ] ; then
2016-12-24 18:28:21 +09:00
install_elrepo
2018-06-09 12:29:48 +09:00
[ ! " $( command -v yum-config-manager) " ] && yum install -y yum-utils > /dev/null 2>& 1
[ x" $( yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}' ) " != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>& 1
2018-12-14 22:36:49 +09:00
if centosversion 6; then
if is_64bit; then
rpm_kernel_name = "kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"
rpm_kernel_devel_name = "kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"
rpm_kernel_url_1 = "http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"
else
rpm_kernel_name = "kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"
rpm_kernel_devel_name = "kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"
rpm_kernel_url_1 = "http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"
fi
rpm_kernel_url_2 = "https://dl.lamp.sh/files/"
wget -c -t3 -T60 -O ${ rpm_kernel_name } ${ rpm_kernel_url_1 } ${ rpm_kernel_name }
if [ $? -ne 0 ] ; then
rm -rf ${ rpm_kernel_name }
wget -c -t3 -T60 -O ${ rpm_kernel_name } ${ rpm_kernel_url_2 } ${ rpm_kernel_name }
fi
wget -c -t3 -T60 -O ${ rpm_kernel_devel_name } ${ rpm_kernel_url_1 } ${ rpm_kernel_devel_name }
if [ $? -ne 0 ] ; then
rm -rf ${ rpm_kernel_devel_name }
wget -c -t3 -T60 -O ${ rpm_kernel_devel_name } ${ rpm_kernel_url_2 } ${ rpm_kernel_devel_name }
fi
[ -f ${ rpm_kernel_name } ] && rpm -ivh ${ rpm_kernel_name } || echo -e " ${ red } Error: ${ plain } Download ${ rpm_kernel_name } failed, please check it. " ; exit 1
[ -f ${ rpm_kernel_devel_name } ] && rpm -ivh ${ rpm_kernel_devel_name } || echo -e " ${ red } Error: ${ plain } Download ${ rpm_kernel_devel_name } failed, please check it. " ; exit 1
rm -f ${ rpm_kernel_name } ${ rpm_kernel_devel_name }
elif centosversion 7; then
yum -y install kernel-ml kernel-ml-devel
if [ $? -ne 0 ] ; then
echo -e " ${ red } Error: ${ plain } Install latest kernel failed, please check it. "
exit 1
fi
2016-12-24 18:28:21 +09:00
fi
2018-01-05 21:16:38 +09:00
elif [ [ x" ${ release } " = = x"debian" || x" ${ release } " = = x"ubuntu" ] ] ; then
2016-12-24 18:28:21 +09:00
[ [ ! -e "/usr/bin/wget" ] ] && apt-get -y update && apt-get -y install wget
2018-05-12 00:50:19 +09:00
echo -e " ${ green } Info: ${ plain } Getting latest kernel version... "
2017-01-21 00:33:25 +09:00
get_latest_version
2018-05-19 00:31:49 +09:00
if [ -n ${ modules_deb_name } ] ; then
wget -c -t3 -T60 -O ${ deb_kernel_modules_name } ${ deb_kernel_modules_url }
if [ $? -ne 0 ] ; then
echo -e " ${ red } Error: ${ plain } Download ${ deb_kernel_modules_name } failed, please check it. "
exit 1
fi
fi
2016-12-24 18:28:21 +09:00
wget -c -t3 -T60 -O ${ deb_kernel_name } ${ deb_kernel_url }
if [ $? -ne 0 ] ; then
echo -e " ${ red } Error: ${ plain } Download ${ deb_kernel_name } failed, please check it. "
exit 1
fi
2018-05-19 00:31:49 +09:00
[ -f ${ deb_kernel_modules_name } ] && dpkg -i ${ deb_kernel_modules_name }
2016-12-24 18:28:21 +09:00
dpkg -i ${ deb_kernel_name }
2018-05-19 00:31:49 +09:00
rm -f ${ deb_kernel_name } ${ deb_kernel_modules_name }
2016-12-24 18:28:21 +09:00
else
2016-12-25 10:51:41 +09:00
echo -e " ${ red } Error: ${ plain } OS is not be supported, please change to CentOS/Debian/Ubuntu and try again. "
2016-12-24 18:28:21 +09:00
exit 1
fi
2016-12-29 16:05:27 +09:00
install_config
2017-10-28 12:10:43 +09:00
sysctl_config
reboot_os
2016-12-24 18:28:21 +09:00
}
2017-10-28 12:10:43 +09:00
2016-12-24 18:28:21 +09:00
clear
echo "---------- System Information ----------"
echo " OS : $opsy "
echo " Arch : $arch ( $lbit Bit) "
echo " Kernel : $kern "
echo "----------------------------------------"
echo " Auto install latest kernel for TCP BBR"
echo
2016-12-24 20:36:10 +09:00
echo " URL: https://teddysun.com/489.html"
2016-12-24 18:28:21 +09:00
echo "----------------------------------------"
echo
echo "Press any key to start...or Press Ctrl+C to cancel"
char = ` get_char`
2017-10-28 12:10:43 +09:00
install_bbr 2>& 1 | tee ${ cur_dir } /install_bbr.log