#!/usr/bin/bash

ASCEND_SECLOG="/var/log/ascend_seclog"
logFile="${ASCEND_SECLOG}/ascend_install.log"
runLogFile="${ASCEND_SECLOG}/ascend_run_servers.log"
installInfo="/etc/ascend_install.info"
ASCEND_DRIVER_CFG_FILE="/etc/ascend_driver.conf"
KMSAGENT_CONFIG_ITEM="kmsagent"
KMSAGENT_WORK_DIR="/var/kmsagentd"
KMSAGENT_CONF_MAIN_KSF="/var/kmsagentd/kmsconf.ksf"
KMSAGENT_SERVICE_DIR="/lib/systemd/system"
KMSAGENT_USER_SERVICE_DIR="/usr/lib/systemd/system"
KMSAGENT_SERVICE_NAME="ascend-kmsagent.service"
ASCEND_DRIVER_SETUP_SCRIPT="ascend_driver_config.sh"
username=HwHiAiUser
usergroup=HwHiAiUser
hotreset_status_file="/var/log/hotreset_status.log"
preinst_flag_first_file="/var/log/ascend_preinst_first_flag"
driverCrlStatusFile="/root/ascend_check/driver_crl_status_tmp"
davinci_num_file="/var/log/davinci_num.log"

occupy_space=300

OPERATION_LOGDIR="${ASCEND_SECLOG}"
OPERATION_LOGPATH="${OPERATION_LOGDIR}/operation.log"
LOG_OPERATION_INSTALL="Install"
LOG_OPERATION_UPGRADE="Upgrade"
LOG_OPERATION_UNINSTALL="Uninstall"
LOG_LEVEL_SUGGESTION="SUGGESTION"
LOG_LEVEL_MINOR="MINOR"
LOG_LEVEL_MAJOR="MAJOR"
LOG_LEVEL_UNKNOWN="UNKNOWN"
LOG_RESULT_SUCCESS="success"
LOG_RESULT_FAILED="failed"
# the two are both for secure-install-path
first_time_install_drv_flag="NA"
old_drv_install_path="NA"
install_for_all="no"
native_pkcs_conf=""

# pkg arch
PKG_ARCH="UNKNOWN"

SHELL_DIR=$(cd "$(dirname "$0")" || exit; pwd)
COMMON_SHELL="$SHELL_DIR/common.sh"
if [ -e ${COMMON_SHELL} ]; then
    source "${COMMON_SHELL}"
fi

export input_install_for_all=n
export native_pkcs_conf

install_info_key_array=("Driver_Install_Type" "UserName" "UserGroup" "Driver_Install_Path_Param" "Firmware_Install_Path_Param" "Firmware_Install_Type"
                        "Driver_Install_For_All" "Driver_Install_Mode")

function setFileChmod() {
    local option="$1"
    local mod="$2"
    local file_path="$3"

    if [ ${input_install_for_all} == y ]; then
        local mod=${mod:0:-1}${mod: -2:1}
    fi

    chmod ${option} "${mod}" "${file_path}" >& /dev/null
    if [ $? -ne 0 ]; then
        echo "[ERROR]chmod ${mod} $file_path failed!"
        exit 1
    fi
}

function createFile() {
    local _file=$1
    if [ -e "${_file}" ]; then
        rm -f "${_file}"
    fi
    touch "${_file}"
    chown -h "$2" "${_file}"
    setFileChmod -f "$3" "${_file}"
    if [ $? -ne 0 ]; then
        return 1
    fi
    return 0
}

function getInstallParam() {
    local _key="$1"
    local _file="$2"
    local _param

    if [ ! -f "${_file}" ];then
        exit 1
    fi

    # deal with abnormal install-cfg file.
    # when install-cfg file is abnormal, command 'grep' can not be used but 'sed' does.
    local normal_args
    grep -r "${_key}" "${_file}" | grep -q '='
    if [ $? -ne 0 ]; then
        normal_args=$(sed -n '/=/p' ${_file})
        echo "${normal_args}" > ${_file}
    fi

    for key_param in "${install_info_key_array[@]}"; do
        if [ ${key_param} == ${_key} ]; then
            _param=`grep -r "${_key}=" "${_file}" | cut -d"=" -f2-`
            break;
        fi
    done
    echo "${_param}"
}

function crossVersion() {
    if [ -f /etc/HiAI_install.info ]; then
        . /etc/HiAI_install.info
        if [ -z $Install_Path_Param ]; then
            drvEcho "[ERROR]ERR_NO:0x0094;ERR_DES:Operation failed, An all-in-one RUN package is found, which needs to be uninstalled before proceeding."
        else
            drvEcho "[ERROR]ERR_NO:0x0094;ERR_DES:Operation failed, An all-in-one RUN package is found in $Install_Path_Param, which needs to be uninstalled before proceeding."
        fi
        exit
    fi
}

function log() {
   cur_date=`date +"%Y-%m-%d %T"`
   user_id=`id | awk '{printf $1}'`
    echo "[Driver] [$cur_date] [$user_id] "$1 >> $logFile
}

function drvEcho() {
    cur_date=`date +"%Y-%m-%d %T"`
    echo "[Driver] [$cur_date] $1"
}

function drvColorEcho() {
    cur_date=`date +"%Y-%m-%d %T"`
    echo -e  "[Driver] [$cur_date] $1"
}

function kernel_version_is_upgrade() {
    dev_num=$(lspci -tv | grep d801 | wc -l)
    if [ $dev_num -eq 1 ] || [ $dev_num -eq 2 ];then
        main=$(uname -r | awk -F . '{print $1}')
        minor=$(uname -r | awk -F . '{print $2}')
        if [ $main -lt 4 ];then
            echo "[WARNING]Please upgrade kernel version."
        else
            if [ $minor -le 5 ] && [ $main -eq 4 ];then
                echo "[WARNING]Please upgrade kernel version."
            fi
        fi
    fi
}

function get_kmsagent_config() {
    if [ $kmsagent_is_enable = y ];then
        return 0
    fi

    if [ -f $ASCEND_DRIVER_CFG_FILE ];then
        local kms_config_txt=`grep -r "${KMSAGENT_CONFIG_ITEM}=" "${ASCEND_DRIVER_CFG_FILE}" | cut -d"=" -f2-`
        if [ "${kms_config_txt}X" = "enableX" ];then
            kmsagent_is_enable=y
        fi
    fi
}

function exitLog() {
    cur_date=`date +"%Y-%m-%d %T"`
    drvEcho "[INFO]End time: ${cur_date}"
    drvEcho "[INFO]End time: ${cur_date}" >> $logFile
    exit $1
}

function errorUsage() {
    if [ $# -eq 1 ]; then
        drvEcho "[ERROR]ERR_NO:0x0004;ERR_DES: Unrecognized parameters: ${1}. Try './xxx.run --help' for more information."
        exitLog 1
    elif [ $# -eq 2 ]; then
        log "$2"
        drvEcho "$2"
        exitLog "$1"
    else
        drvEcho "[ERROR]ERR_NO:0x0004;ERR_DES: Unrecognized parameters. Try './xxx.run --help' for more information."
        exit 1
    fi
}

# LogFile polling and backup
function rotateLog() {
    echo "${logFile} {
        su root root
        daily
        size=5M
        rotate 3
        missingok
        create 440 root root
    }" > /etc/logrotate.d/ascend-install
}

function startLog() {
    cur_date=`date +"%Y-%m-%d %T"`
    drvEcho "[INFO]Start time: $cur_date"
    drvEcho "[INFO]Start time: $cur_date" >> $logFile
}

function installationCompletionMessage() {
    local run_install_type="$1"
    local new_path

    new_path="${Install_Path_Param%/}"
    if [ -e "$hotreset_status_file" ]; then
        hotreset_status=`cat "$hotreset_status_file"`
        rm -f "$hotreset_status_file"
    else
        hotreset_status="unknown"
    fi

    # Convert it to lowercase.
    run_install_type="${run_install_type,,}"
    # delete 'e' from install type.
    run_install_type="${run_install_type/e/}ed"

    local start_time=$(date +%s)
    local cnt=0
    local tool_path="$new_path/driver/tools/upgrade-tool"
    if [[ -e ${tool_path} && "$hotreset_status"x = "success"x ]] || \
        [[ "$first_time_install_drv_flag"x = "Y"x && "$PCIE_INSMOD_STATUS_BEFORE_INSTALL"x = "n"x && "$force"x = "n"x ]]; then
        hotreset_status="unknown"
        while (($(date +%s) - "start_time" < 60)) || [[ ${cnt} -lt 3 ]]
        do
            cnt=$(($cnt+1))
            timeout 20s ${tool_path} --device_index -1 --boot_status | grep -E "fail|Unknown argument" >> /dev/null 2>&1
            if [ $? -ne 0 ]; then
                timeout 20s ${tool_path} --device_index -1 --boot_status | grep "boot status" | grep -v "boot status:3" >> /dev/null 2>&1
                if [ $? -ne 0 ]; then
                    hotreset_status="success"
                    break
                fi
            fi
            sleep 10
        done
        if [ -e $davinci_num_file ]; then
            source $davinci_num_file
        fi
        if [ "$hotreset_status"x = "unknown"x ] || [ -e $davinci_num_file -a $scan_davinci_num -ne $all_davinci_num ]; then
            drvEcho "[WARNING]There are some chips not ready, please check after reboot"
            log "[WARNING]There are some chips not ready, please check after reboot"
            rm -f  $davinci_num_file
        fi
    fi

    if [ "$hotreset_status"x = "success"x ] || [ "$installType"x = "docker"x ] || [ "$installType"x = "devel"x ] ; then
        drvColorEcho  "[INFO]\033[32mDriver package ${run_install_type} successfully! The new version takes effect immediately. \033[0m"
        if [ "$installType"x = "docker"x ];then
            # lib-put-path is different from the others.
            if [ "${lib_put_path}"x = "specific"x ]; then
                echo -e "Please make sure that\n    - LD_LIBRARY_PATH includes $new_path/driver/lib64\n"\
                        "   - Please refer to the instruction manual for specific details"
            else
                echo -e "Please make sure that\n    - LD_LIBRARY_PATH includes $new_path/driver/lib64/common:$new_path/driver/lib64/driver\n"\
                        "   - Please refer to the instruction manual for specific details"
            fi
        fi
    else
        if [ "$hotreset_status"x = "ko_abort"x ]; then
            drvColorEcho "[INFO]\033[32mDriver package ${run_install_type} finished! \033[0m"
            drvColorEcho "[WARNING]Kernel modules can not be removed, reboot needed for installation/upgrade to take effect!"
        else
            drvColorEcho "[INFO]\033[32mDriver package ${run_install_type} successfully! \033[0m\033[31mReboot needed for installation/upgrade to take effect! \033[0m"
        fi
    fi
}

function uninstallationCompletionMessage() {
    if [ -e "$hotreset_status_file" ]; then
        hotreset_status=`cat "$hotreset_status_file"`
        hotreset_status=${hotreset_status%%.*}
        rm -f "$hotreset_status_file"
    else
        hotreset_status="unknown"
    fi
    if [ "$hotreset_status"x = "scan_success"x ] || [ "$Driver_Install_Type"x = "docker"x ] || [ "$Driver_Install_Type"x = "devel"x ]; then
        drvColorEcho  "[INFO]\033[32mDriver package uninstalled successfully! Uninstallation takes effect immediately. \033[0m"
    else
        if [ "$hotreset_status"x = "ko_abort"x ]; then
            drvColorEcho "[INFO]\033[32mDriver package uninstalled finished! \033[0m"
            drvColorEcho "[WARNING]Kernel modules can not be removed, reboot needed for uninstallation to take effect!"
        else
            drvColorEcho "[INFO]\033[32mDriver package uninstalled successfully! \033[0m\033[31mReboot needed for uninstallation to take effect! \033[0m"
        fi
    fi
}
# check whether hotreset fails
function isHotresetFailed(){
    if [ "${hotreset_status}" = "scan_success"* ] || [ "${hotreset_status}" = "success" ]; then
        echo "false"
    else
        echo "true"
    fi
}
# support absolute path and relative path
function getAbsolutePath(){

    local current_path="${PWD}" parent_dir=""
    flag1=$(echo "${Install_Path_Param:0:3}" |grep "\./")''$(echo "$Install_Path_Param" |grep "~/")''$(echo "$Install_Path_Param" |grep "/\.")
    flag2=$(echo "${Install_Path_Param:0:1}" |grep "/")

    if [ -z $flag1  ] && [  -z $flag2  ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0003;ERR_DES:install-path input error, install failed"
    fi
    if [ ! -z $flag1 ];then
        cd "$runPackagePath" >& /dev/null
        log "[INFO]enter runPackagePath:$runPackagePath"

        eval "cd ${Install_Path_Param}" >& /dev/null
        if [ $? -ne 0 ]; then
            # get parent directory
            parent_dir=`dirname "${Install_Path_Param}"`
            log "[INFO]parent_dir value is [${parent_dir}]"

            eval "cd ${parent_dir}" >& /dev/null
            if [ $? -eq 0 ]; then
                cd - >& /dev/null
                eval "mkdir ${Install_Path_Param}" >& /dev/null
                if [ $? -ne 0 ]; then
                    log "[ERROR][${parent_dir}] is invalid."
                    drvEcho "[ERROR]Relative path $Install_Path_Param doesn't exist, please input a valid path"
                    exitLog 1
                else
                    log "[INFO]create dir [${Install_Path_Param}] success."
                    setFileChmod -f 755 ${Install_Path_Param}
                    eval "cd ${Install_Path_Param}" >& /dev/null
                fi
            else
                log "[ERROR][${parent_dir}] is invalid."
                drvEcho "[ERROR]Relative path $Install_Path_Param doesn't exist, please input a valid path"
                exitLog 1
            fi
        fi

        log "[INFO]enter Install_Path_Param=$Install_Path_Param, pwd: $PWD "
        Install_Path_Param="${PWD}"
        cd "${current_path}" >& /dev/null

        log "[INFO]current path: $PWD"
    fi
    log "[INFO]Install_Path_Param=$Install_Path_Param"
}

# check if the installation path is valid
function isValidPath() {
    [ $uninstall = y ] && return 0
    makeDefaultPath=n
    if [ "$input_install_path" = "" ]; then
        if [ -f $installInfo ]; then
            Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
            if [ ! -z "$Driver_Install_Path_Param" ]; then
                Install_Path_Param="$Driver_Install_Path_Param"
            fi
        fi
    else
        Install_Path_Param="${input_install_path}"
    fi

    getAbsolutePath
    if [ ! -d "$Install_Path_Param" ]; then
        if [ "$Install_Path_Param" = "/usr/local/Ascend" ]; then
            mkdir -p "$Install_Path_Param"
            setFileChmod -f 755 "$Install_Path_Param"
            makeDefaultPath=y
        else
            parentPath=`dirname "$Install_Path_Param"`
            if [ ! -d "$parentPath" ];then
                errorUsage 1 "[ERROR]ERR_NO:0x0003;ERR_DES:install path $parentPath not exists,runpackage only support create one level of directory,need create $parentPath."
            fi
            su - "$username" -s /bin/bash -c "test -x $parentPath"
            if [ $? -ne 0 ]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0003;ERR_DES:The $username do not have the permission to access $parentPath, please reset the directory to a right permission."
            fi
            mkdir -p "$Install_Path_Param"
            setFileChmod -f 755 "$Install_Path_Param"
            makeDefaultPath=y
        fi
    fi

    su - "$username" -s /bin/bash -c "test -x $Install_Path_Param"
    if [ $? -ne 0 ]; then
        if [ $makeDefaultPath = y ]; then
            rm -rf "$Install_Path_Param"
        fi
        errorUsage 1 "[ERROR]ERR_NO:0x0003;ERR_DES:The $username do not have the permission to access $Install_Path_Param, please reset the directory to a right permission."
    fi
    # format the installation path after checking its validity
    which realpath >/dev/null 2>&1 && Install_Path_Param=`realpath $Install_Path_Param 2>/dev/null`
}

# check env tool before installation
function checkEnvTool() {
    checkToolFile="${SHELL_DIR}/check_tools.conf"
    [ -e "${checkToolFile}" ] || return

    local strLeakTool=""
    local retCheckEnvTool="y"

    while read toolFileLine || [[ -n ${toolFileLine} ]]
    do
        # Some object only need to install one of toolFileLine
        toolA=`echo ${toolFileLine} | cut -d \, -f 1`
        toolB=`echo ${toolFileLine} | cut -d \, -f 2`
        which ${toolA} > /dev/null 2>&1 || which ${toolB} > /dev/null 2>&1
        if [ $? -ne 0 ]; then
            strLeakTool="${strLeakTool}${toolFileLine},"
            retCheckEnvTool="n"
            continue;
        fi
    done < ${checkToolFile}

    if [ "${retCheckEnvTool}"x = "n"x ]; then
        errorUsage 1 "[ERROR]The list of missing tools: ${strLeakTool}"
    fi

    return 0
}

function checkEnvFile() {
    # check /etc/pam.d/su Indicates whether to forcibly enter the password when su user
    if [ -e /etc/pam.d/su ]; then
        grep "auth" /etc/pam.d/su | grep "sufficient" |grep "pam_rootok.so" | grep -v "#" >/dev/null 2>&1
        if [ $? -ne 0 ];then
            drvEcho "[WARNING]The Root use cmd(su user) must enter the user passwd forcibly(set by /etc/pam.d/su)"
            log "[WARNING]The Root user cmd(su user) must enter the user passwd forcibly(set by /etc/pam.d/su)"
        fi
    fi
    return 0
}

function checkItems() {
    # set status of PCIe driver for first installation
    # drv_pcie_host: Physical machine
    # drv_vpcie: Compute-slicing virtual-machine
    PCIE_INSMOD_STATUS_BEFORE_INSTALL="n"
    lsmod | grep -E "drv_pcie_host|drv_vpcie" >& /dev/null && PCIE_INSMOD_STATUS_BEFORE_INSTALL="y"
    log "[INFO]PCIE_INSMOD_STATUS_BEFORE_INSTALL=${PCIE_INSMOD_STATUS_BEFORE_INSTALL}"

    checkEnvTool
    checkEnvFile
}

# check if there are multiple run processes in execution
function checkProcess(){
    name=`ps -ef | awk '$2=='$$'{print $10}'|rev|cut -d "/" -f1|rev`
    checkname=`echo "$name" | awk -F "-" '{print $1"-"$2}'`
    shellname=`echo $0 |rev |cut -d "/" -f1 |rev`
    process=`ps -ef | grep -v "grep" | grep -w "$shellname" |grep -w "${checkname}-.*.run" 2>/dev/null`
    pid=`echo "$process" | awk -F ' ' '{print $2}'`
    ret=`echo "$process" | awk -F ' ' '{print $3}' | grep -v "$pid" | wc -l`
    if [ $ret -gt 1 ]; then
        log "[INFO]$name;$shellname;$ret;$process"
        errorUsage 1 "[ERROR]ERR_NO:0x0094;ERR_DES:There is already a process being executed,please do not execute multiple tasks at the same time"
    fi
}

# check the disk space of the installation directory before installation or upgrade，driver need 300M，firmware need 32M.
function checkFreeSpace(){
    [ $uninstall = y ] && return 0
    freeSpace=`df -BM "$Install_Path_Param" |awk '/[0-9]%/{print $(NF-2)}'`
    freeSpace=${freeSpace:: -1}
    log "[INFO]freeSpace:${freeSpace} freeSpace_test ${freeSpace_test} occupy_space:$occupy_space"
    if [ ${freeSpace} -le $occupy_space ];then
        errorUsage 1 "[ERROR]free space only ${freeSpace}, cannot install driver package (greater than ${occupy_space}M), please make sure enough space under the installation path"
    fi
}

# check if the user exists
function checkUser(){
    ret=`cat /etc/passwd | cut -f1 -d':' | grep -w "$1" -c`
    if [ $ret -le 0 ]; then
        return 1
    else
        return 0
    fi
}

function isExistsGroup(){
    local ret=`cat /etc/group | cut -f1 -d':' | grep -w "$1" -c`
    if [ $ret -le 0 ]; then
        return 1
    else
        return 0
    fi
}

# check the association between users and user groups
function checkGroup(){
    result=$(groups "$2" | grep ":")
    if [ "${result}X" != "X" ]; then
        group_user_related=`groups "$2"|awk -F":" '{print $2}'|grep -w "$1"`
    else
        group_user_related=`groups "$2"|grep -w "$1"`
    fi
    if [ "${group_user_related}x" != "x" ];then
        return 0
    else
        return 1
    fi
}

# check installation conditions
function checkUserAndGroup() {
    [ $uninstall = y ] && return 0
    checkUser "${username}"
    if [ $? -ne 0 ];then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:${username} not exists! Please add ${username}"
    fi
    isExistsGroup "${usergroup}"
    if [ $? -ne 0 ];then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:${usergroup} group not exists! Please add ${usergroup} group"
    fi

    checkGroup "${usergroup}" "${username}"
    if [ $? -ne 0 ];then
        errorUsage 1 "[ERROR]ERR_NO:0x0096;ERR_DES:${usergroup} not right! Please check the relatianship of ${username} and ${usergroup}"
    fi
    drvEcho "[INFO]set username and usergroup, ${username}:${usergroup}"

}

function getUserInfo() {
    if [ -f ${installInfo} ]; then
        UserName=$(getInstallParam "UserName" "${installInfo}")
        UserGroup=$(getInstallParam "UserGroup" "${installInfo}")
        Driver_Install_For_All=$(getInstallParam "Driver_Install_For_All" "${installInfo}")
        if [ ${input_install_username} = y ] || [ ${input_install_usergroup} = y ]; then
            if [ "x${UserName}" = "x" ]; then
                sub_file=`echo $Install_Path_Param |awk -F"/" '{print $NF}'`
                username_cur=`ls -l "${Install_Path_Param}/../" |grep -w "${sub_file}" |awk '{print $3}'`
                if [ "x${username}" != "x${username_cur}" ]; then
                    echo "username: ${username} not equel to username_cur: ${username_cur}"
                    errorUsage 1 "[ERROR]ERR_NO:0x0095;ERR_DES:The user and group are not same with last installation,do not support overwriting installation"
                fi
            else
                if [ "x${username}" != "x${UserName}" ]; then
                    echo "username: ${username} not equel to UserName: ${UserName}"
                    errorUsage 1 "[ERROR]ERR_NO:0x0095;ERR_DES:The user and group are not same with last installation,do not support overwriting installation"
                else
                    username="${UserName}"
                fi
            fi

            if [ "x${UserGroup}" = "x" ]; then
                sub_file=`echo $Install_Path_Param |awk -F"/" '{print $NF}'`
                usergroup_cur=`ls -l "${Install_Path_Param}/../" |grep -w "${sub_file}" |awk '{print $4}'`
                if [ "x${usergroup}" != "x${usergroup_cur}" ]; then
                    echo "username: ${usergroup} not equel to usergroup_cur: ${usergroup_cur}"
                    errorUsage 1 "[ERROR]ERR_NO:0x0095;ERR_DES:The user and group are not same with last installation,do not support overwriting installation"
                fi
            else
                if [ "x${usergroup}" != "x${UserGroup}" ]; then
                    echo "username: ${usergroup} not equel to UserGroup: ${UserGroup}"
                    errorUsage 1 "[ERROR]ERR_NO:0x0095;ERR_DES:The user and group are not same with last installation,do not support overwriting installation"
                else
                    usergroup="${UserGroup}"
                fi
            fi
        fi
        if [ ${input_install_username} = n ] || [ ${input_install_usergroup} = n ]; then
            if [ "x${UserName}" != "x" ] && [ $uninstall = n ]; then
                if [ "${UserName}" = "root" ] && [ $upgrade != y ]; then
                    errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:username not permission for root, check /etc/ascend_install.info"
                else
                    username="${UserName}"
                    if [ "x$Driver_Install_For_All" = "xyes" ] && [ $upgrade = y ]; then
                        install_for_all="$Driver_Install_For_All"
                        input_install_for_all=y
                    fi
                fi
            fi
            if [ "x${UserGroup}" != "x" ]; then
                if [ "${UserGroup}" = "root" ] && [ $uninstall = n ] && [ $upgrade != y ]; then
                    errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:usergroup not permission for root, check /etc/ascend_install.info"
                else
                    usergroup="${UserGroup}"
                    if [ "x$Driver_Install_For_All" = "xyes" ] && [ $upgrade = y ]; then
                        install_for_all="$Driver_Install_For_All"
                        input_install_for_all=y
                    fi
                fi
            fi
        fi
    fi
}

# check if root permission
function isRoot() {
    if [ $(id -u) -ne 0 ]; then
        drvEcho "[ERROR]ERR_NO:0x0093;ERR_DES:do not have root permission, operation failed, please use root permission!"
        exit 1
    fi
}

# get the version number under the installation path (version2)
function getVersionInstalled() {
    version2="none"
    if [ -f "$1"/driver/version.info ]; then
        version2=`cat "$1"/driver/version.info | awk -F '=' '$1=="Version" {print $2}'`
    fi
    echo $version2
}

# get the version number in the run package (version1)
function getVersionInRunFile() {
    version1="none"
    if [ -f ./version.info ]; then
        version1=`cat version.info | awk -F '=' '$1=="Version" {print $2}'`
    fi
    echo $version1
}

function logBaseVersion() {
    if [ -f ${installInfo} ];then
        Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
        if [ ! -z "$Driver_Install_Path_Param" ]; then
            installed_version=$(getVersionInstalled "$Driver_Install_Path_Param")
            if [ ! "${installed_version}"x = ""x ]; then
                drvEcho "[INFO]base version is ${installed_version}."
                log "[INFO]base version is ${installed_version}."
                return 0
            fi
        fi
    fi
    log "[INFO]base version was destroyed or not exist."
}

# determine whether the command returns a failure, and report an error if it fails.
# $1:Operation type, $2:ret code,   $3:(Optional)print messages
function error() {
    local operation="$1"
    local retcode="$2"
    local msg="$3"
    if [ ${retcode} -ne 0 ]; then
        logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_FAILED}" "${installType}" "${all_parma}"
    fi

    if [ $# -eq 3 ]; then
        if [ ${retcode} -ne 0 ]; then
            drvEcho "[ERROR]${msg}"
            log "[ERROR]${msg}"
            exitLog 1
        fi
    elif [ $# -eq 2 ]; then
        if [ ${retcode} -ne 0 ]; then
            exitLog 1
        fi
    fi
}

# update /etc/ascend_install.info
function updateInstallInfo() {
    local installMode_before=""

    if [ -d "$installInfo" ]; then
        rm -rf "$installInfo"
    fi

    if [ -f "$installInfo" ]; then
        UserName=$(getInstallParam "UserName" "${installInfo}")
        UserGroup=$(getInstallParam "UserGroup" "${installInfo}")
        Driver_Install_Type=$(getInstallParam "Driver_Install_Type" "${installInfo}")
        Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
        Driver_Install_For_All=$(getInstallParam "Driver_Install_For_All" "${installInfo}")
        if [ -z "$UserName" ]; then
            updateInstallParam "UserName" "$username" "$installInfo"
        fi
        if [ -z "$UserGroup" ]; then
            updateInstallParam "UserGroup" "$usergroup" "$installInfo"
        fi
        updateInstallParam "Driver_Install_Type" "$installType" "$installInfo"
        updateInstallParam "Driver_Install_Path_Param" "$Install_Path_Param" "$installInfo"
        updateInstallParam "Driver_Install_For_All" "$install_for_all" "$installInfo"
    else
        createFile "$installInfo" "root":"root" 644
        updateInstallParam "UserName" "$username" "$installInfo"
        updateInstallParam "UserGroup" "$usergroup" "$installInfo"
        updateInstallParam "Driver_Install_Type" "$installType" "$installInfo"
        updateInstallParam "Driver_Install_Path_Param" "$Install_Path_Param" "$installInfo"
        updateInstallParam "Driver_Install_For_All" "$install_for_all" "$installInfo"
    fi
    if [ "${upgrade}" = "y" ]; then
        installMode_before="$(getInstallParam "Driver_Install_Mode" "${installInfo}")"
        if [ -z "${installMode_before}" ]; then
            updateInstallParam "Driver_Install_Mode" "${installMode}" "${installInfo}"
        else
            updateInstallParam "Driver_Install_Mode" "${installMode_before}" "${installInfo}"
        fi
    else
        updateInstallParam "Driver_Install_Mode" "${installMode}" "${installInfo}"
    fi
    setFileChmod -f 644 $installInfo
}

function backupKmsData(){
    # Backup kmsagent data to backup_data.
    if [ -f "./driver/script/kmsagent_backup_conf.sh" ]; then
        ./driver/script/kmsagent_backup_conf.sh $KMSAGENT_WORK_DIR $username $usergroup >>$logFile 2>&1
    fi
}

function initKmsagentService(){
    local new_path="${Install_Path_Param%/}"
    local kms_library_path="${new_path}/driver/lib64/inner:${new_path}/driver/lib64:${new_path}/driver/lib64/driver:${new_path}/driver/lib64/common"
    local kms_restore_path="${new_path}/driver/script/kmsagent_restore_conf.sh"

    if [ $docker != y ] && [ $devel != y ]; then

        if [ ! -f "./driver/script/kmsagent.service" ];then
            # Not need init kmsagent service.
            return 0
        fi
        if [ $1 == "false" ]; then
            ./driver/script/kmsagent_install.sh ${new_path}/driver/tools/kmsagent ${new_path}/driver/script/kmsagent.conf $KMSAGENT_WORK_DIR $username $usergroup $kms_library_path $kms_restore_path "false" >>$logFile 2>&1
            return $?
        fi
        # 1. Create driver config file
        if [ -d $KMSAGENT_SERVICE_DIR ]; then
            KMSAGENT_SERVICES="${KMSAGENT_SERVICE_DIR}/${KMSAGENT_SERVICE_NAME}"
            source ./driver/script/kmsagent.service
            systemctl daemon-reload 1>/dev/null 2>&1
        elif [ -d $KMSAGENT_USER_SERVICE_DIR ]; then
            KMSAGENT_SERVICES="${KMSAGENT_USER_SERVICE_DIR}/${KMSAGENT_SERVICE_NAME}"
            source ./driver/script/kmsagent.service
            systemctl daemon-reload 1>/dev/null 2>&1
        else
            log "[WARNING]The current environment does not support kmsagent services and can't use the model protection function."
            drvEcho "[WARNING]The current environment does not support kmsagent services and can't use the model protection function."
        fi

        createFile "$ASCEND_DRIVER_CFG_FILE" "root":"root" 644
        sed -i "/${KMSAGENT_CONFIG_ITEM}=/d" "${ASCEND_DRIVER_CFG_FILE}"
        if [ $kmsagent_is_enable = y ];then
            echo "${KMSAGENT_CONFIG_ITEM}=enable" >> "${ASCEND_DRIVER_CFG_FILE}"
        else
            echo "${KMSAGENT_CONFIG_ITEM}=disable" >> "${ASCEND_DRIVER_CFG_FILE}"
        fi
        setFileChmod -f 644 $ASCEND_DRIVER_CFG_FILE

        # Init kmsagent log file.
        local user_home_path=`eval echo "~${username}"`
        chown -fh $username:$usergroup ${user_home_path}/kmsagent_*.log >& /dev/null
        log "[INFO]Switch to the file owner to config the kmsagent_log in the home dir: $?"

        chown -fh $username:$usergroup ${KMSAGENT_WORK_DIR}/kmsagent_*.log >& /dev/null
        log "[INFO]Switch to the file owner to config the kmsagent_log in the work dir: $?"

        # 2. Create kmsagent work dir and restore backup data.
        ./driver/script/kmsagent_install.sh ${new_path}/driver/tools/kmsagent ${new_path}/driver/script/kmsagent.conf $KMSAGENT_WORK_DIR $username $usergroup $kms_library_path $kms_restore_path "true" >>$logFile 2>&1
        # 3. Auto start kms service.
        if [ $kmsagent_is_enable = y ]; then
            ${new_path}/driver/script/${ASCEND_DRIVER_SETUP_SCRIPT} $KMSAGENT_CONFIG_ITEM start >> $runLogFile 2>&1 &
        fi
    fi
}

function parent_dirs_permision_check(){
    current_dir="$1" parent_dir="" short_install_dir=""
    local owner="" mod_num=""

    parent_dir=$(dirname "${current_dir}")
    short_install_dir=$(basename "${current_dir}")
    log "[INFO]parent_dir value is [${parent_dir}] and children_dir value is [${short_install_dir}]"

    if [ "${current_dir}"x = "/"x ]; then
        log "[INFO]parent_dirs_permision_check success"
        return 0
    else
        owner=$(stat -c %U "${parent_dir}"/"${short_install_dir}")
        if [ "${owner}" != "root" ]; then
            log "[WARNING][${short_install_dir}] permision isn't right, it should belong to root."
            return 1
        fi
        log "[INFO][${short_install_dir}] belongs to root."

        mod_num=$(stat -c %a "${parent_dir}"/"${short_install_dir}")
        mod_num=${mod_num: -3}
        if [ ${mod_num} -lt 755 ] && [ ${input_install_for_all} == n ]; then
            log "[WARNING][${short_install_dir}] permission is too small, it is recommended that the permission be 755 for the root user."
            return 2
        elif [ ${mod_num} -eq 755 ] && [ ${input_install_for_all} == n ]; then
            log "[INFO][${short_install_dir}] permission is ok."
        else
            if [ ${input_install_for_all} == n ]; then
                log "[WARNING][${short_install_dir}] permission is too high, it is recommended that the permission be 755 for the root user."
            fi
        fi
        if [ ${mod_num} -lt 750 ] && [ ${input_install_for_all} == y ]; then
             log "[WARNING][${parent_dir}/${short_install_dir}] permission is too small."
             return 2
        fi

        parent_dirs_permision_check "${parent_dir}"
    fi
}

function install_path_should_belong_to_root() {
    local ret=0

    # install drv first time
    if [ ${first_time_install_drv_flag} = "Y" ]; then
        # default dir doesn't exist or exists, but permission not correct
        if [ "${Install_Path_Param}" = "/usr/local/Ascend" ]; then
            mkdir -p "${Install_Path_Param}"
            setFileChmod -f 755 "${Install_Path_Param}"
            chown -fh root:root "${Install_Path_Param}" >& /dev/null
        fi

        parent_dirs_permision_check "${Install_Path_Param}" && ret=$? || ret=$?
        if [ ${ret} -eq 1 ]; then
            log "[ERROR][${short_install_dir}] permision not right, it should belong to root."
            drvColorEcho  "[ERROR]\033[31mThe given directory, including its parents, should belong to root, details in : $logFile \033[0m"
            return 1
        elif [ ${ret} -eq 2 ]; then
            log "[ERROR][${short_install_dir}] permission is too small."
            drvColorEcho  "[ERROR]\033[31mThe given directory, or its parents, permission is too small, details in : $logFile \033[0m"
            return 1
        fi
    # it has already installed before.
    else
        # if upgrade and doesn't give install-path
        if [ "${old_drv_install_path}" = "${Install_Path_Param}" ]; then
            # if upgrade, default path
            if [ "${Install_Path_Param}" = "/usr/local/Ascend" ] || [ "${Install_Path_Param}" = "/usr/local/HiAI" ]; then
                setFileChmod -f 755 "${Install_Path_Param}"
                chown -fh root:root "${Install_Path_Param}" >& /dev/null
            fi
            # dir permission check
            parent_dirs_permision_check "${Install_Path_Param}" && ret=$? || ret=$?
            # --quiet
            [ ${quiet} = y ] && [ ${ret} -ne 0 ] && return 0

            if [ ${ret} -ne 0 ]; then
                echo "You are going to put run-files on a unsecure install-path, do you want to continue? [y/n]"
                while true
                do
                    read yn
                    if [ "$yn" = n ]; then
                        echo "Stop installation!"
                        return 1
                    elif [ "$yn" = y ]; then
                        break;
                    else
                        echo "ERR_NO:0x0002;ERR_DES:input error, please input again!"
                    fi
                done
            fi
        # upgrade and give install-path
        else
            parent_dirs_permision_check "${Install_Path_Param}" && ret=$? || ret=$?
            if [ ${ret} -ne 0 ]; then
                log "[ERROR]the given dir, or its parents, permission is invalid."
                drvColorEcho " [ERROR]\033[31mThe given dir, or its parents, permission is invalid, details in : $logFile \033[0m"
                return 1
            fi
        fi
    fi

    return 0
}

# check whether any script size is zero or not.
function check_local_file_size() {
    local filelist="${Driver_Install_Path_Param}"/driver/script/filelist.csv
    local install_type=""

    [ -e "${filelist}" ] && [ $(stat -c %s "${filelist}") -ne 0 ] || { log "[INFO]filelist.csv doesn't exist or its size is zero." && return 1; }

    # check whether any file size is zero, if yes, it will return 1 directly.
    cd "${Driver_Install_Path_Param}" >& /dev/null
    # the full install-type and the run install-type contain the same scripts.
    [ "${Driver_Install_Type}" = "full" ] && install_type="run" || install_type="${Driver_Install_Type}"
    if stat -c %s $(grep "\.sh" "${filelist}" | grep -w "${install_type}" | awk -F [,] '{print $4}') | grep -wq "0"; then
        log "[INFO]there is a local script with zero size."
        cd - >& /dev/null
        return 1
    fi
    cd - >& /dev/null

    log "[INFO]check_local_file_size success."
    return 0
}

function installRun() {
    if [ $full_install = y ] || [ $upgrade = y ] || [ $run = y ]; then
        [ "$Driver_Install_Type" = "docker" ] || kernel_version_is_upgrade
    fi
    updateInstallInfo
    ./driver/script/run_driver_install.sh "$Install_Path_Param" $installType $force $package_type
    driver_install_status=$?
    if [ $driver_install_status -eq 0 ];then
        # Init kmsagent service.
        initKmsagentService "true"
        installationCompletionMessage $1
    else
        initKmsagentService "false"
        drvColorEcho "[INFO]Failed to ${1,,} driver package, please retry after uninstall and reboot!"
    fi
}

function exitInstallInfo() {
    drvColorEcho "[ERROR]\033[31mThe davinci nodes are occupied by some processes, please stop processes and install or uninstall again, details in : $logFile \033[0m"
    log "[ERROR]The davinci nodes are occupied by some processes, please stop processes and install or uninstall again."
    drvColorEcho "[INFO]If you want to install or uninstall the driver forcibly, add the force parameter. For details, see [--help]."
    logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_FAILED}" "${installType}" "${all_parma}"
    exitLog 1
}

function uninstallRun() {
    if [ -f "$Driver_Install_Path_Param"/driver/script/${ASCEND_DRIVER_SETUP_SCRIPT} ]; then
        "$Driver_Install_Path_Param"/driver/script/${ASCEND_DRIVER_SETUP_SCRIPT} $KMSAGENT_CONFIG_ITEM stop >> $runLogFile
    fi

    operation="${LOG_OPERATION_UNINSTALL}"
    Driver_Install_Type=$(getInstallParam "Driver_Install_Type" "${installInfo}")
    Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
    [ -f /etc/pss.cfg ] && native_pkcs_conf=$(cat /etc/pss.cfg)
    # not check CRL when in docker or devel mode
    if [ "$uninstall"x == "n"x ] && [ ! "$Driver_Install_Type"x == "docker"x ] && [ ! "$Driver_Install_Type"x == "devel"x ] && [ "$feature_crl_check"x == "y"x ]; then
        [ ${input_path_flag} = "y" ] && export NEW_Driver_Install_Path="${Install_Path_Param}"
        . ./driver/script/device_crl_check.sh
        #check CRL of images
        device_images_crl_check && ret=$? || ret=$?
        if [ ${ret} -ne 0 ];then
            if [ ${ret} -eq 2 ]; then
                drvColorEcho "[ERROR]\033[31mThe software signature verification failed because the signature mode used by the software is inconsistent with the current configuration. Currently configured is [${native_pkcs_conf}], details in : $logFile \033[0m"
            else
                drvColorEcho "[ERROR]\033[31mDevice_images_crl_check failed, details in : $logFile \033[0m"
            fi
            log "[ERROR]new device crl check failed, stop upgrade"
            rm -f $driverCrlStatusFile
            exitLog 1
        fi

        rm -f /etc/pss.cfg >& /dev/null
        log "[INFO]remove /etc/pss.cfg success"
    fi
    # set hot reset flag
    local phyflag=""
    if [ "$force" = n ]; then
        if [ -f "$Driver_Install_Path_Param"/driver/tools/upgrade-tool ]; then
            systemd-detect-virt -v | grep "kvm" >> /dev/null 2>&1
            phyflag=$?
            timeout 20s "$Driver_Install_Path_Param"/driver/tools/upgrade-tool --device_index -1 --boot_status 2>> /dev/null | grep -v fail | grep "boot status" | grep -v "boot status:0" >> /dev/null 2>&1
            if [ $? -eq 0 ]; then
                if [ "$phyflag"x = "0"x ]; then
                    log "[INFO]VM scene, continue to uninstall the old software package."
                else
                    if [ checkUserDocker ] && [ setHotResetFlag ]; then
                        log "[INFO]Check docker process and set hot reset flag is over, continue to uninstall the old software package."
                    else
                        exitInstallInfo
                    fi
                fi
            else
                log "[WARNING]The chip can not set the hot reset flag."
            fi
        fi
    fi
    # remove version.info
    if [ -f "$Driver_Install_Path_Param"/driver/version.info ];then
       chattr -i "$Driver_Install_Path_Param"/driver/version.info > /dev/null 2>&1
       rm -rf "$Driver_Install_Path_Param"/driver/version.info
       log "[INFO]rm -rf version.info success"
    fi
    if [ ! "$Driver_Install_Type" = "devel" ] && [ ! "$Driver_Install_Type" = "docker" ]; then
        # This is for compatibility with earlier versions.
        if [ -f "$Driver_Install_Path_Param"/host_sys_stop.sh ]; then
            "$Driver_Install_Path_Param"/host_sys_stop.sh
        fi
        if [ -f "$Driver_Install_Path_Param"/host_servers_remove.sh ]; then
            bash "$Driver_Install_Path_Param"/host_servers_remove.sh
        else
            ./host_servers_remove.sh
        fi
    fi

    # if new-install-path is the same as the old one, the original directory will not be deleted.
    [ "${uninstall}" = "n" ] && export NEW_Driver_Install_Path="${Install_Path_Param}"
    uninstall_result=n
    if check_local_file_size; then
        if [ -f "$Driver_Install_Path_Param"/driver/script/run_driver_uninstall.sh ]; then
            "$Driver_Install_Path_Param"/driver/script/run_driver_uninstall.sh --uninstall "$Driver_Install_Path_Param" $force && uninstall_result=y
        fi
    fi
    if [ $uninstall_result = n ]; then
        ./driver/script/run_driver_uninstall.sh --uninstall "$Driver_Install_Path_Param" $force
        if [ $? -eq 0 ]; then
            uninstall_result=y
        else
            log "[WARNING]uninstall driver failed"
        fi
    fi

    if [ $uninstall = y ] && [ $uninstall_result = n ]; then
        drvEcho "[ERROR]ERR_NO:0x0090;ERR_DES:uninstall driver failed, details in : ${ASCEND_SECLOG}/ascend_install.log"
        logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_FAILED}" "${installType}" "${all_parma}"
        log "[ERROR]ERR_NO:0x0090;ERR_DES:uninstall driver failed"
        exitLog 1
    fi

    if [ $uninstall_result = y ]; then
        log "[INFO]uninstall driver success"
        if [ $uninstall = y ]; then
            # when the installation path is empty, delete it, make sure the directory exists before using ls
            if [ -d "${Driver_Install_Path_Param}" ] && [ `ls "${Driver_Install_Path_Param}" | wc -l` -eq 0 ];then
               rm -rf "${Driver_Install_Path_Param}"
            fi
            sed -i '/Driver_Install_Path_Param=/d' $installInfo
            sed -i '/Driver_Install_Type=/d' $installInfo
            sed -i '/Driver_Install_Mode=/d' ${installInfo}
            sed -i '/Driver_Install_For_All=/d' ${installInfo}
            if [ ` grep -c -i "Install_Path_Param" $installInfo ` -eq 0 ]; then
                rm -f $installInfo
            fi

            logOperation "${operation}" "${start_time}" "${runfilename}" "${LOG_RESULT_SUCCESS}" "${installType}" "${all_parma}"
            uninstallationCompletionMessage
            exitLog 0
        fi
    fi
    unset "Driver_Install_Path_Param"

}

function changeLogMode() {
    if [ ! -f $logFile ]; then
        touch $logFile
    fi
    setFileChmod -f 640 $logFile
}

function logOperation() {
    local operation="$1"
    local start_time="$2"
    local runfilename="$3"
    local result="$4"
    local install_type="$5"
    local cmdlist="$6"
    local level

    if [ "${operation}" = "${LOG_OPERATION_INSTALL}" ]; then
        level="${LOG_LEVEL_SUGGESTION}"
    elif [ "${operation}" = "${LOG_OPERATION_UPGRADE}" ]; then
        level="${LOG_LEVEL_MINOR}"
    elif [ "${operation}" = "${LOG_OPERATION_UNINSTALL}" ]; then
        level="${LOG_LEVEL_MAJOR}"
    else
        level="${LOG_LEVEL_UNKNOWN}"
    fi

    if [ ! -d "${OPERATION_LOGDIR}" ]; then
        mkdir -p ${OPERATION_LOGDIR}
        setFileChmod -f 750 ${OPERATION_LOGDIR}
    fi

    if [ ! -f "${OPERATION_LOGPATH}" ]; then
        touch ${OPERATION_LOGPATH}
        setFileChmod -f 640 ${OPERATION_LOGPATH}
    fi

    if [ $upgrade = y ] || [ $uninstall = y ]; then
        echo "${operation} ${level} root ${start_time} 127.0.0.1 ${runfilename} ${result}"\
            "cmdlist=${cmdlist}." >> ${OPERATION_LOGPATH}
    else
        echo "${operation} ${level} root ${start_time} 127.0.0.1 ${runfilename} ${result}"\
            "install_type=${install_type}; cmdlist=${cmdlist}." >> ${OPERATION_LOGPATH}
    fi
}

function uniqueMode() {
    if [ ! -z $installType ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:only support one type: full/run/docker/devel, operation failed!"
    fi
}

function unsupportParam() {
    if [ $uninstall = y ];then
        if [ $i -eq 1 ];then
            return 0
        fi
        if [ $force = y ] && [ $i -eq 2 ];then
            log "[INFO]Uninstall and take effect after reboot"
            return 0
        else
            errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:uninstall can't use with other parameters except force."
        fi
    fi
    # version/check can only be used independently.
    if [ "${version}" = "y" ] || [ "${check}" = "y" ]; then
        if [ $i -gt 1 ]; then
            errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:version/check can't use with other parameters."
        fi
    else
        # if not input full/run/docker/upgrade/devel parameter, installation will stop.
        if [ $j -ne 1 ]; then
            if [ "${force}" = "y" ]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:The parameter needs to be used with full/run/upgrade/uninstall."
            else
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:The parameter needs to be used with full/run/docker/upgrade/devel."
            fi
        else
            # if install for all, docker-install-type will not be allowed.
            if [ "${input_install_for_all}" = "y" ] && [[ "${docker}" = "y" || "${upgrade}" = "y" ]]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:install-for-all param need used with full/run/devel."
            fi
            # if input install-path, upgrade-install-type will not be allowed.
            if [ "${input_path_flag}" = "y" ] && [ "${upgrade}" = "y" ]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:install-path param need used with full/run/docker/devel."
            fi
            # chip features determine whether vnpu_host/vnpu_guest is supported or not.
            if [ "${feature_virt_scene}" = "n" ] && [ "${vnpu_host}" = "y" -o "${vnpu_guest}" = "y" -o "${vnpu_docker_host}" = "y" ]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:vnpu_host/vnpu_guest/vnpu_docker_host is not supported here."
            fi
            # if does support, mode vnpu_host/vnpu_guest only full/run is allowed.
            if [ "${feature_virt_scene}" = "y" ] && [ "${vnpu_host}" = "y" -o "${vnpu_guest}" = "y" -o "${vnpu_docker_host}" = "y" ] && [ "${full_install}" = "n" -a "${run}" = "n" ]; then
                errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:vnpu_host/vnpu_guest/vnpu_docker_host param need used with full/run."
            fi
            # if the installation user is specified, upgrade-install-type will not be allowed.
            if [ "${input_install_username}" = "y" ] || [ "${input_install_usergroup}" = "y" ]; then
                if [ "${input_install_username}" = "y" ] && [ "${input_install_usergroup}" = "y" ]; then
                    if [ "$upgrade" = "y" ]; then
                        errorUsage 1 "[ERROR]ERR_NO:0x0004;ERR_DES:install-username and install-usergroup params need used with full/run/docker/devel."
                    fi
                else
                    # need to specify user name and user group at the same time
                    drvEcho "[ERROR]ERR_NO:0x0004;ERR_DES:Username and usergroup are not specified at the same time."
                    drvEcho "[ERROR]Please input the right params and try again."
                    log "[ERROR]ERR_NO:0x0004;ERR_DES:Username and usergroup are not specified at the same time."
                    exitLog 1
                fi
            fi
        fi
    fi
}

function checkArch() {
    local curpath="$(dirname $(readlink -f "${BASH_SOURCE:-$0}"))"
    local scene_filepath="${curpath}/../scene.info"
    local arch

    if [ -f "${scene_filepath}" ]; then
        arch="$(grep "^arch=" "${scene_filepath}" | cut -d = -f 2)"
        if [ "${arch}" != "" ]; then
            PKG_ARCH="${arch}"
        fi
    fi

    if [ "$(arch)" != "${PKG_ARCH/-/_}" ]; then
        drvColorEcho "[ERROR]\033[31mArch mismatch, src package is ${PKG_ARCH}, cur os is $(arch) \033[0m"
        exitLog 1
    fi
}

function updateInstallParam() {
    local _key="$1"
    local _val="$2"
    local _file="$3"

    if [ ! -f "${_file}" ]; then
        exit 1
    fi

    for key_param in "${install_info_key_array[@]}"; do
        if [ ${key_param} == ${_key} ]; then
            sed -i "/${_key}=/d" "${_file}"
            echo "${_key}=${_val}" >> "${_file}"
            break
        fi
    done
}

user=`cat /etc/passwd | grep -w ^"HwHiAiUser"`
if [ "${user}" == "" ];then
    groupadd HwHiAiUser
    useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash
    mkdir -p -m 0755 /usr/local/Ascend/
    touch /usr/local/Ascend/creatuserHwHiAiUser
fi

crossVersion

if [ ! -d "${ASCEND_SECLOG}" ]; then
    mkdir -p ${ASCEND_SECLOG}
    setFileChmod -f 755 /var/log
    setFileChmod -f 750 ${ASCEND_SECLOG}
fi

if [ -f "${installInfo}" ]; then
    setFileChmod -f 644 "${installInfo}"
    UserName=$(getInstallParam "UserName" "${installInfo}")
    UserGroup=$(getInstallParam "UserGroup" "${installInfo}")
    if [ ! -z "$UserName" ]; then
        username="$UserName"
    fi
    if [ ! -z "$UserGroup" ]; then
        usergroup="$UserGroup"
    fi
fi

full_install=y
uninstall=n
upgrade=n
input_install_path=""
input_path_flag=n
input_install_username=n
input_install_usergroup=n
Install_Path_Param="/usr/local/Ascend"
operation="Install"
quiet=n
force=n
run=n
version=n
devel=n
installType=""
installMode="normal"
install_for_all="no"
docker=n
check=n
kmsagent_is_enable=n
vnpu_host=n
vnpu_guest=n
vnpu_docker_host=n
runPackagePath=""
driver_install_status=0

start_time=$(date +"%Y-%m-%d %T")
all_parma="$@"
if [ -z "$all_parma" ]; then
    errorUsage
fi

if [ -f "/etc/uvp_version" ] && [ ! -h "/etc/uvp_version" ];then
    systemctl status sshd 2>&1 | grep chroot | grep -v "grep" &>/dev/null
    if [ $? -eq 0 ];then
        force=y
    fi
fi

package_type=$1
if [ $1 -eq 2 ]; then
    full_install=n
    upgrade=y
    operation="Upgrade"
    package_type=$1
else
    name=$(rpm -qa | grep "Ascend.*driver" | sed 's/Ascend\(.*\)driver.*/\1/')
    if [[ $name =~ ^[0-9]{3} ]]; then
        full_install=n
        upgrade=y
        operation="Upgrade"
        package_type=2
    fi
fi

startLog
drvEcho "[INFO]LogFile: ${ASCEND_SECLOG}/ascend_install.log"
drvEcho "[INFO]OperationLogFile: ${ASCEND_SECLOG}/operation.log"
log "[INFO]UserCommand: $runfilename $all_parma"

isRoot
changeLogMode

checkProcess
logBaseVersion

if [ $upgrade = y ] || [ $full_install = y ] || [ $run = y ] || [ $devel = y ] || [ $docker = y ]; then
    drvColorEcho  "[WARNING]\033[33mDo not power off or restart the system during the installation/upgrade\033[0m"
fi

get_kmsagent_config

if [ $input_install_username = y ] || [ $input_install_usergroup = y ]; then
    if [ -z $username ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:input_install_username is empty"
    elif [ $username = "root" ] && [ ${input_install_for_all} = n ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:username not permission for root"
    fi

    if [ -z $usergroup ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:input_install_group is empty"
    elif [ $usergroup = "root" ] && [ ${input_install_for_all} = n ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0091;ERR_DES:usergroup not permission for root"
    fi
fi

trap "logOperation \"${operation}\" \"${start_time}\" \"${runfilename}\" \"${LOG_RESULT_FAILED}\" \"${installType}\" \"${all_parma}\";exit 1" \
INT QUIT TERM HUP
if [ $upgrade = y ]; then
    uniqueMode
    if [ -f ${installInfo} ];then
        Driver_Install_Type=$(getInstallParam "Driver_Install_Type" "${installInfo}")
        if [ -z "$Driver_Install_Type" ]; then
            installType="full"
        else
            installType="$Driver_Install_Type"
        fi
    else
        installType="full"
    fi
fi

if [ "${input_path_flag}" = "y" ]; then
    source "${SHELL_DIR}/common_func.inc"
    check_install_path_valid "${input_install_path}"
    if [ $? -ne 0 ]; then
        errorUsage 1 "[ERROR]ERR_NO:0x0003;ERR_DES:The install-path [${input_install_path}] is invalid according to regular-expression, only characters in [a-z,A-Z,0-9,-,_] are supported."
    else
        log "[INFO]check_install_path_valid success."
    fi
fi

getUserInfo
rotateLog
checkUserAndGroup
isValidPath
checkFreeSpace

# Prevent empty directories from occupying the disk space.
if [ -d /usr/local/bin/npu-smi ]; then
    rm -rf /usr/local/bin/npu-smi
fi
if [ -d /usr/local/sbin/npu-smi ]; then
    rm -rf /usr/local/sbin/npu-smi
fi

if [ $full_install = y ] || [ $upgrade = y ] || [ $run = y ]; then
    [ "$Driver_Install_Type" = "docker" ] || checkItems
fi

if [ -f ${installInfo} ]; then
    Driver_Install_Path_Param=$(getInstallParam "Driver_Install_Path_Param" "${installInfo}")
    # first installation scenario
    if [ -z "$Driver_Install_Path_Param" ]; then
        # uninstall scenario
        if [ $uninstall = y ]; then
            error "${LOG_OPERATION_UNINSTALL}" 1 "ERR_NO:0x0080;ERR_DES:Driver package is not installed on this device, uninstall failed"
        # installation scenario
        elif [ $full_install = y ] || [ $upgrade = y ] || [ $run = y ] || [ $docker = y ] || [ $devel = y ]; then
            first_time_install_drv_flag="Y"
            install_path_should_belong_to_root
            if [ $? -ne 0 ]; then
                exitLog 1
            fi
            operation="${LOG_OPERATION_INSTALL}"
        fi
    else
        first_time_install_drv_flag="N"
        old_drv_install_path="${Driver_Install_Path_Param}"

        version1=$(getVersionInRunFile)
        version2=$(getVersionInstalled "$Driver_Install_Path_Param")
        # uninstall scenario
        if [ $uninstall = y ]; then
            echo "uninstall scenario, try to uninstallRun"
            uninstallRun
        # overwrite installation scenarios
        elif [ $full_install = y ] || [ $run = y ] || [ $docker = y ] || [ $devel = y ]; then
            Driver_Install_Path=`cat /etc/ascend_install.info | grep ^"Driver_Install_Path_Param" | awk -F "=" '{print $2}'`
          Npusmi_Install_Path=`cat ${Driver_Install_Path}/driver/script/filelist.csv | grep npu-smi | awk -F ',' '{print $4}'`
          for i in ${Npusmi_Install_Path}
          do
            rm -rf "${i}"
          done
          sleep 3
          bash ${Driver_Install_Path}/driver/script/uninstall.sh
          first_time_install_drv_flag="Y"
              install_path_should_belong_to_root
          if [ $? -ne 0 ]; then
              exitLog 1
          fi
          chattr -i -R ${Driver_Install_Path}
          operation="${LOG_OPERATION_INSTALL}"
        # upgrade scenario
        elif [ $upgrade = y ]; then
            install_path_should_belong_to_root
            if [ $? -ne 0 ]; then
                exitLog 1
            fi
            if [ -f ./driver/script/ver_check.sh ]; then
                ./driver/script/ver_check.sh $check $quiet || exitLog 1
            fi
            backupKmsData
            uninstallRun
            isValidPath
            #installRun "Upgrade"
            operation="${LOG_OPERATION_UPGRADE}"
        fi
    fi
else
    # uninstall scenario
    if [ $uninstall = y ]; then
        error "${LOG_OPERATION_UNINSTALL}" 1 "ERR_NO:0x0080;ERR_DES:Driver package is not installed on this device, uninstall failed"
    # installation scenario
    elif [ $full_install = y ] || [ $upgrade = y ] || [ $run = y ] || [ $docker = y ] || [ $devel = y ]; then
        first_time_install_drv_flag="Y"
        install_path_should_belong_to_root || exitLog 1
        operation="${LOG_OPERATION_INSTALL}"
    fi
fi

installType="full"
install_path_should_belong_to_root
updateInstallInfo

[ -e "${hotreset_status_file}" ] && echo "Flag_Install_not_Uninstall" >> ${hotreset_status_file}
echo "PCIE_INSMOD_STATUS_BEFORE_INSTALL=$PCIE_INSMOD_STATUS_BEFORE_INSTALL" > $preinst_flag_first_file
echo "first_time_install_drv_flag=$first_time_install_drv_flag" >> $preinst_flag_first_file
