338 lines
9.4 KiB
Plaintext
338 lines
9.4 KiB
Plaintext
|
|
#!/bin/sh
|
||
|
|
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
||
|
|
#
|
||
|
|
# This program is free software; you can redistribute it and/or modify
|
||
|
|
# it under the terms of the GNU General Public License version 2 and
|
||
|
|
# only version 2 as published by the Free Software Foundation.
|
||
|
|
#
|
||
|
|
# This program is distributed in the hope that it will be useful,
|
||
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
# GNU General Public License for more details.
|
||
|
|
|
||
|
|
SYS_LIVEPATCH=/sys/kernel/livepatch
|
||
|
|
G_TMP_DIR=/tmp/hotpatch.$$
|
||
|
|
G_PATCH_FILE=
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: usage
|
||
|
|
# Input:
|
||
|
|
# Return: 0-success
|
||
|
|
#########################################################
|
||
|
|
OS_HP_HELP()
|
||
|
|
{
|
||
|
|
echo "usage: os_hotpatch"
|
||
|
|
echo "-w|--check <filepath> : check hotpatch"
|
||
|
|
echo "-l|--load <filepath> : load hotpatch"
|
||
|
|
echo "-a|--active <patchname> : active hotpatch"
|
||
|
|
echo "-r|--rollback <patchname> : rollback/deactive hotpatch"
|
||
|
|
echo "-d|--delete <patchname> : delete/unload hotpatch"
|
||
|
|
echo "-q|--query <patchname>/all : query hotpatch"
|
||
|
|
echo "-h|--help : show this help information"
|
||
|
|
}
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: check hotpatch file before install
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch file path
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
OS_HP_CHECK()
|
||
|
|
{
|
||
|
|
path=$1
|
||
|
|
if [ ! -f "$path" ]; then
|
||
|
|
echo "The file $path is not exit"
|
||
|
|
exit 1;
|
||
|
|
fi
|
||
|
|
EXTRACT_HP $path
|
||
|
|
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||
|
|
echo "The file $path is invalid"
|
||
|
|
CLEAN_UP
|
||
|
|
exit 1;
|
||
|
|
fi
|
||
|
|
CLEAN_UP
|
||
|
|
echo "The file $path is valid"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: active a hotpatch
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch name(klp-xxx.tar.gz)
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
OS_HP_ACTIVE()
|
||
|
|
{
|
||
|
|
file=$1
|
||
|
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||
|
|
patch_install=`lsmod | grep -w $patch_name`
|
||
|
|
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
echo "patch $file not load"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||
|
|
if [ ${is_active} == 1 ]; then
|
||
|
|
echo "patch already active"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo 1 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||
|
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||
|
|
if [ ${is_active} == 1 ]; then
|
||
|
|
echo "active patch $file success"
|
||
|
|
exit 0
|
||
|
|
else
|
||
|
|
echo "active patch $file fail"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: deactive a hotpatch
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch name(klp-xxx.tar.gz)
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
OS_HP_DEACTIVE()
|
||
|
|
{
|
||
|
|
file=$1
|
||
|
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||
|
|
patch_install=`lsmod | grep -w $patch_name`
|
||
|
|
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
echo "patch $file not load"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||
|
|
if [ ${is_active} == 0 ]; then
|
||
|
|
echo "patch $file already deactive"
|
||
|
|
exit 0
|
||
|
|
else
|
||
|
|
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||
|
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||
|
|
if [ ${is_active} != 1 ]; then
|
||
|
|
echo "deactive patch $file success"
|
||
|
|
exit 0
|
||
|
|
else
|
||
|
|
echo "deactive patch $file fail"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: remove a hotpatch
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch name(klp-xxx.tar.gz)
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
OS_HP_REMOVE()
|
||
|
|
{
|
||
|
|
file=$1
|
||
|
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||
|
|
patch_install=`lsmod | grep -w $patch_name`
|
||
|
|
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
echo "patch $file not load"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||
|
|
if [ ${is_active} == 0 ]; then
|
||
|
|
rmmod ${patch_name}
|
||
|
|
else
|
||
|
|
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||
|
|
rmmod ${patch_name}
|
||
|
|
fi
|
||
|
|
|
||
|
|
patch_install=`lsmod | grep -w $patch_name`
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
echo "remove patch $file success"
|
||
|
|
exit 0
|
||
|
|
else
|
||
|
|
echo "remove patch $file failed"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
#########################################################
|
||
|
|
# Description: query a hotpatch
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch name(klp-xxx.tar.gz) or all
|
||
|
|
# Return: 0-success,1-not load,2-deactive,3-active,4-fault
|
||
|
|
#########################################################
|
||
|
|
OS_HP_INQUIRY()
|
||
|
|
{
|
||
|
|
file=$1
|
||
|
|
lret=0
|
||
|
|
if [ "all" == $file ];then
|
||
|
|
cd ${SYS_LIVEPATCH}
|
||
|
|
if [ -z "`ls -d */ 2>/dev/null`" ];then
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
for patch in `ls -d */ 2>/dev/null`
|
||
|
|
do
|
||
|
|
patch_id=${patch%/}
|
||
|
|
patch_id=${patch_id#klp_}
|
||
|
|
echo "Patch Name: ${patch_id}"
|
||
|
|
lstate=`cat /${SYS_LIVEPATCH}/${patch}/enabled 2>/dev/null`
|
||
|
|
if [ -z "$lstate" ];then
|
||
|
|
echo "Patch State: Removing"
|
||
|
|
echo "-----------------------------------------------------------"
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
if [ $lstate -eq 1 ];then
|
||
|
|
echo "Patch State: Active"
|
||
|
|
else
|
||
|
|
echo "Patch State: Deactive"
|
||
|
|
fi
|
||
|
|
cd ${SYS_LIVEPATCH}/${patch} 2>/dev/null
|
||
|
|
depends=`ls -d */ 2>/dev/null`
|
||
|
|
echo "Changes:"
|
||
|
|
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||
|
|
echo "Denpendency: ${depends%/}"
|
||
|
|
echo "-----------------------------------------------------------"
|
||
|
|
done
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
patch=`echo ${file%.tar.gz}|tr '-' '_'`
|
||
|
|
patch_install=`lsmod | grep -w $patch`
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
patch_id=${patch%/}
|
||
|
|
patch_id=${patch_id#klp_}
|
||
|
|
echo "Patch Name: ${patch_id}"
|
||
|
|
if [ `cat /${SYS_LIVEPATCH}/${patch}/enabled` -eq 1 ];then
|
||
|
|
echo "Patch State: Active"
|
||
|
|
lret=3
|
||
|
|
else
|
||
|
|
echo "Patch State: Deactive"
|
||
|
|
lret=2
|
||
|
|
fi
|
||
|
|
cd ${SYS_LIVEPATCH}/${patch}
|
||
|
|
depends=`ls -d */ 2>/dev/null`
|
||
|
|
echo "Changes:"
|
||
|
|
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||
|
|
echo "Denpendency: ${depends%/}"
|
||
|
|
echo "-----------------------------------------------------------"
|
||
|
|
|
||
|
|
exit $lret
|
||
|
|
}
|
||
|
|
#########################################################
|
||
|
|
# Description: extract hotpatch tar to tmp dir
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch file path
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
EXTRACT_HP()
|
||
|
|
{
|
||
|
|
mkdir $G_TMP_DIR
|
||
|
|
tar xzf $1 -C $G_TMP_DIR
|
||
|
|
l_ret=$?
|
||
|
|
if [ $l_ret -eq 0 ];then
|
||
|
|
#find the hotpatch module
|
||
|
|
G_PATCH_FILE=$(find $G_TMP_DIR|grep -w "klp.*\.ko")
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
#########################################################
|
||
|
|
# Description: clean up the tmp dir
|
||
|
|
# Input:
|
||
|
|
# Return: none
|
||
|
|
#########################################################
|
||
|
|
CLEAN_UP()
|
||
|
|
{
|
||
|
|
rm -rf $G_TMP_DIR
|
||
|
|
}
|
||
|
|
#########################################################
|
||
|
|
# Description: install a hotpatch
|
||
|
|
# Input:
|
||
|
|
# $1: hotpatch file path
|
||
|
|
# Return: 0-success,1-failed
|
||
|
|
#########################################################
|
||
|
|
OS_HP_INSTALL()
|
||
|
|
{
|
||
|
|
path=$1
|
||
|
|
|
||
|
|
if [ ! -f "$path" ]; then
|
||
|
|
echo "The file $path is not exit"
|
||
|
|
exit 1;
|
||
|
|
fi
|
||
|
|
EXTRACT_HP $path
|
||
|
|
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||
|
|
echo "The file $path is invalid!"
|
||
|
|
CLEAN_UP
|
||
|
|
exit 1;
|
||
|
|
fi
|
||
|
|
patch_name=`echo ${G_PATCH_FILE%.ko}|tr '-' '_'`
|
||
|
|
patch_name=${patch_name##*/}
|
||
|
|
patch_install=`lsmod | grep -w $patch_name`
|
||
|
|
if [ "$patch_install" == "" ]; then
|
||
|
|
echo "insmod $G_PATCH_FILE"
|
||
|
|
insmod $G_PATCH_FILE
|
||
|
|
L_RET=$?
|
||
|
|
if [ 0 -ne ${L_RET} ]; then
|
||
|
|
echo "install patch $path fail"
|
||
|
|
CLEAN_UP
|
||
|
|
return 1
|
||
|
|
else
|
||
|
|
echo "install patch $path success"
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
echo "patch $path already install"
|
||
|
|
fi
|
||
|
|
CLEAN_UP
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
#----------------------------main-------------------------#
|
||
|
|
if [ ! -d ${SYS_LIVEPATCH} ];then
|
||
|
|
echo "this OS does not support kernel livepatch"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
input_args=`getopt -a -o l:a:r:d:w:q: -l load:,active:,delete:,check:,rollback:,query:,help, -- "$@" 2>&1`
|
||
|
|
eval set -- "${input_args}"
|
||
|
|
while true;
|
||
|
|
do
|
||
|
|
case "$1" in
|
||
|
|
-w|--check)
|
||
|
|
OS_HP_CHECK "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-l|--load)
|
||
|
|
OS_HP_INSTALL "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-a|--active)
|
||
|
|
OS_HP_ACTIVE "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-r|--rollback)
|
||
|
|
OS_HP_DEACTIVE "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-d|--delete)
|
||
|
|
OS_HP_REMOVE "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-q|--query)
|
||
|
|
OS_HP_INQUIRY "$2"
|
||
|
|
exit $?
|
||
|
|
;;
|
||
|
|
-h|--help)
|
||
|
|
OS_HP_HELP
|
||
|
|
exit 0
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
OS_HP_HELP
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
done
|