Skip to content

Commit 09accba

Browse files
daniel-nolandclaude
andcommitted
fix(dpdk): prepend program-name placeholder in eal::init
rte_eal_init treats argv[0] as the program name and skips it during option parsing. The wrapper was passing the caller's args verbatim, so the first flag was silently swallowed on every call -- including in production callers and in any test that hands eal::init a list of flags. Fix by prepending a static `c"dataplane"` placeholder inside the wrapper. The placeholder lives in .rodata; DPDK's argparse only mutates the argv pointer array, never the strings, so the cast_mut is sound (documented as a SAFETY comment). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 08e23f9 commit 09accba

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

dpdk/src/eal.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,21 @@ pub fn init(args: impl IntoIterator<Item = impl AsRef<str>>) -> Eal {
124124
// The easiest way I know how to do that is by bundling the pre-shift logic into its own scope.
125125
// The system memory will be free by the time this scope closes.
126126
let eal = {
127+
const ARG0: &CStr = c"dataplane";
127128
let mut args = ValidatedEalArgs::new(args).unwrap_or_else(|e| {
128129
Eal::fatal_error(e.to_string());
129130
});
130-
let mut c_args: Vec<_> = args.0.iter_mut().map(|s| s.as_ptr().cast_mut()).collect();
131+
// EAL treats argv[0] as the program name and ignores it; this
132+
// slot would otherwise eat the first real flag.
133+
// We side step this by prepending a dummy program name pointer.
134+
// SAFETY: ARG0 points into .rodata; DPDK reads argv[0] for prog_name and
135+
// only mutates the argv array's pointer slots, never the strings. The
136+
// cast_mut is a type accommodation for the FFI signature, not a license
137+
// to write through the pointer.
138+
let mut c_args: Vec<_> = [ARG0.as_ptr().cast_mut()]
139+
.into_iter()
140+
.chain(args.0.iter_mut().map(|s| s.as_ptr().cast_mut()))
141+
.collect();
131142
let ret = unsafe { dpdk_sys::rte_eal_init(c_args.len() as _, c_args.as_mut_ptr() as _) };
132143
if ret < 0 {
133144
EalErrno::assert(unsafe { dpdk_sys::rte_errno_get() });

0 commit comments

Comments
 (0)