Ip: allow set_mtu to skip asserting the resulting mtu - #4657
Conversation
6cb3067 to
738c997
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the Ip tool’s set_mtu helper to support “best-effort” MTU updates for drivers that clamp/ignore MTU changes, by adding an assert_success flag (defaulting to the current strict behavior).
Changes:
- Extend
Ip.set_mtu()withassert_success: bool = True. - When
assert_successis disabled, avoid failing the caller on MTU readback mismatch (intended behavior per PR description).
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
738c997 to
60ffe9e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:275
- When
assert_successis False, the code currently logs only that the assertion was skipped, but it doesn’t log the actual MTU mismatch. This contradicts the PR description (“logs the mismatch instead of failing”) and makes troubleshooting harder. Consider logging nic name + requested/actual MTU, and reuse that context in the exception message whenassert_successis True.
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
self.node.log.debug(
"set_mtu: skipping result assertion since assert_success was False. "
)
lisa/tools/ip.py:268
- There’s a whitespace-only line after the
ip link setcall (line 267). This can trip linters and creates noisy diffs; use a real blank line (no trailing spaces).
self.run(f"link set dev {nic_name} mtu {mtu}", force_run=True, sudo=True)
new_mtu = self.get_mtu(nic_name=nic_name)
60ffe9e to
b6543d8
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:274
- When
assert_success=False, the debug log doesn’t include the interface name or the requested/actual MTU, which makes it hard to diagnose driver clamping/ignoring MTU changes. Also, there’s a whitespace-only line after theip link setcall that can trip linters.
self.run(f"link set dev {nic_name} mtu {mtu}", force_run=True, sudo=True)
new_mtu = self.get_mtu(nic_name=nic_name)
if new_mtu != mtu:
if assert_success:
lisa/tools/ip.py:262
- Nit:
mtu_fileassignment is missing spaces around=, and theelse:block is unnecessary. Keeping this aligned with the surrounding style improves readability and avoids lint noise.
mtu_file=f"/sys/class/net/{nic_name}/mtu"
if self.node.shell.exists(self.node.get_pure_path(mtu_file)):
return int(cat.read(mtu_file, force_run=True))
else:
return int(self.get_detail(nic_name, "mtu"))
d09e593 to
48e69ea
Compare
48e69ea to
df9ba93
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:279
set_mtu(..., assert_success=False)is described as logging the MTU mismatch instead of failing, but the current debug message doesn't include the wanted/got MTU (or nic name), making the log much less actionable. Also, whenassert_success=True, the exception message should include the nic and a hint to useassert_success=Falsefor best-effort updates on drivers that clamp MTU.
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
self.node.log.debug(
"set_mtu: skipping result assertion since assert_success was False. "
)
lisa/tools/ip.py:262
- PEP 8/style: add spaces around the assignment, and avoid the redundant
elseafter an earlyreturnto keep the control flow clearer.
mtu_file=f"/sys/class/net/{nic_name}/mtu"
if self.node.shell.exists(self.node.get_pure_path(mtu_file)):
return int(cat.read(mtu_file, force_run=True))
else:
return int(self.get_detail(nic_name, "mtu"))
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:279
- When
assert_success=False, the code logs a generic message but does not log the actual MTU mismatch (wanted vs observed), even though the PR description states the mismatch should be logged. Also, the failure exception message could include a hint that some drivers clamp/ignore MTU changes and how to proceed.
new_mtu = self.get_mtu(nic_name=nic_name)
if new_mtu != mtu:
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
self.node.log.debug(
"set_mtu: skipping result assertion since assert_success was False. "
)
lisa/tools/ip.py:262
get_mtu()falls back toget_detail()when the sysfs MTU file is missing, butget_detail()callsself.run(..., force_run=False)which is cached byTool.run_async(command+flags). That can return stale MTU values afterset_mtu()and cause false mismatches/failures. Use a forcedip -d link showcall (or otherwise bypass the cache) in this fallback path.
def get_mtu(self, nic_name: str) -> int:
cat = self.node.tools[Cat]
mtu_file=f"/sys/class/net/{nic_name}/mtu"
if self.node.shell.exists(self.node.get_pure_path(mtu_file)):
return int(cat.read(mtu_file, force_run=True))
else:
return int(self.get_detail(nic_name, "mtu"))
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
lisa/tools/ip.py:291
- When
assert_success=Falseand the MTU doesn't match, the log message doesn't include the interface name or the wanted/actual MTU values, which makes troubleshooting harder (especially since the whole point of the flag is to allow silent clamping).
if new_mtu != mtu:
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
self.node.log.debug(
"set_mtu: skipping result assertion since assert_success was False. "
)
lisa/tools/ip.py:262
- PEP8/style: missing spaces around
=in themtu_fileassignment, and theelse:is unnecessary after areturn. This file generally uses standard spacing and early returns.
def get_mtu(self, nic_name: str) -> int:
cat = self.node.tools[Cat]
mtu_file=f"/sys/class/net/{nic_name}/mtu"
if self.node.shell.exists(self.node.get_pure_path(mtu_file)):
return int(cat.read(mtu_file, force_run=True))
else:
return int(self.get_detail(nic_name, "mtu"))
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Suppressed comments (3)
lisa/tools/iperf3.py:108
get_version()and_is_buggy_multithreaded_version()reference_version_pattern,_first_multithreaded_version, and_first_fixed_version, but those attributes are not defined anywhere in this class/file. This will raise AttributeError at runtime and prevents the intended version gating from working.
def get_version(self) -> Optional[LisaVersionInfo]:
# ``iperf3 --version`` prints e.g. ``iperf 3.16 (cJSON 1.7.15)``.
output = self.run("--version", force_run=True).stdout
version_string = get_matched_str(output, self._version_pattern)
if not version_string:
lisa/tools/iperf3.py:133
_is_buggy_multithreaded_version()is currently unused, so known-buggy iperf3 versions will not trigger a source rebuild. If this method is intended to gate installs, incorporate it into the_install()decision.
def _install(self) -> bool:
posix_os: Posix = cast(Posix, self.node.os)
try:
posix_os.install_packages("iperf3")
lisa/tools/ip.py:296
- The exception message for an MTU mismatch omits the interface name and doesn't give any hint for how callers can handle drivers that clamp/ignore MTU changes (which is the motivation for
assert_success). Includingnic_nameand a brief remediation hint will make failures much easier to diagnose.
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
7411528 to
b032ba5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Suppressed comments (4)
lisa/tools/iperf3.py:22
parse_versionandLisaVersionInfoare used below but aren't imported in this module, causing a NameError whenget_version()is executed.
from lisa.util import LisaException, check_till_timeout, constants, get_matched_str
lisa/tools/ip.py:269
get_mtu()falls back to returning 0 when it can't read MTU from sysfs oripoutput. Returning 0 can silently mask real failures and will make callers treat MTU as valid (e.g. tests that log/compare MTU values). Prefer raising aLisaExceptionwhen MTU can't be determined so failures are actionable.
else:
mtu = self.get_detail(nic_name, "mtu")
if mtu:
return int(mtu)
else:
self.node.log.debug(
f"Could not find mtu information for interface {nic_name}"
)
return 0
lisa/tools/ip.py:299
- When
assert_successis True,set_mtu()previously failed via an assertion. The new code raisesLisaExceptionand also doesn't check whetherip link setitself succeeded before comparing MTU. To keep behavior consistent and provide clearer failures, capture the command result and (whenassert_successis True) assert on both the command exit code and the observed MTU; when false, log and return without raising.
self.run(f"link set dev {nic_name} mtu {mtu}", force_run=True, sudo=True)
new_mtu = self.get_mtu(nic_name=nic_name)
if new_mtu != mtu:
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
self.node.log.debug(
f"set_mtu: expected new mtu {mtu}, got {new_mtu} instead. "
lisa/microsoft/testsuites/dpdk/dpdktestpmd.py:601
queues_and_servicing_coreis initially calculated as(queues * len(nic_to_include)) + service_cores, but inside the reduction loop it's recomputed asqueues + service_cores, which ignores how many NICs are included and can under-allocate cores when more than one NIC is present.
while queues_and_servicing_core > (threads_available - 2 - core_offset):
# if less, split the number of queues
queues = queues // 2
queues_and_servicing_core = queues + service_cores
txd = 64 # txd has to be >= 64 for MANA.
b032ba5 to
090ee13
Compare
67bd2a6 to
193c72f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
lisa/tools/ip.py:296
- The new exception message on MTU mismatch doesn’t give any investigation/remediation guidance (and doesn’t include the interface name). Include
nic_nameand a hint that some drivers clamp MTU, and that callers can disable strict verification viaassert_success=False.
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
lisa/tools/ip.py:269
- get_mtu() returns 0 when MTU cannot be determined. 0 is not a valid MTU, and some callers persist the returned value and later pass it back into set_mtu (e.g., restoring MTU in a finally block), which could lead to attempts to set MTU=0 and confusing follow-on failures. Prefer raising a LisaException here so the root cause is explicit.
self.node.log.debug(
f"Could not find mtu information for interface {nic_name}"
)
return 0
lisa/tools/ip.py:296
- The new exception message on MTU mismatch doesn’t include the interface name or actionable guidance. Including both makes failures (or the reason to set assert_success=False) easier to troubleshoot.
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
AI Test Case SelectionSelected 2 test case(s): verify_network_interface_reload_via_ip_link,verify_xfrm_interface Marketplace image: Result: Succeeded |
Some drivers silently clamp or ignore an mtu change, and callers that only want a best effort change had no way to avoid the assertion. Add assert_success, defaulting to the existing behavior, and log the mismatch instead of failing when it is disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5d5f58ad-b9df-4420-ad37-22caee78e925
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:269
- get_mtu() returns 0 when it can’t determine the MTU. This can silently propagate an invalid MTU (e.g., callers may later restore MTU to 0, which will fail or misconfigure the NIC). It’s safer to fail fast with a clear exception when neither /sys nor
ip -d link showyields an MTU.
else:
self.node.log.debug(
f"Could not find mtu information for interface {nic_name}"
)
return 0
lisa/tools/ip.py:296
- The MTU mismatch exception message omits the interface name and doesn’t suggest a next step. Including the NIC and a brief investigation hint will make failures easier to triage (and aligns with other error messages in this file that include operation context).
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
AI Test Case SelectionSelected 1 test case(s): verify_network_interface_reload_via_ip_link Marketplace image: Result: Canceled |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/tools/ip.py:269
get_mtu()now returns0when it cannot find/parse the MTU. This silently changes behavior from the previous implementation (which would fail) and can cause callers to treat an unknown MTU as valid (e.g., later restoring MTU to 0). Consider raising aLisaExceptioninstead so failures are surfaced immediately.
else:
self.node.log.debug(
f"Could not find mtu information for interface {nic_name}"
)
return 0
lisa/tools/ip.py:297
set_mtu()doesn't check the exit code/output ofip link set ... mtu .... When the command fails, the raised exception (or debug log whenassert_success=False) loses the underlying reason from stderr/stdout, making failures hard to investigate. Capture the result, fail/log with command output, and avoid doing an MTU readback when the set command itself failed.
self.run(f"link set dev {nic_name} mtu {mtu}", force_run=True, sudo=True)
new_mtu = self.get_mtu(nic_name=nic_name)
if new_mtu != mtu:
if assert_success:
raise LisaException(f"set mtu failed, wanted {mtu} and got {new_mtu}")
else:
AI Test Case SelectionSelected 2 test case(s): verify_network_interface_reload_via_ip_link,verify_xfrm_interface Marketplace image: Result: Succeeded |
Part 4 of 9 of a stacked series that reworks the DPDK SRIOV hot plug tests. Stacked on #4656, review only the last commit.
Some drivers silently clamp or ignore an mtu change, and callers that only wanted a best effort change had no way to avoid the assertion.
set_mtugainsassert_success, defaulting to the existing behavior, and logs the mismatch instead of failing when it is disabled.Key Test Cases:
verify_dpdk_send_receive_multi_txrx_queue_failsafe|verify_dpdk_send_receive_netvsc
Impacted LISA Features:
Sriov, NetworkInterface
Tested Azure Marketplace Images:
canonical 0001-com-ubuntu-server-jammy 22_04-lts latest