nvnmosd

September 18, 2026 · View on GitHub

[TOC]

Linux-first NMOS daemon: one process hosts multiple NMOS Nodes (by node_seed), sessions (gRPC clients), and session-linked NMOS Senders/Receivers backed by libnvnmos. Clients talk to it over the nvnmosd gRPC API.

The Core NvNmos Concepts guide explains the transport file, activation direction, and identity model shared by the daemon, C API, and GStreamer elements. Daemon design record covers architecture, element integration, and historical rationale. Concurrency and lock ordering documents the no-FFI-under-state invariant. This documentation describes the as-built daemon surface for operators and client authors.

Using the gRPC API

Node flavours:

  • Session-refcounted (default): created on first OpenSession for a node_seed; destroyed when the last session on that node closes.
  • Persistent: created with AddNode; survives until RemoveNode.

Many sessions may attach to the same Node (same node_seed). Each session owns the resources it registers; activations are routed to the session that added the resource.

AreaRPCs
Node lifecycleAddNode, RemoveNode, OpenSession, CloseSession
ResourcesAddSender, AddReceiver, RemoveResource
IS-05 activationSubscribeActivations (server stream), AckActivation
Out-of-band syncSyncResourceState

Minimal Client Sequence

Most clients use a session-refcounted Node:

  1. Call OpenSession with a NodeConfig. The daemon creates the Node if the seed is new, or attaches the session to the existing Node for that seed.
  2. Start SubscribeActivations immediately and keep the stream open while the session is in use.
  3. Call AddSender or AddReceiver with the session handle, a caller-chosen resource name, and its configuring transport file.
  4. For each ActivationEvent, apply the transport-file change to the local data plane, then call AckActivation with the result.
  5. When the application changes its data plane without an IS-05 activation, call SyncResourceState to update the NMOS state.
  6. Call RemoveResource when a Sender or Receiver is no longer needed, then call CloseSession during clean shutdown. Closing a session also removes any resources it still owns.

The activation stream must be active before resources are added. If session GC is enabled (the default), missing the initial subscription or resubscription deadline implicitly closes the session.

Use nvnmosd-example for a complete Rust client and the gRPC API reference for request fields, responses, preconditions, and errors.

Build and Run

Requires a pre-built libnvnmos.so — see the Rust workspace build instructions for NVNMOS_LIB_DIR and the CMake/Conan flow.

export NVNMOS_LIB_DIR=/absolute/path/to/build
export LD_LIBRARY_PATH="$NVNMOS_LIB_DIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

cargo build --bin nvnmosd
cargo run --bin nvnmosd -- --uds /tmp/nvnmosd.sock

Command Line

Flag / envDefaultMeaning
--uds / NVNMOSD_UDS/tmp/nvnmosd.sockUnix socket for gRPC. Fails if another listener owns the path; removes a stale socket file from a crashed process.

Logging uses tracing; set RUST_LOG as usual (e.g. RUST_LOG=info).

Environment Variables

Session Liveness

These settings control when the daemon implicitly closes a session whose activation subscription is missing or interrupted.

VariableDefaultMeaning
NVNMOSD_SESSION_GConDisable with 0, false, off, or no.
NVNMOSD_SESSION_SUBSCRIBE_TIMEOUT_SEC60Subscribe within this many seconds of OpenSession.
NVNMOSD_SESSION_RESUBSCRIBE_TIMEOUT_SEC5Resubscribe within this many seconds after the activation stream ends.

Node HTTP Port Allocation

VariableDefaultMeaning
NVNMOSD_HTTP_PORT_MIN18080Inclusive lower bound when NodeConfig.http_port is 0.
NVNMOSD_HTTP_PORT_MAX18099Inclusive upper bound.

When NodeConfig.http_port is 0, the daemon picks the first port in [MIN, MAX] that is not already used by another Node and that the host can bind. When http_port is non-zero, the client chooses the port; the daemon rejects the create if that port is already taken by another Node or unavailable on the host.

libnvnmos (inherited by the daemon process)

These are read by libnvnmos when a Node is created. Set them on the nvnmosd process (or any process that loads libnvnmos.so).

VariableDefaultMeaning
NVNMOS_EXPERIMENTAL_SETTINGSoffMount nmos-cpp GET/PATCH /settings/all on the Node HTTP port. Enable with 1, true, on, or yes. Debug only: the JSON includes internal Node settings such as stored transport files.

Linux glibc Heap Trimming

VariableDefaultMeaning
NVNMOSD_MALLOC_TRIMonTrim after teardown when a node has no remaining resources. Disable with 0, false, off, or no.
NVNMOSD_MALLOC_INFOoffLog full malloc_info XML at debug around each trim. Enable with 1, true, on, or yes.

Clients and Tests

ToolRole
gst-nmos-rsGStreamer elements (nmossrc / nmossink) — primary production client.
nvnmosd-exampleInteractive regression client (C nvnmos-example equivalent).
nvnmosd-benchScale / latency smoke across many sessions and resources.
Session GC integration testsIntegration tests for implicit CloseSession.

Example smoke (two terminals, rust/ workspace root, NVNMOS_LIB_DIR set):

# Terminal 1
cargo run --bin nvnmosd

# Terminal 2
cargo run --bin nvnmosd-example

See the Rust workspace smoke test for example flags (--interface-ip, --hold-secs, Connection API PATCH round-trip).

Scale benchmark guide.

Other Ways to Use NvNmos

Use the C API to embed the NMOS control plane directly in a Media Node application.

Use the GStreamer elementsnmossrc and nmossink — to connect GStreamer pipelines to nvnmosd and configure the data plane.