From ce16eb7d8da5cc8467cc1106e02caf5bc5cbeca2 Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Thu, 11 Jul 2024 03:32:36 -0400 Subject: [PATCH 1/6] Add try when using psutil.process_iter --- src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py | 6 +++++- .../dhcp_utilities/dhcprelayd/dhcprelayd.py | 6 +++++- .../dhcp_utilities/dhcpservd/dhcpservd.py | 6 +++++- src/sonic-dhcp-utilities/tests/common_utils.py | 5 ++++- src/sonic-dhcp-utilities/tests/test_dhcprelayd.py | 1 + src/sonic-dhcp-utilities/tests/test_dhcpservd.py | 1 + src/sonic-dhcp-utilities/tests/test_utils.py | 3 ++- 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py index f6975c452cdd..9663c1e07d30 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py @@ -160,7 +160,11 @@ def get_target_process_cmds(process_name): """ res = [] for proc in psutil.process_iter(): - if proc.name() == process_name: + try: + curr_proc_name = proc.name() + except psutil.NoSuchProcess: + continue + if curr_proc_name == process_name: res.append(proc.cmdline()) return res diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py index 66139500d0a5..4d7ed0fbee8d 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py @@ -319,7 +319,11 @@ def _kill_exist_relay_releated_process(self, new_dhcp_interfaces, process_name, # Get old dhcrelay process and get old dhcp interfaces for proc in psutil.process_iter(): - if proc.name() == process_name: + try: + curr_proc_name = proc.name() + except psutil.NoSuchProcess: + continue + if curr_proc_name == process_name: cmds = proc.cmdline() index = 0 target_procs.append(proc) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py index e8341e436b7c..4bdf996e73c8 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py @@ -39,7 +39,11 @@ def _notify_kea_dhcp4_proc(self): Send SIGHUP signal to kea-dhcp4 process """ for proc in psutil.process_iter(): - if KEA_DHCP4_PROC_NAME in proc.name(): + try: + curr_proc_name = proc.name() + except psutil.NoSuchProcess: + continue + if KEA_DHCP4_PROC_NAME in curr_proc_name: proc.send_signal(signal.SIGHUP) break diff --git a/src/sonic-dhcp-utilities/tests/common_utils.py b/src/sonic-dhcp-utilities/tests/common_utils.py index 6f3c07a174f8..bae3f6e03f96 100644 --- a/src/sonic-dhcp-utilities/tests/common_utils.py +++ b/src/sonic-dhcp-utilities/tests/common_utils.py @@ -65,11 +65,14 @@ def mock_get_config_db_table(table_name): class MockProc(object): - def __init__(self, name, pid=None, status=psutil.STATUS_RUNNING): + def __init__(self, name, pid=None, exited=False): self.proc_name = name self.pid = pid + self.exited = exited def name(self): + if self.exited: + raise psutil.NoSuchProcess(self.pid) return self.proc_name def send_signal(self, sig_num): diff --git a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py index 0cc95ad6a21c..d63641b1255c 100644 --- a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py +++ b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py @@ -111,6 +111,7 @@ def test_kill_exist_relay_releated_process(mock_swsscommon_dbconnector_init, new process_iter_ret = [] for running_proc in running_procs: process_iter_ret.append(MockProc(running_proc)) + process_iter_ret.append(MockProc("exited_proc", exited=True)) with patch.object(psutil, "process_iter", return_value=process_iter_ret), \ patch.object(ConfigDbEventChecker, "enable"): dhcp_db_connector = DhcpDbConnector() diff --git a/src/sonic-dhcp-utilities/tests/test_dhcpservd.py b/src/sonic-dhcp-utilities/tests/test_dhcpservd.py index 4c8175b7e0bc..b55703aeb416 100644 --- a/src/sonic-dhcp-utilities/tests/test_dhcpservd.py +++ b/src/sonic-dhcp-utilities/tests/test_dhcpservd.py @@ -66,6 +66,7 @@ def test_dump_dhcp4_config(mock_swsscommon_dbconnector_init, enabled_checker): def test_notify_kea_dhcp4_proc(process_list, mock_swsscommon_dbconnector_init, mock_get_render_template, mock_parse_port_map_alias): proc_list = [MockProc(process_name) for process_name in process_list] + proc_list.append(MockProc("exited_proc", exited=True)) with patch.object(psutil, "process_iter", return_value=proc_list), \ patch.object(MockProc, "send_signal", MagicMock()) as mock_send_signal: dhcp_db_connector = DhcpDbConnector() diff --git a/src/sonic-dhcp-utilities/tests/test_utils.py b/src/sonic-dhcp-utilities/tests/test_utils.py index cf69c2f93377..383abeeb115d 100644 --- a/src/sonic-dhcp-utilities/tests/test_utils.py +++ b/src/sonic-dhcp-utilities/tests/test_utils.py @@ -142,7 +142,8 @@ def test_validate_ttr_type(test_data): def test_get_target_process_cmds(): - with patch.object(psutil, "process_iter", return_value=[MockProc("dhcrelay", 1), MockProc("dhcpmon", 2)], + with patch.object(psutil, "process_iter", return_value=[MockProc("dhcrelay", 1), MockProc("dhcpmon", 2), + MockProc("exited_proc", 3, exited=True)], new_callable=PropertyMock): res = utils.get_target_process_cmds("dhcrelay") expected_res = [ From 2e5f684a3f0aec670de3e0da452ac7f9cd59f2fa Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Thu, 11 Jul 2024 05:14:55 -0400 Subject: [PATCH 2/6] Update --- .../dhcp_utilities/common/utils.py | 9 +++--- .../dhcp_utilities/dhcprelayd/dhcprelayd.py | 30 ++++++++++--------- .../dhcp_utilities/dhcpservd/dhcpservd.py | 7 ++--- .../tests/common_utils.py | 4 ++- .../tests/test_dhcprelayd.py | 20 ++++++++----- src/sonic-dhcp-utilities/tests/test_utils.py | 18 ++++------- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py index 9663c1e07d30..a130bb47104e 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py @@ -150,22 +150,21 @@ def _parse_table_to_dict(table): return ret -def get_target_process_cmds(process_name): +def get_target_process(process_name): """ Get running process cmds Args: process_name: name of process Returns: - List of cmds list + List of process """ res = [] for proc in psutil.process_iter(): try: - curr_proc_name = proc.name() + if proc.name() == process_name: + res.append(proc) except psutil.NoSuchProcess: continue - if curr_proc_name == process_name: - res.append(proc.cmdline()) return res diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py index 4d7ed0fbee8d..5413755e218d 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py @@ -8,7 +8,7 @@ import syslog import time from swsscommon import swsscommon -from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process_cmds, is_smart_switch +from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process, is_smart_switch from dhcp_utilities.common.dhcp_db_monitor import DhcpRelaydDbMonitor, DhcpServerTableIntfEnablementEventChecker, \ VlanTableEventChecker, VlanIntfTableEventChecker, DhcpServerFeatureStateChecker, MidPlaneTableEventChecker @@ -224,7 +224,10 @@ def _check_dhcp_relay_processes(self): """ Check whether dhcrelay running as expected, if not, dhcprelayd will exit with code 1 """ - running_cmds = get_target_process_cmds("dhcrelay") + try: + running_cmds = [proc.cmdline() for proc in get_target_process("dhcrelay")] + except psutil.NoSuchProcess: + running_cmds = [] running_cmds.sort() expected_cmds = [value for key, value in self.dhcp_relay_supervisor_config.items() if "isc-dhcpv4-relay" in key] expected_cmds.sort() @@ -318,21 +321,20 @@ def _kill_exist_relay_releated_process(self, new_dhcp_interfaces, process_name, target_procs = [] # Get old dhcrelay process and get old dhcp interfaces - for proc in psutil.process_iter(): + for proc in get_target_process(process_name): try: - curr_proc_name = proc.name() + cmds = proc.cmdline() except psutil.NoSuchProcess: continue - if curr_proc_name == process_name: - cmds = proc.cmdline() - index = 0 - target_procs.append(proc) - while index < len(cmds): - if cmds[index] == "-id": - old_dhcp_interfaces.add(cmds[index + 1]) - index += 2 - else: - index += 1 + + index = 0 + target_procs.append(proc) + while index < len(cmds): + if cmds[index] == "-id": + old_dhcp_interfaces.add(cmds[index + 1]) + index += 2 + else: + index += 1 if len(target_procs) == 0: return NOT_FOUND_PROC diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py index 4bdf996e73c8..73a928eb08c9 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcpservd/dhcpservd.py @@ -40,12 +40,11 @@ def _notify_kea_dhcp4_proc(self): """ for proc in psutil.process_iter(): try: - curr_proc_name = proc.name() + if KEA_DHCP4_PROC_NAME in proc.name(): + proc.send_signal(signal.SIGHUP) + break except psutil.NoSuchProcess: continue - if KEA_DHCP4_PROC_NAME in curr_proc_name: - proc.send_signal(signal.SIGHUP) - break def dump_dhcp4_config(self): """ diff --git a/src/sonic-dhcp-utilities/tests/common_utils.py b/src/sonic-dhcp-utilities/tests/common_utils.py index bae3f6e03f96..f5eb4e018f86 100644 --- a/src/sonic-dhcp-utilities/tests/common_utils.py +++ b/src/sonic-dhcp-utilities/tests/common_utils.py @@ -65,7 +65,7 @@ def mock_get_config_db_table(table_name): class MockProc(object): - def __init__(self, name, pid=None, exited=False): + def __init__(self, name, pid=1, exited=False): self.proc_name = name self.pid = pid self.exited = exited @@ -79,6 +79,8 @@ def send_signal(self, sig_num): pass def cmdline(self): + if self.exited: + raise psutil.NoSuchProcess(self.pid) if self.proc_name == "dhcrelay": return ["/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2"] diff --git a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py index d63641b1255c..edc5cb8daac4 100644 --- a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py +++ b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py @@ -195,23 +195,27 @@ def test_execute_supervisor_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_run.assert_called_once_with(["supervisorctl", op, "dhcpmon-Vlan1000"], check=True) -@pytest.mark.parametrize("target_cmds", [[["/usr/bin/dhcrelay"]], [["/usr/bin/dhcpmon"]]]) -def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, target_cmds): - exp_config = {"isc-dhcpv4-relay-Vlan1000": ["/usr/bin/dhcrelay"]} - with patch("dhcp_utilities.dhcprelayd.dhcprelayd.get_target_process_cmds", return_value=target_cmds), \ +@pytest.mark.parametrize("target_procs", [[MockProc("dhcrelay")], [MockProc("dhcrelay", exited=True)], + [MockProc("dhcpmon")]]) +def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, target_procs): + exp_config = { + "isc-dhcpv4-relay-Vlan1000": [ + "/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", + "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2" + ] + } + with patch("dhcp_utilities.dhcprelayd.dhcprelayd.get_target_process", return_value=target_procs), \ patch.object(DhcpRelayd, "dhcp_relay_supervisor_config", return_value=exp_config, new_callable=PropertyMock), \ patch.object(sys, "exit", mock_exit_func): dhcp_db_connector = DhcpDbConnector() dhcprelayd = DhcpRelayd(dhcp_db_connector, None) - exp_cmds = [value for key, value in exp_config.items() if "isc-dhcpv4-relay" in key] - exp_cmds.sort() try: dhcprelayd._check_dhcp_relay_processes() except SystemExit: - assert exp_cmds != target_cmds + assert target_procs[0].exited or target_procs[0].name() != "dhcrelay" else: - assert exp_cmds == target_cmds + assert not target_procs[0].exited and target_procs[0].name() == "dhcrelay" def test_get_dhcp_relay_config(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init): diff --git a/src/sonic-dhcp-utilities/tests/test_utils.py b/src/sonic-dhcp-utilities/tests/test_utils.py index 383abeeb115d..e1cb407abc65 100644 --- a/src/sonic-dhcp-utilities/tests/test_utils.py +++ b/src/sonic-dhcp-utilities/tests/test_utils.py @@ -141,18 +141,12 @@ def test_validate_ttr_type(test_data): assert res == test_data[2] -def test_get_target_process_cmds(): - with patch.object(psutil, "process_iter", return_value=[MockProc("dhcrelay", 1), MockProc("dhcpmon", 2), - MockProc("exited_proc", 3, exited=True)], - new_callable=PropertyMock): - res = utils.get_target_process_cmds("dhcrelay") - expected_res = [ - [ - "/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", - "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2" - ] - ] - assert res == expected_res +def test_get_target_process(): + proc_list = [MockProc("dhcrelay", 1), MockProc("dhcpmon", 2), + MockProc("exited_proc", 3, exited=True)] + with patch.object(psutil, "process_iter", return_value=proc_list, new_callable=PropertyMock): + res = utils.get_target_process("dhcrelay") + assert res == [proc_list[0]] @pytest.mark.parametrize("is_smart_switch", [True, False]) From 4b7f9ad103739d902364649f3ac348872b1c2287 Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Thu, 11 Jul 2024 05:15:37 -0400 Subject: [PATCH 3/6] Set include_dhcp_server to y --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index 6425005d646b..502184690194 100644 --- a/rules/config +++ b/rules/config @@ -150,7 +150,7 @@ INCLUDE_NAT = y INCLUDE_DHCP_RELAY = y # INCLUDE_DHCP_SERVER - build and install dhcp-server package -INCLUDE_DHCP_SERVER ?= n +INCLUDE_DHCP_SERVER ?= y # INCLUDE_P4RT - build docker-p4rt for P4RT support INCLUDE_P4RT = n From 84298a32dedf94fb541e5e36f2a00152de1b3223 Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Thu, 11 Jul 2024 23:27:05 -0400 Subject: [PATCH 4/6] Revert "Set include_dhcp_server to y" This reverts commit 4b7f9ad103739d902364649f3ac348872b1c2287. --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index 502184690194..6425005d646b 100644 --- a/rules/config +++ b/rules/config @@ -150,7 +150,7 @@ INCLUDE_NAT = y INCLUDE_DHCP_RELAY = y # INCLUDE_DHCP_SERVER - build and install dhcp-server package -INCLUDE_DHCP_SERVER ?= y +INCLUDE_DHCP_SERVER ?= n # INCLUDE_P4RT - build docker-p4rt for P4RT support INCLUDE_P4RT = n From e03ef8beb8e3c23a2de65a2f05fd764478bea2cd Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Mon, 15 Jul 2024 03:19:12 -0400 Subject: [PATCH 5/6] Update --- .../dhcp_utilities/common/utils.py | 14 ++++++++++++++ .../dhcp_utilities/dhcprelayd/dhcprelayd.py | 18 ++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py index a130bb47104e..59051e6cb720 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py @@ -168,6 +168,20 @@ def get_target_process(process_name): return res +def get_process_cmd(proc): + """ + Get running process cmd + Args: + proc: process handler + Returns: + List of cmd, None if process not exist + """ + try: + return proc.cmdline() + except psutil.NoSuchProcess: + return None + + def is_smart_switch(device_metadata): """ Check in device metadata whether subtype is smartswitch diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py index 5413755e218d..af05c6edd50b 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py @@ -8,7 +8,8 @@ import syslog import time from swsscommon import swsscommon -from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process, is_smart_switch +from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process, is_smart_switch, \ + get_process_cmd from dhcp_utilities.common.dhcp_db_monitor import DhcpRelaydDbMonitor, DhcpServerTableIntfEnablementEventChecker, \ VlanTableEventChecker, VlanIntfTableEventChecker, DhcpServerFeatureStateChecker, MidPlaneTableEventChecker @@ -224,10 +225,12 @@ def _check_dhcp_relay_processes(self): """ Check whether dhcrelay running as expected, if not, dhcprelayd will exit with code 1 """ - try: - running_cmds = [proc.cmdline() for proc in get_target_process("dhcrelay")] - except psutil.NoSuchProcess: - running_cmds = [] + running_cmds = [] + for proc in get_target_process("dhcrelay"): + cmd = get_process_cmd(proc) + if cmd is None: + continue + running_cmds.append(cmd) running_cmds.sort() expected_cmds = [value for key, value in self.dhcp_relay_supervisor_config.items() if "isc-dhcpv4-relay" in key] expected_cmds.sort() @@ -322,9 +325,8 @@ def _kill_exist_relay_releated_process(self, new_dhcp_interfaces, process_name, # Get old dhcrelay process and get old dhcp interfaces for proc in get_target_process(process_name): - try: - cmds = proc.cmdline() - except psutil.NoSuchProcess: + cmds = get_process_cmd(proc) + if cmds is None: continue index = 0 From 6e5df96b16e74e9d2657b77be453f7ce48731e0b Mon Sep 17 00:00:00 2001 From: yaqiangz Date: Mon, 15 Jul 2024 04:28:16 -0400 Subject: [PATCH 6/6] Update --- .../dhcp_utilities/common/utils.py | 20 ++--------- .../dhcp_utilities/dhcprelayd/dhcprelayd.py | 35 ++++++++----------- .../tests/test_dhcprelayd.py | 16 ++++----- src/sonic-dhcp-utilities/tests/test_utils.py | 19 ++++++---- 4 files changed, 37 insertions(+), 53 deletions(-) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py index 59051e6cb720..325553f536af 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py @@ -150,38 +150,24 @@ def _parse_table_to_dict(table): return ret -def get_target_process(process_name): +def get_target_process_cmds(process_name): """ Get running process cmds Args: process_name: name of process Returns: - List of process + List of cmds list """ res = [] for proc in psutil.process_iter(): try: if proc.name() == process_name: - res.append(proc) + res.append(proc.cmdline()) except psutil.NoSuchProcess: continue return res -def get_process_cmd(proc): - """ - Get running process cmd - Args: - proc: process handler - Returns: - List of cmd, None if process not exist - """ - try: - return proc.cmdline() - except psutil.NoSuchProcess: - return None - - def is_smart_switch(device_metadata): """ Check in device metadata whether subtype is smartswitch diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py index af05c6edd50b..01e6d5499cf5 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py @@ -8,8 +8,7 @@ import syslog import time from swsscommon import swsscommon -from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process, is_smart_switch, \ - get_process_cmd +from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process_cmds, is_smart_switch from dhcp_utilities.common.dhcp_db_monitor import DhcpRelaydDbMonitor, DhcpServerTableIntfEnablementEventChecker, \ VlanTableEventChecker, VlanIntfTableEventChecker, DhcpServerFeatureStateChecker, MidPlaneTableEventChecker @@ -225,12 +224,7 @@ def _check_dhcp_relay_processes(self): """ Check whether dhcrelay running as expected, if not, dhcprelayd will exit with code 1 """ - running_cmds = [] - for proc in get_target_process("dhcrelay"): - cmd = get_process_cmd(proc) - if cmd is None: - continue - running_cmds.append(cmd) + running_cmds = get_target_process_cmds("dhcrelay") running_cmds.sort() expected_cmds = [value for key, value in self.dhcp_relay_supervisor_config.items() if "isc-dhcpv4-relay" in key] expected_cmds.sort() @@ -324,19 +318,20 @@ def _kill_exist_relay_releated_process(self, new_dhcp_interfaces, process_name, target_procs = [] # Get old dhcrelay process and get old dhcp interfaces - for proc in get_target_process(process_name): - cmds = get_process_cmd(proc) - if cmds is None: + for proc in psutil.process_iter(): + try: + if proc.name() == process_name: + cmds = proc.cmdline() + index = 0 + target_procs.append(proc) + while index < len(cmds): + if cmds[index] == "-id": + old_dhcp_interfaces.add(cmds[index + 1]) + index += 2 + else: + index += 1 + except psutil.NoSuchProcess: continue - - index = 0 - target_procs.append(proc) - while index < len(cmds): - if cmds[index] == "-id": - old_dhcp_interfaces.add(cmds[index + 1]) - index += 2 - else: - index += 1 if len(target_procs) == 0: return NOT_FOUND_PROC diff --git a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py index edc5cb8daac4..4914ff020d63 100644 --- a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py +++ b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py @@ -195,16 +195,12 @@ def test_execute_supervisor_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_run.assert_called_once_with(["supervisorctl", op, "dhcpmon-Vlan1000"], check=True) -@pytest.mark.parametrize("target_procs", [[MockProc("dhcrelay")], [MockProc("dhcrelay", exited=True)], - [MockProc("dhcpmon")]]) -def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, target_procs): +@pytest.mark.parametrize("target_procs_cmds", [[["dhcrelay", "-d"]], [["dhcpmon"]]]) +def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, target_procs_cmds): exp_config = { - "isc-dhcpv4-relay-Vlan1000": [ - "/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", - "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2" - ] + "isc-dhcpv4-relay-Vlan1000": ["dhcrelay", "-d"] } - with patch("dhcp_utilities.dhcprelayd.dhcprelayd.get_target_process", return_value=target_procs), \ + with patch("dhcp_utilities.dhcprelayd.dhcprelayd.get_target_process_cmds", return_value=target_procs_cmds), \ patch.object(DhcpRelayd, "dhcp_relay_supervisor_config", return_value=exp_config, new_callable=PropertyMock), \ patch.object(sys, "exit", mock_exit_func): @@ -213,9 +209,9 @@ def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscom try: dhcprelayd._check_dhcp_relay_processes() except SystemExit: - assert target_procs[0].exited or target_procs[0].name() != "dhcrelay" + assert target_procs_cmds[0] != exp_config["isc-dhcpv4-relay-Vlan1000"] else: - assert not target_procs[0].exited and target_procs[0].name() == "dhcrelay" + assert target_procs_cmds[0] == exp_config["isc-dhcpv4-relay-Vlan1000"] def test_get_dhcp_relay_config(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init): diff --git a/src/sonic-dhcp-utilities/tests/test_utils.py b/src/sonic-dhcp-utilities/tests/test_utils.py index e1cb407abc65..4a41049fe06e 100644 --- a/src/sonic-dhcp-utilities/tests/test_utils.py +++ b/src/sonic-dhcp-utilities/tests/test_utils.py @@ -141,12 +141,19 @@ def test_validate_ttr_type(test_data): assert res == test_data[2] -def test_get_target_process(): - proc_list = [MockProc("dhcrelay", 1), MockProc("dhcpmon", 2), - MockProc("exited_proc", 3, exited=True)] - with patch.object(psutil, "process_iter", return_value=proc_list, new_callable=PropertyMock): - res = utils.get_target_process("dhcrelay") - assert res == [proc_list[0]] +def test_get_target_process_cmds(): + with patch.object(psutil, "process_iter", return_value=[MockProc("dhcrelay", 1), + MockProc("dhcrelay", 1, exited=True), + MockProc("dhcpmon", 2)], + new_callable=PropertyMock): + res = utils.get_target_process_cmds("dhcrelay") + expected_res = [ + [ + "/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", + "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2" + ] + ] + assert res == expected_res @pytest.mark.parametrize("is_smart_switch", [True, False])