From fb523d6c78880f14f65fc660a9fdbf868496f4e7 Mon Sep 17 00:00:00 2001 From: jinsaihang Date: Fri, 24 Jan 2025 16:28:37 +0800 Subject: [PATCH] adapt get_alarm for kenel 5.10 Signed-off-by: jinsaihang --- adapt_5.10_kenel_for_syssentry.patch | 702 +++++++++++++++++++++++++++ sysSentry.spec | 9 +- 2 files changed, 710 insertions(+), 1 deletion(-) create mode 100644 adapt_5.10_kenel_for_syssentry.patch diff --git a/adapt_5.10_kenel_for_syssentry.patch b/adapt_5.10_kenel_for_syssentry.patch new file mode 100644 index 0000000..0ffb2a9 --- /dev/null +++ b/adapt_5.10_kenel_for_syssentry.patch @@ -0,0 +1,702 @@ +From 13bf2a16a1f61cf68cde88d5928f7ceae5396a28 Mon Sep 17 00:00:00 2001 +From: jinsaihang +Date: Fri, 24 Jan 2025 16:24:43 +0800 +Subject: [PATCH] adapt file + +--- + config/xalarm.conf | 3 + + src/python/syssentry/alarm.py | 209 ++++++++++++++++++++++++++ + src/python/syssentry/callbacks.py | 17 +++ + src/python/syssentry/global_values.py | 4 + + src/python/syssentry/load_mods.py | 16 ++ + src/python/syssentry/sentryctl | 25 ++- + src/python/syssentry/syssentry.py | 14 +- + src/python/syssentry/task_map.py | 5 +- + src/python/xalarm/register_xalarm.py | 4 +- + src/python/xalarm/xalarm_api.py | 6 +- + src/python/xalarm/xalarm_config.py | 33 +++- + src/python/xalarm/xalarm_daemon.py | 7 +- + src/python/xalarm/xalarm_transfer.py | 8 +- + 13 files changed, 332 insertions(+), 19 deletions(-) + create mode 100644 src/python/syssentry/alarm.py + +diff --git a/config/xalarm.conf b/config/xalarm.conf +index 14c6d39..323d2dd 100644 +--- a/config/xalarm.conf ++++ b/config/xalarm.conf +@@ -1,2 +1,5 @@ + [filter] + id_mask = 1001-1128 ++ ++[log] ++level=info +diff --git a/src/python/syssentry/alarm.py b/src/python/syssentry/alarm.py +new file mode 100644 +index 0000000..e5cc313 +--- /dev/null ++++ b/src/python/syssentry/alarm.py +@@ -0,0 +1,209 @@ ++# coding: utf-8 ++# Copyright (c) 2024 Huawei Technologies Co., Ltd. ++# sysSentry is licensed under the 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. ++ ++""" ++use for report alarm ++""" ++import threading ++from typing import Dict, List ++from datetime import datetime ++import time ++import logging ++import json ++import sys ++ ++from xalarm.register_xalarm import xalarm_register,xalarm_getid,xalarm_getlevel,xalarm_gettype,xalarm_gettime,xalarm_getdesc ++from xalarm.xalarm_api import Xalarm ++ ++from .global_values import InspectTask ++from .task_map import TasksMap ++ ++# 告警ID映射字典,key为插件名,value为告警ID(类型为数字) ++task_alarm_id_dict: Dict[str, int] = {} ++ ++# 告警老化时间字典,key为告警ID,value为老化时间(类型为数字,单位为秒) ++alarm_id_clear_time_dict: Dict[int, int] = {} ++ ++# 告警事件列表,key为告警ID,value为告警ID对应的告警事件列表(类型为list) ++alarm_list_dict: Dict[int, List[Xalarm]] = {} ++# 告警事件列表锁 ++alarm_list_lock = threading.Lock() ++ ++id_filter = [] ++id_base = 1001 ++clientId = -1 ++ ++MILLISECONDS_UNIT_SECONDS = 1000 ++MAX_NUM_OF_ALARM_ID = 128 ++MIN_ALARM_ID = 1001 ++MAX_ALARM_ID = (MIN_ALARM_ID + MAX_NUM_OF_ALARM_ID - 1) ++ ++def update_alarm_list(alarm_info: Xalarm): ++ alarm_id = xalarm_getid(alarm_info) ++ if alarm_id < MIN_ALARM_ID or alarm_id > MAX_ALARM_ID: ++ logging.warning(f"Invalid alarm_id {alarm_id}") ++ return ++ timestamp = xalarm_gettime(alarm_info) ++ if not timestamp: ++ logging.error("Retrieve timestamp failed") ++ return ++ alarm_list_lock.acquire() ++ try: ++ # new alarm is inserted into list head ++ if alarm_id not in alarm_list_dict: ++ logging.warning(f"update_alarm_list: alarm_id {alarm_id} not found in alarm_list_dict") ++ return ++ alarm_list = alarm_list_dict[alarm_id] ++ ++ alarm_list.insert(0, alarm_info) ++ # clear alarm_info older than clear time threshold ++ clear_index = -1 ++ clear_time = alarm_id_clear_time_dict[alarm_id] ++ for i in range(len(alarm_list)): ++ if (timestamp - xalarm_gettime(alarm_list[i])) / MILLISECONDS_UNIT_SECONDS > clear_time: ++ clear_index = i ++ break ++ if clear_index >= 0: ++ alarm_list_dict[alarm_id] = alarm_list[:clear_index] ++ finally: ++ alarm_list_lock.release() ++ ++def validate_alarm_id(alarm_id): ++ if alarm_id is None: ++ return False ++ try: ++ alarm_id = int(alarm_id) ++ if MIN_ALARM_ID <= alarm_id <= MAX_ALARM_ID: ++ return True ++ else: ++ return False ++ except ValueError: ++ return False ++ ++def validate_alarm_clear_time(alarm_clear_time): ++ try: ++ alarm_clear_time = int(alarm_clear_time) ++ if alarm_clear_time > 0 and alarm_clear_time <= sys.maxsize: ++ return True ++ else: ++ return False ++ except ValueError: ++ return False ++ ++def alarm_register(): ++ logging.debug(f"alarm_register: enter") ++ # 初始化告警ID映射字典、告警老化时间字典 ++ for task_type in TasksMap.tasks_dict: ++ for task_name in TasksMap.tasks_dict[task_type]: ++ task = TasksMap.tasks_dict[task_type][task_name] ++ if not validate_alarm_id(task.alarm_id): ++ logging.warning(f"Invalid alarm_id {task.alarm_id}: ignore {task_name} alarm") ++ continue ++ if not validate_alarm_clear_time(task.alarm_clear_time): ++ logging.warning(f"Invalid alarm_clear_time {task.alarm_clear_time}: ignore {task_name} alarm") ++ continue ++ task.alarm_id = int(task.alarm_id) ++ task.alarm_clear_time = int(task.alarm_clear_time) ++ alarm_id = task.alarm_id ++ alarm_clear_time = task.alarm_clear_time ++ ++ alarm_list_dict[alarm_id] = [] ++ task_alarm_id_dict[task_name] = alarm_id ++ if alarm_id not in alarm_id_clear_time_dict: ++ alarm_id_clear_time_dict[alarm_id] = alarm_clear_time ++ else: ++ alarm_id_clear_time_dict[alarm_id] = max(alarm_clear_time, alarm_id_clear_time_dict[alarm_id]) ++ logging.info(f"alarm_register: {task_name} is registered") ++ # 注册告警回调 ++ id_filter = [True] * 128 ++ clientId = xalarm_register(update_alarm_list, id_filter) ++ if clientId < 0: ++ logging.info(f'register xalarm: failed') ++ return clientId ++ logging.info('register xalarm: success') ++ return clientId ++ ++def get_alarm_result(task_name: str, time_range: int, detailed: bool) -> List[Dict]: ++ alarm_list_lock.acquire() ++ try: ++ if task_name not in task_alarm_id_dict: ++ logging.debug("task_name does not exist") ++ return [] ++ alarm_id = task_alarm_id_dict[task_name] ++ clear_time = alarm_id_clear_time_dict[alarm_id] ++ if alarm_id not in alarm_list_dict: ++ logging.debug("alarm_id does not exist") ++ return [] ++ alarm_list = alarm_list_dict[alarm_id] ++ logging.debug(f"get_alarm_result: alarm_list of {alarm_id} has {len(alarm_list)} elements") ++ # clear alarm_info older than clear time threshold ++ stop_index = -1 ++ timestamp = datetime.now().timestamp() ++ for i in range(len(alarm_list)): ++ logging.debug(f"timestamp, alarm_list[{i}].timestamp: {timestamp}, {xalarm_gettime(alarm_list[i])}") ++ if timestamp - (xalarm_gettime(alarm_list[i])) / MILLISECONDS_UNIT_SECONDS > time_range: ++ stop_index = i ++ break ++ if timestamp - (xalarm_gettime(alarm_list[i])) / MILLISECONDS_UNIT_SECONDS > clear_time: ++ stop_index = i ++ break ++ if stop_index >= 0: ++ alarm_list = alarm_list[:stop_index] ++ logging.debug(f"get_alarm_result: final alarm_list of {alarm_id} has {len(alarm_list)} elements") ++ ++ def xalarm_to_dict(alarm_info: Xalarm) -> dict: ++ timestamp = alarm_info.timetamp.tv_sec + alarm_info.timetamp.tv_usec / 1000000 ++ dt_object = datetime.fromtimestamp(int(timestamp)) ++ return { ++ 'alarm_id': xalarm_getid(alarm_info), ++ 'alarm_type': xalarm_gettype(alarm_info), ++ 'alarm_level': xalarm_getlevel(alarm_info), ++ 'timestamp': dt_object.strftime("%Y-%m-%d %H:%M:%S"), ++ 'msg1': xalarm_getdesc(alarm_info) ++ } ++ ++ alarm_list = [xalarm_to_dict(alarm) for alarm in alarm_list] ++ ++ # keep detail ++ for alarm in alarm_list: ++ alarm_info = alarm['msg1'] ++ alarm_info = json.loads(alarm_info) ++ if not detailed: ++ if 'details' in alarm_info: ++ alarm_info.pop('details', None) ++ alarm.pop('msg1', None) ++ ++ # dump each {key,value} of details in one line ++ if 'details' in alarm_info and isinstance(alarm_info['details'], dict): ++ for key in alarm_info['details']: ++ alarm_info['details'][key] = str(alarm_info['details'][key]) ++ ++ alarm['alarm_info'] = alarm_info ++ alarm_list = [alarm for alarm in alarm_list if 'alarm_source' in alarm['alarm_info'] and alarm['alarm_info']['alarm_source'] == task_name] ++ ++ alarm_level_mapping = { ++ 1: 'MINOR_ALM', ++ 2: 'MAJOR_ALM', ++ 3: 'CRITICAL_ALM' ++ } ++ ++ alarm_type_mapping = { ++ 1: 'ALARM_TYPE_OCCUR', ++ 2: 'ALARM_TYPE_RECOVER' ++ } ++ ++ for alarm in alarm_list: ++ alarm['alarm_level'] = alarm_level_mapping.get(alarm['alarm_level'], 'UNKNOWN_LEVEL') ++ alarm['alarm_type'] = alarm_type_mapping.get(alarm['alarm_type'], 'UNKNOWN_TYPE') ++ return alarm_list ++ ++ finally: ++ alarm_list_lock.release() +diff --git a/src/python/syssentry/callbacks.py b/src/python/syssentry/callbacks.py +index d0d0719..d2dff24 100644 +--- a/src/python/syssentry/callbacks.py ++++ b/src/python/syssentry/callbacks.py +@@ -18,6 +18,7 @@ import logging + + from .task_map import TasksMap, ONESHOT_TYPE, PERIOD_TYPE + from .mod_status import EXITED_STATUS, RUNNING_STATUS, WAITING_STATUS, set_runtime_status ++from .alarm import get_alarm_result + + + def task_get_status(mod_name): +@@ -41,6 +42,22 @@ def task_get_result(mod_name): + + return "success", task.get_result() + ++def task_get_alarm(data): ++ """get alarm by mod name""" ++ task_name = data['task_name'] ++ time_range = data['time_range'] ++ try: ++ detailed = data['detailed'] ++ except KeyError: ++ logging.debug("Key 'detailed' does not exist in the dictionary") ++ detailed = None ++ task = TasksMap.get_task_by_name(task_name) ++ if not task: ++ return "failed", f"cannot find task by name {task_name}" ++ if not task.load_enabled: ++ return "failed", f"mod {task_name} is not enabled" ++ ++ return "success", get_alarm_result(task_name, time_range, detailed) + + def task_stop(mod_name): + """stop by mod name""" +diff --git a/src/python/syssentry/global_values.py b/src/python/syssentry/global_values.py +index 483d544..b123b2d 100644 +--- a/src/python/syssentry/global_values.py ++++ b/src/python/syssentry/global_values.py +@@ -27,6 +27,7 @@ CTL_SOCKET_PATH = "/var/run/sysSentry/control.sock" + SYSSENTRY_CONF_PATH = "/etc/sysSentry" + INSPECT_CONF_PATH = "/etc/sysSentry/inspect.conf" + TASK_LOG_DIR = "/var/log/sysSentry" ++DEFAULT_ALARM_CLEAR_TIME = 15 + + SENTRY_RUN_DIR_PERM = 0o750 + +@@ -76,6 +77,9 @@ class InspectTask: + self.env_file = "" + # start mode + self.conflict = "up" ++ # alarm id ++ self.alarm_id = -1 ++ self.alarm_clear_time = DEFAULT_ALARM_CLEAR_TIME + + def start(self): + """ +diff --git a/src/python/syssentry/load_mods.py b/src/python/syssentry/load_mods.py +index 5be5540..ac15380 100644 +--- a/src/python/syssentry/load_mods.py ++++ b/src/python/syssentry/load_mods.py +@@ -24,6 +24,7 @@ from .task_map import TasksMap, ONESHOT_TYPE, PERIOD_TYPE + from .cron_process import PeriodTask + from .mod_status import set_task_status + ++from xalarm.register_xalarm import MIN_ALARM_ID, MAX_ALARM_ID + ONESHOT_CONF = 'oneshot' + PERIOD_CONF = 'period' + +@@ -41,6 +42,8 @@ CONF_TASK_RESTART = 'task_restart' + CONF_ONSTART = 'onstart' + CONF_ENV_FILE = 'env_file' + CONF_CONFLICT = 'conflict' ++CONF_ALARM_ID = 'alarm_id' ++CONF_ALARM_CLEAR_TIME = 'alarm_clear_time' + + MOD_FILE_SUFFIX = '.mod' + MOD_SUFFIX_LEN = 4 +@@ -194,6 +197,18 @@ def parse_mod_conf(mod_name, mod_conf): + task.heartbeat_interval = heartbeat_interval + task.load_enabled = is_enabled + ++ try: ++ task.alarm_id = mod_conf.get(CONF_TASK, CONF_ALARM_ID) ++ except configparser.NoOptionError: ++ task.alarm_id = None ++ logging.warning(f"{mod_name} alarm_id not set, alarm_id is None") ++ ++ if task.alarm_id is not None: ++ try: ++ task.alarm_clear_time = mod_conf.get(CONF_TASK, CONF_ALARM_CLEAR_TIME) ++ except configparser.NoOptionError: ++ logging.warning(f"{mod_name} not set alarm_clear_time, use 15s as default") ++ + if CONF_ONSTART in mod_conf.options(CONF_TASK): + is_onstart = (mod_conf.get(CONF_TASK, CONF_ONSTART) == 'yes') + if task_type == PERIOD_CONF: +@@ -328,3 +343,4 @@ def reload_single_mod(mod_name): + res, ret = reload_mod_by_name(mod_name) + + return res, ret ++ +diff --git a/src/python/syssentry/sentryctl b/src/python/syssentry/sentryctl +index e94491f..c2e3cef 100644 +--- a/src/python/syssentry/sentryctl ++++ b/src/python/syssentry/sentryctl +@@ -25,6 +25,8 @@ MAX_PARAM_LENGTH = 256 + + RESULT_MSG_DATA_LEN = 4 + CTL_MSG_LEN_LEN = 3 ++ALARM_MSG_DATA_LEN = 6 ++DEFAULT_ALARM_TIME_RANGE = 10 + + def status_output_format(res_data): + """format output""" +@@ -57,6 +59,8 @@ def res_output_handle(res_struct, req_type): + status_output_format(res_struct['data']) + elif req_type == 'get_result': + result_output_format(res_struct['data']) ++ elif req_type == 'get_alarm': ++ result_output_format(res_struct['data']) + elif res_struct['ret'] == "failed": + print(res_struct['data']) + +@@ -75,6 +79,7 @@ def client_send_and_recv(request_data, data_str_len): + print("sentryctl: client creat socket error") + return None + ++ # connect to syssentry + try: + client_socket.connect(CTL_SOCKET_PATH) + except OSError: +@@ -82,6 +87,7 @@ def client_send_and_recv(request_data, data_str_len): + print("sentryctl: client connect error") + return None + ++ # msg: CTL{len}{data} + req_data_len = len(request_data) + request_msg = "CTL" + str(req_data_len).zfill(3) + request_data + +@@ -94,8 +100,8 @@ def client_send_and_recv(request_data, data_str_len): + print("sentryctl: client communicate error") + return None + ++ # res: RES{len}{data} + res_magic = res_data[:3] +- + if res_magic != "RES": + print("res msg format error") + return None +@@ -128,6 +134,10 @@ if __name__ == '__main__': + parser_status.add_argument('task_name') + parser_get_result = subparsers.add_parser('get_result', help='get task result') + parser_get_result.add_argument('task_name') ++ parser_get_alarm = subparsers.add_parser('get_alarm', help='get task alarm') ++ parser_get_alarm.add_argument('task_name') ++ parser_get_alarm.add_argument('-s', '--time_range', type=int, default=DEFAULT_ALARM_TIME_RANGE, help='Specified time range') ++ parser_get_alarm.add_argument('-d', '--detailed', action='store_true', help='Print Detailed Information') + parser_list = subparsers.add_parser('list', help='show all loaded task mod') + + client_args = parser.parse_args() +@@ -142,6 +152,17 @@ if __name__ == '__main__': + req_msg_struct = {"type": "get_status", "data": client_args.task_name} + elif client_args.cmd_type == 'get_result': + req_msg_struct = {"type": "get_result", "data": client_args.task_name} ++ elif client_args.cmd_type == 'get_alarm': ++ if not isinstance(client_args.time_range, int) or client_args.time_range <= 0: ++ print(f"time_range is not a positive integer: {client_args.time_range}") ++ req_msg_struct = { ++ "type": "get_alarm", ++ "data": { ++ 'task_name': client_args.task_name, ++ 'time_range': client_args.time_range, ++ 'detailed': client_args.detailed, ++ } ++ } + elif client_args.cmd_type == 'reload': + req_msg_struct = {"type": "reload", "data": client_args.task_name} + else: +@@ -155,6 +176,8 @@ if __name__ == '__main__': + request_message = json.dumps(req_msg_struct) + if client_args.cmd_type == 'get_result': + result_message = client_send_and_recv(request_message, RESULT_MSG_DATA_LEN) ++ elif client_args.cmd_type == 'get_alarm': ++ result_message = client_send_and_recv(request_message, ALARM_MSG_DATA_LEN) + else: + result_message = client_send_and_recv(request_message, CTL_MSG_LEN_LEN) + if not result_message: +diff --git a/src/python/syssentry/syssentry.py b/src/python/syssentry/syssentry.py +index 0956e1e..c87256d 100644 +--- a/src/python/syssentry/syssentry.py ++++ b/src/python/syssentry/syssentry.py +@@ -28,7 +28,7 @@ from .sentry_config import SentryConfig, get_log_level + from .task_map import TasksMap + from .global_values import SENTRY_RUN_DIR, CTL_SOCKET_PATH, SENTRY_RUN_DIR_PERM + from .cron_process import period_tasks_handle +-from .callbacks import mod_list_show, task_start, task_get_status, task_stop, task_get_result ++from .callbacks import mod_list_show, task_start, task_get_status, task_stop, task_get_result, task_get_alarm + from .mod_status import get_task_by_pid, set_runtime_status + from .load_mods import load_tasks, reload_single_mod + from .heartbeat import (heartbeat_timeout_chk, heartbeat_fd_create, +@@ -36,7 +36,11 @@ from .heartbeat import (heartbeat_timeout_chk, heartbeat_fd_create, + from .result import RESULT_MSG_HEAD_LEN, RESULT_MSG_MAGIC_LEN, RESULT_MAGIC + from .result import RESULT_LEVEL_ERR_MSG_DICT, ResultLevel + from .utils import get_current_time_string ++from .alarm import alarm_register + ++from xalarm.register_xalarm import xalarm_unregister ++ ++clientId = -1 + + CPU_EXIST = True + try: +@@ -58,6 +62,7 @@ CTL_MSG_MAGIC_LEN = 3 + CTL_MSG_LEN_LEN = 3 + CTL_MAGIC = "CTL" + RES_MAGIC = "RES" ++ALARM_MSG_DATA_LEN = 6 + + CTL_LISTEN_QUEUE_LEN = 5 + SERVER_EPOLL_TIMEOUT = 0.3 +@@ -68,6 +73,7 @@ type_func = { + 'stop': task_stop, + 'get_status': task_get_status, + 'get_result': task_get_result, ++ 'get_alarm': task_get_alarm, + 'reload': reload_single_mod + } + +@@ -260,6 +266,8 @@ def server_recv(server_socket: socket.socket): + res_head = RES_MAGIC + if cmd_type == "get_result": + res_data_len = str(len(res_data)).zfill(RESULT_MSG_HEAD_LEN - RESULT_MSG_MAGIC_LEN) ++ elif cmd_type == "get_alarm": ++ res_data_len = str(len(res_data)).zfill(ALARM_MSG_DATA_LEN) + else: + res_data_len = str(len(res_data)).zfill(CTL_MSG_MAGIC_LEN) + res_head += res_data_len +@@ -643,9 +651,13 @@ def main(): + _ = SentryConfig.init_param() + TasksMap.init_task_map() + load_tasks() ++ clientId = alarm_register() + main_loop() + + except Exception: + logging.error('%s', traceback.format_exc()) + finally: ++ if clientId != -1: ++ xalarm_unregister(clientId) + release_pidfile() ++ +diff --git a/src/python/syssentry/task_map.py b/src/python/syssentry/task_map.py +index 70aa19d..27e97ff 100644 +--- a/src/python/syssentry/task_map.py ++++ b/src/python/syssentry/task_map.py +@@ -13,16 +13,16 @@ + tasks map class and initialize function. + """ + import logging ++from typing import Dict + + ONESHOT_TYPE = "ONESHOT" + PERIOD_TYPE = "PERIOD" + + TASKS_MAP = None + +- + class TasksMap: + """task map class""" +- tasks_dict = {} ++ tasks_dict: Dict[str, Dict] = {} + + @classmethod + def init_task_map(cls): +@@ -65,3 +65,4 @@ class TasksMap: + logging.debug("getting task by name: %s", res) + break + return res ++ +diff --git a/src/python/xalarm/register_xalarm.py b/src/python/xalarm/register_xalarm.py +index 4f51e66..2a6dabf 100644 +--- a/src/python/xalarm/register_xalarm.py ++++ b/src/python/xalarm/register_xalarm.py +@@ -115,6 +115,7 @@ class AlarmRegister: + def stop_thread(self) -> None: + self.thread_should_stop = True + self.thread.join() ++ self.socket.close() + + + def xalarm_register(callback: callable, id_filter: list) -> int: +@@ -147,7 +148,7 @@ def xalarm_unregister(clientId: int) -> None: + ALARM_REGISTER_INFO = None + + +-def xalarm_upgrade(clientId: int, id_filter: list) -> bool: ++def xalarm_upgrade(id_filter: list, clientId: int) -> bool: + global ALARM_REGISTER_INFO + if clientId < 0: + sys.stderr.write("xalarm_upgrade: invalid client\n") +@@ -193,4 +194,3 @@ def xalarm_getdesc(alarm_info: Xalarm) -> str: + except UnicodeError: + desc_str = None + return desc_str +- +diff --git a/src/python/xalarm/xalarm_api.py b/src/python/xalarm/xalarm_api.py +index c365019..863bd02 100644 +--- a/src/python/xalarm/xalarm_api.py ++++ b/src/python/xalarm/xalarm_api.py +@@ -98,15 +98,15 @@ class Xalarm: + def msg1(self, msg): + """msg1 setter + """ +- if len(msg) > 512: +- raise ValueError("msg1 length must below 512") ++ if len(msg) > MAX_MSG_LEN: ++ raise ValueError(f"msg1 length must below {MAX_MSG_LEN}") + self._msg1 = msg + + + def alarm_bin2stu(bin_data): + """alarm binary to struct + """ +- struct_data = struct.unpack("@HBBll512s", bin_data) ++ struct_data = struct.unpack(f"@HBBll{MAX_MSG_LEN}s", bin_data) + + alarm_info = Xalarm(1001, 2, 1, 0, 0, "") + alarm_info.alarm_id = struct_data[0] +diff --git a/src/python/xalarm/xalarm_config.py b/src/python/xalarm/xalarm_config.py +index 8e56d10..754a816 100644 +--- a/src/python/xalarm/xalarm_config.py ++++ b/src/python/xalarm/xalarm_config.py +@@ -15,9 +15,10 @@ Create: 2023-11-02 + """ + + import re ++import os + import dataclasses + import logging +-from configparser import ConfigParser ++import configparser + + + MAIN_CONFIG_PATH = '/etc/sysSentry/xalarm.conf' +@@ -27,6 +28,34 @@ MIN_ID_NUMBER = 1001 + MAX_ID_NUMBER = 1128 + MAX_ID_MASK_CAPACITY = 128 + ++# log ++CONF_LOG = 'log' ++CONF_LOG_LEVEL = 'level' ++LogLevel = { ++ "debug": logging.DEBUG, ++ "info": logging.INFO, ++ "warning": logging.WARNING, ++ "error": logging.ERROR, ++ "critical": logging.CRITICAL ++} ++ ++ ++def get_log_level(filename=MAIN_CONFIG_PATH): ++ if not os.path.exists(filename): ++ return logging.INFO ++ ++ try: ++ config = configparser.ConfigParser() ++ config.read(filename) ++ if not config.has_option(CONF_LOG, CONF_LOG_LEVEL): ++ return logging.INFO ++ log_level = config.get(CONF_LOG, CONF_LOG_LEVEL) ++ if log_level.lower() in LogLevel: ++ return LogLevel.get(log_level.lower()) ++ return logging.INFO ++ except configparser.Error: ++ return logging.INFO ++ + + @dataclasses.dataclass + class AlarmConfig: +@@ -106,7 +135,7 @@ def config_init(): + """ + alarm_config = AlarmConfig() + +- cfg = ConfigParser() ++ cfg = configparser.ConfigParser() + cfg.read(MAIN_CONFIG_PATH) + + id_mask = parse_id_mask(cfg) +diff --git a/src/python/xalarm/xalarm_daemon.py b/src/python/xalarm/xalarm_daemon.py +index 00e8886..3ab211c 100644 +--- a/src/python/xalarm/xalarm_daemon.py ++++ b/src/python/xalarm/xalarm_daemon.py +@@ -21,7 +21,7 @@ import signal + import fcntl + import socket + +-from .xalarm_config import config_init ++from .xalarm_config import config_init, get_log_level + from .xalarm_server import server_loop, SOCK_FILE + + ALARM_DIR = "/var/run/xalarm" +@@ -120,9 +120,10 @@ def alarm_process_create(): + os.mkdir(ALARM_DIR) + os.chmod(ALARM_DIR, ALARM_DIR_PERMISSION) + ++ log_level = get_log_level() ++ log_format = "%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s" + +- logging.basicConfig(filename=ALARM_LOGFILE, level=logging.INFO, +- format='%(asctime)s|%(levelname)s| %(message)s') ++ logging.basicConfig(filename=ALARM_LOGFILE, level=log_level, format=log_format) + + signal.signal(signal.SIGTERM, signal_handler) + +diff --git a/src/python/xalarm/xalarm_transfer.py b/src/python/xalarm/xalarm_transfer.py +index 010d2ee..d135095 100644 +--- a/src/python/xalarm/xalarm_transfer.py ++++ b/src/python/xalarm/xalarm_transfer.py +@@ -62,7 +62,6 @@ def cleanup_closed_connections(server_sock, epoll, fd_to_socket): + to_remove.append(fileno) + + for fileno in to_remove: +- epoll.unregister(fileno) + fd_to_socket[fileno].close() + del fd_to_socket[fileno] + logging.info(f"cleaned up connection {fileno} for client lost connection.") +@@ -97,13 +96,12 @@ def wait_for_connection(server_sock, epoll, fd_to_socket, thread_should_stop): + logging.info(f"connection reach max num of {MAX_CONNECTION_NUM}, closed current connection!") + connection.close() + continue +- epoll.register(connection.fileno(), select.EPOLLOUT) + fd_to_socket[connection.fileno()] = connection + except socket.error as e: +- logging.debug("socket error, reason is %s", e) ++ logging.debug(f"socket error, reason is {e}") + break + except (KeyError, OSError, ValueError) as e: +- logging.debug("wait for connection failed %s", e) ++ logging.debug(f"wait for connection failed {e}") + + + def transmit_alarm(server_sock, epoll, fd_to_socket, bin_data): +@@ -122,7 +120,7 @@ def transmit_alarm(server_sock, epoll, fd_to_socket, bin_data): + except (BrokenPipeError, ConnectionResetError): + to_remove.append(fileno) + for fileno in to_remove: +- epoll.unregister(fileno) + fd_to_socket[fileno].close() + del fd_to_socket[fileno] + logging.info(f"cleaned up connection {fileno} for client lost connection.") ++ +-- +2.43.0 + diff --git a/sysSentry.spec b/sysSentry.spec index 883f713..98b2b26 100644 --- a/sysSentry.spec +++ b/sysSentry.spec @@ -4,7 +4,7 @@ Summary: System Inspection Framework Name: sysSentry Version: 1.0.2 -Release: 27 +Release: 28 License: Mulan PSL v2 Group: System Environment/Daemons Source0: https://gitee.com/openeuler/sysSentry/releases/download/v%{version}/%{name}-%{version}.tar.gz @@ -37,6 +37,7 @@ Patch24: change-status-of-period-task-and-sort-mod-file.patch Patch25: set-logrotate.patch Patch26: hbm_online_repair-add-unload-driver.patch Patch27: add-pyxalarm-and-pySentryNotify-add-multi-users-supp.patch +Patch28: adapt_5.10_kenel_for_syssentry.patch BuildRequires: cmake gcc-c++ BuildRequires: python3 python3-setuptools @@ -238,6 +239,12 @@ rm -rf %{buildroot} %attr(0550,root,root) %{python3_sitelib}/syssentry/bmc_alarm.py %changelog +* Fri Jan 24 2025 jinsaihang - 1.0.2-28 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:adapt get_alarm for kenel 5.10 + * Wed Jan 22 2025 shixuantong - 1.0.2-27 - Type:bugfix - CVE:NA -- Gitee