#!/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=/lib/modules/hotpatch.$$ G_PATCH_FILE= ######################################################### # Description: usage # Input: # Return: 0-success ######################################################### OS_HP_HELP() { echo "usage: os_hotpatch" echo "-w|--check : check hotpatch" echo "-l|--load : load hotpatch" echo "-a|--active : active hotpatch" echo "-r|--rollback : rollback/deactive hotpatch" echo "-d|--delete : delete/unload hotpatch" echo "-q|--query /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() { rm -rf $G_TMP_DIR mkdir -p $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