Skip to content

Resource Control

Librux resource control is the operating model for managed subsystem processes. It is not a global Linux sandbox and it does not block every process a user can start from a shell. It applies when a subsystem is launched as a managed package through Librux.

Use this page after you understand Runtime Configuration, CLI Tools, and the normal service model. For runnable checks, see Add Resource Policy. For the package layout itself, see Subsystem Packages.

Operating Model

A managed launch has four stages.

  1. a package declares the resources it needs
  2. librux-resourced.service accepts or rejects the claim
  3. the launcher starts the process only after a lease is granted
  4. the lease is released only after the managed process scope is gone

Resource guarantees apply only to managed package launches.

librux launch run ./dist/my_controller.libruxpkg --detach

Web Console Runtime launches use the same detached service-owned path. Package installation only stores and validates reusable packages; Runtime creates the running subsystem instance. When a package is launched, resource admission, environment injection, affinity, brokered FD policy, and cgroup placement match librux launch run --detach.

For role: app packages installed from the Web Console Packages page and launched from Runtime, the application boundary is stricter than a generic subsystem package.

  • the package must set resources.sandbox.network: brokered
  • the application subsystem must not claim NIC, link-layer, CAN, serial, or device resources
  • browser UI must be packaged as static frontend assets and served from /api/v1/packages/<package-id>/ui/

This prevents managed application code from self-hosting a native HTTP or WebSocket frontend with direct AF_INET, AF_INET6, or AF_PACKET sockets. If a package needs a browser-facing REST or WebSocket backend for its packaged static UI, declare frontend.context.api or frontend.context.ws in package.yaml and open the corresponding listener through the resource broker with open_frontend_tcp_listener. Application subsystems talk to the robot through compound capability bindings; hardware and field resources stay behind gateways and components.

Runtime Configuration

Resource authority is configured under resource_service.

resource_service:
  mode: "auto"        # auto, required, or disabled
  # socket_path: "/run/librux/resourced.sock"
Mode Operator meaning
auto Use librux-resourced when reachable and allow local ownership fallback where the runtime permits it. This is the default install posture.
required Treat the resource service as mandatory. Managed launches fail when the resource service is unavailable.
disabled Disable the managed resource authority path. Managed app start/stop through the control backend is not available.

For appliance or managed robot hosts, prefer required once service setup and resource policy are validated. Keep auto while bringing up a new host or debugging a development install.

Service Checks

Installed product hosts should have the resource service running.

. <prefix>/env.sh
librux system status
librux resource status
librux resource inventory

The default Linux service socket is this.

/run/librux/resourced.sock

Installed system services prepare /run/librux as root:librux with mode 2770. The non-root librux-control.service user can create its control socket there, while resource-service access remains limited to the Librux runtime group.

If services were not installed, install them from the selected prefix.

sudo <prefix>/bin/librux system install --prefix <prefix>

Adjust socket/client policy when needed.

sudo <prefix>/bin/librux system install \
  --prefix <prefix> \
  --resource-group librux \
  --client-user robot \
  --socket-mode 0660

Install serial/USB device policy when managed packages need device-node access.

sudo <prefix>/bin/librux-device-policy-install \
  --device-group librux-device \
  --device-mode 0660

Operators should not add normal users to the Librux device group. Device access should be granted per managed package process by librux-resourced.

Managed Launch Lifecycle

Validate and build a package.

librux package validate ./my_controller
librux package build ./my_controller \
  --out ./dist/my_controller.libruxpkg \
  --force

Run it under resource control.

librux launch run ./dist/my_controller.libruxpkg \
  --config <prefix>/runtime/config.yaml

Detached launch and lease inspection.

librux launch run ./dist/my_controller.libruxpkg --detach
librux resource status
librux launch status <lease-id>
librux resource stop <lease-id>

Reusable packages can be launched as named instances when their package manifest declares the corresponding parameters.

librux launch run ./dist/manipulator_servo.libruxpkg \
  --instance demo.left_manipulator \
  --set subsystem.name=demo.left_manipulator \
  --set controller.robot_id=left_ps_ca \
  --runtime-dir /run/librux/packages/demo.left_manipulator \
  --detach

The launcher rejects --set keys that are not declared by the package. This keeps resource admission and command shape controlled by the package manifest. By default, installed packages use the prefix state root such as /opt/librux/var/run/packages/<instance-id> for runtime files. Source checkout packages without an installed prefix fall back to package-local var/instances/<instance-id>. Explicit relative runtime dirs stay package-local. Explicit absolute runtime dirs are limited to /run/librux or temporary directories because librux-resourced may create them from a service-owned launch path.

Package Resource Declaration

A managed package declares resource requirements in package.yaml.

schema_version: 1
name: control.arm_controller
entrypoint:
  command: bin/controller
  args: ["--config", "config/controller.yaml"]
resources:
  cpu:
    cores: [2, 3]
    exclusive: true
  network:
    interfaces:
      - name: enp4s0
        mode: shared
        policy: control-plane
  link_layer:
    interfaces:
      - name: enp5s0
        mode: exclusive
        access: raw_packet
        protocols: [ethercat]
        grant:
          capabilities: [CAP_NET_RAW]
  devices:
    paths:
      - /dev/ttyUSB0
    can:
      - can0
  sandbox:
    network: brokered
    can: brokered
    devices: managed

The entrypoint is resolved from the package directory unless it is absolute. Relative paths cannot escape the package directory.

Resource Semantics

Resource Semantics
CPU affinity is the minimum guarantee; cgroup v2 cpuset placement is used when available
NIC IP networking claim for selected adapters; brokered network mode can deliver accepted UDP/TCP sockets
Link-layer NIC exclusive raw Ethernet fieldbus claim for EtherCAT, CC-Link IE TSN, Profinet RT, or custom L2 protocols
CAN SocketCAN interface claim, treated as an exclusive outlet resource
Serial / TTY exclusive device-node claim for /dev/ttyUSB*, /dev/ttyACM*, /dev/ttyAMA*, /dev/ttyS*, and similar paths
Device nodes managed device FDs can be delivered by the resource service

resources.network.interfaces and resources.link_layer.interfaces both name Linux network interfaces, but they describe different authority models. network is for IP socket policy. link_layer is for packages that need direct AF_PACKET raw Ethernet access, such as a SOEM EtherCAT gateway.

Link-layer claims are exclusive and conflict with ordinary network claims on the same interface. They are also incompatible with resources.sandbox.network. brokered, because brokered network mode intentionally blocks direct AF_PACKET socket creation.

The launch report separates affinity from cgroup placement. Treat attach.affinity_applied=true as the minimum CPU result. If attach.cgroup_degraded=true, the process is pinned by affinity but strict cpuset containment was not available on that host.

Some industrial Ethernet stacks need raw Ethernet access and cannot receive a pre-opened UDP/TCP/CAN FD. EtherCAT through SOEM is the common example because SOEM opens and drives the packet socket inside the gateway process.

For this class of gateway, librux-resourced keeps admission and ownership centralized but does not relay fieldbus packets.

  1. the package declares an exclusive resources.link_layer.interfaces claim
  2. librux-resourced rejects conflicting claims for the same NIC
  3. the managed child is launched with the requested bounded capability, normally CAP_NET_RAW
  4. the gateway opens its raw packet socket directly and owns the realtime data path

Supported protocol labels are ethercat, cclink_ie_tsn, profinet_rt, and custom_l2. The current grant allowlist is CAP_NET_RAW and CAP_NET_ADMIN. Use CAP_NET_ADMIN only when the gateway must configure the interface itself.

Brokered Handles

Brokered modes prevent common direct resource bypasses inside managed packages and deliver accepted handles through the resource broker.

Supported brokered paths.

  • network sockets with resources.sandbox.network - brokered
  • SocketCAN with resources.sandbox.can - brokered
  • device nodes with resources.sandbox.devices - managed

Link-layer raw packet access is intentionally not a brokered handle in this release. It is a lease plus launch-time capability grant so EtherCAT-class control loops do not pay a per-packet resource-service hop.

In brokered mode, the launched process receives.

LIBRUX_RESOURCE_LEASE_ID
LIBRUX_RESOURCE_SERVICE_SOCKET
LIBRUX_CONTROL_SOCKET

The SDK asks librux-resourced for a resource handle. The service verifies the live lease, opens the accepted socket or device, applies host policy such as SO_BINDTODEVICE where needed, and transfers the FD with SCM_RIGHTS.

The data path then uses the received FD directly; traffic does not route through the control backend.

LIBRUX_CONTROL_SOCKET is separate from brokered resource handles. It points to the host-local control backend Unix domain socket, normally /run/librux/control.sock, and is used by SDK lifecycle, heartbeat, Event slot request, and Procedure/Operation registration messages. This keeps SDK runtime bookkeeping available even when a package sandbox blocks direct AF_INET socket creation under resources.sandbox.network: brokered.

Stop And Cleanup

stop is a bounded termination path, not a guarantee that the app handles SIGTERM. Librux first sends SIGTERM to give the managed process scope a short cleanup opportunity. If any live process remains after the grace window, the runtime escalates to SIGKILL and only marks the lease released after the process scope is gone.

Runtime Graph and lbx subsystem expose this as process terminate. Force kill is a separate operator action that skips the SIGTERM grace window and sends SIGKILL immediately.

The stop report is factual.

  • signal_sent=true means the graceful stop signal was sent.
  • kill_sent=true means the process scope did not exit during the grace window and Librux used SIGKILL.
  • graceful=true means the scope exited without SIGKILL.
  • stop_method records the observed stop path, such as sigterm, sigkill, already_dead, or no_process.

For Python and other runtimes, application-level signal handling is best effort. Handlers can be delayed by blocking calls, native extensions, wrapper shells, or worker child processes. Managed app stop should therefore be treated as process-scope termination, not as application-level SIGTERM acknowledgement.

Direct Execution

During development, a subsystem can still be run directly from a shell, IDE, or debugger. Librux does not globally block ordinary Linux process execution.

If the process uses the Librux SDK, direct execution still registers a subsystem session with the control backend. That registration is for subsystem identity, routing, and lifecycle diagnostics; it is not a resource-control lease.

Direct execution is not a managed launch. The process does not receive.

  • a resource lease
  • managed environment injection
  • CPU/cgroup placement
  • brokered NIC/CAN/TTY/device FDs
  • link-layer capability grants such as CAP_NET_RAW
  • Web Console lifecycle ownership

Resource-control guarantees apply only when the subsystem is started through librux launch, librux deploy, or a managed Runtime launch in the Web Console. Product deployments that must prevent unmanaged execution should enforce that through host or appliance policy, including restricted shell access, root policy, device permissions, udev policy, and service ownership.

Use librux subsystem status, librux subsystem sessions, and librux subsystem cleanup <name> --stale to inspect or clear subsystem lifecycle state during repeated direct-run development.

Validation

Use Add Resource Policy for reproducible checks covering.

  • CPU lease smoke
  • brokered NIC sockets
  • link-layer raw packet launch grants
  • brokered SocketCAN
  • brokered TTY device FDs