Skip to content

Commit 74df8d2

Browse files
committed
tests: skip 16-bit guard copy tests when namespace is in 64-bit guard PI mode
When ns_mgmt_supported=False, TestNVMe.setUp/tearDown never touch the namespace. If the device is configured with 64-bit guard PI (e.g. QEMU started with pif=2, or namespace left reformatted by a previous run), copy descriptor format 0 and format 2 commands would fail with NVMe status "Invalid Format" instead of being skipped cleanly. Signed-off-by: Daniel Wagner <wagi@kernel.org>
1 parent 3c82378 commit 74df8d2

1 file changed

Lines changed: 57 additions & 1 deletion

File tree

tests/nvme_copy_test.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,53 @@ def _check_ns_copy_limits(self):
8686
if missing:
8787
self.skipTest(f"{', '.join(missing)} are 0, copy not supported on this namespace")
8888

89+
def _get_current_ns_pif(self):
90+
"""
91+
Return the Protection Information Format (pif) of the currently active
92+
LBA format on self.ns1.
93+
94+
Reads the raw ``flbas`` byte from ``id-ns`` to determine the active
95+
lbaf index (NVMe spec: bits[3:0] are lbaf_index[3:0], bits[6:5] are
96+
lbaf_index[5:4]), then looks up that entry in the ``nvm-id-ns`` elbafs
97+
array. Returns 0 if either command fails or the pif field is absent
98+
(0 = 16-bit guard / no PI, the safe default for format 0/2 copy).
99+
"""
100+
id_ns_cmd = f"{self.nvme_bin} id-ns {self.ns1} --output-format=json"
101+
result = self.run_cmd(id_ns_cmd)
102+
if result.returncode != 0:
103+
return 0
104+
flbas = int(json.loads(result.stdout).get("flbas", 0))
105+
lbaf_idx = (flbas & 0xF) | (((flbas >> 5) & 0x3) << 4)
106+
107+
nvm_id_ns_cmd = f"{self.nvme_bin} nvm-id-ns {self.ns1} --output-format=json"
108+
result = self.run_cmd(nvm_id_ns_cmd)
109+
if result.returncode != 0:
110+
return 0
111+
elbafs = json.loads(result.stdout).get("elbafs", [])
112+
if lbaf_idx < len(elbafs):
113+
return elbafs[lbaf_idx].get("pif", 0)
114+
return 0
115+
116+
def _check_16b_guard_ns(self):
117+
"""
118+
Skip the test if the current namespace uses a non-16-bit-guard PI
119+
format and namespace management is not available to restore it.
120+
121+
Copy descriptor formats 0 and 2 require the namespace to use 16-bit
122+
guard PI (pif=0) or no PI. When namespace management is supported,
123+
TestNVMe.setUp() already recreates the namespace with flbas=0 (no
124+
metadata, no PI), so this is a no-op in that case. When namespace
125+
management is not available and the namespace is already in a 64-bit
126+
guard PI format (e.g. QEMU started with pif=2, or left over from a
127+
previous test run), the copy command would fail with "Invalid Format"
128+
rather than being skipped cleanly.
129+
"""
130+
if not self.ns_mgmt_supported and self._get_current_ns_pif() != 0:
131+
self.skipTest(
132+
"current namespace uses non-16-bit-guard PI and namespace "
133+
"management is not supported; cannot run 16-bit guard copy test"
134+
)
135+
89136
def _find_64b_guard_lbaf_index(self):
90137
"""
91138
Search the nvm-id-ns elbafs for a format with 64-bit guard PI (pif == 2).
@@ -215,9 +262,16 @@ class TestNVMeCopyFormat0(TestNVMeCopy):
215262
NVMe Copy tests using Descriptor Format 0.
216263
217264
Format 0 uses 16-bit guard PI and copies within a single namespace.
218-
No special namespace formatting is required.
265+
No special namespace formatting is required; the test is skipped if the
266+
current namespace is already using a non-16-bit-guard PI format and
267+
namespace management is not available to restore it.
219268
"""
220269

270+
def setUp(self):
271+
""" Pre Section for TestNVMeCopyFormat0 """
272+
super().setUp()
273+
self._check_16b_guard_ns()
274+
221275
def test_copy_format_0(self):
222276
""" Test copy with descriptor format 0 """
223277
self._check_format_supported(0)
@@ -275,13 +329,15 @@ def _run_format_3_copy(self, **kwargs):
275329
def test_copy_format_2(self):
276330
""" Test copy with descriptor format 2 """
277331
self._check_format_supported(2)
332+
self._check_16b_guard_ns()
278333
self._check_ns_copy_limits()
279334
self._enable_cdfe_for_format(2)
280335
self.copy(0, 1, 2, descriptor_format=2, snsids=self.ns1_nsid)
281336

282337
def test_copy_format_2_sopts(self):
283338
""" Test copy with descriptor format 2 and source options """
284339
self._check_format_supported(2)
340+
self._check_16b_guard_ns()
285341
self._check_ns_copy_limits()
286342
self._enable_cdfe_for_format(2)
287343
self.copy(0, 1, 2, descriptor_format=2, snsids=self.ns1_nsid, sopts=0)

0 commit comments

Comments
 (0)