DOCA Common workflows
Where to start: The verbs run configure → build → modify → run → test → debug, with ## use and ## log as supplementary
foundation verbs (the use verb walks the universal foundation
skeleton; the log verb is the verb-side of the two-tier log model
folded in from the historical doca-log content). The ## test verb
is an iterative loop (cap-query cross-check → lifecycle smoke →
PE-drive verification → loop back if any of the three findings
mutate the configure step), not a one-shot pass.
Read this file when the loader sent you here from
SKILL.md. For the universal primitives (log / buf /
ctx / dev / progress engine), the doca-common version overlay,
the Common error taxonomy, the observability surface, and the safety
policy that these workflows assume, see
CAPABILITIES.md. For the universal
modify-a-shipped-sample workflow and the cross-library
DOCA_ERROR_* taxonomy these workflows rest on, see
doca-programming-guide.
For the cross-cutting debug ladder that the Common debug verb feeds
into, see doca-debug.
Each verb below describes the shape of the workflow, not a copy-paste recipe. The agent's job is to walk the user through the steps in order, verifying preconditions before recommending the next call.
install
DOCA Common is part of every DOCA install — installing doca-common
in isolation is not a thing. The install verb routes to
doca-setup for the env / install
chain, and to
doca-public-knowledge-map ## Layout of an installed DOCA package
for the on-disk layout the rest of this file assumes.
The agent's checks before declaring the install ready for any foundation work:
pkg-config --modversion doca-commonreturns a semver string — this is the universal anchor every doca-common workflow assumes. If the query fails, the install is broken; route todoca-setup ## debuglayer 1 (install).doca_caps --versionagrees with thepkg-configresult per the four-way match rule indoca-version CAPABILITIES.md ## Version compatibility.- The Common headers are resolvable under
$(pkg-config --variable=includedir doca-common) (
doca_buf.h,doca_ctx.h,doca_dev.h,doca_pe.h,doca_log.h,doca_mmap.h, …) per the headers-win-over-docs rule indoca-version.
If any of the three checks fails, stop — this skill's
workflows assume the install is healthy, and a partial install is a
doca-setup concern.
configure
Goal: bring up the universal doca-common foundation that every higher-level library context (Flow, RDMA, Eth, DMA, Comch, Rmax, …) is going to consume.
Steps the agent should walk the user through:
- Confirm the installed DOCA version. Use the procedure in
doca-version TASKS.md ## configure. Quote the version observed (pkg-config --modversion doca-common, thendoca_caps --version); do not assume "latest". The four-way match rule lives indoca-version CAPABILITIES.md ## Version compatibility. - Enumerate devices and pick one. Call
doca_devinfo_create_list(&devinfos, &num); iterate; pick thedoca_devinfowhosedoca_devinfo_get_pci_addr_str/_get_ibdev_name/_get_iface_namematches the device the user named. PerCAPABILITIES.md ## dev, the devinfo is read-only and the open step is separate. - Run the capability queries for whatever the user wants to
use. Before opening the device, run the matching
doca_*_cap_*family against the chosendoca_devinfo. This is the cap-query-is-runtime-authority rule fromCAPABILITIES.md ## dev. If a required capability is false, stop — climb back up to the user's intent (different device, different feature set), do not retry. - Open the device. Call
doca_dev_open(devinfo, &dev). From this point thedoca_devinfopointer is still valid until the matchingdoca_devinfo_destroy_listcall; the openeddoca_devis what per-library contexts consume. - Enumerate representors if the user's case needs them. On a
BlueField host with the DPU in switch mode, the host program
discovers DPU-side function representors through
doca_devinfo_rep_create_list(dev, filter, &reps, &num)and opens the ones it needs withdoca_dev_rep_open. The representor handle is what the user passes todoca_flowactions,doca_ethqueues, etc., when steering traffic to a specific DPU-side function. - Create the progress engine.
doca_pe_create(&pe)produces the universal task-completion drain. One PE per worker thread is the default shape perCAPABILITIES.md ## progress engine. - Wire DOCA Log if the user wants their own emissions. Register
each log source via
doca_log_register_source(<name>, &source_id)at component init time; pick the level enum from the always-present set (CRITICAL/ERROR/WARNING/INFO/DEBUG) perCAPABILITIES.md ## log. The agent walks the two-tier model with the user BEFORE any code change — see## logfor the verb-side workflow. - Hand off to the per-library skill. Open the user's primary
library context (
doca_rdma_create,doca_eth_txq_create,doca_comch_client_create, …) per the matching library's## configureverb;doca_pe_connect_ctx(pe, ctx)BEFOREdoca_ctx_start(ctx)so completions surface.
If any step fails with a DOCA_ERROR_*, route through the error
taxonomy in
CAPABILITIES.md ## Error taxonomy
before retrying.
build
Goal: compile a doca-common consumer (or any DOCA app, since they
all link doca-common transitively) against the user's installed
DOCA, with pkg-config as the source of truth for include + link
flags.
The build pattern for any DOCA C/C++ consumer is fully documented
in
doca-programming-guide TASKS.md ## build.
This skill carries only the doca-common-specific overlay:
| Slot | Value for doca-common | Why it matters |
|---|---|---|
pkg-config module name |
doca-common (always present on any healthy install; the universal anchor) |
The Common surface is the foundation every higher-level library depends on. The agent's probe rule is pkg-config --exists doca-common first; if it fails, the install is broken (route to doca-setup ## debug layer 1) |
| Required runtime libs | libdoca_common (returned by pkg-config --libs doca-common) |
Any DOCA app links this transitively through its primary library's .pc, but a Common-only consumer (e.g. a device-discovery tool) links it directly |
| Include flags | pkg-config --cflags doca-common resolves to includes under $(pkg-config --variable=includedir doca-common) (doca_buf.h, doca_ctx.h, doca_dev.h, doca_pe.h, doca_log.h, doca_mmap.h, doca_error.h, doca_types.h, …) |
Hand-typed -I lines drift between releases; only pkg-config survives a DOCA upgrade |
| Link flags | pkg-config --libs doca-common returns the canonical -l list |
Hand-typed -l lines are the failure mode; the order matters for static-linking and pkg-config knows the right shape |
| Minimum required DOCA version | Query with pkg-config --modversion doca-common; never hardcode in build files |
The four-way match rule in doca-version CAPABILITIES.md ## Version compatibility requires the build-time version to be reachable; hardcoding it breaks the chain |
| Companion library probes (optional) | If the release exposes a standalone doca-log.pc (release-dependent), probe it with pkg-config --exists doca-log and use it for the log subsystem; otherwise the log surface ships through doca-common |
Per CAPABILITIES.md ## Version compatibility, the agent must verify on the user's install — never quote one shape from memory |
For non-C consumers (Rust, Go, Python), the wrapper consumes the
same *.so set through FFI; the build-time version visibility goes
through the language's own FFI generator (e.g. bindgen against
doca_ctx.h / doca_dev.h / doca_buf.h / doca_pe.h /
doca_log.h). The lifecycle, the cap-query rule, the PE drive
loop, and the two-tier log model still apply — the wrapper consumes
a *.so that has its own runtime version per
doca-version CAPABILITIES.md ## Version compatibility.
modify
Goal: take the closest-fitting shipped DOCA sample (any of them —
doca-common primitives show up in every shipped sample's *_main.c)
and apply a minimum diff to add or change the foundation wiring
(device pick, buffer registration, PE drive loop, log lines),
without rewriting from scratch.
The universal modify-a-shipped-sample workflow is in
doca-programming-guide TASKS.md ## modify;
this skill provides the doca-common-specific slot fill.
| Slot | Value | Source |
|---|---|---|
| Sample tree | Any shipped sample's *_main.c under /opt/mellanox/doca/samples/<library>/<sample>/. doca-common has no dedicated sample directory — the Common foundation is wired into every shipped sample's *_main.c (open device → create PE → create per-library ctx → connect_ctx → start → run loop → drain → stop → destroy) |
Confirmed by ls /opt/mellanox/doca/samples/ and reading any sample's *_main.c |
| Pick the closest sample | Whichever sample the user is already modifying for their primary library. The Common foundation is identical across them; modifying the foundation of an unrelated sample is a strictly larger diff than the user needs | Per the path-selection table in CAPABILITIES.md ## Capabilities and modes |
| Identify the foundation modify surface | Device pick (the doca_devinfo_create_list loop's filter / pick condition); buffer wiring (doca_mmap_set_memrange, doca_buf_inventory_buf_get_by_args callers); PE drive loop (doca_pe_progress location and cadence); log wiring (the doca_log_register_source call at init and the DOCA_LOG_* emissions across the file) |
The sample's existing *_main.c is the carrier; the user's foundation edits are the diff |
| Keep the lifecycle intact | Do NOT delete doca_pe_connect_ctx (the sample wired it; removing it is the universal "tasks submit but nothing completes" failure mode); do NOT reorder ctx_start before pe_connect_ctx; do NOT remove the doca_ctx_get_num_inflight_tasks drain on shutdown |
Per the lifecycle order in CAPABILITIES.md ## ctx and CAPABILITIES.md ## progress engine |
| Keep the build manifest unchanged | The sample's existing meson.build already wires the right pkg-config modules (doca-common at minimum); do not switch to a hand-rolled Makefile for "simplicity" — it removes the version-check rail |
Per the build slot table in ## build |
The agent's anti-pattern alert: a "clean rewrite" that swaps the sample's foundation wiring for hand-rolled code is almost always the wrong shape. The sample is the verified source of truth for the exact release that's installed; keeping the minimum diff is what keeps the user's code on the supported path.
run
Goal: actually execute the built program, observe completions arriving, and demonstrate the PE drive loop is healthy before the user starts adding real protocol logic.
Steps the agent should walk the user through:
- Confirm the active DOCA install. Re-quote
pkg-config --modversion doca-commonanddoca_caps --version; they must agree. A mismatch means the binary is loading a differentlibdoca_common.sothan the one its build-timepkg-configsaw — debug viadoca-version TASKS.md ## debugbefore assuming a Common bug. - Set the SDK log tier explicitly on first run. Pass
--sdk-log-level WARNING(most shipped samples / reference apps accept it) orDOCA_LOG_LEVEL_SDK=WARNINGin the environment. The default is WARNING perCAPABILITIES.md ## log; for first runs the agent should default the SDK tier to WARNING (do not crank to DEBUG) so the user's own lines are not buried in DOCA-library internal trace. - Set the app log tier explicitly on first run. Use
doca_log_level_set_global_lower_limiton the app-tier registry (or the per-source setter for fine-grained control). For first runs the agent should default the app tier to DEBUG so the user can see their own DEBUG-shaped lines; drop to INFO for steady-state operation. - Drive the PE on every loop iteration. The minimal run loop
is
while (running) doca_pe_progress(pe);— for a control-plane thread, prefer the notification handle (doca_pe_get_notification_handledoca_pe_request_notification+epoll_wait+ clear, thenprogress) so the thread is not busy-polling. PerCAPABILITIES.md ## progress engine, skipping the PE drive is the universal "my program does nothing" symptom.
- Submit one task and confirm it completes. Use the
per-library
task_*_submitfor the user's primary library; confirm the completion callback fires throughdoca_pe_progress. This is the cheapest smoke that the foundation is alive. If the callback never fires, capture both possibilities: a foundation failure (PE not driven or context not connected) and a per-library failure (task submission or callback registration), then route through## debugwithout assuming which layer owns it. - Capture the structured log. Redirect
stderrto a file (2> doca.log) so the subsequent## testiterations have a stable artifact to diff against.
For the runtime version + LD_LIBRARY_PATH cross-checks that
underlie "the program built but does nothing", see
doca-version TASKS.md ## run.
test
Goal: prove the foundation is behaving as expected — the device was picked correctly, the cap-queries the configure step ran still hold, the lifecycle is in order, and the PE drive loop is wired — before claiming the "wire doca-common into the app" journey is done.
## test is an iterative loop, not a one-shot pass. The agent's
job is to run the four steps below in order, and loop back to
step 1 after the first evidence-backed spec mutation. A finding on
that complete rerun triggers escalation rather than another mutation.
Treating validate-once as good-enough is the failure mode this loop
replaces; the first spec mutation re-opens validate.
The eval-loop overlay (rows apply to every Common skeleton, not just one):
| Step | Why this is a loop, not a step | Where the substance lives |
|---|---|---|
| 1 → 2 → 1 | Cap-query cross-check (step 2) may reveal the device does not support a feature the user assumed; loop back to step 1 with a different device or a different feature set | ## configure step 3 + CAPABILITIES.md ## dev |
| 1 → 3 → 1 | Lifecycle smoke (step 3) may reveal a missing doca_pe_connect_ctx or a misordered ctx_start; loop back to step 1 with the order fixed |
CAPABILITIES.md ## ctx lifecycle |
| 1 → 4 → 1 | PE-drive verification (step 4) may reveal doca_pe_progress is never called or is called on the wrong PE; loop back to step 1 with the loop fixed |
CAPABILITIES.md ## progress engine |
| 4 → ## debug | Tasks submit, PE is driven, completions still do not arrive — escalate to the Common debug overlay | ## debug |
The agent's rule: the first evidence-backed mutation between steps re-opens the four steps for one complete rerun. A further useful mutation is captured for escalation instead of opening another rerun. Skipping the re-validate after the first mutation is the universal foundation-layer failure mode.
Steps:
- Cap-query baseline. Save the output of every
doca_*_cap_*query the user ran in## configurestep 3 as a baseline. A laterDOCA_ERROR_NOT_SUPPORTEDis the diff against this snapshot — without it, the agent has no way to disambiguate "the device never supported this" from "something changed". - Cap-query re-check. Re-run the same
doca_*_cap_*queries on the running program (or viadoca_caps --list-devsif the library exposes that cap publicly). The result must match the configure-time baseline; if it does not, the device or firmware state changed (mode flip, firmware burn — seedoca-hardware-safety) and the user is operating on a different surface than they thought. - Lifecycle smoke. With the user's smallest possible
reproducer (one device, one PE, one ctx, one task), confirm:
doca_pe_connect_ctxhappens BEFOREdoca_ctx_start; the per-library task submit happens AFTERdoca_ctx_start; the shutdown path drains viadoca_ctx_get_num_inflight_tasks/doca_pe_get_num_inflight_tasksbefore destroy. Catches the most common lifecycle-order bugs. - PE-drive verification. Confirm
doca_pe_progress(pe)is reachable in the user's main loop on the same thread that created the PE. Catches the case where the run loop drives a different PE than the one the contexts are connected to.
Loop termination: run the four-step sweep once and permit at most one
evidence-backed mutation followed by one complete rerun. Stop when
that second sweep finishes, even if another mutation appears useful.
If all four steps are not green without mutating a prior step,
escalate to
doca-debug TASKS.md ## debug
with the captured log + baseline + version state as evidence.
debug
Goal: when a doca_* call returns a DOCA_ERROR_* or the program
does not make forward progress, narrow the cause to a single layer
before recommending any code change.
Routing summary. This anchor is the doca-common-specific debug overlay: lifecycle errors, cap-query mismatches, PE drive loop gaps, log-tier confusion. For the cross-cutting debug ladder (install / version / build / link / runtime / program / driver) plus the cross-cutting tooling surface (
gdb,valgrind,--sdk-log-level,DOCA_LOG_LEVEL, thedoca-<lib>-tracebuild flavor, container-vs-native debug, core dumps, Developer Forum escalation), seedoca-debug ## debug. The agent should walk the cross-cutting ladder first whenever the symptom layer is not yet known; this Common overlay layers on top once the symptom is confirmed to be inside the foundation surface.
Walk in this order — do not skip steps:
- Tier-confusion sanity (cheapest). If the symptom is "my log
lines do not appear" or "my console is flooded", the first
hypothesis is two-tier confusion per
CAPABILITIES.md ## log. Walk the table before any code change. - Lifecycle order. If the error is
DOCA_ERROR_BAD_STATE, walk the lifecycle for whichever subsystem the call belongs to:doca_ctx_*→CAPABILITIES.md ## ctx;doca_mmap_*/doca_buf_*→CAPABILITIES.md ## buf;doca_pe_*→CAPABILITIES.md ## progress engine;doca_log_*→CAPABILITIES.md ## log. - Cap-query mismatch. If the error is
DOCA_ERROR_NOT_SUPPORTED, the call assumed a capability the activedoca_devinfodoes not advertise. Re-run the matchingdoca_*_cap_*query and compare against the cap baseline from## teststep 1. - PE drive loop. If tasks submit and never complete, the PE
is not being driven on the thread that owns the connected
contexts. Confirm
doca_pe_progress(pe)is in the main loop and is the samepethatdoca_pe_connect_ctxwas called against. - Permission envelope. If the error is
DOCA_ERROR_NOT_PERMITTED, this is a host-side env issue (kernel module loads, user group, ulimits, IOMMU mode, missing capabilities) — route todoca-setup TASKS.md ## debug. - Version sanity. If a previously working spec now fails or
behaves differently, confirm the installed DOCA version did not
change via the four-source coherence check in
doca-version TASKS.md ## debuglayer 2. A library upgrade between sessions is a common and easy-to-miss cause. - Escalation criteria. If the lifecycle is correct, the
cap-queries hold, the PE is driven, permissions are right, and
the version is unchanged AND the symptom persists — the bug is
below the Common API surface (driver or firmware). Stop
attempting Common-spec changes; capture state per
doca-debug ## test(the read-only triple) and escalate viadoca-debug ## debugWhere to ask for help to the public DOCA Developer Forum.
use
Goal: walk the universal foundation skeleton — the exact sequence every DOCA app of every shape follows before the per-library specialization begins.
This verb is the use-the-foundation counterpart to
## configure: it names the sequence so the agent
can quote it the same way every time, regardless of which higher-
level library the user's primary work is in.
The universal skeleton, in order:
doca_devinfo_create_list(&devinfos, &num)— read-only enumeration of every candidate device DOCA sees on the host or BlueField.- Pick the
doca_devinfothe user wants — by PCIe address (doca_devinfo_get_pci_addr_str), by IB device name (_get_ibdev_name), by interface name (_get_iface_name), or by any other identifier the user provided. - Run the cap-queries — for every feature the user assumed,
run the matching
doca_*_cap_*against the chosendoca_devinfo. The output is the capability snapshot (perCAPABILITIES.md ## Observability) that the rest of the session compares against. doca_dev_open(devinfo, &dev)— open the chosen device. From here thedoca_devis the handle every per-librarydoca_*_set_devcall consumes.- (Optional) Enumerate representors. On a BlueField with the
DPU in switch mode, the host program calls
doca_devinfo_rep_create_list(dev, filter, &reps, &num)and opens the representors it needs withdoca_dev_rep_open. doca_pe_create(&pe)— create the universal task-completion drain. One PE per worker thread is the default shape.- Per-library
doca_<library>_create(...)— create the per-library context the user's primary work needs (adoca_flow_port, adoca_rdma, adoca_eth_txq, adoca_dma, …). The handle this returns wraps adoca_ctxunder the hood. - Configure the per-library context — call the library's
*_set_*setters BEFOREdoca_ctx_start. Setters called after start returnDOCA_ERROR_BAD_STATE. - (For zero-copy I/O) wire the buffer stack.
doca_mmap_create→doca_mmap_set_memrange→doca_mmap_add_dev(mmap, dev)→doca_mmap_set_permissions→doca_mmap_start. Thendoca_buf_inventory_createover the mmap →doca_buf_inventory_start. Buffers are handed out bydoca_buf_inventory_buf_get_by_argson demand. doca_pe_connect_ctx(pe, ctx)— register the context with the PE so its task completions surface throughdoca_pe_progress. Skipping this is the canonical "tasks submit but nothing completes" failure mode.doca_ctx_start(ctx)— transition the context to RUNNING.- Drive the run loop —
while (running) doca_pe_progress(pe);(or the notification-handle variant for control-plane threads). - Submit tasks via the per-library task API. Completions surface through the PE on the thread that drives it.
- Shutdown. Drain inflight tasks
(
doca_ctx_flush_tasks(ctx)ordoca_pe_progress(pe)untildoca_pe_get_num_inflight_tasks(pe) == 0) →doca_ctx_stop(ctx)→ per-librarydoca_<library>_destroy(...)→ buffer-stack teardown (doca_buf_inventory_stop→_destroy→doca_mmap_stop→_destroy) →doca_pe_destroy(pe)→doca_dev_close(dev)→doca_devinfo_destroy_list(devinfos).
The agent's rule: this sequence is the same regardless of which
higher-level library is layered on top. When the user asks
"what's the doca-common skeleton I need before I open my Flow port
/ my RDMA context / my Eth queue / my DMA context?", the answer is
this list, with the per-library _create call slotted into step 7
and the library's _set_* setters into step 8.
log
Goal: wire DOCA Log into a DOCA app (or into a freshly modified DOCA sample) so the user's own emission lines run alongside the DOCA library's own log lines, with the two tiers under independent control.
This verb is the verb-side of the two-tier model documented in
CAPABILITIES.md ## log. It is folded from
the historical doca-log skill into this skill because the log
subsystem ships through the doca-common pkg-config module per
CAPABILITIES.md ## Version compatibility.
Steps the agent should walk the user through:
- Confirm DOCA Log is the right primitive for this app. Walk
the path-selection rule in
CAPABILITIES.md ## log. If the codebase has no DOCA-side context (nodoca_*calls, no DOCA libraries linked), DOCA Log is not the right answer — language-native logging is. Recommending DOCA Log for the user when the path-selection rule rules it out is a wrong answer regardless of how cleanly the rest of the configure step goes. - Walk the two-tier model with the user, BEFORE any code. Per
the two-tier table in
CAPABILITIES.md ## log, the agent must surface that SDK level controls DOCA library internals (defaultWARNING; setter--sdk-log-level/DOCA_LOG_LEVEL_SDK) and app level controls user code emissions (defaultINFO; setter is the app-sidedoca_log_level_set_global_lower_limit). Confusing the two is the number-one first-app debug failure. The agent should confirm the user's intent (do they want to see DOCA library internal lines, their own lines, or both) and pick the tiers accordingly. - Register each log source ONCE before any emission. For the
user's own source files (typically one per
.cfile or per component), calldoca_log_register_source(<name>, &source_id)at component init time. PerCAPABILITIES.md ## logobjects table, an unregistered source ID passed to aDOCA_LOG_*macro returnsDOCA_ERROR_INVALID_VALUE. The register call sits BEFORE anyDOCA_LOG_*from that source; do not invert the order. - Optionally install a custom backend / sink. The default sink
is
stderr(created implicitly viadoca_log_backend_create_standardon most app init paths). If the user wants log lines to land in a file, an fd, a buffer, or syslog, use the matchingdoca_log_backend_create_with_*(and the_sdkvariant for the SDK tier). PerCAPABILITIES.md ## Safety policycustom-sink rule, the writes inherit the sink's own permission envelope; validate the sink with a small write at registration time before any production traffic. - Smoke one emission per level the user cares about. Emit one
DOCA_LOG_INFO, oneDOCA_LOG_DBG, and oneDOCA_LOG_ERRfrom the user's own source. Confirm the line shape (timestamp / level / source / message) matches the per-line format the shipped DOCA samples produce. - Iterate the tier flip. Run with
SDK=WARNING, App=DEBUG; confirm the user's own DEBUG lines appear and DOCA library internals are quiet. Flip toSDK=DEBUG, App=WARNING; confirm DOCA library internals flood and the user's own DEBUG lines disappear. If either iteration does not behave as expected, route to## debugstep 1.
For the verb-side run / test iteration on the log surface, the
universal ## run steps 2 and 3 already cover the
first-run tier defaults. The ## test step that exercises the
two-tier flip is the iteration described above.
Deferred task verbs
The following verbs are out of scope for this skill but are commonly asked in the same conversations. Route them as follows so the agent does not invent guidance:
- deploy. Deploying DOCA apps at scale, routing log output to
centralized aggregation systems, K8s sidecars — out of scope for
this skill; partial guidance in
doca-public-knowledge-mapfor DOCA Log Service and DOCA Telemetry Service routing, anddoca-container-deploymentfor the container path. - rollback. Coordinated rollback across multiple hosts /
DPUs — out of scope for this skill. For single-host config
rollback within a session, the right verb is destroying contexts
/ mmaps / inventories in reverse-order and re-running
## configurewith corrected parameters. - performance tuning. Per-context completion vectors, NUMA-aware PE placement, multi-thread PE topologies, high-rate log emission with async sinks — touched by this skill but owned by the per-library skill (for completion vectors and queue placement) and by the user's own application design (for PE topology and sink batching). DOCA Log itself is a synchronous primitive; performance-shaped concerns are owned by the custom-sink implementation, not by the DOCA Log API surface.
- service-side logging. Configuring log destinations for DOCA services (DMS, DTS, Firefly, …) is owned by the matching service skill, not by this library skill. This skill is the primitive the user wires into their own DOCA app.
Command appendix
Every command below is cross-cutting on doca-common — it answers a recurring class of question that comes up in the verbs above. The agent should treat the class as load-bearing; the worked example is a single instance. Run-as user is the unprivileged user unless noted.
Infra-aware preamble (every row below). Per the bundle's
detect → prefer → fall back → report contract documented in
doca-structured-tools-contract ## The agent behavior contract,
the agent should:
- Probe for the matching structured helper FIRST (
doca-env --jsonfor version + devices + libraries in one shot;doca-capability-snapshotfor per-device capability flags;version-matrix.jsonfor "available since" lookups). - If the probe succeeds, the structured tool's output is the
authoritative answer and the agent SHOULD NOT also run the
manual command in the row below. Report "using structured
<tool>". - If the probe fails, fall back to the manual command in the row. Report "falling back to manual chain".
- The schemas the structured tools emit are defined in
doca-structured-tools-contract ## Schemas; the version-handling semantics (four-way match, NGC, headers-win) are owned bydoca-version.
| Command (worked example) | Owning step | Class of question it answers | What healthy output looks like |
|---|---|---|---|
pkg-config --modversion doca-common |
## install check 1; ## configure step 1; ## build |
What is the build-time doca-common version on this install? | A semver string matching doca_caps --version |
pkg-config --cflags --libs doca-common |
## build |
What include + link flags does the linker need for any DOCA app? | -I paths under $(pkg-config --variable=includedir doca-common); -l line including -ldoca_common |
pkg-config --exists doca-log; echo $? |
## build; ## log |
Does this install publish a standalone doca-log.pc, or is DOCA Log folded into doca-common.pc? |
Exit 0 means standalone; exit nonzero means use doca-common for the log surface too |
doca_caps --version |
## install check 2; ## debug step 6 |
What is the runtime DOCA version on this host? | A semver string matching pkg-config --modversion doca-common |
doca_caps --list-devs |
## configure step 2; ## use step 1 |
Which devices on this host can be used as a doca_dev? |
One row per visible device with PCIe address and capability flags |
ls "$(pkg-config --variable=includedir doca-common)/" |
## configure; ## modify |
Which Common headers are installed (the headers-win-over-docs anchor)? | A list including doca_buf.h, doca_ctx.h, doca_dev.h, doca_pe.h, doca_log.h, doca_mmap.h, doca_error.h |
<binary> --sdk-log-level WARNING 2> doca.log |
## run step 2 |
What does the SDK tier emit at WARNING (production default)? | Mostly silent on a healthy run; warnings are rare and load-bearing when they fire |
<binary> --sdk-log-level DEBUG 2> doca.log |
## test |
What does the SDK tier emit at DEBUG (DOCA library internal trace)? | A flood of per-call DOCA library internal log lines; the user's own DEBUG lines remain controlled by the app tier and are not affected by this flag |
DOCA_LOG_LEVEL_SDK=DEBUG <binary> 2> doca.log |
## run step 2 |
Same as above via env var (for samples that don't accept --sdk-log-level) |
Same shape |
grep -RH 'doca_log_register_source|DOCA_LOG_INFO' /opt/mellanox/doca/samples/ | head |
## modify; ## log |
Which shipped samples have canonical DOCA Log usage to read as a reference? | Multiple hits across samples/<library>/<sample>/*_main.c — DOCA Log is in every sample |
cat /opt/mellanox/doca/applications/VERSION |
## install check 2; ## debug step 6 |
What does the install tree itself claim its version is? | A semver string matching the other version sources |
For commands shared across libraries (pkg-config --modversion,
doca_caps, cat /opt/mellanox/doca/applications/VERSION,
DOCA_LOG_LEVEL / DOCA_LOG_LEVEL_SDK) the cross-library overlay
is in
doca-debug TASKS.md ## Command appendix;
this table adds the doca-common-specific rows on top.
Three cross-cutting rules for this appendix:
- Never invent Common symbols or paths. The Common ABI is
large and version-gated;
ls $(pkg-config --variable=includedir doca-common)on the user's install and the installeddoca_*.hheaders are the only safe sources. - Never paraphrase a Common
DOCA_ERROR_*. Quotedoca_error_get_descr()verbatim — the layer-classifier indoca-debug ## debuglayer 5 needs the exact text. - Cross-link instead of duplicate. Cross-cutting commands (the
read-only triple,
dmesg,lspci,mlxconfig -d <pcie> q) live indoca-debug TASKS.md ## Command appendix; this appendix names only the doca-common-specific ones.