Skip to content

Commit 970ebea

Browse files
Merge pull request #60 from robertbaldyga/dd-gnu-coreutils
dd: Resolve gnu-coreutils version of dd
2 parents 929be9f + 3128db0 commit 970ebea

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

test_tools/dd.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,55 @@
11
#
22
# Copyright(c) 2019-2021 Intel Corporation
33
# Copyright(c) 2024 Huawei Technologies Co., Ltd.
4+
# Copyright(c) 2026 Unvertical
45
# SPDX-License-Identifier: BSD-3-Clause
56
#
67

78
import type_def.size as size
89
from core.test_run import TestRun
10+
from connection.utils.output import CmdException
911
from test_tools.common.linux_command import LinuxCommand
1012

1113

14+
# TODO: Remove it when it's fixed in uutils.
15+
#
16+
# The uutils coreutils `dd` (the default `dd` on some recent distros, e.g.
17+
# Ubuntu 26.04) does not page-align its O_DIRECT buffer to bdev block size.
18+
# As a result iflag=direct / oflag=direct transfers are unreliable.
19+
# On kernel 7.0 there is a strict BIO alignment check, which makes I/O
20+
# fail, sometimes in very nasty ways, especially in bio-based block device
21+
# drivers.
22+
#
23+
# As a temporary solution, fall back to gnu-coreutils.
24+
_gnu_dd_binary = {}
25+
26+
27+
def _resolve_gnu_dd():
28+
executor = TestRun.executor
29+
cached = _gnu_dd_binary.get(id(executor))
30+
if cached:
31+
return cached
32+
33+
output = None
34+
for candidate in ("dd", "gnudd"):
35+
output = executor.run(f"{candidate} --version")
36+
version = f"{output.stdout}\n{output.stderr}".lower()
37+
if output.exit_code == 0 and "coreutils" in version and "uutils" not in version:
38+
_gnu_dd_binary[id(executor)] = candidate
39+
return candidate
40+
41+
raise CmdException(
42+
"GNU dd not found. The system 'dd' is not GNU coreutils (likely a uutils "
43+
"reimplementation, which mis-aligns O_DIRECT buffers) and no 'gnudd' binary "
44+
"is available. Install the GNU coreutils package on the DUT (e.g. "
45+
"'gnu-coreutils', which provides the 'gnudd' binary).",
46+
output,
47+
)
48+
49+
1250
class Dd(LinuxCommand):
1351
def __init__(self):
14-
LinuxCommand.__init__(self, TestRun.executor, 'dd')
52+
LinuxCommand.__init__(self, TestRun.executor, _resolve_gnu_dd())
1553

1654
def block_size(self, value: size.Size):
1755
return self.set_param('bs', int(value.get_value()))

0 commit comments

Comments
 (0)