Files
openGauss-OM/script/local/LocalCheckOS.py
coolany eae422baf3 适配CM组件
Signed-off-by: coolany <kyosang@163.com>

support cgroup

追加合入
2022-03-05 18:51:52 +08:00

2140 lines
72 KiB
Python

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#############################################################################
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------
# Description : LocalCheckOS.py is a utility to check OS info on local node.
#############################################################################
import os
import sys
import subprocess
import glob
import getopt
import subprocess
import platform
import time
from datetime import datetime
localDirPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(sys.path[0] + "/../")
from gspylib.common.ParameterParsecheck import Parameter
from os_platform.UserPlatform import g_Platform
from gspylib.common.GaussLog import GaussLog
from gspylib.common.DbClusterInfo import dbClusterInfo
from gspylib.common.Common import DefaultValue
from gspylib.common.ErrorCode import ErrorCode
from base_utils.os.cmd_util import CmdUtil
from domain_utils.cluster_file.config_param import ConfigParam
from base_utils.os.disk_util import DiskUtil
from domain_utils.cluster_file.version_info import VersionInfo
from base_utils.os.net_util import NetUtil
from domain_utils.domain_common.cluster_constants import ClusterConstants
from os_platform.linux_distro import LinuxDistro
sys.path.insert(0, localDirPath + "/../../lib")
import psutil
ACTION_CHECK_OS_VERSION = "Check_OS_Version"
ACTION_CHECK_KERNEL_VERSION = "Check_Kernel_Version"
ACTION_CHECK_UNICODE = "Check_Unicode"
ACTION_CHECK_TIMEZONE = "Check_TimeZone"
ACTION_CHECK_DISK_CONFIGURE = "Check_Disk_Configure"
ACTION_CHECK_BLOCKDEV_CONFIGURE = "Check_BlockDev_Configure"
ACTION_CHECK_IO_CONFIGURE = "Check_IO_Configure"
ACTION_CHECK_LOGICAL_BLOCK = "Check_Logical_Block"
ACTION_CHECK_IO_REQUEST = "Check_IO_Request"
ACTION_CHECK_ASYNCHRONOUS_IO_REQUEST = "Check_Asynchronous_IO_Request"
ACTION_CHECK_NETWORK_CONFIGURE = "Check_Network_Configure"
ACTION_CHECK_NETWORK_BOND_MODE = "Check_Network_Bond_Mode"
ACTION_CHECK_SWAP_MEMORY_CONFIGURE = "Check_Swap_Memory_Configure"
ACTION_CHECK_TIME_CONSISTENCY = "Check_Time_Consistency"
ACTION_CHECK_FIREWALL_SERVICE = "Check_Firewall_Service"
ACTION_CHECK_THP_SERVICE = "Check_THP_Service"
ACTION_SET_BLOCKDEV_CONFIGURE = "Set_BlockDev_Configure"
ACTION_SET_IO_CONFIGURE = "Set_IO_Configure"
ACTION_SET_REMOVEIPC_VALUE = "Set_RemoveIPC_Value"
ACTION_SET_SESSION_PROCESS = "Set_Session_Process"
ACTION_SET_NETWORK_CONFIGURE = "Set_Network_Configure"
ACTION_SET_THP_SERVICE = "Set_THP_Service"
ACTION_SET_LOGICAL_BLOCK = "Set_Logical_Block"
ACTION_SET_IO_REQUEST = "Set_IO_REQUEST"
ACTION_SET_ASYNCHRONOUS_IO_REQUEST = "Set_Asynchronous_IO_Request"
#############################################################################
# Global variables
#############################################################################
netWorkLevel = 10000
expectMTUValue = 8192
expectRXValue = 4096
expectTXValue = 4096
MASTER_INSTANCE = 0
STANDBY_INSTANCE = 1
g_logger = None
g_opts = None
g_clusterInfo = None
netWorkBondInfo = None
###########################################################################
# mounts
###########################################################################
class mounts:
"""
Class: mounts
"""
def __init__(self):
"""
function : Init class mounts
input : NA
output : NA
"""
self.entries = dict() # dictionary key=partition value=mount object
self.errormsg = None
class GSMount:
"""
Class: GSMount
"""
def __init__(self):
"""
function : Init class GSMount
input : NA
output : NA
"""
self.partition = None
self.dir = None
self.type = None
self.options = set() # mount options
def __str__(self):
"""
function : Convert to a string
input : NA
output : string
"""
optionstring = ''
first = True
for k in self.options:
if not first:
optionstring = "%s," % optionstring
thisoption = k
optionstring = "%s%s" % (optionstring, thisoption)
first = False
return "%s on %s type %s (%s)" % (self.partition, self.dir,
self.type, optionstring)
def collectMounts():
"""
function : Collector mounts
input : NA
output : Instantion
"""
data = mounts()
p = subprocess.Popen(["mount"], shell=False, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = p.communicate()
data.errormsg = result[1].decode().strip()
if p.returncode:
return data
for line in result[0].decode().splitlines():
mdata = GSMount()
words = line.strip().split()
mdata.partition = words[0]
mdata.dir = words[2]
mdata.type = words[4]
# get the options string
tmpa = words[5]
tmpb = tmpa.strip().strip("()")
tmpc = tmpb.split(",")
for op in tmpc:
mdata.options.add(op)
data.entries[mdata.partition] = mdata
return data
###########################################################################
# blockdev:
###########################################################################
class blockdev:
"""
Class: blockdev
"""
def __init__(self):
"""
function : Init class blockdev
input : NA
output : NA
"""
self.ra = dict() # key is device name value is getra value
self.errormsg = ''
def collectBlockdev():
"""
function : Collector blockdev
input : NA
output : Instantion
"""
data = blockdev()
devices = list()
try:
# If the directory of '/' is disk array, all disk prereads will be set
devlist = DiskUtil.getDevices()
cmd = "mount | awk '{if( $3==\"/\" ) print $1}' |" \
" sed 's/\/dev\///' | sed 's/[0-9]//'"
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n%s" % output)
for dev in devlist:
if (dev.strip() == output.strip()):
continue
devices.append("/dev/%s" % dev)
except Exception as e:
data.errormsg = e.__str__()
for d in devices:
p = subprocess.Popen(["/sbin/blockdev", "--getra", "%s" % d],
shell=False, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = p.communicate()
data.errormsg += result[1].decode().strip()
if p.returncode:
continue
data.ra[d] = result[0].decode().strip()
return data
###########################################################################
# platform: uname
###########################################################################
class uname:
"""
Class: uname
"""
def __init__(self):
"""
function : Init class uname
input : NA
output : NA
"""
self.output = None
self.errormsg = None
def collectUname():
"""
function : Collector uname
input : NA
output : Instantion
"""
data = uname()
p = subprocess.Popen(["uname", "-r"], shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = p.communicate()
data.errormsg = result[1].decode().strip()
if p.returncode:
return data
data.output = result[0].decode().strip()
return data
###########################################################################
# unicode
###########################################################################
class codename:
"""
Class: codename
"""
def __init__(self):
"""
function : Init class codename
input : NA
output : NA
"""
self.output = None
self.errormsg = None
def collectUnicode():
"""
function : Collector unicode
input : NA
output : Instantion
"""
data = codename()
cmd = "locale | grep '^LANG='"
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception((ErrorCode.GAUSS_505["GAUSS_50502"] % "Unicode") +
("The cmd is : %s" % cmd))
data.output = output
return data
###########################################################################
# timezone
###########################################################################
class timezone:
"""
Class: timezone
"""
def __init__(self):
"""
function : Init class timezone
input : NA
output : NA
"""
self.output = None
self.errormsg = None
def collectTimeZone():
"""
function : Collector timezone
input : NA
output : Instantion
"""
data = timezone()
cmd = "date -R | awk -F ' ' '{print $NF}'"
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception((ErrorCode.GAUSS_505["GAUSS_50502"] % "TimeZone") +
("The cmd is : %s" % cmd))
data.output = output
return data
###########################################################################
# platform: version
###########################################################################
class platformInfo:
"""
Class: platformInfo
"""
def __init__(self):
"""
function : Init class platforminfo
input : NA
output : NA
"""
self.distname = ""
self.version = ""
self.id = ""
self.bits = ""
self.linkage = ""
self.patchlevel = ""
def collectplatformInfo():
"""
function : Collector platforminfo
input : NA
output : Instantion
"""
data = platformInfo()
distname, version, idnum = LinuxDistro.linux_distribution()
bits, linkage = platform.architecture()
data.distname = distname
data.version = version
data.id = idnum
data.bits = bits
data.linkage = linkage
# os-release is added since SLE 12;
# SuSE-release will be removed in a future service pack or release
if (distname == "SuSE" and version in ("11", "12")):
if os.path.exists('/etc/SuSE-release'):
cmd = "grep -i 'PATCHLEVEL' /etc/SuSE-release |" \
" awk -F '=' '{print $2}'"
else:
cmd = "grep -i 'VERSION_ID' /etc/os-release |" \
" awk -F '.' '{print $2}' | sed 's/\"//'"
(status, output) = subprocess.getstatusoutput(cmd)
if (status == 0 and output != ""):
data.patchlevel = output.strip()
else:
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n%s " % output)
return data
###########################################################################
# I/O schedulers
###########################################################################
class ioschedulers:
"""
Class: ioschedulers
"""
def __init__(self):
"""
function : Init class ioschedulers
input : NA
output : NA
"""
# key is device name, value is scheduler name
self.devices = dict()
self.errormsg = ''
# key is device name, value is optional configuration list
self.allItem = {}
def collectIOschedulers():
"""
function : Collector IOschedulers
input : NA
output : Instantion
"""
data = ioschedulers()
devices = set()
try:
files = DiskUtil.getDevices()
for f in files:
fname = "/sys/block/%s/queue/scheduler" % f
words = fname.split("/")
if len(words) != 6:
continue
devices.add(words[3].strip())
except Exception as e:
data.errormsg = e.__str__()
for d in devices:
try:
with open("/sys/block/%s/queue/scheduler" % d, 'r') as fd:
scheduler = fd.read()
words = scheduler.split("[")
if len(words) != 2:
continue
words = words[1].split("]")
if len(words) != 2:
continue
data.devices[d] = words[0].strip()
data.allItem[d] = scheduler.replace("[", "").replace("]",
"").split()
except Exception as e:
data.errormsg += e.__str__()
return data
###########################################################################
# I/O REQUEST #device_name
###########################################################################
class ioRequest():
"""
Class: ioRequest
"""
def __init__(self):
"""
function : Init class ioRequest
input : NA
output : NA
"""
self.devices = dict()
self.errormsg = ''
def collectIORequest():
"""
function : Collector ioRequest
input : NA
output : Dict
"""
data = ioRequest()
devices = []
try:
files = glob.glob("/sys/block/*/queue/nr_requests")
for f in files:
words = f.split("/")
if len(words) != 6:
continue
devices.append(words[3].strip())
except Exception as e:
data.errormsg = e.__str__()
result = {}
for d in devices:
try:
with open("/sys/block/%s/queue/nr_requests" % d, 'r') as fd:
request = fd.read()
result[d] = request
except Exception as e:
data.errormsg += e.__str__()
return result
###########################################################################
# Asynchronous I/O REQUEST #device_name
###########################################################################
class AsynchronousIoRequest():
"""
Class: AsynchronousIoRequest
"""
def __init__(self):
"""
function : Init class AsynchronousIoRequest
input : NA
output : NA
"""
self.devices = dict()
self.errormsg = ''
def collectAsynchronousIORequest():
"""
function : Collector AsynchronousIORequest
input : NA
output : List
"""
data = AsynchronousIoRequest()
result = []
try:
with open("/proc/sys/fs/aio-max-nr", 'r') as fd:
request = fd.read()
result.append(request)
except Exception as e:
data.errormsg += e.__str__()
return result
###########################################################################
# LogicalBlock
###########################################################################
class LogicalBlock():
"""
class: LogicalBlock
"""
def __init__(self):
"""
function : Init class LogicalBlock
input : NA
output : NA
"""
self.devices = dict()
self.errormsg = ''
def collectLogicalBlock():
"""
function : Collector LogicalBlock
input : NA
output : Dict
"""
data = LogicalBlock()
devices = set()
try:
files = glob.glob("/sys/block/*/queue/logical_block_size")
for f in files:
words = f.split("/")
if len(words) != 6:
continue
devices.add(words[3].strip())
except Exception as e:
data.errormsg = e.__str__()
result = {}
for d in devices:
try:
with open("/sys/block/%s/queue/logical_block_size" % d, 'r') as fd:
request = fd.read()
result[d] = request
except Exception as e:
data.errormsg += e.__str__()
return result
###########################################################################
# getTHPandOSInitFile:
###########################################################################
def getTHPandOSInitFile():
"""
function : We know that the centos have same init file and THP file
as RedHat.
input : NA
output : String, String
"""
THPFile = "/sys/kernel/mm/transparent_hugepage/enabled"
initFile = DefaultValue.getOSInitFile()
if (initFile == ""):
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"]
% "startup file of current OS" +
" The startup file for SUSE OS is"
" /etc/init.d/boot.local.The startup file for Redhat"
" OS is /etc/rc.d/rc.local.")
return (THPFile, initFile)
###########################################################################
# THP Server:
###########################################################################
class THPServer:
"""
Class: THPServer
"""
def __init__(self):
"""
function : Init class THPServer
input : NA
output : NA
"""
self.status = ""
def collectTHPServer():
"""
function : collect THPServer
input : NA
output : instantion
"""
data = THPServer()
THPFile = getTHPandOSInitFile()[0]
if (os.path.exists(THPFile)):
cmd = "grep '\[never\]' %s | wc -l" % THPFile
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.debug("Failed to obtain THP service status. Commands for"
" obtaining THP server status: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_510["GAUSS_51001"]
+ " Error: \n%s" % output)
if (output.strip().isdigit()):
num = int(output.strip())
else:
num = 1
if (num > 0):
data.status = "disabled"
else:
data.status = "enabled"
else:
data.status = "disabled"
return data
def disRemoveIPC():
"""
function : close RemoveIPC
input : NA
output : NA
"""
g_logger.debug("disbale RemoveIPC.")
distName = g_Platform.getCurrentPlatForm()[0]
if distName.upper() in ("OPENEULER", "KYLIN"):
cmd = "setenforce 0"
subprocess.getstatusoutput(cmd)
initFile = "/usr/lib/systemd/system/systemd-logind.service"
if os.path.exists(initFile):
close_cmd = "if [ `systemctl show systemd-logind | " \
"grep RemoveIPC` != \"RemoveIPC=no\" ]; " \
"then echo 'RemoveIPC=no' >> " \
"/usr/lib/systemd/system/systemd-logind.service; " \
"sed -i '/RemoveIPC=yes/'d " \
"/usr/lib/systemd/system/systemd-logind.service; fi;"
disableRemoveIPCLog(close_cmd)
initFile = "/etc/systemd/logind.conf"
if os.path.exists(initFile):
close_cmd = "if [ `loginctl show-session | " \
"grep RemoveIPC` != \"RemoveIPC=no\" ]; " \
"then echo 'RemoveIPC=no' >> " \
"/etc/systemd/logind.conf; " \
"sed -i '/RemoveIPC=yes/'d " \
"/etc/systemd/logind.conf; fi;"
disableRemoveIPCLog(close_cmd)
cmd = "systemctl daemon-reload"
disableRemoveIPCLog(cmd)
cmd = "systemctl restart systemd-logind"
disableRemoveIPCLog(cmd)
cmd = "systemctl show systemd-logind | grep RemoveIPC && " \
"loginctl show-session | grep RemoveIPC"
output = disableRemoveIPCLog(cmd)
ipcCheckNum = 0
for result in output.split("\n"):
if result == "RemoveIPC=no":
ipcCheckNum = ipcCheckNum + 1
if ipcCheckNum < 1:
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n cmd:\"systemctl show systemd-logind"
" | grep RemoveIPC and loginctl show-session "
"| grep RemoveIPC\" The result"
" cannot be all no")
g_logger.debug("Successfully change RemoveIPC to no.")
def disableRemoveIPCLog(cmd):
"""
function : disable remove IPCLog
input : cmd
output : NA
"""
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
g_logger.debug("Failed to disbale RemoveIPC. Commands"
" for disbale RemoveIPC: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_510["GAUSS_51002"]
+ " Error: \n%s" % output)
return output
def CheckSessionProcess():
"""
function : Set User Session Process Control
input : NA
output : NA
"""
g_logger.debug("Setting User Session Process Control.")
etcFile = "/etc/pam.d/sshd"
if os.path.exists(etcFile):
set_cmd = "sed -i '/.*session\+.*pam_limits\.so/d' /etc/pam.d/sshd;" \
"echo 'session required pam_limits.so' >> " \
"/etc/pam.d/sshd; "
setSeesionProcess(set_cmd)
g_logger.debug("Successfully Set Session Process.")
def setSeesionProcess(cmd):
"""
function : Set User Session Process Control
input : cmd
output : NA
"""
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
g_logger.debug("Failed to set session process. Commands"
" for set session process: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_510["GAUSS_51003"]
+ " Error: \n%s" % output)
return output
def disTHPServer():
"""
function : close THP Server
input : NA
output : NA
"""
g_logger.debug("Closing the THP service.")
(THPFile, initFile) = getTHPandOSInitFile()
if (os.path.exists(initFile)):
# 1.close thp
close_cmd = "(if test -f '%s'; then echo never > %s;fi)" \
% (THPFile, THPFile)
(status, output) = subprocess.getstatusoutput(close_cmd)
if (status != 0):
g_logger.debug("Failed to close THP service. Commands"
" for closing THP server: %s." % close_cmd)
g_logger.logExit(ErrorCode.GAUSS_510["GAUSS_51002"]
+ " Error: \n%s" % output)
# 2.add close cmd to init file
cmd = "sed -i '/^.*transparent_hugepage.*enabled.*echo" \
" never.*$/d' %s &&" % initFile
cmd += "echo \"%s\" >> %s" % (close_cmd, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n%s" % output)
g_logger.debug("Successfully closed the THP service.")
###########################################################################
# network card parameter:
###########################################################################
class netWork:
"""
Class: netWork
"""
def __init__(self):
"""
function : Init class netWork
input : NA
output : NA
"""
self.netLevel = ""
self.netNum = ""
self.variables = dict()
self.modeType = False
self.nums = 0
def CheckNetWorkBonding(serviceIP, bondMode=False):
"""
function : Check NetWork ConfFile
input : String, bool
output : List
"""
networkCardNum = NetUtil.getNICNum(serviceIP)
NetWorkConfFile = DefaultValue.getNetWorkConfFile(networkCardNum)
if (NetWorkConfFile.find("No such file or directory") >= 0
and DefaultValue.checkDockerEnv()):
return
networkCardNumList = []
networkCardNumList.append(networkCardNum)
bondingConfFile = "/proc/net/bonding/%s" % networkCardNum
if os.path.exists(NetWorkConfFile):
cmd = "grep -i 'BONDING_OPTS\|BONDING_MODULE_OPTS' %s" \
% NetWorkConfFile
(status, output) = subprocess.getstatusoutput(cmd)
if ((status == 0) and (output.strip() != "")):
if ((output.find("mode") > 0)
and os.path.exists(bondingConfFile)):
networkCardNumList = networkCardNumList + \
checkBondMode(bondingConfFile, bondMode)
else:
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50611"] +
"The cmd is " + cmd)
else:
g_logger.log("BondMode Null")
else:
flag = NetUtil.getNetWorkBondFlag(networkCardNum)[0]
if flag:
if os.path.exists(bondingConfFile):
networkCardNumList = networkCardNumList + \
checkBondMode(bondingConfFile, bondMode)
else:
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50611"]
+ "Without NetWorkConfFile mode.")
else:
g_logger.log("BondMode Null")
if (len(networkCardNumList) != 1):
del networkCardNumList[0]
return networkCardNumList
def checkBondMode(bondingConfFile, isCheck):
"""
function : Check Bond mode
input : String, bool
output : List
"""
netNameList = []
cmd = "grep -w 'Bonding Mode' %s | awk -F ':' '{print $NF}'" \
% bondingConfFile
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0 or output.strip() == ""):
g_logger.debug("Failed to obtain network card bonding information."
" Commands for getting: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50611"]
+ " Error: \n%s" % output)
if ("active-backup" in output):
netWorkBondInfo.modeType = 1
netWorkBondInfo.nums = 0
if isCheck:
g_logger.log("BondMode %s" % output.strip())
else:
cmd = "grep -w 'Slave Interface' %s | awk -F ':' '{print $NF}'" \
% bondingConfFile
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.debug("Failed to obtain network card bonding "
"information. Commands for getting: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50611"]
+ " Error: \n%s" % output)
for networkname in output.split('\n'):
netNameList.append(networkname.strip())
netWorkBondInfo.nums = netWorkBondInfo.nums + 1
return netNameList
def getNetWorkTXRXValue(networkCardNum, valueType):
"""
function : Check Bond mode
input : int, String
output : int
"""
cmd = "/sbin/ethtool -g %s | grep '%s:' | tail -n 2" % (networkCardNum,
valueType)
(status, output) = subprocess.getstatusoutput(cmd)
if (output.find("Operation not supported") >= 0
and DefaultValue.checkDockerEnv()):
g_logger.log(" Warning reason: Failed to obtain the"
" network card TXRX value in docker container. Commands "
"for obtain the network card TXRX: %s. Error: \n%s"
% (cmd, output))
return (0, 0)
if (status != 0 or len(output.splitlines()) != 2):
g_logger.debug("Failed to obtain network card %s value. Commands"
" for getting information: %s." % (valueType, cmd))
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50612"]
% valueType + " Error: \n%s" % output)
# redhat2.0 here means EulerOS, because we get the os version 2.0
valueMax = output.splitlines()[0].split(':')[1].split(' ')[0].strip()
valueStr = output.splitlines()[1].split(':')[1].split(' ')[0].strip()
if (not str(valueStr).isdigit() or not str(valueMax).isdigit()):
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50612"] % valueType
+ " Error: \ncmd:%s\noutput:%s" % (cmd, output))
if (int(valueMax) < int(valueStr)):
valueTmp = valueMax
valueMax = valueStr
valueStr = valueTmp
return (int(valueStr), int(valueMax))
def GetNetWorkCardInfo(networkCardNum):
"""
function : Get NetWorkCard Info
input : int
output : instantion
"""
# set network card mtu and queue length
g_logger.debug("Obtaining the value about mtu and queue length"
" from network card configuration.")
data = netWork()
data.netNum = networkCardNum
# check the network card format.
# if Speed >= 10000Mb/s, do the setting; else, nothing
cmdGetSpeedStr = "/sbin/ethtool %s | grep 'Speed:'" % networkCardNum
(status, output) = subprocess.getstatusoutput(cmdGetSpeedStr)
if (status == 0 and output.find("Speed:") >= 0
and output.find("Mb/s") >= 0):
data.netLevel = int(output.split(':')[1].strip()[:-4])
# get default mtu value
valueMTU = psutil.net_if_stats()[networkCardNum].mtu
data.variables["mtu"] = valueMTU
if (data.netLevel >= int(netWorkLevel)):
# get default rx value
(valueRX, valueRXMax) = getNetWorkTXRXValue(networkCardNum, "RX")
data.variables["rx"] = valueRX
data.variables["rx_max"] = valueRXMax
# get default tx value
(valueTX, valueTXMax) = getNetWorkTXRXValue(networkCardNum, "TX")
data.variables["tx"] = valueTX
data.variables["tx_max"] = valueTXMax
else:
g_logger.debug("Warning: The speed of current card \"%s\""
" is less than %s Mb/s." % (networkCardNum,
netWorkLevel))
elif (netWorkBondInfo.modeType == 1):
data.netLevel = int(0)
netWorkBondInfo.nums = netWorkBondInfo.nums - 1
if (output.find("Speed:") >= 0):
g_logger.log(" Warning reason: Obtain the network card "
"speed value is failed. Maybe the network card "
"\"%s\" is not working." % networkCardNum)
else:
g_logger.log(" Warning reason: Obtain the network card "
"speed value is failed. Commands for obtain the "
"network card speed: %s. Error: \n%s"
% (cmdGetSpeedStr, output))
if (netWorkBondInfo.nums == 0):
g_logger.log(" Warning reason: Failed to obtain speed rate"
" value for all bound networks card.")
else:
data.netLevel = int(0)
if (output.find("Speed:") >= 0):
g_logger.log(" Warning reason: Failed to obtain the "
"network card speed value. Maybe the network card"
" \"%s\" is not working." % networkCardNum)
else:
g_logger.log(" Warning reason: Failed to obtain the"
" network card speed value. Commands for obtain"
" the network card speed: %s. Error: \n%s"
% (cmdGetSpeedStr, output))
g_logger.debug("Successfully obtained the mtu and queue length value"
" from network card.")
return data
def setNetWorkMTUOrTXRXValue(networkCardNum, valueType,
expectValue, initFileName):
"""
function : Set NetWork MTU Or TXRX Value
input : int, String, String, String
output : NA
"""
if (valueType == "tx" or valueType == "rx"):
cmd = "/sbin/ethtool -G %s %s %s" % (networkCardNum,
valueType, expectValue)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
if (valueType == 'tx' or valueType == 'rx'):
if (output.find("no ring parameters changed, aborting") < 0):
isPrint = True
else:
isPrint = False
else:
isPrint = True
if isPrint:
g_logger.debug("Failed to set network card %s value."
" Commands for setting: %s." % (valueType, cmd))
g_logger.logExit(ErrorCode.GAUSS_506["GAUSS_50613"]
% valueType + " Error: \n%s" % output)
# write setting cmds into init file
if (valueType == "tx" or valueType == "rx"):
cmdWrite = "sed -i \"/^.*\\/sbin\\/ethtool -G %s %s %s$/d\" %s" \
% (networkCardNum, valueType, expectValue, initFileName)
cmdInit = """%s && echo "%s">>%s""" % (cmdWrite, cmd, initFileName)
(status, output) = subprocess.getstatusoutput(cmdInit)
if (status != 0):
g_logger.debug("Faile to write %s setting commands into init file."
" Commands for setting: %s." % (valueType, cmdInit))
g_logger.logExit(ErrorCode.GAUSS_502["GAUSS_50205"]
% initFileName + " Error: \n%s" % output)
def SetNetWorkCardInfo(networkCardNum, data):
"""
function : Set NetWorkCard Info
input : int, instantion, Bool
output : NA
"""
g_logger.debug("Setting the network card configuration value.")
if (int(data.netLevel) >= int(netWorkLevel)):
initFile = getTHPandOSInitFile()[1]
for k in list(data.variables.keys()):
if ((k == "rx") and int(data.variables[k].__str__()) < expectRXValue):
targetValue = min(expectRXValue, int(data.variables["rx_max"].__str__()))
setNetWorkMTUOrTXRXValue(
data.netNum, k,
targetValue,
initFile)
g_logger.debug(
"Set the \"%s\" '%s' value from \"%s\" to \"%s\"."
% (networkCardNum, k, int(data.variables[k].__str__()), targetValue))
if ((k == "tx") and int(data.variables[k].__str__()) < expectTXValue):
targetValue = min(expectTXValue, int(data.variables["tx_max"].__str__()))
setNetWorkMTUOrTXRXValue(
data.netNum, k,
targetValue,
initFile)
g_logger.debug(
"Set the \"%s\" '%s' value from \"%s\" to \"%s\"."
% (networkCardNum, k, int(data.variables[k].__str__()), targetValue))
# after doing setting the value, please wait a moment,
# then we can get the real netwrok card information.
time.sleep(2)
g_logger.debug("Successfully setted the network card value.")
def CheckNetWorkCardInfo(data):
"""
function : Check NetWorkCard Info
input : Instantion
output : NA
"""
g_logger.debug("Checking the network card configuration value.")
for k in list(data.variables.keys()):
value = int(data.variables[k].__str__())
if (k == "mtu"):
if g_opts.mtuValue != "" and int(value) != int(g_opts.mtuValue):
g_logger.log(" Abnormal:"
" network '%s' '%s' value[%s:%s]"
" is different from the other node [%s:%s]"
% (data.netNum, k,
NetUtil.GetHostIpOrName(),
value, g_opts.hostname, g_opts.mtuValue))
elif (int(value) != int(expectMTUValue)):
g_logger.log(" Warning reason: network '%s' '%s'"
" RealValue '%s' ExpectedValue '%s'"
% (data.netNum, k, value, expectMTUValue))
elif ((k == "rx") and
int(value) < int(data.variables["rx_max"].__str__())):
if (int(data.netLevel) >= int(netWorkLevel)):
g_logger.log(" Warning reason: network '%s' '%s'"
" RealValue '%s' ExpectValue '%s'."
% (data.netNum, k, value,
data.variables["rx_max"].__str__()))
elif ((k == "tx") and
int(value) < int(data.variables["tx_max"].__str__())):
if (int(data.netLevel) >= int(netWorkLevel)):
g_logger.log(" Warning reason: network '%s' '%s' "
"RealValue '%s' ExpectValue '%s'."
% (data.netNum, k, value,
data.variables["tx_max"].__str__()))
else:
g_logger.log(" network '%s' '%s' RealValue '%s'"
" ExpectValue '%s'. [Normal]"
% (data.netNum, k, value,
data.variables["tx_max"].__str__()))
g_logger.debug("Successfully checked the network card value.")
def GetInterruptCountNum(cardname):
"""
function : We can makesure that all dev names is startwith 'ethX-'
and endwith '-X'
input : String
output : Int
"""
cmd = "cat /proc/interrupts | grep '%s-' | wc -l" % cardname
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.debug("Failed to obtain network card interrupt"
" count numbers. Commands for getting interrupt"
" count numbers: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n%s" % output)
if (not str(output.strip()).isdigit()):
return 0
return int(output.strip())
def CheckNetWorkCardInterrupt(data, isSetting=False):
"""
function : Check NetWorkCard Interrupt
input : Instantion, Bool
output : NA
"""
g_logger.debug("Setting the network card interrupt value.")
if (int(data.netLevel) >= int(netWorkLevel)):
cmd = "for i in `cat /proc/interrupts | grep '%s-' |" \
" awk -F ' ' '{print $1}' | awk -F ':' '{print $1}'`;" \
" do cat /proc/irq/$i/smp_affinity ; done" % data.netNum
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.debug("Failed to obtain network card interrupt value."
" Commands for getting interrupt value: %s." % cmd)
g_logger.logExit(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd
+ " Error: \n%s" % output)
# cpu core number followed by 1 2 4 8,every 4 left shift one
Mapping = {0: "1", 1: "2", 2: "4", 3: "8"}
flag = "Normal"
for index, eachLine in enumerate(output.split()):
# Remove the ','
eachLine = eachLine.replace(",", "")
# Replace 0000,00001000 to 1,Remove invalid content
validValue = eachLine.replace("0", "")
# Convert the row index to the expected value
expandNum = Mapping[index % 4]
# Convert line index to expected position
expandBit = index // 4 * -1 - 1
# value and position is correct
if (len(eachLine) * -1) > expandBit:
g_logger.debug("Network card [%s] multi-queue support is"
" not enabled.\n" % data.netNum)
flag = "Error"
break
if (eachLine[expandBit] == expandNum and validValue == expandNum):
continue
else:
g_logger.debug("Network card [%s] multi-queue support is not"
" enabled.\n" % data.netNum)
flag = "Error"
break
if (flag == "Normal"):
pass
else:
if (isSetting):
g_logger.debug("The network card '%s' interrupt is not"
" be setted." % data.netNum)
cmd = "ps ax | grep -v grep | grep -q irqbalance; echo $?"
(status, output) = subprocess.getstatusoutput(cmd)
if (output.strip() == "0"):
g_logger.log(" Warning: irqbalance is running and"
" will likely override this script's"
" affinitization. Please stop the irqbalance"
" service and/or execute 'killall"
" irqbalance'.")
killcmd = "%s irqbalance" % CmdUtil.findCmdInPath("killall")
(status, output) = subprocess.getstatusoutput(killcmd)
if status != 0:
g_logger.log("Failed to execute killall irqbalance")
count = int(GetInterruptCountNum(data.netNum))
i = 0
while (i < count):
# the dev name type like this: eth1-1,
# eth1-rx-1, eth1-tx-1, eth1-TxRx-1
cmd_IRQ = "cat /proc/interrupts | grep '%s.*-' | " \
"awk -F ' ' '{print $1}' | awk -F ':' " \
"'{print $1}'| awk 'NR==%s'" \
% (data.netNum, str(i + 1))
(status, output) = subprocess.getstatusoutput(cmd_IRQ)
if status != 0 or output.strip() == "":
g_logger.debug(
"Failed to obtain network card interrupt value. "
"Commands for getting interrupt value: %s."
% cmd_IRQ)
else:
IRQ = output.strip()
g_logger.log("The network '%s' interrupt "
"configuration path:"
" /proc/irq/%s/smp_affinity."
% (data.netNum, IRQ))
num = 2 ** i
# Under SuSE platform, when the length is
# greater than 8, the ',' must be used.
value = str(hex(num))[2:]
if (len(value) > 16 and value[-1] == 'L'):
value = value[:-1]
result_value = ''
while (len(value) > 8):
result_value = ",%s%s" \
% (value[-8:], result_value)
value = value[:-8]
result_value = "%s%s" % (value, result_value)
cmd_set = "echo '%s'> /proc/irq/%s/smp_affinity" \
% (result_value, IRQ)
(status, output) = subprocess.getstatusoutput(cmd_set)
if (status != 0):
g_logger.log(
"Failed to set network '%s' IRQ. Commands for"
" setting: %s." % (data.netNum, cmd_set))
else:
g_logger.log(
"Set network card '%s' IRQ to \"%s\"."
% (data.netNum, result_value))
i = i + 1
g_logger.debug("Successfully setted the network card interrupt value.")
def CheckNetWorkCardPara(serviceIP, isSetting=False):
"""
function : Check NetWorkCard Para
input : String, Bool
output : NA
"""
global expectMTUValue
# get the network parameter values from the configuration file
dirName = os.path.dirname(os.path.realpath(__file__))
configFile = "%s/../gspylib/etc/conf/check_list.conf" % dirName
checkList = ['mtu', 'rx', 'tx']
netParameterList = ConfigParam.getConfigFilePara(configFile,
'/sbin/ifconfig',
checkList)
if (('mtu' in list(netParameterList.keys())) and
(netParameterList['mtu'].strip() != '')):
expectMTUValue = netParameterList['mtu'].strip()
# set network card mtu and queue length
networkCardNumList = DefaultValue.CheckNetWorkBonding(serviceIP)
# if len=1, it means that there is no bonding
if (len(networkCardNumList) == 1):
data = GetNetWorkCardInfo(networkCardNumList[0].strip())
if not isSetting:
CheckNetWorkCardInfo(data)
CheckNetWorkCardInterrupt(data)
else:
SetNetWorkCardInfo(networkCardNumList[0].strip(), data)
CheckNetWorkCardInterrupt(data, True)
else:
for networkCardNum in networkCardNumList:
data = GetNetWorkCardInfo(networkCardNum)
if not isSetting:
CheckNetWorkCardInfo(data)
CheckNetWorkCardInterrupt(data)
else:
SetNetWorkCardInfo(networkCardNum, data)
CheckNetWorkCardInterrupt(data, True)
###########################################################################
# meminfo:
###########################################################################
class meminfo:
"""
Class: meminfo
"""
def __init__(self):
"""
function : Init class meminfo
input : NA
output : NA
"""
self.memvalue = 0
self.errormsg = None
class swapinfo:
"""
class: swapinfo
"""
def __init__(self):
"""
function : Init class swapinfo
input : NA
output : NA
"""
self.swapvalue = 0
self.errormsg = None
def collectSwapInfo():
"""
function : Collect Swap Info
input : NA
output : Instantion
"""
data = swapinfo()
cmd = "cat /proc/meminfo | grep SwapTotal"
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception((ErrorCode.GAUSS_505["GAUSS_50502"] % "SwapTotal") +
("The cmd is:%s" % cmd))
try:
listname = output.strip().split(' ')
val = int(listname[len(listname) - 2])
factor = listname[len(listname) - 1]
if factor == 'kB':
data.swapvalue = val * 1024
elif factor == '':
data.swapvalue = val
except Exception as e:
raise Exception(ErrorCode.GAUSS_505["GAUSS_50502"] % "SwapTotal"
+ " Error: \n%s" % str(e))
return data
def collectMemInfo():
"""
function : Collect Memory information
input : NA
output : Instantion
"""
data = meminfo()
cmd = "cat /proc/meminfo | grep MemTotal"
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
raise Exception((ErrorCode.GAUSS_505["GAUSS_50502"] % "MemTotal") +
("The cmd is %s " % cmd))
try:
listname = output.strip().split(' ')
val = int(listname[len(listname) - 2])
factor = listname[len(listname) - 1]
if factor == 'kB':
data.memvalue = val * 1024
elif factor == '':
data.memvalue = val
except Exception as e:
raise Exception(ErrorCode.GAUSS_505["GAUSS_50502"] % "MemTotal"
+ " Error: \n%s" % str(e))
return data
###########################################################################
# firewall:
###########################################################################
class firewall:
"""
class: firewall
"""
def __init__(self):
"""
function : Init class firewall
input : NA
output : NA
"""
self.status = ""
self.distname = ""
self.errormsg = ""
def collectfirewall():
"""
function : Collect firewall
input : NA
output : Instantion
"""
data = firewall()
distname = LinuxDistro.linux_distribution()[0]
if distname in ("redhat", "centos", "euleros", "openEuler"):
data.distname = distname.upper()
if g_Platform.isPlatFormEulerOSOrRHEL7X():
cmd = "systemctl status firewalld.service"
else:
cmd = "service iptables status"
else:
data.distname = "SUSE"
cmd = "SuSEfirewall2 status"
status, output = subprocess.getstatusoutput(cmd)
if status != 0:
data.errormsg = output
return data
if distname in ("redhat", "centos", "euleros", "openEuler"):
if g_Platform.isPlatFormEulerOSOrRHEL7X():
if (output.strip()).find("Active: "
"active (running)") > 0:
data.status = "enabled"
else:
data.status = "disabled"
else:
if (output.strip()).find("Firewall is not"
" running") > 0:
data.status = "disabled"
else:
data.status = "enabled"
else:
if (output.strip()).find("SuSEfirewall2 not"
" active") > 0:
data.status = "disabled"
else:
data.status = "enabled"
return data
###########################################################################
# ntp: time consistence
###########################################################################
class ntp:
"""
class: ntp
"""
def __init__(self):
"""
function : Init class ntp
input : NA
output : NA
"""
self.running = False
self.hosts = set()
self.currenttime = ""
self.errormsg = None
def collectNtpd():
"""
function : Collect Ntpd
input : NA
output : Instantion
"""
data = ntp()
p = subprocess.Popen(["pgrep", "ntpd"], shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = p.communicate()
if data.errormsg:
data.errormsg = "%s\n%s" % (data.errormsg, result[1].strip())
else:
data.errormsg = result[1].strip()
if not p.returncode:
for line in result[0].splitlines():
if line.strip().isdigit():
data.running = True
data.currenttime = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
return data
#############################################################################
# CheckLinuxMounts:
#############################################################################
def CheckLinuxMounts():
"""
function : Check Linux Mounts
input : NA
output : NA
"""
xfs_mounts = list()
expectedOption = "inode64"
data = collectMounts()
for k in list(data.entries.keys()):
entry = data.entries[k]
if entry.type == "xfs":
xfs_mounts.append(entry)
for mnt in xfs_mounts:
if mnt.type != "xfs":
g_logger.log("The device '%s' is not XFS filesystem and"
" is expected to be so." % mnt.partition)
continue
is_find = "failed"
for opt in mnt.options:
if (opt == expectedOption):
is_find = "success"
break
if (is_find == "failed"):
g_logger.log("XFS filesystem on device %s is missing the "
"recommended mount option '%s'." % (mnt.partition,
expectedOption))
#############################################################################
def CheckBlockdev(isSetting=False):
"""
function : Check Block dev
input : Bool
output : NA
"""
expectedReadAhead = "16384"
data = collectBlockdev()
for dev in list(data.ra.keys()):
ra = data.ra[dev]
if int(ra) < int(expectedReadAhead):
if not isSetting:
g_logger.log("On device (%s) 'blockdev readahead' RealValue"
" '%s' ExpectedValue '%s'."
% (dev, ra, expectedReadAhead))
else:
SetBlockdev(expectedReadAhead, dev)
g_logger.log("On device (%s) set 'blockdev readahead' from"
" '%s' to '%s'." % (dev, ra, expectedReadAhead))
def SetBlockdev(expectedReadAhead, devname):
"""
function : Set Block dev
input : String, String
output : NA
"""
g_logger.debug("Setting block dev value.")
initFile = getTHPandOSInitFile()[1]
cmd = "/sbin/blockdev --setra %s %s " % (expectedReadAhead, devname)
cmd += " && echo \"/sbin/blockdev --setra %s %s\" >> %s" \
% (expectedReadAhead, devname, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if status != 0:
g_logger.log("Failed to set block dev '%s'. Error:\n%s"
% (devname, output))
#############################################################################
def CheckIOSchedulers(isSetting=False):
"""
function : Check IO Schedulers
input : Bool
output : NA
"""
# The IO Schedulers in ubuntu system is default value,
# so that it cannot be modified
distname, version = LinuxDistro.linux_distribution()[0:2]
if distname == "debian" and version == "buster/sid":
return
data = collectIOschedulers()
for dev in list(data.devices.keys()):
expectedScheduler = "deadline"
# Vda disk only supports mq-deadline
if (expectedScheduler not in data.allItem[dev]
and "mq-deadline" in data.allItem[dev]):
expectedScheduler = "mq-deadline"
scheduler = data.devices[dev]
if scheduler != expectedScheduler:
if not isSetting:
g_logger.log("On device (%s) 'IO scheduler' RealValue '%s' "
"ExpectedValue '%s'." % (dev, scheduler,
expectedScheduler))
else:
SetIOSchedulers(dev, expectedScheduler)
g_logger.log("On device (%s) set 'IO scheduler' from"
" '%s' to '%s'." % (dev, scheduler,
expectedScheduler))
def SetIOSchedulers(devname, expectedScheduler):
"""
function : Set IO Schedulers
input : String
output : NA
"""
g_logger.debug("Set IO Schedulers value.")
initFile = getTHPandOSInitFile()[1]
cmd = " echo %s >> /sys/block/%s/queue/scheduler" \
% (expectedScheduler, devname)
cmd += " && echo \"echo %s >> /sys/block/%s/queue/scheduler\" >> %s" \
% (expectedScheduler, devname, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.log("Failed to set dev '%s' IO Schedulers. Error:\n%s"
% (devname, output))
def CheckIORequest(isSetting=False):
"""
function : Check IO Request
input : Bool
output : NA
"""
expectedScheduler = "32768"
data = collectIORequest()
if len(data) == 0:
g_logger.log(" WARNING:Not find IO Request file.")
for i in list(data.keys()):
reuqest = data[i]
if int(reuqest) != int(expectedScheduler):
g_logger.log(" WARNING:On device (%s) 'IO Request' "
"RealValue '%s' ExpectedValue '%s'"
% (i, reuqest.strip(), expectedScheduler))
if isSetting:
SetIORequest(expectedScheduler, i)
def SetIORequest(expectedScheduler, dev):
"""
function : Set IO Request
input : String, String
output : NA
"""
g_logger.debug("Set IO Request value!")
initFile = getTHPandOSInitFile()[1]
cmd = " echo %s >> /sys/block/%s/queue/nr_requests" \
% (expectedScheduler, dev)
cmd += " && echo \"echo %s >> /sys/block/%s/queue/nr_requests\" >> %s" \
% (expectedScheduler, dev, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.log(" WARNING:Failed to set dev '%s' IO Request."
" Error:\n%s" % (dev, output))
#############################################################################
def CheckAsyIOrequests(isSetting=False):
"""
function : Check Asy IO requests
input : Bool
output : NA
"""
expectedScheduler = "104857600"
cnnum = 0
dnnum = 0
instancenum = 0
hostname = NetUtil.GetHostIpOrName()
dbnode = g_clusterInfo.getDbNodeByName(hostname)
for i in dbnode.coordinators:
if i.datadir != "":
cnnum += 1
for i in dbnode.datanodes:
if (i.instanceType == MASTER_INSTANCE):
dnnum += 1
if (i.instanceType == STANDBY_INSTANCE):
dnnum += 1
instancenum = (dnnum + cnnum) * 1048576
data = collectAsynchronousIORequest()
if len(data) == 0:
g_logger.log(" WARNING:Not find AsynchronousIORequest file.")
if int(instancenum) > int(expectedScheduler):
SetAsyIOrequests(instancenum)
else:
SetAsyIOrequests(expectedScheduler)
else:
for i in iter(data):
request = i
if (int(request) < int(instancenum) and
int(expectedScheduler) < int(instancenum)):
if isSetting:
SetAsyIOrequests(instancenum)
elif (int(request) < int(expectedScheduler) and
int(instancenum) < int(expectedScheduler)):
if isSetting:
SetAsyIOrequests(expectedScheduler)
elif (int(expectedScheduler) < int(request) and
int(instancenum) < int(request)):
if isSetting:
SetAsyIOrequests(request)
def SetAsyIOrequests(expectedScheduler):
"""
function : Set Asy IO requests
input : String
output : NA
"""
g_logger.debug("Set Asynchronous IO Maximum requests value!")
initFile = getTHPandOSInitFile()[1]
cmd = " echo %s >> /proc/sys/fs/aio-max-nr" % expectedScheduler
cmd += " && echo \"echo %s >> /proc/sys/fs/aio-max-nr\" >> %s" \
% (expectedScheduler, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.log("Failed to set Asynchronous IO Maximum Request."
" Error:\n%s" % (output))
#############################################################################
def CheckClogicalBlock(isSetting=True):
"""
function : Check Clogical Block
input : Bool
output : NA
"""
expectedScheduler = "512"
data = collectLogicalBlock()
if len(data) == 0:
g_logger.log(" Warning:Not find clogical block file,"
"please check it.")
for i in list(data.keys()):
reuqest = data[i]
if int(reuqest) < int(expectedScheduler):
g_logger.log(" Warning:On device (%s) ' ClogicalBlock"
" Request' RealValue '%d' ExpectedValue '%d'"
% (i, int(reuqest), int(expectedScheduler)))
if isSetting:
SetClogicalBlock(expectedScheduler, i)
def SetClogicalBlock(expectedScheduler, dev):
"""
function : Set Clogical Block
input : String, String
output : NA
"""
g_logger.debug("Set logicalBlock value!")
initFile = getTHPandOSInitFile()[1]
cmd = " echo %s >> /sys/block/%s/queue/logical_block_size" \
% (expectedScheduler, dev)
cmd += " && echo \"echo %s >> /sys/block/%s/queue/logical_block_size\"" \
" >> %s" % (expectedScheduler, dev, initFile)
(status, output) = subprocess.getstatusoutput(cmd)
if (status != 0):
g_logger.error("Failed to set dev '%s' logicalBlock by excuting"
" command:\n%s\nOutput:\n%s" % (dev, cmd, str(output)))
#############################################################################
def CheckPlatformInfo():
"""
function : Check Platform Info
input : NA
output : NA
"""
data = collectplatformInfo()
if (data.distname == "SuSE"):
if (data.version == "11" and data.patchlevel == "1"):
mixedType = "%s%sSP%s" % (data.distname, data.version,
data.patchlevel)
platformStr = "%s_%s_SP%s_%s" % (data.distname, data.version,
data.patchlevel, data.bits)
elif (data.version == "11" and data.patchlevel in ("2", "3", "4")):
mixedType = "%s%s" % (data.distname, data.version)
platformStr = "%s_%s_SP%s_%s" % (data.distname, data.version,
data.patchlevel, data.bits)
elif (data.version == "12" and
data.patchlevel in ("0", "1", "2", "3")):
mixedType = "%s%s" % (data.distname, data.version)
platformStr = "%s_%s_SP%s_%s" % (data.distname, data.version,
data.patchlevel, data.bits)
else:
platformStr = "%s_%s_SP%s_%s" % (data.distname, data.version,
data.patchlevel, data.bits)
g_logger.log("False %s %s" % (data.distname, platformStr))
return
elif (data.distname in ("redhat", "centos", "asianux")):
if (data.version in ("6.4", "6.5", "6.6", "6.7", "6.8", "6.9")):
mixedType = "%s6" % data.distname
platformStr = "%s_%s_%s" % (data.distname,
data.version, data.bits)
elif (data.version[0:3]
in ("7.0", "7.1", "7.2", "7.3", "7.4", "7.5", "7.6", "7.7",
"7.8", "7.9")):
mixedType = "%s7" % data.distname
platformStr = "%s_%s_%s" % (data.distname, data.version,
data.bits)
else:
platformStr = "%s_%s_%s" % (data.distname, data.version,
data.bits)
g_logger.log("False %s %s" % (data.distname, platformStr))
return
elif (data.distname == "euleros" or data.distname == "openEuler" or data.distname == "kylin"):
mixedType = "%s" % data.distname
platformStr = "%s_%s_%s" % (data.distname, data.version, data.bits)
elif (data.distname == "debian" or data.version == "buster/sid"):
mixedType = "%s" % data.distname
platformStr = "%s_%s_%s" % (data.distname, data.version, data.bits)
else:
platformStr = "%s_%s_%s" % (data.distname, data.version, data.bits)
g_logger.log("False unknown %s" % platformStr)
return
g_logger.log("True %s %s" % (mixedType, platformStr))
return
#############################################################################
def CheckUname():
"""
function : Check Uname
input : NA
output : NA
"""
data = collectUname()
g_logger.log("KernelVersion %s" % data.output)
#############################################################################
def CheckUnicode():
""""
function : Check Unicode
input : NA
output : NA
"""
data = collectUnicode()
g_logger.log("Unicode %s" % data.output)
#############################################################################
def CheckTimeZone():
"""
function : Check Time Zone
input : NA
output : NA
"""
data = collectTimeZone()
g_logger.log("TimeZone %s" % data.output)
#############################################################################
def CheckNtp():
"""
function : Check Ntp
input : NA
output : NA
"""
data = collectNtpd()
if not data.running:
g_logger.log("False, %s" % data.currenttime)
else:
g_logger.log("True, %s" % data.currenttime)
#############################################################################
def CheckTHPServer():
"""
function : Check THP Server
input : NA
output : NA
"""
expectedValues = "disabled"
data = collectTHPServer()
if data.status != expectedValues:
g_logger.log("The THP service status RealValue '%s'"
" ExpectedValue '%s'." % (data.status, expectedValues))
#############################################################################
def CheckFirewallServer():
"""
function : Check Firewall Server
input : NA
output : NA
"""
expectedValues = "disabled"
data = collectfirewall()
if data.status == "":
return
elif (data.status != expectedValues):
g_logger.log("The firewall service status RealVaue '%s'"
" ExpectedValue '%s'" % (data.status, expectedValues))
#############################################################################
def CheckMemInfo():
"""
function : Check Mem Info
input : NA
output : NA
"""
memdata = collectMemInfo()
swapdata = collectSwapInfo()
if (swapdata.swapvalue > memdata.memvalue):
g_logger.log("SwapMemory %s TotalMemory %s" % (swapdata.swapvalue,
memdata.memvalue))
#############################################################################
class CmdOptions():
"""
Class: CmdOptions
"""
def __init__(self):
"""
function : Init class CmdOptions
input : NA
output : NA
"""
self.action = ""
self.user = ""
self.extrachecklist = []
self.logFile = ""
self.confFile = ""
self.mtuValue = ""
self.hostname = ""
self.mppdbfile = ""
#########################################################
# Init global log
#########################################################
def initGlobals():
"""
function : init Globals
input : NA
output : NA
"""
global g_logger
global g_clusterInfo
g_logger = GaussLog(g_opts.logFile, "LocalCheckOS")
g_clusterInfo = dbClusterInfo()
if (g_opts.confFile != "" and g_opts.confFile is not None):
g_clusterInfo.initFromXml(g_opts.confFile)
def usage():
"""
Usage:
python3 --help | -?
python3 LocalCheckOS -t action [-l logfile] [-X xmlfile] [-V]
Common options:
-t The type of action.
-s the path of MPPDB file
-l --log-file=logfile The path of log file.
-? --help Show this help screen.
-X --xmlfile = xmlfile Cluster config file
--ntp-server NTP server node's IP.
-V --version
"""
print(usage.__doc__)
def parseCommandLine():
"""
function : Parse command line and save to global variables
input : NA
output : NA
"""
try:
opts, args = getopt.getopt(sys.argv[1:], "t:s:l:X:V?",
["help", "log-file=", "xmlfile=",
"MTUvalue=", "hostname=",
"ntp-server=", "version"])
except Exception as e:
usage()
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
% str(e))
if (len(args) > 0):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
% str(args[0]))
global g_opts
g_opts = CmdOptions()
for (key, value) in opts:
if (key == "-?" or key == "--help"):
usage()
sys.exit(0)
elif (key == "-V" or key == "--version"):
print("%s %s" % (sys.argv[0].split("/")[-1],
VersionInfo.COMMON_VERSION))
sys.exit(0)
elif (key == "-t"):
g_opts.action = value
elif (key == "-s"):
g_opts.mppdbfile = value
elif (key == "-X" or key == "--xmlfile"):
g_opts.confFile = value
elif (key == "-l" or key == "--log-file"):
g_opts.logFile = os.path.realpath(value)
elif (key == "--MTUvalue"):
g_opts.mtuValue = value
elif (key == "--hostname"):
g_opts.hostname = value
Parameter.checkParaVaild(key, value)
def checkParameter():
"""
function : check parameter
input : NA
output : NA
"""
if (g_opts.action == ""):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"] % 't' + '.')
if (g_opts.action != ACTION_CHECK_OS_VERSION
and g_opts.action != ACTION_CHECK_KERNEL_VERSION
and g_opts.action != ACTION_CHECK_UNICODE
and g_opts.action != ACTION_CHECK_TIMEZONE
and g_opts.action != ACTION_CHECK_DISK_CONFIGURE
and g_opts.action != ACTION_CHECK_BLOCKDEV_CONFIGURE
and g_opts.action != ACTION_CHECK_IO_CONFIGURE
and g_opts.action != ACTION_CHECK_IO_REQUEST
and g_opts.action != ACTION_CHECK_ASYNCHRONOUS_IO_REQUEST
and g_opts.action != ACTION_CHECK_LOGICAL_BLOCK
and g_opts.action != ACTION_CHECK_NETWORK_CONFIGURE
and g_opts.action != ACTION_CHECK_NETWORK_BOND_MODE
and g_opts.action != ACTION_CHECK_SWAP_MEMORY_CONFIGURE
and g_opts.action != ACTION_CHECK_TIME_CONSISTENCY
and g_opts.action != ACTION_CHECK_FIREWALL_SERVICE
and g_opts.action != ACTION_CHECK_THP_SERVICE
and g_opts.action != ACTION_SET_BLOCKDEV_CONFIGURE
and g_opts.action != ACTION_SET_NETWORK_CONFIGURE
and g_opts.action != ACTION_SET_IO_CONFIGURE
and g_opts.action != ACTION_SET_REMOVEIPC_VALUE
and g_opts.action != ACTION_SET_SESSION_PROCESS
and g_opts.action != ACTION_SET_THP_SERVICE
and g_opts.action != ACTION_SET_LOGICAL_BLOCK
and g_opts.action != ACTION_SET_IO_REQUEST
and g_opts.action != ACTION_SET_ASYNCHRONOUS_IO_REQUEST):
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50004"] % "t")
if (g_opts.logFile == ""):
dirName = os.path.dirname(os.path.realpath(__file__))
g_opts.logFile = os.path.join(dirName, ClusterConstants.LOCAL_LOG_FILE)
def getLocalIPAddr():
"""
function: get local ip
input : NA
output: Ips
"""
Ips = []
if g_opts.confFile == "":
Ips.append(DefaultValue.getIpByHostName())
return Ips
for node in g_clusterInfo.dbNodes:
if (node.name == NetUtil.GetHostIpOrName()):
Ips.append(node.backIps[0])
return Ips
def doLocalCheck():
"""
function: check OS item on local node
input : NA
output: NA
"""
global netWorkBondInfo
netWorkBondInfo = netWork()
function_dict = {ACTION_CHECK_OS_VERSION: CheckPlatformInfo,
ACTION_CHECK_KERNEL_VERSION: CheckUname,
ACTION_CHECK_UNICODE: CheckUnicode,
ACTION_CHECK_TIMEZONE: CheckTimeZone,
ACTION_CHECK_DISK_CONFIGURE: CheckLinuxMounts,
ACTION_CHECK_SWAP_MEMORY_CONFIGURE: CheckMemInfo,
ACTION_CHECK_TIME_CONSISTENCY: CheckNtp,
ACTION_CHECK_FIREWALL_SERVICE: CheckFirewallServer,
ACTION_SET_REMOVEIPC_VALUE: disRemoveIPC,
ACTION_SET_SESSION_PROCESS: CheckSessionProcess,
ACTION_CHECK_THP_SERVICE: CheckTHPServer,
ACTION_SET_THP_SERVICE: disTHPServer}
function_keys = list(function_dict.keys())
function_dict_false = {ACTION_CHECK_BLOCKDEV_CONFIGURE: CheckBlockdev,
ACTION_CHECK_IO_CONFIGURE: CheckIOSchedulers,
ACTION_CHECK_IO_REQUEST: CheckIORequest,
ACTION_CHECK_LOGICAL_BLOCK: CheckClogicalBlock}
function_keys_false = list(function_dict_false.keys())
function_dict_true = {ACTION_SET_BLOCKDEV_CONFIGURE: CheckBlockdev,
ACTION_SET_IO_CONFIGURE: CheckIOSchedulers,
ACTION_SET_IO_REQUEST: CheckIORequest,
ACTION_SET_LOGICAL_BLOCK: CheckClogicalBlock}
function_keys_true = list(function_dict_true.keys())
if (g_opts.action in function_keys):
function_dict[g_opts.action]()
elif (g_opts.action in function_keys_false):
function_dict_false[g_opts.action](False)
elif (g_opts.action in function_keys_true):
function_dict_true[g_opts.action](True)
elif (g_opts.action == ACTION_CHECK_ASYNCHRONOUS_IO_REQUEST):
if (g_opts.confFile != "" and g_opts.confFile is not None):
CheckAsyIOrequests(False)
elif (g_opts.action == ACTION_CHECK_NETWORK_CONFIGURE):
for localAddres in nodeIps:
CheckNetWorkCardPara(localAddres, False)
elif (g_opts.action == ACTION_CHECK_NETWORK_BOND_MODE):
CheckNetWorkBonding(DefaultValue.getIpByHostName(), True)
elif (g_opts.action == ACTION_SET_NETWORK_CONFIGURE):
for localAddres in nodeIps:
CheckNetWorkCardPara(localAddres, True)
elif (g_opts.action == ACTION_SET_ASYNCHRONOUS_IO_REQUEST):
if (g_opts.confFile != "" and g_opts.confFile is not None):
CheckAsyIOrequests(True)
else:
g_logger.logExit(ErrorCode.GAUSS_500["GAUSS_50004"] % 't' +
" Value: %s." % g_opts.action)
if __name__ == '__main__':
"""
main function
"""
try:
parseCommandLine()
checkParameter()
initGlobals()
except Exception as e:
GaussLog.exitWithError(str(e))
try:
nodeIps = []
nodeIps = getLocalIPAddr()
doLocalCheck()
g_logger.closeLog()
except Exception as e:
g_logger.logExit(str(e))
sys.exit(0)