update cve scan method and cve fix method
(cherry picked from commit 6a2dfa07137b27519b17275cae3431617d424714)
This commit is contained in:
parent
7fe5dc26b4
commit
4a7ac20463
@ -1,628 +0,0 @@
|
|||||||
From 0f0cbce6c93b97e312cafead937b46e6b2ceaf51 Mon Sep 17 00:00:00 2001
|
|
||||||
From: wang-guangge <wangguangge@huawei.com>
|
|
||||||
Date: Thu, 9 Nov 2023 10:46:33 +0800
|
|
||||||
Subject: [PATCH] support kabi check
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/manages/vulnerability_manage.py | 2 +-
|
|
||||||
hotpatch/hotupgrade.py | 97 +++++-
|
|
||||||
hotpatch/updateinfo_parse.py | 3 +
|
|
||||||
hotpatch/upgrade_en.py | 413 ++++++++++++++++++++++++++
|
|
||||||
4 files changed, 506 insertions(+), 9 deletions(-)
|
|
||||||
create mode 100644 hotpatch/upgrade_en.py
|
|
||||||
|
|
||||||
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
|
|
||||||
index c41a7fa..bad2dee 100644
|
|
||||||
--- a/ceres/manages/vulnerability_manage.py
|
|
||||||
+++ b/ceres/manages/vulnerability_manage.py
|
|
||||||
@@ -620,7 +620,7 @@ class VulnerabilityManage:
|
|
||||||
Tuple[str, str]
|
|
||||||
a tuple containing two elements (update result, log).
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"dnf update {rpm_name} -y")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(f"dnf upgrade-en {rpm_name} -y")
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
return TaskExecuteRes.FAIL, stderr
|
|
||||||
if "Complete" not in stdout:
|
|
||||||
diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py
|
|
||||||
index f61e37f..c508e07 100644
|
|
||||||
--- a/hotpatch/hotupgrade.py
|
|
||||||
+++ b/hotpatch/hotupgrade.py
|
|
||||||
@@ -12,16 +12,14 @@
|
|
||||||
# ******************************************************************************/
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
-from time import sleep
|
|
||||||
import dnf.base
|
|
||||||
import dnf.exceptions
|
|
||||||
import hawkey
|
|
||||||
+from time import sleep
|
|
||||||
from dnf.cli import commands
|
|
||||||
from dnf.cli.option_parser import OptionParser
|
|
||||||
-
|
|
||||||
-# from dnf.cli.output import Output
|
|
||||||
from dnfpluginscore import _, logger
|
|
||||||
-
|
|
||||||
+from .upgrade_en import UpgradeEnhanceCommand
|
|
||||||
from .hot_updateinfo import HotUpdateinfoCommand
|
|
||||||
from .updateinfo_parse import HotpatchUpdateInfo
|
|
||||||
from .syscare import Syscare
|
|
||||||
@@ -37,6 +35,9 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
usage = ""
|
|
||||||
syscare = Syscare()
|
|
||||||
hp_list = []
|
|
||||||
+ is_need_accept_kernel_hp = False
|
|
||||||
+ is_kernel_coldpatch_installed = False
|
|
||||||
+ kernel_coldpatch = ''
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def set_argparser(parser):
|
|
||||||
@@ -50,6 +51,13 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
parser.add_argument(
|
|
||||||
"--takeover", default=False, action='store_true', help=_('kernel cold patch takeover operation')
|
|
||||||
)
|
|
||||||
+ parser.add_argument(
|
|
||||||
+ "-f",
|
|
||||||
+ dest='force',
|
|
||||||
+ default=False,
|
|
||||||
+ action='store_true',
|
|
||||||
+ help=_('force retain kernel rpm package if kernel kabi check fails'),
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def configure(self):
|
|
||||||
"""Verify that conditions are met so that this command can run.
|
|
||||||
@@ -104,17 +112,72 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
|
|
||||||
def run_transaction(self) -> None:
|
|
||||||
"""
|
|
||||||
- apply hot patches
|
|
||||||
+ apply hot patches, and process kabi check for kernel package rpm.
|
|
||||||
Returns:
|
|
||||||
None
|
|
||||||
"""
|
|
||||||
# syscare need a little bit time to process the installed hot patch
|
|
||||||
sleep(0.5)
|
|
||||||
+
|
|
||||||
+ is_all_kernel_hp_actived = True
|
|
||||||
+ # hotpatch that fail to be activated will be automatically uninstalled
|
|
||||||
+ target_remove_hp = []
|
|
||||||
+ acceptable_hp = []
|
|
||||||
for hp in self.hp_list:
|
|
||||||
- self._apply_hp(hp)
|
|
||||||
- if self.opts.takeover and self.is_need_accept_kernel_hp:
|
|
||||||
+ status = self._apply_hp(hp)
|
|
||||||
+ if status:
|
|
||||||
+ target_remove_hp.append(hp)
|
|
||||||
+ if not hp.startswith('patch-kernel-'):
|
|
||||||
+ continue
|
|
||||||
+ if status:
|
|
||||||
+ is_all_kernel_hp_actived &= False
|
|
||||||
+ else:
|
|
||||||
+ is_all_kernel_hp_actived &= True
|
|
||||||
+ acceptable_hp.append(hp)
|
|
||||||
+
|
|
||||||
+ for ts_item in self.base.transaction:
|
|
||||||
+ if ts_item.action not in dnf.transaction.FORWARD_ACTIONS:
|
|
||||||
+ continue
|
|
||||||
+ if str(ts_item.pkg) == self.kernel_coldpatch:
|
|
||||||
+ self.is_kernel_coldpatch_installed = True
|
|
||||||
+
|
|
||||||
+ self.keep_hp_operation_atomic(is_all_kernel_hp_actived, target_remove_hp)
|
|
||||||
+
|
|
||||||
+ if self.is_need_accept_kernel_hp and acceptable_hp:
|
|
||||||
+ logger.info(_('No available kernel cold patch for takeover, gonna accept available kernel hot patch.'))
|
|
||||||
+ for hp in acceptable_hp:
|
|
||||||
self._accept_kernel_hp(hp)
|
|
||||||
|
|
||||||
+ def keep_hp_operation_atomic(self, is_all_kernel_hp_actived, target_remove_hp):
|
|
||||||
+ """
|
|
||||||
+ Keep hotpatch related operation atomic. Once one kernel hotpatch is not successfully activated or
|
|
||||||
+ kabi check fails, uninstall the kernel coldpatch. And unsuccessfully activated hotpatch package
|
|
||||||
+ will be removed.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ is_all_kernel_hp_actived(bool): are all kernel related hotpatches activated
|
|
||||||
+ target_remove_hp(list): target remove hotpatch list
|
|
||||||
+ """
|
|
||||||
+ upgrade_en = UpgradeEnhanceCommand(self.cli)
|
|
||||||
+
|
|
||||||
+ if self.is_kernel_coldpatch_installed:
|
|
||||||
+ if not is_all_kernel_hp_actived:
|
|
||||||
+ logger.info(_('Gonna remove %s due to some kernel hotpatch activation failed.'), self.kernel_coldpatch)
|
|
||||||
+ upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.is_need_accept_kernel_hp = False
|
|
||||||
+ # process kabi check
|
|
||||||
+ elif not upgrade_en.kabi_check(str(self.kernel_coldpatch)) and not self.opts.force:
|
|
||||||
+ logger.info(_('Gonna remove %s due to Kabi check failed.'), self.kernel_coldpatch)
|
|
||||||
+ # rebuild rpm database for processing kernel rpm remove operation
|
|
||||||
+ upgrade_en.rebuild_rpm_db()
|
|
||||||
+ upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.is_need_accept_kernel_hp = True
|
|
||||||
+
|
|
||||||
+ if target_remove_hp:
|
|
||||||
+ logger.info(_('Gonna remove unsuccessfully activated hotpatch rpm.'))
|
|
||||||
+ for hotpatch in target_remove_hp:
|
|
||||||
+ upgrade_en.remove_rpm(hotpatch)
|
|
||||||
+
|
|
||||||
def _apply_hp(self, hp_full_name):
|
|
||||||
pkg_info = self._parse_hp_name(hp_full_name)
|
|
||||||
hp_subname = self._get_hp_subname_for_syscare(pkg_info)
|
|
||||||
@@ -123,6 +186,7 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
logger.info(_('Apply hot patch failed: %s.'), hp_subname)
|
|
||||||
else:
|
|
||||||
logger.info(_('Apply hot patch succeed: %s.'), hp_subname)
|
|
||||||
+ return status
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _get_hp_subname_for_syscare(pkg_info: dict) -> str:
|
|
||||||
@@ -394,9 +458,11 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
"""
|
|
||||||
process takeover operation.
|
|
||||||
"""
|
|
||||||
+ if not self.get_kernel_hp_list():
|
|
||||||
+ return
|
|
||||||
kernel_coldpatch = self.get_target_installed_kernel_coldpatch_of_hotpatch()
|
|
||||||
- self.is_need_accept_kernel_hp = False
|
|
||||||
if kernel_coldpatch:
|
|
||||||
+ self.kernel_coldpatch = kernel_coldpatch
|
|
||||||
logger.info(_("Gonna takeover kernel cold patch: ['%s']" % kernel_coldpatch))
|
|
||||||
success = self._install_rpm_pkg([kernel_coldpatch])
|
|
||||||
if success:
|
|
||||||
@@ -412,6 +478,21 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
+ def get_kernel_hp_list(self) -> list:
|
|
||||||
+ """
|
|
||||||
+ Get kernel hp list from self.hp_list.
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ list: kernel hp list
|
|
||||||
+ e.g.
|
|
||||||
+ ['patch-kernel-5.10.0-153.12.0.92.oe2203sp2-ACC-1-1.x86_64']
|
|
||||||
+ """
|
|
||||||
+ kernel_hp_list = []
|
|
||||||
+ for hp in self.hp_list:
|
|
||||||
+ if hp.startswith('patch-kernel-'):
|
|
||||||
+ kernel_hp_list.append(hp)
|
|
||||||
+ return kernel_hp_list
|
|
||||||
+
|
|
||||||
def get_target_installed_kernel_coldpatch_of_hotpatch(self) -> str:
|
|
||||||
"""
|
|
||||||
get the highest kernel cold patch of hot patch in "dnf hot-updateinfo list cves", if the corresponding
|
|
||||||
diff --git a/hotpatch/updateinfo_parse.py b/hotpatch/updateinfo_parse.py
|
|
||||||
index 4760378..fc39d48 100644
|
|
||||||
--- a/hotpatch/updateinfo_parse.py
|
|
||||||
+++ b/hotpatch/updateinfo_parse.py
|
|
||||||
@@ -322,6 +322,9 @@ class HotpatchUpdateInfo(object):
|
|
||||||
cmd = ["uname", "-r"]
|
|
||||||
kernel_version = ''
|
|
||||||
kernel_version, return_code = cmd_output(cmd)
|
|
||||||
+ # 'uname -r' show the kernel version-release.arch of the current system
|
|
||||||
+ # [root@openEuler hotpatch]# uname -r
|
|
||||||
+ # 5.10.0-136.12.0.86.oe2203sp1.x86_64
|
|
||||||
if return_code != SUCCEED:
|
|
||||||
return kernel_version
|
|
||||||
kernel_version = kernel_version.split('\n')[0]
|
|
||||||
diff --git a/hotpatch/upgrade_en.py b/hotpatch/upgrade_en.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..266bcae
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/hotpatch/upgrade_en.py
|
|
||||||
@@ -0,0 +1,413 @@
|
|
||||||
+#!/usr/bin/python3
|
|
||||||
+# ******************************************************************************
|
|
||||||
+# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
|
|
||||||
+# 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.
|
|
||||||
+# ******************************************************************************/
|
|
||||||
+import dnf
|
|
||||||
+import gzip
|
|
||||||
+import subprocess
|
|
||||||
+from dnfpluginscore import _
|
|
||||||
+from dnf.cli import commands
|
|
||||||
+from dnf.cli.commands.upgrade import UpgradeCommand
|
|
||||||
+from dnf.cli.option_parser import OptionParser
|
|
||||||
+
|
|
||||||
+SUCCEED = 0
|
|
||||||
+FAIL = 255
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def cmd_output(cmd):
|
|
||||||
+ try:
|
|
||||||
+ result = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
+ result.wait()
|
|
||||||
+ return result.stdout.read().decode('utf-8'), result.returncode
|
|
||||||
+ except Exception as e:
|
|
||||||
+ print("error: ", e)
|
|
||||||
+ return str(e), FAIL
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+@dnf.plugin.register_command
|
|
||||||
+class UpgradeEnhanceCommand(dnf.cli.Command):
|
|
||||||
+ SYMVERS_FILE = "/boot/symvers-%s.gz"
|
|
||||||
+
|
|
||||||
+ aliases = ['upgrade-en']
|
|
||||||
+ summary = _(
|
|
||||||
+ 'upgrade with KABI(Kernel Application Binary Interface) check. If the loaded kernel modules \
|
|
||||||
+ have KABI compatibility with the new version kernel rpm, the kernel modules can be installed \
|
|
||||||
+ and used in the new version kernel without recompling.'
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def set_argparser(parser):
|
|
||||||
+ parser.add_argument(
|
|
||||||
+ 'packages',
|
|
||||||
+ nargs='*',
|
|
||||||
+ help=_('Package to upgrade'),
|
|
||||||
+ action=OptionParser.ParseSpecGroupFileCallback,
|
|
||||||
+ metavar=_('PACKAGE'),
|
|
||||||
+ )
|
|
||||||
+ parser.add_argument(
|
|
||||||
+ "-f",
|
|
||||||
+ dest='force',
|
|
||||||
+ default=False,
|
|
||||||
+ action='store_true',
|
|
||||||
+ help=_('force retain kernel rpm package if kernel kabi check fails'),
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ def configure(self):
|
|
||||||
+ """Verify that conditions are met so that this command can run.
|
|
||||||
+
|
|
||||||
+ These include that there are enabled repositories with gpg
|
|
||||||
+ keys, and that this command is being run by the root user.
|
|
||||||
+ """
|
|
||||||
+ demands = self.cli.demands
|
|
||||||
+ demands.sack_activation = True
|
|
||||||
+ demands.available_repos = True
|
|
||||||
+ demands.resolving = True
|
|
||||||
+ demands.root_user = True
|
|
||||||
+ commands._checkGPGKey(self.base, self.cli)
|
|
||||||
+ if not self.opts.filenames:
|
|
||||||
+ commands._checkEnabledRepo(self.base)
|
|
||||||
+ self.upgrade_minimal = None
|
|
||||||
+ self.all_security = None
|
|
||||||
+ self.skipped_grp_specs = None
|
|
||||||
+
|
|
||||||
+ def run(self):
|
|
||||||
+ self.upgrade()
|
|
||||||
+
|
|
||||||
+ def run_transaction(self):
|
|
||||||
+ """
|
|
||||||
+ Process kabi check for kernel rpm package installed this time. If the kernel rpm pakcgae fails kabi check,
|
|
||||||
+ uninstall it.
|
|
||||||
+ """
|
|
||||||
+ for ts_item in self.base.transaction:
|
|
||||||
+ if ts_item.action not in dnf.transaction.FORWARD_ACTIONS:
|
|
||||||
+ continue
|
|
||||||
+ if ts_item.pkg.name == 'kernel':
|
|
||||||
+ kernel_pkg = str(ts_item.pkg)
|
|
||||||
+ success = self.kabi_check(kernel_pkg)
|
|
||||||
+ if not success and not self.opts.force:
|
|
||||||
+ print('Gonna remove %s due to kabi check failed.' % kernel_pkg)
|
|
||||||
+ # rebuild rpm database for processing kernel rpm remove operation
|
|
||||||
+ self.rebuild_rpm_db()
|
|
||||||
+ self.remove_rpm(kernel_pkg)
|
|
||||||
+
|
|
||||||
+ def remove_rpm(self, pkg: str):
|
|
||||||
+ """
|
|
||||||
+ Remove rpm package via command line.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ pkg(str): package name
|
|
||||||
+ e.g.
|
|
||||||
+ kernel-5.10.0-153.18.0.94.oe2203sp2.x86_64
|
|
||||||
+ """
|
|
||||||
+ remove_cmd = ["dnf", "remove", pkg, "-y"]
|
|
||||||
+ output, return_code = cmd_output(remove_cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ print('Remove package failed: %s.' % pkg)
|
|
||||||
+ exit(1)
|
|
||||||
+ else:
|
|
||||||
+ print('Remove package succeed: %s.' % pkg)
|
|
||||||
+ # do not achieve the expected result of installing related kernel rpm
|
|
||||||
+ exit(1)
|
|
||||||
+
|
|
||||||
+ def rebuild_rpm_db(self):
|
|
||||||
+ """
|
|
||||||
+ Rebuild rpm database for processing kernel rpm remove operation.
|
|
||||||
+ """
|
|
||||||
+ rebuilddb_cmd = ["rpm", "--rebuilddb"]
|
|
||||||
+ output, return_code = cmd_output(rebuilddb_cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ print('Rebuild rpm database failed.')
|
|
||||||
+ else:
|
|
||||||
+ print('Rebuild rpm database succeed.')
|
|
||||||
+
|
|
||||||
+ def kabi_check(self, pkg: str) -> bool:
|
|
||||||
+ """
|
|
||||||
+ Process kabi check after upgrading kernel rpm.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ pkg(str): package name
|
|
||||||
+ e.g.
|
|
||||||
+ kernel-5.10.0-153.18.0.94.oe2203sp2.x86_64
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ bool: kabi check result
|
|
||||||
+ """
|
|
||||||
+ print("Kabi check for %s:" % pkg)
|
|
||||||
+ # version-release.arch
|
|
||||||
+ evra = pkg.split("-", 1)[1]
|
|
||||||
+ symvers_file = self.SYMVERS_FILE % (evra)
|
|
||||||
+
|
|
||||||
+ target_symvers_symbol_crc_mapping, return_code = self.get_target_symvers_symbol_crc_mapping(symvers_file)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ print('[Fail] Cannot find the symvers file of %s.', pkg)
|
|
||||||
+ return False
|
|
||||||
+ module_actual_symbol_crc_mapping = self.get_module_actual_symbol_crc_mapping()
|
|
||||||
+
|
|
||||||
+ module_different_symbol_crc_mapping = self.compare_actual_and_target_symvers_symbol_crc_mapping(
|
|
||||||
+ module_actual_symbol_crc_mapping, target_symvers_symbol_crc_mapping
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ sum_module_num = len(module_actual_symbol_crc_mapping)
|
|
||||||
+ fail_module_num = len(module_different_symbol_crc_mapping)
|
|
||||||
+ pass_module_num = sum_module_num - fail_module_num
|
|
||||||
+
|
|
||||||
+ reminder_statement = "Here are %s loaded kernel modules in this system, %s pass, %s fail." % (
|
|
||||||
+ sum_module_num,
|
|
||||||
+ pass_module_num,
|
|
||||||
+ fail_module_num,
|
|
||||||
+ )
|
|
||||||
+
|
|
||||||
+ if fail_module_num > 0:
|
|
||||||
+ print('[Fail] %s' % reminder_statement)
|
|
||||||
+ self.output_symbol_crc_difference_report(module_different_symbol_crc_mapping)
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ print('[Success] %s' % reminder_statement)
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+ def output_symbol_crc_difference_report(self, module_different_symbol_crc_mapping: dict):
|
|
||||||
+ """
|
|
||||||
+ Format the output for symbol crc difference report.
|
|
||||||
+ The output is as follows:
|
|
||||||
+
|
|
||||||
+ Failed modules are as follows:
|
|
||||||
+ No. Module Difference
|
|
||||||
+ 1 upatch ipv6_chk_custom_prefix : 0x0c994af2 != 0x0c994af3
|
|
||||||
+ pcmcia_reset_card : 0xe9bed965 != null
|
|
||||||
+ 2 crct10dif_pclmul crypto_unregister_shash: 0x60f5b0b7 != 0x0c994af3
|
|
||||||
+ __fentry__ : 0xbdfb6dbb != null
|
|
||||||
+ """
|
|
||||||
+ print('Failed modules are as follows:')
|
|
||||||
+
|
|
||||||
+ title = ['No.', 'Module', 'Difference']
|
|
||||||
+ # column width
|
|
||||||
+ sequence_width = len(title[0])
|
|
||||||
+ module_width = len(title[1])
|
|
||||||
+ symbol_width = crc_info_width = 0
|
|
||||||
+
|
|
||||||
+ for seq, module_name in enumerate(module_different_symbol_crc_mapping):
|
|
||||||
+ # the sequence starts from 1
|
|
||||||
+ seq = seq + 1
|
|
||||||
+ sequence_width = max(sequence_width, len(str(seq)))
|
|
||||||
+ different_symbol_crc_mapping = module_different_symbol_crc_mapping[module_name]
|
|
||||||
+ module_width = max(module_width, len(module_name))
|
|
||||||
+ for symbol, crc_list in different_symbol_crc_mapping.items():
|
|
||||||
+ symbol_width = max(symbol_width, len(symbol))
|
|
||||||
+ crc_info = "%s != %s" % (crc_list[0], crc_list[1])
|
|
||||||
+ crc_info_width = max(crc_info_width, len(crc_info))
|
|
||||||
+
|
|
||||||
+ # print title
|
|
||||||
+ print('%-*s %-*s %s' % (sequence_width, title[0], module_width, title[1], title[2]))
|
|
||||||
+
|
|
||||||
+ for seq, module_name in enumerate(module_different_symbol_crc_mapping):
|
|
||||||
+ seq = seq + 1
|
|
||||||
+ print('%-*s %-*s' % (sequence_width, seq, module_width, module_name), end='')
|
|
||||||
+ different_symbol_crc_mapping = module_different_symbol_crc_mapping[module_name]
|
|
||||||
+ is_first_symbol = True
|
|
||||||
+ for symbol, crc_list in different_symbol_crc_mapping.items():
|
|
||||||
+ crc_info = "%s != %s" % (crc_list[0], crc_list[1])
|
|
||||||
+ if is_first_symbol:
|
|
||||||
+ print(' %-*s: %s' % (symbol_width, symbol, crc_info), end='')
|
|
||||||
+ is_first_symbol = False
|
|
||||||
+ else:
|
|
||||||
+ print(
|
|
||||||
+ ' %-*s %-*s: %s' % (sequence_width + module_width, "", symbol_width, symbol, crc_info), end=''
|
|
||||||
+ )
|
|
||||||
+ print('')
|
|
||||||
+
|
|
||||||
+ def compare_actual_and_target_symvers_symbol_crc_mapping(
|
|
||||||
+ self, module_actual_symbol_crc_mapping: dict, target_symvers_symbol_crc_mapping: dict
|
|
||||||
+ ) -> dict:
|
|
||||||
+ """
|
|
||||||
+ Compare the actual symbol crc mapping with the target symvers symbol crc mapping.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ module_actual_symbol_crc_mapping(dict): module actual symbol crc mapping
|
|
||||||
+ e.g.
|
|
||||||
+ {
|
|
||||||
+ 'upatch': {
|
|
||||||
+ 'ipv6_chk_custom_prefix': '0x0c994af3',
|
|
||||||
+ 'pcmcia_reset_card': '0xe9bed965',
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ target_symvers_symbol_crc_mapping(dict): target symvers symbol crc mapping
|
|
||||||
+ e.g.
|
|
||||||
+ {
|
|
||||||
+ 'ipv6_chk_custom_prefix': '0x0c994af2',
|
|
||||||
+ 'pcmcia_reset_card': '0xe9bed965',
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ dict: module different symbol crc mapping
|
|
||||||
+ e.g.
|
|
||||||
+ {
|
|
||||||
+ 'upatch': {
|
|
||||||
+ 'ipv6_chk_custom_prefix': ['0x0c994af3', '0x0c994af2'].
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ """
|
|
||||||
+ module_different_symbol_crc_mapping = dict()
|
|
||||||
+ for module_name, actual_symbol_crc_mapping in module_actual_symbol_crc_mapping.items():
|
|
||||||
+ different_symbol_crc_mapping = dict()
|
|
||||||
+ for actual_symbol, actual_crc in actual_symbol_crc_mapping.items():
|
|
||||||
+ if actual_symbol not in target_symvers_symbol_crc_mapping:
|
|
||||||
+ continue
|
|
||||||
+ elif target_symvers_symbol_crc_mapping[actual_symbol] != actual_symbol_crc_mapping[actual_symbol]:
|
|
||||||
+ different_symbol_crc_mapping[actual_symbol] = [
|
|
||||||
+ actual_crc,
|
|
||||||
+ target_symvers_symbol_crc_mapping[actual_symbol],
|
|
||||||
+ ]
|
|
||||||
+ if not different_symbol_crc_mapping:
|
|
||||||
+ continue
|
|
||||||
+ module_different_symbol_crc_mapping[module_name] = different_symbol_crc_mapping
|
|
||||||
+ return module_different_symbol_crc_mapping
|
|
||||||
+
|
|
||||||
+ def get_module_actual_symbol_crc_mapping(self) -> dict:
|
|
||||||
+ """
|
|
||||||
+ Get the module actual symbol crc mapping of the driver modules currently being loaded in the system.
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ dict: module actual symbol crc mapping
|
|
||||||
+ e.g.
|
|
||||||
+ {
|
|
||||||
+ 'upatch': {
|
|
||||||
+ 'ipv6_chk_custom_prefix': '0x0c994af3',
|
|
||||||
+ 'pcmcia_reset_card': '0xe9bed965',
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ """
|
|
||||||
+ module_actual_symbol_crc_mapping = dict()
|
|
||||||
+ lsmod_cmd = ["lsmod"]
|
|
||||||
+ # 'lsmod' shows all modules loaded in the system
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# lsmod
|
|
||||||
+ # Module Size Used by
|
|
||||||
+ # upatch 53248 0
|
|
||||||
+ # nft_fib_inet 16384 1
|
|
||||||
+ # nft_fib_ipv4 16384 1 nft_fib_inet
|
|
||||||
+ list_output, return_code = cmd_output(lsmod_cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ return module_actual_symbol_crc_mapping
|
|
||||||
+
|
|
||||||
+ content = list_output.split('\n')
|
|
||||||
+ for line in content[1:]:
|
|
||||||
+ if not line:
|
|
||||||
+ continue
|
|
||||||
+ module_name = line.split()[0]
|
|
||||||
+ modinfo_cmd = ['modinfo', module_name, '-n']
|
|
||||||
+ # 'modinfo module_name -n' shows module path information
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# modinfo upatch -n
|
|
||||||
+ # /lib/modules/5.10.0-153.12.0.92.oe2203sp2.x86_64/weak-updates/syscare/upatch.ko
|
|
||||||
+ module_path_output, return_code = cmd_output(modinfo_cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ module_path = module_path_output.split('\n')[0]
|
|
||||||
+ actual_symbol_crc_mapping, return_code = self.get_actual_symbol_crc_mapping(module_path)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ continue
|
|
||||||
+
|
|
||||||
+ module_actual_symbol_crc_mapping[module_name] = actual_symbol_crc_mapping
|
|
||||||
+ return module_actual_symbol_crc_mapping
|
|
||||||
+
|
|
||||||
+ def get_actual_symbol_crc_mapping(self, module_path: str) -> (dict, int):
|
|
||||||
+ """
|
|
||||||
+ Get actual symbol crc mapping for specific module.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ module_path(str): loaded module path
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ dict, bool: actual symbol crc mapping, return code
|
|
||||||
+ """
|
|
||||||
+ actual_symbol_crc_mapping = dict()
|
|
||||||
+ modprobe_cmd = ['modprobe', '--dump', module_path]
|
|
||||||
+ # 'modprobe --dump module_path' shows module related kabi information
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# modprobe --dump \
|
|
||||||
+ # /lib/modules/5.10.0-153.12.0.92.oe2203sp2.x86_64/weak-updates/syscare/upatch.ko
|
|
||||||
+ # 0xe32130cf module_layout
|
|
||||||
+ # 0x9c4befaf kmalloc_caches
|
|
||||||
+ # 0xeb233a45 __kmalloc
|
|
||||||
+ # 0xd6ee688f vmalloc
|
|
||||||
+ # 0x349cba85 strchr
|
|
||||||
+ # 0x754d539c strlen
|
|
||||||
+ crc_symbol_output_lines, return_code = cmd_output(modprobe_cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ return actual_symbol_crc_mapping, return_code
|
|
||||||
+
|
|
||||||
+ crc_symbol_output = crc_symbol_output_lines.split('\n')
|
|
||||||
+ for crc_symbol_line in crc_symbol_output:
|
|
||||||
+ if not crc_symbol_line:
|
|
||||||
+ continue
|
|
||||||
+ crc_symbol_line = crc_symbol_line.split()
|
|
||||||
+ crc, symbol = crc_symbol_line[0], crc_symbol_line[1]
|
|
||||||
+ actual_symbol_crc_mapping[symbol] = crc
|
|
||||||
+ return actual_symbol_crc_mapping, return_code
|
|
||||||
+
|
|
||||||
+ def get_target_symvers_symbol_crc_mapping(self, symvers_file: str) -> (dict, int):
|
|
||||||
+ """
|
|
||||||
+ Get target symbol crc mapping from symvers file of kernel rpm package. The symvers file content is
|
|
||||||
+ as follows(e.g.):
|
|
||||||
+
|
|
||||||
+ 0x0c994af3 ipv6_chk_custom_prefix vmlinux EXPORT_SYMBOL
|
|
||||||
+ 0xe9bed965 pcmcia_reset_card vmlinux EXPORT_SYMBOL
|
|
||||||
+ 0x55417264 unregister_vt_notifier vmlinux EXPORT_SYMBOL_GPL
|
|
||||||
+ 0x8c8905c0 set_anon_super vmlinux EXPORT_SYMBOL
|
|
||||||
+ 0x3ba051a9 __cleancache_invalidate_page vmlinux EXPORT_SYMBOL
|
|
||||||
+
|
|
||||||
+ the first column is crc(Cyclic Redundancy Check), and the second column is symbol.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ symvers_file(str): symvers file path
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ dict, int: target symvers symbol crc mapping, return_code
|
|
||||||
+ e.g.
|
|
||||||
+ {
|
|
||||||
+ 'ipv6_chk_custom_prefix': '0x0c994af3',
|
|
||||||
+ 'pcmcia_reset_card': '0xe9bed965',
|
|
||||||
+ },
|
|
||||||
+ SUCCEED
|
|
||||||
+ """
|
|
||||||
+ symvers_symbol_crc_mapping = dict()
|
|
||||||
+ try:
|
|
||||||
+ content = gzip.open(symvers_file, 'rb')
|
|
||||||
+ except FileNotFoundError as e:
|
|
||||||
+ print("error: ", e)
|
|
||||||
+ return symvers_symbol_crc_mapping, FAIL
|
|
||||||
+
|
|
||||||
+ for line in content.readlines():
|
|
||||||
+ line = line.decode()
|
|
||||||
+ line = line.split()
|
|
||||||
+ crc, symbol = line[0], line[1]
|
|
||||||
+ symvers_symbol_crc_mapping[symbol] = crc
|
|
||||||
+ content.close()
|
|
||||||
+ return symvers_symbol_crc_mapping, SUCCEED
|
|
||||||
+
|
|
||||||
+ def upgrade(self):
|
|
||||||
+ """
|
|
||||||
+ Use UpgradeCommand to process the upgrade operation.
|
|
||||||
+ """
|
|
||||||
+ upgrade = UpgradeCommand(self.cli)
|
|
||||||
+ upgrade.upgrade_minimal = self.upgrade_minimal
|
|
||||||
+ upgrade.opts = self.opts
|
|
||||||
+ upgrade.opts.filenames = self.opts.filenames
|
|
||||||
+ upgrade.opts.pkg_specs = self.opts.pkg_specs
|
|
||||||
+ upgrade.opts.grp_specs = self.opts.grp_specs
|
|
||||||
+
|
|
||||||
+ upgrade.upgrade_minimal = None
|
|
||||||
+ upgrade.all_security = None
|
|
||||||
+ upgrade.skipped_grp_specs = None
|
|
||||||
+
|
|
||||||
+ upgrade.run()
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
From 831aca01a20fcd67b1d6ff604a0334aaa419efd5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: gongzt <gong_zhengtang@163.com>
|
|
||||||
Date: Sat, 11 Nov 2023 17:47:25 +0800
|
|
||||||
Subject: Modify the regular expression of kernel filter
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/manages/vulnerability_manage.py | 14 +++++++-------
|
|
||||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
|
|
||||||
index c41a7fa..39f475d 100644
|
|
||||||
--- a/ceres/manages/vulnerability_manage.py
|
|
||||||
+++ b/ceres/manages/vulnerability_manage.py
|
|
||||||
@@ -166,7 +166,7 @@ class VulnerabilityManage:
|
|
||||||
return rpm_info
|
|
||||||
|
|
||||||
for line in stdout.splitlines():
|
|
||||||
- rpm_name, new_rpm_info = line.split(":",1)
|
|
||||||
+ rpm_name, new_rpm_info = line.split(":", 1)
|
|
||||||
old_rpm_info = rpm_info.get(rpm_name, "")
|
|
||||||
rpm_info[rpm_name] = new_rpm_info if new_rpm_info > old_rpm_info else old_rpm_info
|
|
||||||
LOGGER.debug("query installed rpm package info succeed!")
|
|
||||||
@@ -200,7 +200,7 @@ class VulnerabilityManage:
|
|
||||||
# ("kernel", "x86_64.", "5.10.0-60.105.0.132.oe2203"),
|
|
||||||
# ("kernel-debuginfo", "x86_64", "5.10.0-60.105.0.132.oe2203")
|
|
||||||
# ]
|
|
||||||
- rpm_info = re.findall("^(kernel\S*)\.([a-z468_]+)\s+(\S+)", stdout, re.MULTILINE)
|
|
||||||
+ rpm_info = re.findall("^(kernel)\.([a-z468_]+)\s+(\S+)", stdout, re.MULTILINE)
|
|
||||||
|
|
||||||
if not rpm_info:
|
|
||||||
return result
|
|
||||||
@@ -243,7 +243,7 @@ class VulnerabilityManage:
|
|
||||||
# ("CVE-2021-43976", "Important/Sec.", "kernel-4.19.90-2201.1.0.0132.oe1.x86_64"),
|
|
||||||
# ("CVE-2021-0941", "Important/Sec.", "kernel-4.19.90-2201.1.0.0132.oe1.x86_64")
|
|
||||||
# ]
|
|
||||||
- all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+)", stdout)
|
|
||||||
+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel-\d\S+)", stdout)
|
|
||||||
if not all_cve_info:
|
|
||||||
return unfixed_cves
|
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ class VulnerabilityManage:
|
|
||||||
# ("CVE-2023-1513", "Important/Sec.", "kernel-4.19.90-2304.1.0.0196.oe1.x86_64", "patch-kernel-4.19.90-2112.."),
|
|
||||||
# ("CVE-2021-xxxx", "Important/Sec.", "-", "patch-redis-6.2.5-1-SGL_CVE_2023_1111_CVE_2023_1112-1-1.x86_64")
|
|
||||||
# ]
|
|
||||||
- all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+|-)\s+(patch-kernel\S+|-)", stdout)
|
|
||||||
+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel-\d\S+|-)\s+(patch-kernel-\d\S+|-)", stdout)
|
|
||||||
if not all_cve_info:
|
|
||||||
return cve_info_list
|
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ class VulnerabilityManage:
|
|
||||||
# ("CVE-2021-43976","Important/Sec.", "kernel-4.19.90-2201.1.0.0132.oe1.x86_64"),
|
|
||||||
# ("CVE-2021-0941","Important/Sec.", "kernel-4.19.90-2201.1.0.0132.oe1.x86_64")
|
|
||||||
# ]
|
|
||||||
- fixed_cves_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+)", stdout)
|
|
||||||
+ fixed_cves_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel-\d\S+)", stdout)
|
|
||||||
|
|
||||||
if not fixed_cves_info:
|
|
||||||
return fixed_cves
|
|
||||||
@@ -407,7 +407,7 @@ class VulnerabilityManage:
|
|
||||||
# ("CVE-2021-xxxx", "Important/Sec.", "-", "patch-redis-6.2.5-1-SGL_CVE_2023_1111_CVE_2023_1112-1-1.x86_64")
|
|
||||||
# ]
|
|
||||||
hotpatch_status = self._query_applied_hotpatch_status()
|
|
||||||
- all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+|-)\s+(patch-kernel\S+|-)", stdout)
|
|
||||||
+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel-\d\S+|-)\s+(patch-kernel-\d\S+|-)", stdout)
|
|
||||||
|
|
||||||
cve_info_fixed_by_coldpatch, cve_info_fixed_by_hotpatch, hotpatch_dic = [], [], defaultdict(str)
|
|
||||||
for cve_id, _, coldpatch, hotpatch in all_cve_info:
|
|
||||||
@@ -472,7 +472,7 @@ class VulnerabilityManage:
|
|
||||||
# ("CVE-2023-1112", "redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server", "NOT-APPLIED"),
|
|
||||||
# ("CVE-2023-1111", "redis-6.2.5-1/ACC-1-1/redis-benchmark", "ACTIVED")
|
|
||||||
# ]
|
|
||||||
- applied_hotpatch_info_list = re.findall(r"(CVE-\d{4}-\d+)\s+(kernel[\w\-/.]+)\s+([A-W]+)", stdout)
|
|
||||||
+ applied_hotpatch_info_list = re.findall(r"(CVE-\d{4}-\d+)\s+(kernel-\d[\w\-/.]+)\s+([A-W]+)", stdout)
|
|
||||||
|
|
||||||
if not applied_hotpatch_info_list:
|
|
||||||
return result
|
|
||||||
--
|
|
||||||
Gitee
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
From ccbd7a6dea68303fb7ec6f777f0e6b8d9e6c7773 Mon Sep 17 00:00:00 2001
|
|
||||||
From: wang-guangge <wangguangge@huawei.com>
|
|
||||||
Date: Wed, 15 Nov 2023 10:35:42 +0800
|
|
||||||
Subject: [PATCH] fix bug in test_hotpatch.py
|
|
||||||
|
|
||||||
---
|
|
||||||
hotpatch/test_hotpatch.py | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hotpatch/test_hotpatch.py b/hotpatch/test_hotpatch.py
|
|
||||||
index f46faed..e903d55 100644
|
|
||||||
--- a/hotpatch/test_hotpatch.py
|
|
||||||
+++ b/hotpatch/test_hotpatch.py
|
|
||||||
@@ -13,8 +13,8 @@
|
|
||||||
import unittest
|
|
||||||
from unittest import mock
|
|
||||||
|
|
||||||
-from .hotpatch import HotpatchCommand
|
|
||||||
-from .syscare import SUCCEED, FAIL
|
|
||||||
+from .hotpatch_ops import HotpatchCommand
|
|
||||||
+from .syscare import FAIL, SUCCEED
|
|
||||||
|
|
||||||
|
|
||||||
class HotpatchTestCase(unittest.TestCase):
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@
|
|||||||
From 5b0551698b60ea0c01ad9ee223f7009f230caa12 Mon Sep 17 00:00:00 2001
|
|
||||||
From: wang-guangge <wangguangge@huawei.com>
|
|
||||||
Date: Mon, 20 Nov 2023 20:51:57 +0800
|
|
||||||
Subject: [PATCH] add specific error information
|
|
||||||
|
|
||||||
---
|
|
||||||
hotpatch/hotupgrade.py | 9 ++++++---
|
|
||||||
hotpatch/upgrade_en.py | 8 +++++---
|
|
||||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py
|
|
||||||
index c508e07..5dfee0d 100644
|
|
||||||
--- a/hotpatch/hotupgrade.py
|
|
||||||
+++ b/hotpatch/hotupgrade.py
|
|
||||||
@@ -12,17 +12,19 @@
|
|
||||||
# ******************************************************************************/
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
+from time import sleep
|
|
||||||
+
|
|
||||||
import dnf.base
|
|
||||||
import dnf.exceptions
|
|
||||||
import hawkey
|
|
||||||
-from time import sleep
|
|
||||||
from dnf.cli import commands
|
|
||||||
from dnf.cli.option_parser import OptionParser
|
|
||||||
from dnfpluginscore import _, logger
|
|
||||||
-from .upgrade_en import UpgradeEnhanceCommand
|
|
||||||
+
|
|
||||||
from .hot_updateinfo import HotUpdateinfoCommand
|
|
||||||
-from .updateinfo_parse import HotpatchUpdateInfo
|
|
||||||
from .syscare import Syscare
|
|
||||||
+from .updateinfo_parse import HotpatchUpdateInfo
|
|
||||||
+from .upgrade_en import UpgradeEnhanceCommand
|
|
||||||
from .version import Versions
|
|
||||||
|
|
||||||
EMPTY_TAG = "-"
|
|
||||||
@@ -184,6 +186,7 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
output, status = self.syscare.apply(hp_subname)
|
|
||||||
if status:
|
|
||||||
logger.info(_('Apply hot patch failed: %s.'), hp_subname)
|
|
||||||
+ logger.info(_('%s'), output)
|
|
||||||
else:
|
|
||||||
logger.info(_('Apply hot patch succeed: %s.'), hp_subname)
|
|
||||||
return status
|
|
||||||
diff --git a/hotpatch/upgrade_en.py b/hotpatch/upgrade_en.py
|
|
||||||
index 266bcae..3053179 100644
|
|
||||||
--- a/hotpatch/upgrade_en.py
|
|
||||||
+++ b/hotpatch/upgrade_en.py
|
|
||||||
@@ -10,13 +10,14 @@
|
|
||||||
# PURPOSE.
|
|
||||||
# See the Mulan PSL v2 for more details.
|
|
||||||
# ******************************************************************************/
|
|
||||||
-import dnf
|
|
||||||
import gzip
|
|
||||||
import subprocess
|
|
||||||
-from dnfpluginscore import _
|
|
||||||
+
|
|
||||||
+import dnf
|
|
||||||
from dnf.cli import commands
|
|
||||||
from dnf.cli.commands.upgrade import UpgradeCommand
|
|
||||||
from dnf.cli.option_parser import OptionParser
|
|
||||||
+from dnfpluginscore import _, logger
|
|
||||||
|
|
||||||
SUCCEED = 0
|
|
||||||
FAIL = 255
|
|
||||||
@@ -111,10 +112,11 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
|
|
||||||
output, return_code = cmd_output(remove_cmd)
|
|
||||||
if return_code != SUCCEED:
|
|
||||||
print('Remove package failed: %s.' % pkg)
|
|
||||||
+ print(output)
|
|
||||||
exit(1)
|
|
||||||
else:
|
|
||||||
print('Remove package succeed: %s.' % pkg)
|
|
||||||
- # do not achieve the expected result of installing related kernel rpm
|
|
||||||
+ # do not achieve the expected result of installing related rpm
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
def rebuild_rpm_db(self):
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
From 27df2fbb6c18c382e7099015915f7efb673a9e06 Mon Sep 17 00:00:00 2001
|
|
||||||
From: rabbitali <wenxin32@foxmail.com>
|
|
||||||
Date: Tue, 21 Nov 2023 09:02:09 +0800
|
|
||||||
Subject: [PATCH] update return log field of the cve fix func
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/manages/vulnerability_manage.py | 22 ++++++++++++----------
|
|
||||||
1 file changed, 12 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
|
|
||||||
index da98297..23ae2ce 100644
|
|
||||||
--- a/ceres/manages/vulnerability_manage.py
|
|
||||||
+++ b/ceres/manages/vulnerability_manage.py
|
|
||||||
@@ -621,11 +621,12 @@ class VulnerabilityManage:
|
|
||||||
a tuple containing two elements (update result, log).
|
|
||||||
"""
|
|
||||||
code, stdout, stderr = execute_shell_command(f"dnf upgrade-en {rpm_name} -y")
|
|
||||||
+ log = stdout + stderr
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
- return TaskExecuteRes.FAIL, stderr
|
|
||||||
- if "Complete" not in stdout:
|
|
||||||
- return TaskExecuteRes.FAIL, stdout
|
|
||||||
- return TaskExecuteRes.SUCCEED, stdout
|
|
||||||
+ return TaskExecuteRes.FAIL, log
|
|
||||||
+ if "Complete" not in log:
|
|
||||||
+ return TaskExecuteRes.FAIL, log
|
|
||||||
+ return TaskExecuteRes.SUCCEED, log
|
|
||||||
|
|
||||||
def _update_hotpatch_by_dnf_plugin(self, hotpatch_pkg: str) -> Tuple[str, str]:
|
|
||||||
"""
|
|
||||||
@@ -645,22 +646,23 @@ class VulnerabilityManage:
|
|
||||||
update_command = f"dnf hotupgrade {hotpatch_pkg} -y"
|
|
||||||
|
|
||||||
code, stdout, stderr = execute_shell_command(update_command)
|
|
||||||
+ log = stdout + stderr
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
- return TaskExecuteRes.FAIL, stderr
|
|
||||||
+ return TaskExecuteRes.FAIL, log
|
|
||||||
|
|
||||||
if "Apply hot patch succeed" not in stdout and "No hot patches marked for install" not in stdout:
|
|
||||||
- return TaskExecuteRes.FAIL, stdout
|
|
||||||
+ return TaskExecuteRes.FAIL, log
|
|
||||||
|
|
||||||
if not self.takeover and self.accepted:
|
|
||||||
try:
|
|
||||||
hotpatch_name = hotpatch_pkg.rsplit(".", 1)[0].split("-", 1)[1]
|
|
||||||
- _, log = self._set_hotpatch_status_by_dnf_plugin(hotpatch_name, "accept")
|
|
||||||
- stdout += f"\n\n{log}"
|
|
||||||
+ _, hotpatch_status_set_log = self._set_hotpatch_status_by_dnf_plugin(hotpatch_name, "accept")
|
|
||||||
+ log += f"\n\n{hotpatch_status_set_log}"
|
|
||||||
except IndexError as error:
|
|
||||||
LOGGER.error(error)
|
|
||||||
- stdout += f"\n\nhotpatch status set failed due to can't get correct hotpatch name!"
|
|
||||||
+ log += f"\n\nhotpatch status set failed due to can't get correct hotpatch name!"
|
|
||||||
|
|
||||||
- return TaskExecuteRes.SUCCEED, stdout
|
|
||||||
+ return TaskExecuteRes.SUCCEED, log
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _set_hotpatch_status_by_dnf_plugin(hotpatch: str, operation: str) -> Tuple[bool, str]:
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,141 +0,0 @@
|
|||||||
From e20bd8319c893134e8496ee41edd23fb17a13780 Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Thu, 23 Nov 2023 20:57:39 +0800
|
|
||||||
Subject: [PATCH] add usage and repet config check
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/script/da-tool.sh | 67 ++++++++++++++++++++++++---
|
|
||||||
1 file changed, 60 insertions(+), 7 deletions(-)
|
|
||||||
mode change 100644 => 100755 extra-tools/da-tool/script/da-tool.sh
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/script/da-tool.sh b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
old mode 100644
|
|
||||||
new mode 100755
|
|
||||||
index ccc3443..efc9592
|
|
||||||
--- a/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
+++ b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
@@ -74,9 +74,18 @@ handle_error() {
|
|
||||||
|
|
||||||
trap 'handle_error' ERR
|
|
||||||
|
|
||||||
+function usage() {
|
|
||||||
+ echo ""
|
|
||||||
+ echo "usage: da-tool.sh [OPTIONS] [ARGS]"
|
|
||||||
+ echo ""
|
|
||||||
+ echo "The most commonly used da-tool.sh options are:"
|
|
||||||
+ echo " -t <duration> set tracing duration, unit: seconds, 1<=duration<=100, default is 10"
|
|
||||||
+ echo " -h show usage"
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
# get opt
|
|
||||||
# while getopts "b:l:t:p:as" opt; do # debug
|
|
||||||
-while getopts "t:" opt; do
|
|
||||||
+while getopts "t:h" opt; do
|
|
||||||
case $opt in
|
|
||||||
a)
|
|
||||||
is_analysis_only_mode=true
|
|
||||||
@@ -87,7 +96,12 @@ while getopts "t:" opt; do
|
|
||||||
is_sample_with_analysis=false
|
|
||||||
;;
|
|
||||||
t)
|
|
||||||
- sleep_time=$OPTARG
|
|
||||||
+ if [[ $OPTARG =~ ^[0-9]+$ ]]; then
|
|
||||||
+ sleep_time=$OPTARG
|
|
||||||
+ else
|
|
||||||
+ usage
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
;;
|
|
||||||
p)
|
|
||||||
parameter="$OPTARG"
|
|
||||||
@@ -96,8 +110,13 @@ while getopts "t:" opt; do
|
|
||||||
pid_filter+=("$value")
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
+ h)
|
|
||||||
+ usage
|
|
||||||
+ exit 1
|
|
||||||
+ ;;
|
|
||||||
\?)
|
|
||||||
echo "Invalid option: -$OPTARG" >&2
|
|
||||||
+ usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -130,6 +149,37 @@ function config_display() {
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
+function arr_repet_ele_check() {
|
|
||||||
+ local arr=("$@")
|
|
||||||
+ for element in "${arr[@]}"; do
|
|
||||||
+ count=$(printf '%s\n' "${arr[@]}" | grep -c -w "$element")
|
|
||||||
+ if [ $count -ge 2 ]; then
|
|
||||||
+ echo " '$element' duplicate configuration, please check '$config_file'"
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+function config_file_check() {
|
|
||||||
+ arr_repet_ele_check ${kernel_symbols[@]} # check kernel
|
|
||||||
+ arr_repet_ele_check ${sched_symbols[@]} # check sched
|
|
||||||
+
|
|
||||||
+ spl_begin=0
|
|
||||||
+ declare -a target_path_tmp
|
|
||||||
+ declare -a user_symbols_arr_tmp
|
|
||||||
+ for ((i = 0; i < ${#user_symbols_arr_split[@]}; i++)); do
|
|
||||||
+ spl_end=${user_symbols_arr_split[$i]}
|
|
||||||
+ unset user_symbols_arr_tmp
|
|
||||||
+ target_path_tmp[${#target_path_tmp[*]}]=${user_symbols_arr[$((${spl_begin}))]}${user_symbols_arr[$((${spl_begin} + 1))]}
|
|
||||||
+ for ((j = ${spl_begin} + 2; j < ${spl_end}; j++)); do
|
|
||||||
+ user_symbols_arr_tmp[${#user_symbols_arr_tmp[*]}]=${user_symbols_arr[$j]}
|
|
||||||
+ done
|
|
||||||
+ spl_begin=${spl_end}
|
|
||||||
+ arr_repet_ele_check ${user_symbols_arr_tmp[@]} # check user symbol of same bin
|
|
||||||
+ done
|
|
||||||
+ arr_repet_ele_check "${target_path_tmp[@]}" # check bin
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
function config_file_resolve() {
|
|
||||||
cum_tmp=0
|
|
||||||
while IFS= read -r line; do
|
|
||||||
@@ -166,6 +216,7 @@ function config_file_resolve() {
|
|
||||||
mkdir -p $sample_log_dir
|
|
||||||
touch $sample_log
|
|
||||||
config_display
|
|
||||||
+ config_file_check
|
|
||||||
}
|
|
||||||
|
|
||||||
function gen_config_for_analysis() {
|
|
||||||
@@ -191,13 +242,15 @@ function gen_config_for_analysis() {
|
|
||||||
function opt_check() {
|
|
||||||
if [ $is_uprobe_sample = false ] && [ $is_kprobe_sample = false ]; then
|
|
||||||
echo "use -m u|k|uk to set uprobe/kprobe/both"
|
|
||||||
+ usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- if [ $sleep_time -ge $((sleep_time_max+1)) ] || [ $sleep_time -le 0 ];then
|
|
||||||
- echo "sampling time should > 0 and <= $sleep_time_max"
|
|
||||||
- exit 1
|
|
||||||
- fi
|
|
||||||
+ if [ $sleep_time -ge $((sleep_time_max + 1)) ] || [ $sleep_time -le 0 ]; then
|
|
||||||
+ echo "sampling time should > 0 and <= $sleep_time_max"
|
|
||||||
+ usage
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear_env() {
|
|
||||||
@@ -462,6 +515,6 @@ echo >/sys/kernel/debug/tracing/uprobe_events
|
|
||||||
echo >/sys/kernel/debug/tracing/kprobe_events
|
|
||||||
echo "sample finish"
|
|
||||||
|
|
||||||
-if [ $is_sample_with_analysis = true ]; then # only sample
|
|
||||||
+if [ $is_sample_with_analysis = true ]; then
|
|
||||||
trace_analysis
|
|
||||||
fi
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,324 +0,0 @@
|
|||||||
From eb0e130cc72a9d5d6f6e53fa96d74a11a3b8f6eb Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Sat, 25 Nov 2023 15:45:14 +0800
|
|
||||||
Subject: [PATCH] add command check, config check , test case
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/script/da-tool.sh | 68 +++++++++++++++++-
|
|
||||||
.../da-tool/test/config_check/config_check.sh | 70 +++++++++++++++++++
|
|
||||||
.../test/config_check/config_test1.conf | 2 +
|
|
||||||
.../test/config_check/config_test2.conf | 2 +
|
|
||||||
.../test/config_check/config_test3.conf | 2 +
|
|
||||||
.../test/config_check/config_test4.conf | 2 +
|
|
||||||
.../test/config_check/config_test5.conf | 2 +
|
|
||||||
.../test/config_check/config_test6.conf | 2 +
|
|
||||||
.../test/config_check/config_test7.conf | 2 +
|
|
||||||
extra-tools/da-tool/test/opt_test/opt_test.sh | 49 +++++++++++++
|
|
||||||
10 files changed, 198 insertions(+), 3 deletions(-)
|
|
||||||
create mode 100755 extra-tools/da-tool/test/config_check/config_check.sh
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test1.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test2.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test3.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test4.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test5.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test6.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/config_check/config_test7.conf
|
|
||||||
create mode 100644 extra-tools/da-tool/test/opt_test/opt_test.sh
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/script/da-tool.sh b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
index efc9592..a25c347 100755
|
|
||||||
--- a/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
+++ b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
@@ -96,7 +96,7 @@ while getopts "t:h" opt; do
|
|
||||||
is_sample_with_analysis=false
|
|
||||||
;;
|
|
||||||
t)
|
|
||||||
- if [[ $OPTARG =~ ^[0-9]+$ ]]; then
|
|
||||||
+ if [[ $OPTARG =~ ^[0-9]{1,3}$ ]]; then
|
|
||||||
sleep_time=$OPTARG
|
|
||||||
else
|
|
||||||
usage
|
|
||||||
@@ -122,6 +122,13 @@ while getopts "t:h" opt; do
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
+shift $((OPTIND - 1))
|
|
||||||
+if [[ $# -ne 0 ]]; then
|
|
||||||
+ echo "Illegal parameter :$@"
|
|
||||||
+ usage
|
|
||||||
+ exit 1
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
function config_display() {
|
|
||||||
echo "kernel_symbols:" >>$sample_log
|
|
||||||
for item in "${kernel_symbols[@]}"; do
|
|
||||||
@@ -154,7 +161,57 @@ function arr_repet_ele_check() {
|
|
||||||
for element in "${arr[@]}"; do
|
|
||||||
count=$(printf '%s\n' "${arr[@]}" | grep -c -w "$element")
|
|
||||||
if [ $count -ge 2 ]; then
|
|
||||||
- echo " '$element' duplicate configuration, please check '$config_file'"
|
|
||||||
+ echo " '$element' duplicate configuration, please check '$config_file'!!!"
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# function names cannot contain '.'
|
|
||||||
+function arr_check_function_support() {
|
|
||||||
+ local symbols_tmp=("$@")
|
|
||||||
+ for symbol in "${symbols_tmp[@]}"; do
|
|
||||||
+ if [[ $symbol =~ \. ]]; then
|
|
||||||
+ echo "$symbol have '.', not support, please check '$config_file!!!'" | tee -a $sample_log
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# kernel symbols should be found in '/proc/kallsyms'
|
|
||||||
+function arr_check_kernel_symbols_exist() {
|
|
||||||
+ local symbols_tmp=("$@")
|
|
||||||
+ for symbol in "${symbols_tmp[@]}"; do
|
|
||||||
+ if grep "\<$symbol\>" /proc/kallsyms >/dev/null; then
|
|
||||||
+ echo "$symbol exist in /proc/kallsyms" >>$sample_log
|
|
||||||
+ else
|
|
||||||
+ echo "$symbol does not exist in /proc/kallsyms, please check '$config_file'!!!" | tee -a $sample_log
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+# user symbols should be found by 'nm bin'
|
|
||||||
+function arr_check_user_symbols_exist() {
|
|
||||||
+ binary=$1
|
|
||||||
+ local symbols_tmp=("${@:2}")
|
|
||||||
+ for symbol in "${symbols_tmp[@]}"; do
|
|
||||||
+ if nm "$binary" | grep -q "\<$symbol\>"; then
|
|
||||||
+ echo "$symbol dost exist in $binary" >>$sample_log
|
|
||||||
+ else
|
|
||||||
+ echo "$symbol does not exist in $binary, please check '$config_file'!!!" | tee -a $sample_log
|
|
||||||
+ exit 1
|
|
||||||
+ fi
|
|
||||||
+ done
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+function arr_check_sched() {
|
|
||||||
+ local sched_tmp=("$@")
|
|
||||||
+ for sched in "${sched_tmp[@]}"; do
|
|
||||||
+ if [[ $sched == "sched_switch" ]]; then
|
|
||||||
+ echo "sched_switch match" >>$sample_log
|
|
||||||
+ else
|
|
||||||
+ echo "s only support sched_switch, please check '$config_file'!!!" | tee -a $sample_log
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -162,7 +219,10 @@ function arr_repet_ele_check() {
|
|
||||||
|
|
||||||
function config_file_check() {
|
|
||||||
arr_repet_ele_check ${kernel_symbols[@]} # check kernel
|
|
||||||
- arr_repet_ele_check ${sched_symbols[@]} # check sched
|
|
||||||
+ arr_check_kernel_symbols_exist ${kernel_symbols[@]}
|
|
||||||
+ arr_check_function_support ${kernel_symbols[@]}
|
|
||||||
+ arr_repet_ele_check ${sched_symbols[@]} # check sched
|
|
||||||
+ arr_check_sched ${sched_symbols[@]}
|
|
||||||
|
|
||||||
spl_begin=0
|
|
||||||
declare -a target_path_tmp
|
|
||||||
@@ -176,6 +236,8 @@ function config_file_check() {
|
|
||||||
done
|
|
||||||
spl_begin=${spl_end}
|
|
||||||
arr_repet_ele_check ${user_symbols_arr_tmp[@]} # check user symbol of same bin
|
|
||||||
+ arr_check_function_support ${user_symbols_arr_tmp[@]}
|
|
||||||
+ arr_check_user_symbols_exist ${target_path_tmp[-1]} ${user_symbols_arr_tmp[@]}
|
|
||||||
done
|
|
||||||
arr_repet_ele_check "${target_path_tmp[@]}" # check bin
|
|
||||||
}
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_check.sh b/extra-tools/da-tool/test/config_check/config_check.sh
|
|
||||||
new file mode 100755
|
|
||||||
index 0000000..20c06a1
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_check.sh
|
|
||||||
@@ -0,0 +1,70 @@
|
|
||||||
+#!/bin/bash
|
|
||||||
+
|
|
||||||
+script_dir=$(
|
|
||||||
+ cd $(dirname $0)
|
|
||||||
+ pwd
|
|
||||||
+)
|
|
||||||
+cd $script_dir/
|
|
||||||
+
|
|
||||||
+datool="../../script/da-tool.sh"
|
|
||||||
+case1_path="../../test"
|
|
||||||
+config_file="/etc/da-tool.conf"
|
|
||||||
+config_tmp="config.tmp"
|
|
||||||
+output_file="config_test.log"
|
|
||||||
+
|
|
||||||
+err_config=(
|
|
||||||
+ ./"config_test1.conf"
|
|
||||||
+ ./"config_test2.conf"
|
|
||||||
+ ./"config_test3.conf"
|
|
||||||
+ ./"config_test4.conf"
|
|
||||||
+ ./"config_test5.conf"
|
|
||||||
+ ./"config_test6.conf"
|
|
||||||
+ ./"config_test7.conf"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
+cat $config_file >$config_tmp
|
|
||||||
+
|
|
||||||
+echo >$output_file
|
|
||||||
+
|
|
||||||
+# loop test config
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+echo "===================================== err_configs ======================================" >>$output_file
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+for config_test in "${err_config[@]}"; do
|
|
||||||
+ echo >$config_file
|
|
||||||
+ echo "================================" "$config_test" "================================" >>$output_file
|
|
||||||
+ cat $config_test >$config_file
|
|
||||||
+ echo "#config start" >>$output_file
|
|
||||||
+ cat $config_test >>$output_file
|
|
||||||
+ echo "#config end" >>$output_file
|
|
||||||
+ $datool -t 1 >>$output_file 2>&1
|
|
||||||
+done
|
|
||||||
+
|
|
||||||
+# user check
|
|
||||||
+g++ $case1_path/case/case1/case1.cpp -o case1_test
|
|
||||||
+
|
|
||||||
+err_user_config=(
|
|
||||||
+ ./"config_user_test1.conf"
|
|
||||||
+ ./"config_user_test2.conf"
|
|
||||||
+ ./"config_user_test3.conf"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
+echo "u,$script_dir/,case1_test,_Z5funcAv,aaaa" >./"config_user_test1.conf"
|
|
||||||
+echo "u,$script_dir/,case1_test,_Z5funcAv,_Z5funcAv" >./"config_user_test2.conf"
|
|
||||||
+echo "u,$script_dir/,case1_test,_Z5funcAv.a" >./"config_user_test3.conf"
|
|
||||||
+
|
|
||||||
+# loop test config
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+echo "===================================== user err_configs ======================================" >>$output_file
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+for config_test in "${err_user_config[@]}"; do
|
|
||||||
+ echo >$config_file
|
|
||||||
+ echo "================================" "$config_test" "================================" >>$output_file
|
|
||||||
+ cat $config_test >$config_file
|
|
||||||
+ echo "#config start" >>$output_file
|
|
||||||
+ cat $config_test >>$output_file
|
|
||||||
+ echo "#config end" >>$output_file
|
|
||||||
+ $datool -t 1 >>$output_file 2>&1
|
|
||||||
+done
|
|
||||||
+
|
|
||||||
+cat $config_tmp >$config_file
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test1.conf b/extra-tools/da-tool/test/config_check/config_test1.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..cc75ca7
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test1.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# kernel repet config
|
|
||||||
+k,udp_recvmsg,udp_recvmsg
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test2.conf b/extra-tools/da-tool/test/config_check/config_test2.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..9b1951d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test2.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# u config err
|
|
||||||
+u,udp_recvmsg
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test3.conf b/extra-tools/da-tool/test/config_check/config_test3.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..dd8004d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test3.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# kenrel config error symbols
|
|
||||||
+k,udp_recvmsg,aaaaaa
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test4.conf b/extra-tools/da-tool/test/config_check/config_test4.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..4afb295
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test4.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# s config error
|
|
||||||
+s,sched_switch2
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test5.conf b/extra-tools/da-tool/test/config_check/config_test5.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..4afb295
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test5.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# s config error
|
|
||||||
+s,sched_switch2
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test6.conf b/extra-tools/da-tool/test/config_check/config_test6.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..4945653
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test6.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# s config repet
|
|
||||||
+s,sched_switch,sched_switch
|
|
||||||
diff --git a/extra-tools/da-tool/test/config_check/config_test7.conf b/extra-tools/da-tool/test/config_check/config_test7.conf
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..6b4088b
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/config_check/config_test7.conf
|
|
||||||
@@ -0,0 +1,2 @@
|
|
||||||
+# not support function check
|
|
||||||
+k,udp_recvmsg,set_bringup_idt_handler.constprop.0
|
|
||||||
diff --git a/extra-tools/da-tool/test/opt_test/opt_test.sh b/extra-tools/da-tool/test/opt_test/opt_test.sh
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..ab7dd65
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/opt_test/opt_test.sh
|
|
||||||
@@ -0,0 +1,49 @@
|
|
||||||
+#!/bin/bash
|
|
||||||
+
|
|
||||||
+script_dir=$(
|
|
||||||
+ cd $(dirname $0)
|
|
||||||
+ pwd
|
|
||||||
+)
|
|
||||||
+cd $script_dir/
|
|
||||||
+
|
|
||||||
+datool_path="../../script/"
|
|
||||||
+
|
|
||||||
+err_commands=(
|
|
||||||
+ "./da-tool.sh -t 0"
|
|
||||||
+ "./da-tool.sh -t 101"
|
|
||||||
+ "./da-tool.sh -t 1000000000000000000000000000"
|
|
||||||
+ "./da-tool.sh -t -10"
|
|
||||||
+ "./da-tool.sh -t 0.12345"
|
|
||||||
+ "./da-tool.sh -t abc"
|
|
||||||
+ "./da-tool.sh -t ~"
|
|
||||||
+ "./da-tool.sh -t -m 5"
|
|
||||||
+ "./da-tool.sh -a"
|
|
||||||
+ "./da-tool.sh -x 1"
|
|
||||||
+ "./da-tool.sh -"
|
|
||||||
+ "./da-tool.sh 1"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
+right_commands=(
|
|
||||||
+ "./da-tool.sh -h"
|
|
||||||
+ #"./da-tool.sh -t 1"
|
|
||||||
+ #"./da-tool.sh"
|
|
||||||
+)
|
|
||||||
+
|
|
||||||
+output_file="opt_test.log"
|
|
||||||
+echo >$output_file
|
|
||||||
+
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+echo "===================================== err_commands ======================================" >>$output_file
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+for command in "${err_commands[@]}"; do
|
|
||||||
+ echo "================================" "$command" "================================" >>$output_file
|
|
||||||
+ $datool_path$command >>$output_file 2>&1
|
|
||||||
+done
|
|
||||||
+
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+echo "===================================== right_commands ====================================" >>$output_file
|
|
||||||
+echo "=========================================================================================" >>$output_file
|
|
||||||
+for command in "${right_commands[@]}"; do
|
|
||||||
+ echo "================================" "$command" "================================" >>$output_file
|
|
||||||
+ $datool_path$command >>$output_file 2>&1
|
|
||||||
+done
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,463 +0,0 @@
|
|||||||
From 2d3710909017239828c51cd5901c23415b865c49 Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Sat, 25 Nov 2023 17:05:11 +0800
|
|
||||||
Subject: [PATCH] Dealing with situations where 'sched' are missing
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/analysis/config.cpp | 4 +-
|
|
||||||
extra-tools/da-tool/analysis/config.h | 3 +-
|
|
||||||
.../da-tool/analysis/function_stack.cpp | 2 +-
|
|
||||||
extra-tools/da-tool/analysis/time_pair.cpp | 23 +++-
|
|
||||||
.../da-tool/analysis/trace_resolve.cpp | 105 +++++++++++++++++-
|
|
||||||
extra-tools/da-tool/analysis/trace_resolve.h | 28 +++--
|
|
||||||
extra-tools/da-tool/main.cpp | 8 +-
|
|
||||||
extra-tools/da-tool/script/da-tool.sh | 25 +++--
|
|
||||||
8 files changed, 159 insertions(+), 39 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/config.cpp b/extra-tools/da-tool/analysis/config.cpp
|
|
||||||
index 08420ad..d84cc5b 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/config.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/config.cpp
|
|
||||||
@@ -45,7 +45,6 @@ void Config::pathInit()
|
|
||||||
|
|
||||||
// debug
|
|
||||||
filename[FILE_TYPE_OUTPUT_RUN_LOG] = pathOutputDebug + "/run.log";
|
|
||||||
- filename[FILE_TYPE_OUTPUT_FUNC_STACK_ALL_INFO] = pathOutput + "/func_stack_all_info";
|
|
||||||
filename[FILE_TYPE_DEBUG_TIME_PAIE] = pathOutputDebug + "/debug_time_pair";
|
|
||||||
filename[FILE_TYPE_DEBUG_TRACE] = pathOutputDebug + "/debug_trace";
|
|
||||||
filename[FILE_TYPE_DEBUG_FUNC_STACK_TRACE] = pathOutputDebug + "/debug_funcstk_trace";
|
|
||||||
@@ -129,6 +128,7 @@ void Config::functionCfgInit()
|
|
||||||
std::ofstream fileDebug(filename[FILE_TYPE_DEBUG_CONFIG], std::ios::out | std::ios::trunc);
|
|
||||||
if (!fileDebug) {
|
|
||||||
std::cout << "file open failed:" << filename[FILE_TYPE_DEBUG_CONFIG] << std::endl;
|
|
||||||
+ file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ void Config::configInit(int argc, char *argv[])
|
|
||||||
readTraceBegin = std::stoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
- readTraceEnd = std::stoi(optarg);
|
|
||||||
+ readTraceLen = std::stoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
if (std::stoi(optarg) < DEBUG_LEVEL_MAX) {
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/config.h b/extra-tools/da-tool/analysis/config.h
|
|
||||||
index ccce0f2..e1a5d4a 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/config.h
|
|
||||||
+++ b/extra-tools/da-tool/analysis/config.h
|
|
||||||
@@ -26,7 +26,6 @@ typedef enum {
|
|
||||||
FILE_TYPE_OUTPUT_DELAY,
|
|
||||||
FILE_TYPE_OUTPUT_RUN_LOG,
|
|
||||||
FILE_TYPE_OUTPUT_FUNC_STACK_DELALY,
|
|
||||||
- FILE_TYPE_OUTPUT_FUNC_STACK_ALL_INFO,
|
|
||||||
FILE_TYPE_OUTPUT_PROCESS_SCHED_INFO,
|
|
||||||
FILE_TYPE_OUTPUT_SUMMARY_SCHED_INFO,
|
|
||||||
|
|
||||||
@@ -109,7 +108,7 @@ public: // function cfg
|
|
||||||
std::vector<std::string>(FILE_TYPE_MAX, "")};
|
|
||||||
|
|
||||||
int readTraceBegin;
|
|
||||||
- int readTraceEnd;
|
|
||||||
+ int readTraceLen;
|
|
||||||
void configInit(int argc, char *argv[]);
|
|
||||||
DEBUG_LEVEL_E getDebugLevel();
|
|
||||||
};
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/function_stack.cpp b/extra-tools/da-tool/analysis/function_stack.cpp
|
|
||||||
index fcc2a8d..f1a8312 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/function_stack.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/function_stack.cpp
|
|
||||||
@@ -341,7 +341,7 @@ void FunctionStack::processDelayAnalysis()
|
|
||||||
void FunctionStack::stackNodeMapDisplay()
|
|
||||||
{
|
|
||||||
Config &cfg = Config::getInstance();
|
|
||||||
- std::cout << "Display the function delay of each pid " << std::endl;
|
|
||||||
+ std::cout << "[INFO] display the function delay of each pid " << std::endl;
|
|
||||||
for (const auto &processInfo : stackNodeMap) {
|
|
||||||
int pid = processInfo.first;
|
|
||||||
if (cfg.filterCfgMap.size() == 0 || cfg.filterCfgMap.count(pid) != 0) {
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/time_pair.cpp b/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
index 037bce1..2c1f813 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
@@ -85,6 +85,7 @@ void TimePair::saveFuncStkDebugToFile(std::ofstream &file, const int &pid, const
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
file << "pid" << "," << pid << ",";
|
|
||||||
+ file << "stk_pid" << "," << stk_pid << ",";
|
|
||||||
file << "timestamp" << "," << timestamp << ",";
|
|
||||||
file << "functionIndex" << "," << functionIndex << ",";
|
|
||||||
file << "isRet" << "," << isRet << ",";
|
|
||||||
@@ -152,6 +153,20 @@ void TimePair::timePairUpdateLoop(const int &pid, const int &functionIndex, cons
|
|
||||||
timePairMap[pid].emplace(functionIndex, infoTmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ Config &cfg = Config::getInstance();
|
|
||||||
+ bool isCfgSchedSwitch = cfg.funcCfgMap.count("sched_switch") > 0;
|
|
||||||
+ int sched_switch_funcidx = -1;
|
|
||||||
+ if (isCfgSchedSwitch) {
|
|
||||||
+ sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex;
|
|
||||||
+ const TraceResolve &trace_resolve_inst = TraceResolve::getInstance();
|
|
||||||
+ const FirstInfo &firstInfo = trace_resolve_inst.getTraceFirstInfo();
|
|
||||||
+ int coreIndex = line_info_tmp.core;
|
|
||||||
+ // This process cannot find the starting sched switch on this core, ignore trace after timestamp
|
|
||||||
+ if (timestamp <= firstInfo.schedSwitchTime[coreIndex] && functionIndex != sched_switch_funcidx) {
|
|
||||||
+ timePairMap[pid][functionIndex].minEndTimeInvalid = timestamp;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (isRet) {
|
|
||||||
if (timePairMap[pid][functionIndex].startTime.size() == 0) { // fist is endtime ,startime=endtime
|
|
||||||
timePairMap[pid][functionIndex].startTime.emplace_back(timestamp);
|
|
||||||
@@ -496,14 +511,18 @@ void TimePair::saveDelayInfoToFile()
|
|
||||||
file << "call_times(r<0),ave(r<0),sum(r<0),min(r<0),max(r<0),p50(r<0),p80(r<0),p95(r<0),p99(r<0),";
|
|
||||||
file << std::endl;
|
|
||||||
for (const auto &processInfo : timePairMap) {
|
|
||||||
+ int pid = processInfo.first;
|
|
||||||
+ if (pid == 0) {
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
for (const auto &funcInfo : processInfo.second) {
|
|
||||||
- if (cfg.filterCfgMap.size() != 0 && cfg.filterCfgMap.count(processInfo.first) == 0) {
|
|
||||||
+ if (cfg.filterCfgMap.size() != 0 && cfg.filterCfgMap.count(pid) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (funcInfo.second.summary.callTimes[DELAY_INFO_ALL] <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
- file << "," << processInfo.first << ",";
|
|
||||||
+ file << "," << pid << ",";
|
|
||||||
file << cfg.IndexToFunction[funcInfo.first] << ",";
|
|
||||||
|
|
||||||
for (int i = 0; i < DELAY_INFO_MAX; i++) {
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/trace_resolve.cpp b/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
index 8424464..38e6d2b 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
@@ -56,6 +56,12 @@ const std::vector<TraceLineReslove> &TraceResolve::getTraceLine() const
|
|
||||||
return traceLineVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
+const FirstInfo &TraceResolve::getTraceFirstInfo() const
|
|
||||||
+{
|
|
||||||
+ return firstInfo;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
void SchedSwitchLine::processStateToEnum(std::string state)
|
|
||||||
{
|
|
||||||
if (state == "R") {
|
|
||||||
@@ -68,9 +74,36 @@ void SchedSwitchLine::processStateToEnum(std::string state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+int countLines(const std::string& filename) {
|
|
||||||
+ std::ifstream file(filename);
|
|
||||||
+ if (!file.is_open()) {
|
|
||||||
+ std::cout << "file open failed:" << filename << std::endl;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ int lineCount = 0;
|
|
||||||
+ std::string line;
|
|
||||||
+ while (std::getline(file, line)) {
|
|
||||||
+ lineCount++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ file.close();
|
|
||||||
+ return lineCount;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void TraceResolve::resolveTrace()
|
|
||||||
{
|
|
||||||
Config &cfg = Config::getInstance();
|
|
||||||
+ int readTraceLen = 0;
|
|
||||||
+ if (cfg.readTraceLen == 0) {
|
|
||||||
+ readTraceLen = countLines(cfg.filename[FILE_TYPE_TRACE]);
|
|
||||||
+ if (readTraceLen <= 0) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ readTraceLen = cfg.readTraceLen;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
std::ifstream file(cfg.filename[FILE_TYPE_TRACE]);
|
|
||||||
if (!file) {
|
|
||||||
std::cout << "file open failed:" << cfg.filename[FILE_TYPE_TRACE] << std::endl;
|
|
||||||
@@ -83,7 +116,6 @@ void TraceResolve::resolveTrace()
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
int line_num = 0;
|
|
||||||
int regex_num = 0;
|
|
||||||
bool isFirstMatch = true;
|
|
||||||
@@ -94,13 +126,15 @@ void TraceResolve::resolveTrace()
|
|
||||||
std::regex patternSchedSwitch(R"(\s+(.+)-(\d+)\s+\[(\d+)\]\s+(.)(.)(.)(.)\s+(\d+)\.(\d+):\s+(sched_switch):\s+prev_comm=.+prev_pid=(\d+)\s+prev_prio=(\d+)\s+prev_state=(\S+)\s+==>\s+next_comm=.+next_pid=(\d+)\s+next_prio=(\d+))");
|
|
||||||
while (getline(file, line)) {
|
|
||||||
line_num++;
|
|
||||||
- if (line_num % 10000 == 0) {
|
|
||||||
- std::cout << regex_num << "/" << line_num << " (matched/lines)" << std::endl;
|
|
||||||
- }
|
|
||||||
if (line_num < cfg.readTraceBegin) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
- if (cfg.readTraceEnd != 0 && line_num > cfg.readTraceBegin + cfg.readTraceEnd) {
|
|
||||||
+ if (line_num % 10000 == 0) {
|
|
||||||
+ double rate = (line_num - cfg.readTraceBegin) * 1.0/ readTraceLen;
|
|
||||||
+ std::cout << "[Resolve] " << std::fixed << std::setprecision(3) << rate * 100 << "%, ";
|
|
||||||
+ std::cout << "Match " << regex_num << std::endl;
|
|
||||||
+ }
|
|
||||||
+ if (cfg.readTraceLen != 0 && line_num > cfg.readTraceBegin + cfg.readTraceLen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -143,6 +177,9 @@ void TraceResolve::resolveTrace()
|
|
||||||
if (isMatch) {
|
|
||||||
if (isFirstMatch) {
|
|
||||||
startTimeIntPart = std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str());
|
|
||||||
+ firstInfo.coreId = std::stoi(match[TRACE_INFO_CPU].str());
|
|
||||||
+ firstInfo.startTime = (std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str()) - startTimeIntPart) * MICRO_PER_SEC \
|
|
||||||
+ + std::stoi(match[TRACE_INFO_TIMESTAMP_FLOAT].str());
|
|
||||||
isFirstMatch = false;
|
|
||||||
}
|
|
||||||
match_info.timestamp = (std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str()) - startTimeIntPart) * MICRO_PER_SEC \
|
|
||||||
@@ -165,7 +202,7 @@ void TraceResolve::resolveTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (traceLineVec.size() > 0) {
|
|
||||||
- std::cout << "trace delay :" << traceLineVec[traceLineVec.size() - 1].timestamp - traceLineVec[0].timestamp << std::endl;
|
|
||||||
+ std::cout << "[INFO] trace delay : " << traceLineVec[traceLineVec.size() - 1].timestamp - traceLineVec[0].timestamp << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
@@ -206,8 +243,64 @@ double TraceResolve::convertTimeIntToDouble(const int ×tamp)
|
|
||||||
return timestamp * 1.0 / MICRO_PER_SEC + startTimeIntPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
+void TraceResolve::firstSchedSwitchTimeAnalysis()
|
|
||||||
+{
|
|
||||||
+ Config &cfg = Config::getInstance();
|
|
||||||
+ bool isCfgSchedSwitch = cfg.funcCfgMap.count("sched_switch") > 0;
|
|
||||||
+ int sched_switch_funcidx = -1;
|
|
||||||
+ if (isCfgSchedSwitch) {
|
|
||||||
+ sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex;
|
|
||||||
+ } else {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ firstInfo.schedSwitchTime.resize(CPU_CORE_NUM_MAX, INT_MAX);
|
|
||||||
+ firstInfo.coreTime.resize(CPU_CORE_NUM_MAX, INT_MAX);
|
|
||||||
+ firstInfo.schedSwitchTime[firstInfo.coreId] = firstInfo.startTime;
|
|
||||||
+ firstInfo.coreTime[firstInfo.coreId] = firstInfo.startTime;
|
|
||||||
+
|
|
||||||
+ for (const auto &line_info_tmp : traceLineVec) {
|
|
||||||
+ std::string functionName = line_info_tmp.functionName;
|
|
||||||
+ int pid = line_info_tmp.pid;
|
|
||||||
+ if (cfg.funcCfgMap.count(functionName) == 0) {
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ int timestamp = line_info_tmp.timestamp;
|
|
||||||
+ int coreIndex = line_info_tmp.core;
|
|
||||||
+ int functionIndex = cfg.funcCfgMap[functionName].functionIndex;
|
|
||||||
+ // first appearance of coreIndex in trace
|
|
||||||
+ if (firstInfo.coreTime[coreIndex] == INT_MAX) {
|
|
||||||
+ firstInfo.coreTime[coreIndex] = timestamp;
|
|
||||||
+ }
|
|
||||||
+ // first appearance of sched_switch in coreIndex's trace
|
|
||||||
+ if (functionIndex == sched_switch_funcidx && firstInfo.schedSwitchTime[coreIndex] == INT_MAX) {
|
|
||||||
+ firstInfo.schedSwitchTime[coreIndex] = timestamp;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void TraceResolve::trace_resolve_proc()
|
|
||||||
{
|
|
||||||
resolveTrace();
|
|
||||||
saveTraceRegexRstToFile();
|
|
||||||
+
|
|
||||||
+ firstSchedSwitchTimeAnalysis();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void TraceResolve::trace_check_show()
|
|
||||||
+{
|
|
||||||
+ Config &cfg = Config::getInstance();
|
|
||||||
+ for (int coreId = 0; coreId < CPU_CORE_NUM_MAX; coreId++) {
|
|
||||||
+ int firstSchedSwitchTime = firstInfo.schedSwitchTime[coreId];
|
|
||||||
+ int firstCoreTime = firstInfo.coreTime[coreId];
|
|
||||||
+ if (cfg.getDebugLevel() >= DEBUG_LEVEL_1) {
|
|
||||||
+ std::cout << "coreId:" << coreId;
|
|
||||||
+ std::cout << ",firstSchedSwitchTime:" << firstSchedSwitchTime;
|
|
||||||
+ std::cout << ",firstCoreTime:" << firstCoreTime << std::endl;
|
|
||||||
+ }
|
|
||||||
+ if (firstSchedSwitchTime != firstCoreTime) {
|
|
||||||
+ std::cout << "[ERROR] core " << coreId << " missing starting scheduling information, result maybe error!!!" << std::endl;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/trace_resolve.h b/extra-tools/da-tool/analysis/trace_resolve.h
|
|
||||||
index df330d5..e943d20 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/trace_resolve.h
|
|
||||||
+++ b/extra-tools/da-tool/analysis/trace_resolve.h
|
|
||||||
@@ -23,18 +23,8 @@
|
|
||||||
// include\linux\sched.h
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
- PROCESS_STATE_TASK_RUNNING, // R
|
|
||||||
- PROCESS_STATE_TASK_INTERRUPTIBLE, // S
|
|
||||||
-// PROCESS_STATE_TASK_UNINTERRUPTIBL, // D
|
|
||||||
-// PROCESS_STATE_TASK_STOPPED, // T
|
|
||||||
-// PROCESS_STATE_TASK_TRACED, //t
|
|
||||||
-//
|
|
||||||
-// PROCESS_STATE_EXIT_DEAD, // X
|
|
||||||
-// PROCESS_STATE_EXIT_ZOMBIE, // Z
|
|
||||||
-// PROCESS_STATE_EXIT_TRACE,
|
|
||||||
-//
|
|
||||||
-// PROCESS_STATE_TASK_PARKED, // P
|
|
||||||
-// PROCESS_STATE_TASK_DEAD, // I
|
|
||||||
+ PROCESS_STATE_TASK_RUNNING, // R
|
|
||||||
+ PROCESS_STATE_TASK_INTERRUPTIBLE, // S
|
|
||||||
PROCESS_STATE_MAX,
|
|
||||||
} PROCESS_STATE_E;
|
|
||||||
|
|
||||||
@@ -64,6 +54,14 @@ public:
|
|
||||||
int functionIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
+class FirstInfo {
|
|
||||||
+public:
|
|
||||||
+ std::vector<int> schedSwitchTime; // [coreId]
|
|
||||||
+ std::vector<int> coreTime; // [coreId]
|
|
||||||
+ int coreId; // first core in trace
|
|
||||||
+ int startTime;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
class TraceResolve {
|
|
||||||
public:
|
|
||||||
static TraceResolve &getInstance() {
|
|
||||||
@@ -81,10 +79,16 @@ private: // regex
|
|
||||||
void resolveTrace();
|
|
||||||
void saveTraceRegexRstToFile();
|
|
||||||
|
|
||||||
+private:
|
|
||||||
+ FirstInfo firstInfo;
|
|
||||||
+ void firstSchedSwitchTimeAnalysis();
|
|
||||||
+
|
|
||||||
public:
|
|
||||||
const std::vector<TraceLineReslove> &getTraceLine() const;
|
|
||||||
+ const FirstInfo &getTraceFirstInfo() const;
|
|
||||||
double convertTimeIntToDouble(const int ×tamp);
|
|
||||||
void trace_resolve_proc();
|
|
||||||
+ void trace_check_show();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/extra-tools/da-tool/main.cpp b/extra-tools/da-tool/main.cpp
|
|
||||||
index b6ec46d..34652f0 100644
|
|
||||||
--- a/extra-tools/da-tool/main.cpp
|
|
||||||
+++ b/extra-tools/da-tool/main.cpp
|
|
||||||
@@ -21,10 +21,10 @@ using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
- cout << "analysis start..." << endl;
|
|
||||||
+ cout << "[STEP 2] analysis start..." << endl;
|
|
||||||
Config &cfg = Config::getInstance();
|
|
||||||
cfg.configInit(argc, argv);
|
|
||||||
- cout << "analysis resolve..." << endl;
|
|
||||||
+ cout << "[STEP 2-1] resolve trace..." << endl;
|
|
||||||
TraceResolve &trace_resolve_inst = TraceResolve::getInstance();
|
|
||||||
trace_resolve_inst.trace_resolve_proc();
|
|
||||||
|
|
||||||
@@ -36,6 +36,8 @@ int main(int argc, char *argv[])
|
|
||||||
|
|
||||||
FunctionStack &fstk = FunctionStack::getInstance();
|
|
||||||
fstk.function_stack_proc();
|
|
||||||
- cout << "analysis finish" << endl;
|
|
||||||
+
|
|
||||||
+ trace_resolve_inst.trace_check_show();
|
|
||||||
+ cout << "[STEP 2-2] analysis finish" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/extra-tools/da-tool/script/da-tool.sh b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
index a25c347..14fd009 100755
|
|
||||||
--- a/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
+++ b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
@@ -316,7 +316,7 @@ function opt_check() {
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear_env() {
|
|
||||||
- echo "clear env..."
|
|
||||||
+ echo "[INFO] clear env..."
|
|
||||||
echo 0 >/sys/kernel/debug/tracing/tracing_on
|
|
||||||
|
|
||||||
events_folder="/sys/kernel/debug/tracing/events/"
|
|
||||||
@@ -361,7 +361,7 @@ function clear_env() {
|
|
||||||
echo 0 >"$event_file"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
- echo "clear env finish"
|
|
||||||
+ echo "[INFO] clear env finish"
|
|
||||||
}
|
|
||||||
|
|
||||||
function sample_init() {
|
|
||||||
@@ -528,10 +528,12 @@ function trace_analysis() {
|
|
||||||
}
|
|
||||||
|
|
||||||
###################### main proc ####################################
|
|
||||||
+echo "[STEP 1] da-tool start"
|
|
||||||
+echo "[STEP 1-1] resolve config"
|
|
||||||
config_file_resolve
|
|
||||||
-
|
|
||||||
+echo "[STEP 1-2] environment initialization"
|
|
||||||
if [ $is_clear = true ]; then
|
|
||||||
- echo "clear"
|
|
||||||
+ echo "[INFO] clear"
|
|
||||||
clear_env
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -555,28 +557,29 @@ uprobe_event_enable $is_uprobe_sample
|
|
||||||
kprobe_event_enable $is_kprobe_sample
|
|
||||||
sched_event_enable $is_kprobe_sample
|
|
||||||
|
|
||||||
-# sampling
|
|
||||||
+echo "[STEP 1-3] start tracing..."
|
|
||||||
+# tracing
|
|
||||||
trace_record_begin
|
|
||||||
|
|
||||||
for ((i = 1; i <= ${sleep_time}; i++)); do
|
|
||||||
- # trace_line_num=$(wc -l < /sys/kernel/debug/tracing/trace) # wrong
|
|
||||||
- echo "sampling " $i/${sleep_time} #", trace line" $trace_line_num
|
|
||||||
+ echo "[INFO] tracing " $i/${sleep_time}
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
-#trace_line_num=$(wc -l < /sys/kernel/debug/tracing/trace) # slow
|
|
||||||
-#echo "trace line" $trace_line_num
|
|
||||||
|
|
||||||
trace_record_end
|
|
||||||
+echo "[STEP 1-4] environment reset..."
|
|
||||||
|
|
||||||
clear_env
|
|
||||||
gen_config_for_analysis
|
|
||||||
+
|
|
||||||
+echo "[STEP 1-5] save trace..."
|
|
||||||
storage_data
|
|
||||||
echo "" >/sys/kernel/debug/tracing/trace
|
|
||||||
# only enable = 0 , clear event
|
|
||||||
echo >/sys/kernel/debug/tracing/uprobe_events
|
|
||||||
echo >/sys/kernel/debug/tracing/kprobe_events
|
|
||||||
-echo "sample finish"
|
|
||||||
-
|
|
||||||
+echo "[STEP 1-6] finish tracing ..."
|
|
||||||
if [ $is_sample_with_analysis = true ]; then
|
|
||||||
trace_analysis
|
|
||||||
fi
|
|
||||||
+echo "[EXIT] da-tool exit..."
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,232 +0,0 @@
|
|||||||
From 904d42948317e9ebfc1b3ae2a83778de4c9b8d2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Sun, 26 Nov 2023 22:17:01 +0800
|
|
||||||
Subject: [PATCH] Soft links for documents
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/README.md | 200 ++--------------------------------
|
|
||||||
1 file changed, 8 insertions(+), 192 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/README.md b/extra-tools/da-tool/README.md
|
|
||||||
index 209b43b..157af65 100644
|
|
||||||
--- a/extra-tools/da-tool/README.md
|
|
||||||
+++ b/extra-tools/da-tool/README.md
|
|
||||||
@@ -1,26 +1,9 @@
|
|
||||||
|
|
||||||
# da-tool
|
|
||||||
|
|
||||||
-通过`uprobe`或`kprobe`采样可获得函数执行的`trace`,但配置比较复杂,`trace`包含的信息很多,显示不直观。本工具旨在简易配置采样,以及分析所配置的函数的时延特征。
|
|
||||||
+通过`uprobe`或`kprobe`采样可获得函数执行的`trace`,但配置比较复杂,`trace`包含的信息很多,显示不直观。本工具旨在简易配置采样,以及分析所配置的函数的时延特征。
|
|
||||||
|
|
||||||
-主要应用场景:分析tcp/udp收发相关函数时延特征。
|
|
||||||
-
|
|
||||||
-## 原理
|
|
||||||
-基于u/kprobe 采样,可获得内核态和用户态函数的起止执行时间和结束执行时间的trace。
|
|
||||||
-可推导出:
|
|
||||||
-+ 函数间的调用关系
|
|
||||||
-+ 函数的执行时间
|
|
||||||
-+ 线程的调度特征
|
|
||||||
-
|
|
||||||
-## 主要功能
|
|
||||||
-
|
|
||||||
-+ 推导调用关系(乱序)
|
|
||||||
-+ 统计各函数调用栈时延信息
|
|
||||||
-+ 线程调度特征
|
|
||||||
-+ 记录系统信息
|
|
||||||
-
|
|
||||||
-## 使用限制
|
|
||||||
-+ 不支持递归函数分析
|
|
||||||
+主要应用场景:分析`tcp/udp`收发相关函数时延特征。
|
|
||||||
|
|
||||||
## 文件夹说明
|
|
||||||
**工程文件夹**
|
|
||||||
@@ -39,180 +22,13 @@
|
|
||||||
+ CMakeLists.txt
|
|
||||||
+ test : 测试程序
|
|
||||||
|
|
||||||
-**本地文件夹**
|
|
||||||
-
|
|
||||||
-+ /etc/da-tool.conf : 配置文件,主要配置需要抓取的函数
|
|
||||||
-+ /var/da-tool:
|
|
||||||
- + tmp
|
|
||||||
- + sample_output_* : 采样文件存放位置,可打包
|
|
||||||
- + analysis_input : 临时用于分析程序的依赖文件
|
|
||||||
- + analysis_output
|
|
||||||
- + debug : 可用于调试的参考日志
|
|
||||||
- + output : 时延结果信息
|
|
||||||
-
|
|
||||||
-## 使用方法
|
|
||||||
-### 命令格式
|
|
||||||
-时延分析工具通过`da-tool.sh`命令采集和分析函数时延,使用格式为
|
|
||||||
-
|
|
||||||
-**da-tool.sh** [-t <*probe time*>]
|
|
||||||
-
|
|
||||||
-|参数|是否必选|参数函数|
|
|
||||||
-|----|--------|-------|
|
|
||||||
-|-t |否| 采集函数 `trace` 的时长,单位秒,最大限制 100,默认10|
|
|
||||||
-
|
|
||||||
-### 自定义配置函数
|
|
||||||
-配置文件:`/etc/da-tool.conf`
|
|
||||||
-
|
|
||||||
-举例如下:
|
|
||||||
-```
|
|
||||||
-# /etc/da-tool.conf
|
|
||||||
-
|
|
||||||
-# kernel symbol config (ref: /proc/kallsyms)
|
|
||||||
-k,udp_recvmsg,udp_sendmsg,dev_queue_xmit,udp_send_skb,sock_recvmsg,__skb_recv_udp,udp_rcv
|
|
||||||
-
|
|
||||||
-# sched config
|
|
||||||
-s,sched_switch
|
|
||||||
-
|
|
||||||
-# user symbol config (format : u,path,bin_name,func1,func2,...,funcN)
|
|
||||||
-# u,/path/,bin_name,sendto
|
|
||||||
-u,/home/git_repo/nda-tool/nda-tool/test/net_demo2/,server_no_blk,recvfrom
|
|
||||||
-u,/home/git_repo/nda-tool/nda-tool/test/net_demo2/,client_to_noblk,sendto
|
|
||||||
-u,/home/git_repo/nda-tool/nda-tool/test/base_demo/,base_demo_cpp,_Z5func1v,_Z5func2v,_Z5func2i,_Z5func3v,_Z5func4v
|
|
||||||
-# end
|
|
||||||
-```
|
|
||||||
-
|
|
||||||
-+ k 开头为 kernel 符号,u 开头为用户态程序符号, s 开头为调度配置(目前仅支持`sched_switch`且必须配置)
|
|
||||||
-+ k 和 s 只能一行配置完
|
|
||||||
-+ u 可以多行配置, 格式:`[u,程序路径,二进制名称,追踪的函数]`
|
|
||||||
-+ 请确保函数存在,否则 `uprobe` 配置不成功,所配置的内核符号应在`/proc/kallsyms`能够查询到,所配置的用户态程序符号仅支持`C/C++`,且通过`objdump`应能够查询到
|
|
||||||
-+ 每行末尾不要有逗号
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-注意,为了支持用户态不同二进制重名函数采集,配置`event`时,命名为`u0_func1`、`u1_func1`...,以上面配置为例,`_Z5func1v`为`u2__Z5func1v`。
|
|
||||||
-### 分析结果说明
|
|
||||||
-
|
|
||||||
-+ 终端输出结果:各函数调用栈的时延信息
|
|
||||||
-+ 文件夹输出结果 : `/var/da-tool/analysis-output/ouput/`
|
|
||||||
- + func_delay_stack : 函数调用栈时延结果
|
|
||||||
- + process_sched_info :进程的调度信息
|
|
||||||
- + summary_delay.csv : 时延分析总结报告
|
|
||||||
- + summary_sched.csv : 调度分析总结报告
|
|
||||||
-
|
|
||||||
-#### 终端输出结果介绍
|
|
||||||
-```
|
|
||||||
-├──pid: 222459{local:(450040, 44.988%), global:(1000346, 100.000%)}
|
|
||||||
-│ ├─────sched_switch{local:(13160, 1.316%, 453.793), global:(13160, 1.316%, 453.793), times:29, (int)ret>=0 times:29}
|
|
||||||
-│ └─────u0_recvfrom{local:(422312, 42.217%, 10.729), global:(537146, 53.696%, 13.646), times:39362, (int)ret>=0 times:20}
|
|
||||||
-│ ├─────sched_switch{local:(2927, 0.293%, 209.071), global:(2927, 0.293%, 209.071), times:14, (int)ret>=0 times:14}
|
|
||||||
-│ └─────sock_recvmsg{local:(55313, 5.529%, 1.405), global:(111907, 11.187%, 2.843), times:39362, (int)ret>=0 times:20}
|
|
||||||
-│ └─────udp_recvmsg{local:(36357, 3.634%, 0.924), global:(56594, 5.657%, 1.438), times:39362, (int)ret>=0 times:20}
|
|
||||||
-│ └─────__skb_recv_udp{local:(20237, 2.023%, 0.514), global:(20237, 2.023%, 0.514), times:39362, (int)ret>=0 times:39342}
|
|
||||||
-
|
|
||||||
-```
|
|
||||||
-以此结果为例,该进程是一个udp非阻塞收包进程。
|
|
||||||
-+ `u0_recvfrom` 为该进程在运行后执行的用户态函数,`u0_` 前缀表示第一个应用程序的函数,实际函数名为`recvfrom`;`sched_switch` 为调度函数;其余函数为内核函数
|
|
||||||
-+ `global` 和 `local` 对应的括号内为该函数执行的时延信息,其中 `local` 是剔除掉子函数和调度所执行的时间 , `global` 为该函数实际执行时长
|
|
||||||
-+ 每个函数的 `global` 和 `local` 的括号内三个信息分别为,时延,该时延所占进程全部时间的百分比,平均时延(时延/执行次数)
|
|
||||||
-+ 每一级函数的 `global` 时间等于本级函数`local`时间与下一级所有函数的 `global` 时间之和
|
|
||||||
-+ `times` 是该函数调用栈的次数,
|
|
||||||
-+ `(int)ret>=0 times`:表示该函数返回值转换为`int`后大于等于0的次数,无返回值函数返回值是无效的值
|
|
||||||
-+ 以上时间单位为微秒
|
|
||||||
-
|
|
||||||
-#### 文件夹结果介绍
|
|
||||||
-
|
|
||||||
-**时延和调用关系信息**:`/var/da-tool/analysis_output/output/func_delay_stack`
|
|
||||||
-```
|
|
||||||
-# 此部分信息为终端输出结果的文件格式存储
|
|
||||||
-pid_222459;sched_switch 13160, localDelaySum ,13160, localAvedelay ,453.793103, localPercentage, 1.316%, globalDelaySum ,13160, globalAvedelay, 453.793103, globalPercentage, 1.316%, times , 29, (int)ret>=0 times ,29
|
|
||||||
-pid_222459;u0_recvfrom;sched_switch 2927, localDelaySum ,2927, localAvedelay ,209.071429, localPercentage, 0.293%, globalDelaySum ,2927, globalAvedelay, 209.071429, globalPercentage, 0.293%, times , 14, (int)ret>=0 times ,14
|
|
||||||
-pid_222459;u0_recvfrom 422312, localDelaySum ,422312, localAvedelay ,10.728926, localPercentage, 42.217%, globalDelaySum ,537146, globalAvedelay, 13.646309, globalPercentage, 53.696%, times ,39362, (int)ret>=0 times ,20
|
|
||||||
-pid_222459;u0_recvfrom;sock_recvmsg 55313, localDelaySum ,55313, localAvedelay ,1.405239, localPercentage, 5.529%, globalDelaySum ,111907, globalAvedelay, 2.843021, globalPercentage, 11.187%, times ,39362, (int)ret>=0 times ,20
|
|
||||||
-pid_222459;u0_recvfrom;sock_recvmsg;udp_recvmsg 36357, localDelaySum ,36357, localAvedelay ,0.923657, localPercentage, 3.634%, globalDelaySum ,56594, globalAvedelay, 1.437783, globalPercentage, 5.657%, times ,39362, (int)ret>=0 times ,20
|
|
||||||
-pid_222459;u0_recvfrom;sock_recvmsg;udp_recvmsg;__skb_recv_udp 20237, localDelaySum ,20237, localAvedelay ,0.514125, localPercentage, 2.023%, globalDelaySum ,20237, globalAvedelay, 0.514125, globalPercentage, 2.023%, times ,39362, (int)ret>=0 times ,39342
|
|
||||||
-```
|
|
||||||
-
|
|
||||||
-**调度信息**:`/var/da-tool/analysis_output/output/process_sched_info`
|
|
||||||
-```
|
|
||||||
-# delaySum : 该pid分析的总时长
|
|
||||||
-# schedSwitchDelay : 调度所占的时间
|
|
||||||
-# runtime :delaySum - schedSwitchDelay
|
|
||||||
-# cpuSwitchTimes : 该pid从一个核切换到另一个核的次数
|
|
||||||
-# core 2, run time 704927 : 表示在cpu2 上运行时长为 704927
|
|
||||||
-# startTime,67551.691078,endTime,67551.701193,coreIndex,2 :在这个时间段内在cpu2上运行
|
|
||||||
-# coreIndex,-1 表示该pid被切走的时长(sched_switch)
|
|
||||||
-
|
|
||||||
-pid,222459,delaySum ,1000368,schedSwitchDelay ,37201,runtime ,963167,cpuSwitchTimes ,1,
|
|
||||||
- core 2, run time 704927
|
|
||||||
- core 3, run time 258240
|
|
||||||
-startTime,67551.691078,endTime,67551.701193,coreIndex,2
|
|
||||||
-startTime,67551.701193,endTime,67551.701970,coreIndex,-1
|
|
||||||
-startTime,67551.701970,endTime,67551.702503,coreIndex,2
|
|
||||||
-startTime,67551.702503,endTime,67551.713700,coreIndex,-1
|
|
||||||
-startTime,67551.713700,endTime,67551.723964,coreIndex,2
|
|
||||||
-startTime,67551.723964,endTime,67551.724119,coreIndex,-1
|
|
||||||
-...
|
|
||||||
-
|
|
||||||
-```
|
|
||||||
-**时延分析总结报告**:`/var/da-tool/analysis_output/output/summary_delay.csv`
|
|
||||||
-
|
|
||||||
-包含信息如下,其中`(r>=0)`表示函数返回值转成`int`后大于等于0的情况。
|
|
||||||
-`ave,sum,min,max,p50,p80,p95,p99`等为时延信息的平均值、总和、极值、各百分位下的数值。
|
|
||||||
-```
|
|
||||||
-pid,function,call_times,ave,sum,min,max,p50,p80,p95,p99,
|
|
||||||
-call_times(r>=0),ave(r>=0),sum(r>=0),min(r>=0),max(r>=0),p50(r>=0),p80(r>=0),p95(r>=0),p99(r>=0),
|
|
||||||
-call_times(r<0),ave(r<0),sum(r<0),min(r<0),max(r<0),p50(r<0),p80(r<0),p95(r<0),p99(r<0),
|
|
||||||
-```
|
|
||||||
-
|
|
||||||
-**调度分析总结报告**:`/var/da-tool/analysis_output/output/summary_sched.csv`
|
|
||||||
-```
|
|
||||||
-pid,delaySum,schedSwitchDelay,schedSwitchPercentage,schedSwitchTimes,cpuSwitchTimes
|
|
||||||
-```
|
|
||||||
-+ delaySum : 总耗时
|
|
||||||
-+ schedSwitchDelay : 调度总耗时
|
|
||||||
-+ schedSwitchPercentage : schedSwitchDelay 占 delaySum 的百分比
|
|
||||||
-+ schedSwitchTimes : 调度次数
|
|
||||||
-+ cpuSwitchTimes : cpu 切换次数
|
|
||||||
-
|
|
||||||
-### 扩展功能
|
|
||||||
-`da-tool` 生成的结果信息可调用 火焰图生成工具,可视化分析结果,
|
|
||||||
-`./flamegraph.pl` 可在 `https://gitee.com/mirrors/FlameGraph` 中获取
|
|
||||||
-```shell
|
|
||||||
-# 全部信息
|
|
||||||
-cat /var/da-tool/analysis_output/output/func_delay_stack | grep -o '^[^,]*' | ./flamegraph.pl --countname "delay sum" > allpid.svg
|
|
||||||
-# 指定pid
|
|
||||||
-cat /var/da-tool/analysis_output/output/func_delay_stack | grep -o '^[^,]*' | grep -E 'pid1|pid2' | ./flamegraph.pl --countname "delay sum" > pid.svg
|
|
||||||
-```
|
|
||||||
|
|
||||||
-### 常见错误说明
|
|
||||||
|
|
||||||
-**配置了不存在的符号**
|
|
||||||
-```
|
|
||||||
-Failed to find symbol aaaa in kernel
|
|
||||||
- Error: Failed to add events.
|
|
||||||
-```
|
|
||||||
-**符号已存在,重复配置**
|
|
||||||
-```
|
|
||||||
-Error: event "aaaa" already exists.
|
|
||||||
- Hint: Remove existing event by 'perf probe -d'
|
|
||||||
- or force duplicates by 'perf probe -f'
|
|
||||||
- or set 'force=yes' in BPF source.
|
|
||||||
- Error: Failed to add events.
|
|
||||||
-```
|
|
||||||
+## 详情
|
|
||||||
|
|
||||||
-采集后会在`/var/da-tool/tmp`文件夹下生成一个`output_时间`格式的文件夹,包含此次采样的结果。
|
|
||||||
-采样脚本的采样日志在此路径下:
|
|
||||||
-```
|
|
||||||
-/var/da-tool/tmp/sample_output_时间/da-tool/sample.log
|
|
||||||
-```
|
|
||||||
+|主题|内容简介|是否发布|
|
|
||||||
+|:----|:-----|:----|
|
|
||||||
+|[openEuler指南](https://gitee.com/openeuler/community/blob/master/zh/contributors/README.md)| 如何参与openEuler社区 | 已发布 |
|
|
||||||
+|[da-tool 使用指南](https://gitee.com/openeuler/docs/blob/stable2-20.03_LTS_SP3/docs/zh/docs/A-Ops/da-tool%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C.md)|1. 安装、配置和运行应用程序<br>2. 分析结果说明<br>3. 使用注意事项|已发布|
|
|
||||||
+|da-tool设计文档|1. 技术原理<br> 2. 开发指南 |暂未发布|
|
|
||||||
|
|
||||||
-### 注意事项
|
|
||||||
-+ 配置注意事项
|
|
||||||
- + 配置`/etc/da-tool.conf` 时,注意所配置符号一定存在
|
|
||||||
- + 某些函数名可能存在点(eg:A.B.C),暂**不支持配置此类函数**,例如经过gcc优化选项`-fipa-sra`优化后,函数符号后缀会有`.rsra.num`。
|
|
||||||
- + 应用程序名也不要有点,建议函数和应用程序**不要包含特殊符号**
|
|
||||||
- + 某些函数可能短时间执行大量次数,此时`trace`很大,解析时间会很长,需要认为评估配置的函数运行情况,合理设置采样时间
|
|
||||||
- + 由于`trace`可能存在不完整的调用关系,很有可能在`trace`中存在的数据分析时舍弃,如果单次采样没有抓到需要的pid信息,建议多采样几次
|
|
||||||
- + 有时`trace`中会有数据丢失,结果可能异常,常见的异常原因为`trace`过大,内核刷新数据时不正常,比如会出现同一个函数只有返回时间没有进入时间的现象,建议减小采样时间。
|
|
||||||
- + 不支持递归函数
|
|
||||||
-+ 本工具单个CPU所使用的跟踪缓存`RingBuffer`大小为 `40960kb` ,当单核的`trace`大小接近此值时数据可能异常,进而导致分析结果错误。
|
|
||||||
-+ 确保`trace` 中有需要采集的函数的完整调用栈
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,443 +0,0 @@
|
|||||||
From 2e77a22e9bda4a3b7caeaa772dfb360470c7dacb Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Tue, 28 Nov 2023 09:42:00 +0800
|
|
||||||
Subject: [PATCH] fix valid time of pid at first core and add case
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/analysis/time_pair.cpp | 8 +-
|
|
||||||
extra-tools/da-tool/analysis/time_pair.h | 7 --
|
|
||||||
.../da-tool/analysis/trace_resolve.cpp | 6 +-
|
|
||||||
extra-tools/da-tool/script/da-tool.sh | 4 +-
|
|
||||||
.../da-tool/test/case/case2/case2_udp_cli.c | 2 +-
|
|
||||||
extra-tools/da-tool/test/case/case3/case3.cpp | 33 +++++++
|
|
||||||
.../da-tool/test/case/case4/case4_udp_cli.c | 37 ++++++++
|
|
||||||
.../test/case/case4/case4_udp_ser_blk.c | 49 +++++++++++
|
|
||||||
.../da-tool/test/case/case5/case5_udp_cli.c | 81 +++++++++++++++++
|
|
||||||
.../da-tool/test/case/case5/case5_udp_ser.c | 88 +++++++++++++++++++
|
|
||||||
10 files changed, 300 insertions(+), 15 deletions(-)
|
|
||||||
create mode 100644 extra-tools/da-tool/test/case/case3/case3.cpp
|
|
||||||
create mode 100644 extra-tools/da-tool/test/case/case4/case4_udp_cli.c
|
|
||||||
create mode 100644 extra-tools/da-tool/test/case/case4/case4_udp_ser_blk.c
|
|
||||||
create mode 100644 extra-tools/da-tool/test/case/case5/case5_udp_cli.c
|
|
||||||
create mode 100644 extra-tools/da-tool/test/case/case5/case5_udp_ser.c
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/time_pair.cpp b/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
index 2c1f813..52aa6aa 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/time_pair.cpp
|
|
||||||
@@ -162,7 +162,7 @@ void TimePair::timePairUpdateLoop(const int &pid, const int &functionIndex, cons
|
|
||||||
const FirstInfo &firstInfo = trace_resolve_inst.getTraceFirstInfo();
|
|
||||||
int coreIndex = line_info_tmp.core;
|
|
||||||
// This process cannot find the starting sched switch on this core, ignore trace after timestamp
|
|
||||||
- if (timestamp <= firstInfo.schedSwitchTime[coreIndex] && functionIndex != sched_switch_funcidx) {
|
|
||||||
+ if (timestamp <= firstInfo.schedSwitchTime[coreIndex] && functionIndex != sched_switch_funcidx && coreIndex != firstInfo.coreId) {
|
|
||||||
timePairMap[pid][functionIndex].minEndTimeInvalid = timestamp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -444,8 +444,10 @@ void TimePair::saveTimePairToFile()
|
|
||||||
for (const auto &funcInfo : processInfo.second) {
|
|
||||||
int pid = processInfo.first;
|
|
||||||
file << "pid:" << pid << "," << std::endl;
|
|
||||||
- file << "functionIndex:" << funcInfo.first << "," << cfg.IndexToFunction[funcInfo.first] << std::endl;
|
|
||||||
- file << "info num," << funcInfo.second.startTime.size() << ",valid info num," << funcInfo.second.callTimes << ",";
|
|
||||||
+ file << "functionIndex:" << funcInfo.first << "," << cfg.IndexToFunction[funcInfo.first] << ",";
|
|
||||||
+ file << "maxStartTimeInvaild:" << funcInfo.second.maxStartTimeInvaild << ",";
|
|
||||||
+ file << "minEndTimeInvalid:" << funcInfo.second.minEndTimeInvalid << "," << std::endl;
|
|
||||||
+ file << "info num," << funcInfo.second.startTime.size() << ",valid info num," << funcInfo.second.summary.callTimes[DELAY_INFO_ALL] << ",";
|
|
||||||
file << "validStartTime," << validTimeOfPid[pid].validStartTime << ",validEndTime," << validTimeOfPid[pid].validEndTime << std::endl;
|
|
||||||
file << "startTime" << ",";
|
|
||||||
for (const auto &startTime : funcInfo.second.startTime) {
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/time_pair.h b/extra-tools/da-tool/analysis/time_pair.h
|
|
||||||
index 9d3e757..ba0b784 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/time_pair.h
|
|
||||||
+++ b/extra-tools/da-tool/analysis/time_pair.h
|
|
||||||
@@ -76,13 +76,6 @@ public:
|
|
||||||
|
|
||||||
// analysis result
|
|
||||||
TimePairSummary summary;
|
|
||||||
- double aveDelay;
|
|
||||||
- int maxDelay;
|
|
||||||
- int minDelay;
|
|
||||||
- int delaySum;
|
|
||||||
- int maxDelayPos;
|
|
||||||
- int minDelayPos;
|
|
||||||
- int callTimes;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TimePair {
|
|
||||||
diff --git a/extra-tools/da-tool/analysis/trace_resolve.cpp b/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
index 38e6d2b..61f0a74 100644
|
|
||||||
--- a/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
+++ b/extra-tools/da-tool/analysis/trace_resolve.cpp
|
|
||||||
@@ -131,8 +131,9 @@ void TraceResolve::resolveTrace()
|
|
||||||
}
|
|
||||||
if (line_num % 10000 == 0) {
|
|
||||||
double rate = (line_num - cfg.readTraceBegin) * 1.0/ readTraceLen;
|
|
||||||
- std::cout << "[Resolve] " << std::fixed << std::setprecision(3) << rate * 100 << "%, ";
|
|
||||||
- std::cout << "Match " << regex_num << std::endl;
|
|
||||||
+ std::cout << "\r" << "[Resolve] " << std::fixed << std::setprecision(3) << rate * 100 << "%, ";
|
|
||||||
+ std::cout << "Match " << regex_num;
|
|
||||||
+ std::cout.flush();
|
|
||||||
}
|
|
||||||
if (cfg.readTraceLen != 0 && line_num > cfg.readTraceBegin + cfg.readTraceLen) {
|
|
||||||
break;
|
|
||||||
@@ -202,6 +203,7 @@ void TraceResolve::resolveTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (traceLineVec.size() > 0) {
|
|
||||||
+ std::cout << std::endl;
|
|
||||||
std::cout << "[INFO] trace delay : " << traceLineVec[traceLineVec.size() - 1].timestamp - traceLineVec[0].timestamp << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/script/da-tool.sh b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
index 14fd009..2b38bc8 100755
|
|
||||||
--- a/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
+++ b/extra-tools/da-tool/script/da-tool.sh
|
|
||||||
@@ -182,10 +182,10 @@ function arr_check_function_support() {
|
|
||||||
function arr_check_kernel_symbols_exist() {
|
|
||||||
local symbols_tmp=("$@")
|
|
||||||
for symbol in "${symbols_tmp[@]}"; do
|
|
||||||
- if grep "\<$symbol\>" /proc/kallsyms >/dev/null; then
|
|
||||||
+ if grep -e "^[0-9a-fA-F]* [a-zA-Z] $symbol$" /proc/kallsyms >/dev/null; then
|
|
||||||
echo "$symbol exist in /proc/kallsyms" >>$sample_log
|
|
||||||
else
|
|
||||||
- echo "$symbol does not exist in /proc/kallsyms, please check '$config_file'!!!" | tee -a $sample_log
|
|
||||||
+ echo "$symbol does not exist in /proc/kallsyms or not support, please check '$config_file'!!!" | tee -a $sample_log
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case2/case2_udp_cli.c b/extra-tools/da-tool/test/case/case2/case2_udp_cli.c
|
|
||||||
index 80f9dd7..1a2a346 100644
|
|
||||||
--- a/extra-tools/da-tool/test/case/case2/case2_udp_cli.c
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case2/case2_udp_cli.c
|
|
||||||
@@ -25,7 +25,7 @@ int main() {
|
|
||||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
|
||||||
server_addr.sin_port = htons(SERVER_PORT);
|
|
||||||
|
|
||||||
- int loop_num =0;
|
|
||||||
+ int loop_num = 0;
|
|
||||||
while (1) {
|
|
||||||
usleep(50000);
|
|
||||||
sprintf(buffer, "loop num : %d", loop_num++);
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case3/case3.cpp b/extra-tools/da-tool/test/case/case3/case3.cpp
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..d6f154f
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case3/case3.cpp
|
|
||||||
@@ -0,0 +1,33 @@
|
|
||||||
+#include <iostream>
|
|
||||||
+#include <vector>
|
|
||||||
+#include <random>
|
|
||||||
+#include <algorithm>
|
|
||||||
+
|
|
||||||
+void sortArray(std::vector<int> &arr)
|
|
||||||
+{
|
|
||||||
+ std::sort(arr.begin(), arr.end());
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int main() {
|
|
||||||
+ std::random_device rd;
|
|
||||||
+ std::mt19937 gen(rd());
|
|
||||||
+ std::uniform_int_distribution<int> dis(1, 100);
|
|
||||||
+ const int count = 100000;
|
|
||||||
+ std::vector<int> numbers;
|
|
||||||
+ numbers.resize(count);
|
|
||||||
+ int loopCnt = 0;
|
|
||||||
+ while(1)
|
|
||||||
+ {
|
|
||||||
+ loopCnt++;
|
|
||||||
+ for (int i = 0; i < count; ++i) {
|
|
||||||
+ int randomNum = dis(gen);
|
|
||||||
+ numbers[i] = randomNum;
|
|
||||||
+ }
|
|
||||||
+ sortArray(numbers);
|
|
||||||
+ std::cout<< "loopCnt:" << loopCnt << std::endl;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+// _Z9sortArrayRSt6vectorIiSaIiEE
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case4/case4_udp_cli.c b/extra-tools/da-tool/test/case/case4/case4_udp_cli.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..1a2a346
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case4/case4_udp_cli.c
|
|
||||||
@@ -0,0 +1,37 @@
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
+#include <arpa/inet.h>
|
|
||||||
+
|
|
||||||
+#define SERVER_IP "127.0.0.1"
|
|
||||||
+#define SERVER_PORT 12345
|
|
||||||
+
|
|
||||||
+int main() {
|
|
||||||
+ int sockfd;
|
|
||||||
+ struct sockaddr_in server_addr;
|
|
||||||
+ char buffer[1024];
|
|
||||||
+
|
|
||||||
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
+ if (sockfd < 0) {
|
|
||||||
+ perror("socket creation failed");
|
|
||||||
+ exit(EXIT_FAILURE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ memset(&server_addr, 0, sizeof(server_addr));
|
|
||||||
+ server_addr.sin_family = AF_INET;
|
|
||||||
+ server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
|
||||||
+ server_addr.sin_port = htons(SERVER_PORT);
|
|
||||||
+
|
|
||||||
+ int loop_num = 0;
|
|
||||||
+ while (1) {
|
|
||||||
+ usleep(50000);
|
|
||||||
+ sprintf(buffer, "loop num : %d", loop_num++);
|
|
||||||
+ sendto(sockfd, buffer, strlen(buffer), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ close(sockfd);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case4/case4_udp_ser_blk.c b/extra-tools/da-tool/test/case/case4/case4_udp_ser_blk.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..faad6e1
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case4/case4_udp_ser_blk.c
|
|
||||||
@@ -0,0 +1,49 @@
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
+#include <arpa/inet.h>
|
|
||||||
+
|
|
||||||
+#define SERVER_PORT 12345
|
|
||||||
+
|
|
||||||
+int main() {
|
|
||||||
+ int sockfd;
|
|
||||||
+ struct sockaddr_in server_addr, client_addr;
|
|
||||||
+ socklen_t client_len;
|
|
||||||
+ char buffer[1024];
|
|
||||||
+
|
|
||||||
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
+ if (sockfd < 0) {
|
|
||||||
+ perror("socket creation failed");
|
|
||||||
+ exit(EXIT_FAILURE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ memset(&server_addr, 0, sizeof(server_addr));
|
|
||||||
+ server_addr.sin_family = AF_INET;
|
|
||||||
+ server_addr.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
+ server_addr.sin_port = htons(SERVER_PORT);
|
|
||||||
+
|
|
||||||
+ if (bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
|
||||||
+ perror("bind failed");
|
|
||||||
+ exit(EXIT_FAILURE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while (1) {
|
|
||||||
+ memset(buffer, 0, sizeof(buffer));
|
|
||||||
+ client_len = sizeof(client_addr);
|
|
||||||
+ ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&client_addr, &client_len);
|
|
||||||
+
|
|
||||||
+ if (recv_len > 0) {
|
|
||||||
+ buffer[recv_len] = '\0';
|
|
||||||
+ printf("recvfrom %s:%d date:%s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);
|
|
||||||
+ } else {
|
|
||||||
+ printf("recv_len=%d\n", recv_len);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ close(sockfd);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case5/case5_udp_cli.c b/extra-tools/da-tool/test/case/case5/case5_udp_cli.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..b8fdb4e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case5/case5_udp_cli.c
|
|
||||||
@@ -0,0 +1,81 @@
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <arpa/inet.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
+#include <pthread.h>
|
|
||||||
+#define BUFFER_SIZE 1024
|
|
||||||
+#define PORT 8888
|
|
||||||
+
|
|
||||||
+void* sendRequest(void* arg) {
|
|
||||||
+ int clientSocket = *(int*)arg;
|
|
||||||
+
|
|
||||||
+ while (1) {
|
|
||||||
+ struct sockaddr_in serverAddress;
|
|
||||||
+ memset(&serverAddress, 0, sizeof(serverAddress));
|
|
||||||
+ serverAddress.sin_family = AF_INET;
|
|
||||||
+ serverAddress.sin_port = htons(PORT);
|
|
||||||
+
|
|
||||||
+ if (inet_pton(AF_INET, "127.0.0.1", &(serverAddress.sin_addr)) <= 0) {
|
|
||||||
+ perror("Invalid server address");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // Send a message to the server
|
|
||||||
+ char* message = "Hello, Server!";
|
|
||||||
+ ssize_t sentBytes = sendto(clientSocket, message, strlen(message), 0,
|
|
||||||
+ (struct sockaddr*)&serverAddress, sizeof(serverAddress));
|
|
||||||
+
|
|
||||||
+ if (sentBytes < 0) {
|
|
||||||
+ perror("Sending message failed");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ printf("Sent message to server\n");
|
|
||||||
+
|
|
||||||
+ // Receive server response
|
|
||||||
+ char buffer[BUFFER_SIZE] = {0};
|
|
||||||
+ socklen_t serverAddressLength = sizeof(serverAddress);
|
|
||||||
+ ssize_t receivedBytes = recvfrom(clientSocket, buffer, BUFFER_SIZE, 0,
|
|
||||||
+ (struct sockaddr*)&serverAddress, &serverAddressLength);
|
|
||||||
+
|
|
||||||
+ if (receivedBytes < 0) {
|
|
||||||
+ perror("Receive response failed");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ printf("Received response from server:%s\n", buffer);
|
|
||||||
+
|
|
||||||
+ usleep(100000);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ close(clientSocket);
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int main() {
|
|
||||||
+ int clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
+ if (clientSocket == -1) {
|
|
||||||
+ perror("Unable to create socket");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ const int numThreads = 5;
|
|
||||||
+ pthread_t tids[numThreads];
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < numThreads; ++i) {
|
|
||||||
+ if (pthread_create(&tids[i], NULL, sendRequest, &clientSocket) != 0) {
|
|
||||||
+ perror("Unable to create socket");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < numThreads; ++i) {
|
|
||||||
+ pthread_join(tids[i], NULL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/extra-tools/da-tool/test/case/case5/case5_udp_ser.c b/extra-tools/da-tool/test/case/case5/case5_udp_ser.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..5468bdb
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/extra-tools/da-tool/test/case/case5/case5_udp_ser.c
|
|
||||||
@@ -0,0 +1,88 @@
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <arpa/inet.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <netinet/in.h>
|
|
||||||
+#include <pthread.h>
|
|
||||||
+#define BUFFER_SIZE 1024
|
|
||||||
+#define PORT 8888
|
|
||||||
+
|
|
||||||
+void* handleClient(void* arg) {
|
|
||||||
+ int serverSocket = *(int*)arg;
|
|
||||||
+
|
|
||||||
+ while (1) {
|
|
||||||
+
|
|
||||||
+ char buffer[BUFFER_SIZE] = {0};
|
|
||||||
+ struct sockaddr_in clientAddress;
|
|
||||||
+ socklen_t clientAddressLength = sizeof(clientAddress);
|
|
||||||
+ ssize_t receivedBytes = recvfrom(serverSocket, buffer, BUFFER_SIZE, 0,
|
|
||||||
+ (struct sockaddr*)&clientAddress, &clientAddressLength);
|
|
||||||
+
|
|
||||||
+ if (receivedBytes < 0) {
|
|
||||||
+ perror("Received message failed");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ printf("Received message from client:%s\n", buffer);
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ char* response = "Hello, Client!";
|
|
||||||
+ ssize_t sentBytes = sendto(serverSocket, response, strlen(response), 0,
|
|
||||||
+ (struct sockaddr*)&clientAddress, clientAddressLength);
|
|
||||||
+
|
|
||||||
+ if (sentBytes < 0) {
|
|
||||||
+ perror("Sending response failed");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ printf("Response has been sent to the client\n");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ close(serverSocket);
|
|
||||||
+
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int main() {
|
|
||||||
+
|
|
||||||
+ int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
+ if (serverSocket == -1) {
|
|
||||||
+ perror("Unable to create socket");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ struct sockaddr_in serverAddress;
|
|
||||||
+ memset(&serverAddress, 0, sizeof(serverAddress));
|
|
||||||
+ serverAddress.sin_family = AF_INET;
|
|
||||||
+ serverAddress.sin_addr.s_addr = INADDR_ANY;
|
|
||||||
+ serverAddress.sin_port = htons(PORT);
|
|
||||||
+
|
|
||||||
+ if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
|
|
||||||
+ perror("Binding failed");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ printf("Waiting for client connection\n");
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ const int numThreads = 5;
|
|
||||||
+ pthread_t tids[numThreads];
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < numThreads; ++i) {
|
|
||||||
+ if (pthread_create(&tids[i], NULL, handleClient, &serverSocket) != 0) {
|
|
||||||
+ perror("Create thread failed");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < numThreads; ++i) {
|
|
||||||
+ pthread_join(tids[i], NULL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
From c5883ae776d766ed0516af636739e09dd5fda04b Mon Sep 17 00:00:00 2001
|
|
||||||
From: LHesperus <2639350497@qq.com>
|
|
||||||
Date: Tue, 28 Nov 2023 10:37:33 +0800
|
|
||||||
Subject: [PATCH] update doc link
|
|
||||||
|
|
||||||
---
|
|
||||||
extra-tools/da-tool/README.md | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/extra-tools/da-tool/README.md b/extra-tools/da-tool/README.md
|
|
||||||
index 157af65..c7a67db 100644
|
|
||||||
--- a/extra-tools/da-tool/README.md
|
|
||||||
+++ b/extra-tools/da-tool/README.md
|
|
||||||
@@ -29,6 +29,6 @@
|
|
||||||
|主题|内容简介|是否发布|
|
|
||||||
|:----|:-----|:----|
|
|
||||||
|[openEuler指南](https://gitee.com/openeuler/community/blob/master/zh/contributors/README.md)| 如何参与openEuler社区 | 已发布 |
|
|
||||||
-|[da-tool 使用指南](https://gitee.com/openeuler/docs/blob/stable2-20.03_LTS_SP3/docs/zh/docs/A-Ops/da-tool%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C.md)|1. 安装、配置和运行应用程序<br>2. 分析结果说明<br>3. 使用注意事项|已发布|
|
|
||||||
+|[时延分析工具 da-tool 使用手册](https://gitee.com/openeuler/docs/blob/stable2-20.03_LTS_SP4/docs/zh/docs/A-Ops/%E6%97%B6%E5%BB%B6%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7%20da-tool%20%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C.md)|1. 安装、配置和运行应用程序<br>2. 分析结果说明<br>3. 使用注意事项|已发布|
|
|
||||||
|da-tool设计文档|1. 技术原理<br> 2. 开发指南 |暂未发布|
|
|
||||||
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
aops-ceres-v1.4.0.tar.gz
Normal file
BIN
aops-ceres-v1.4.0.tar.gz
Normal file
Binary file not shown.
@ -1,25 +1,13 @@
|
|||||||
%define datool_with_testing 0
|
%define datool_with_testing 0
|
||||||
|
|
||||||
Name: aops-ceres
|
Name: aops-ceres
|
||||||
Version: v1.3.4
|
Version: v1.4.0
|
||||||
Release: 12
|
Release: 1
|
||||||
Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on.
|
Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on.
|
||||||
License: MulanPSL2
|
License: MulanPSL2
|
||||||
URL: https://gitee.com/openeuler/%{name}
|
URL: https://gitee.com/openeuler/%{name}
|
||||||
Source0: %{name}-%{version}.tar.gz
|
Source0: %{name}-%{version}.tar.gz
|
||||||
Patch0001: 0001-support-kabi-check.patch
|
|
||||||
Patch0002: 0002-modify-re-of-kernel-filter.patch
|
|
||||||
Patch0003: 0003-fix-bug-in-test_hotpatch.py.patch
|
|
||||||
Patch0004: 0004-Modify-method-of-mark-invalid-data-and-add-summary.patch
|
|
||||||
Patch0005: 0005-add-specific-error-information.patch
|
|
||||||
Patch0006: 0006-update-return-log-field-of-the-cve-fix-func.patch
|
|
||||||
Patch0007: 0007-add-usage-and-repet-config-check.patch
|
|
||||||
Patch0008: 0008-add-command-check-config-check-test-case.patch
|
|
||||||
Patch0009: 0009-Dealing-with-situations-where-sched-are-missing.patch
|
|
||||||
Patch0010: 0010-Soft-links-for-documents.patch
|
|
||||||
Patch0011: 0011-fix-valid-time-of-pid-at-first-core-and-add-case.patch
|
|
||||||
Patch0012: 0012-update-doc-link.patch
|
|
||||||
Patch0013: 0013-restrict-function-redesign-trace-check-proc.patch
|
|
||||||
|
|
||||||
BuildRequires: python3-setuptools
|
BuildRequires: python3-setuptools
|
||||||
Requires: python3-requests python3-jsonschema python3-libconf
|
Requires: python3-requests python3-jsonschema python3-libconf
|
||||||
@ -47,7 +35,7 @@ Requires: perf
|
|||||||
da-tool is a sampling and analysis tool for function delay.
|
da-tool is a sampling and analysis tool for function delay.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n %{name}-%{version} -p1
|
%autosetup -n %{name}-%{version}
|
||||||
|
|
||||||
|
|
||||||
# build for aops-ceres
|
# build for aops-ceres
|
||||||
@ -99,6 +87,10 @@ install -b -m500 ./extra-tools/da-tool/script/da-tool.sh ${RPM_BUILD_ROOT}
|
|||||||
%attr(0500, root, root) %{_bindir}/da-tool-analysis
|
%attr(0500, root, root) %{_bindir}/da-tool-analysis
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Dec 12 2023 wenxin<wenxin32@foxmail.com> - v1.4.0-1
|
||||||
|
- Change CVE rollback task to hotpatch remove
|
||||||
|
- update cve scan method and cve fix method
|
||||||
|
|
||||||
* Mon Dec 4 2023 liuchanggeng<liuchanggeng@huawei.com> - v1.3.4-12
|
* Mon Dec 4 2023 liuchanggeng<liuchanggeng@huawei.com> - v1.3.4-12
|
||||||
- to maintain functional stability, da-tool only releases network related analysis
|
- to maintain functional stability, da-tool only releases network related analysis
|
||||||
- it is not allowed to modify the configuration file of the da-tool
|
- it is not allowed to modify the configuration file of the da-tool
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user