NIF binding for Linx.Sysctl's cross-namespace verbs. Loads
priv/linx_sysctl.so (built by the :linx_sysctl Mix compiler).
Production callers should not use this module directly — go through
Linx.Sysctl, which handles key validation, value rendering, the
:in option, and %Linx.Sysctl.Error{} wrapping.
The ns_paths argument
Each fallible function takes an ns_paths argument: a list of
binaries naming /proc/<pid>/ns/<kind> files (or any other
pinned-namespace file). The NIF opens every fd FIRST in the BEAM's
own namespace (so the paths resolve correctly), then spawns a
throwaway pthread that unshare(CLONE_FS)s + setns(2)s each fd
in order, then performs the I/O, then exits the thread. The BEAM's
own scheduler threads never enter the target namespaces.
An empty list ([]) skips the setns dance — useful for testing
the NIF in isolation, though the public Linx.Sysctl verbs use
the pure-Elixir host path in that case.
Error shape
Every fallible function returns :ok / {:ok, ...} or
{:error, {stage_atom, errno_atom_or_int}}. Stages:
:read/:write/:list— the I/O itself failed.:open_ns— couldn't open one of the namespace files (target process gone, BEAM lacks read access).:unshare—unshare(CLONE_FS)failed (vanishingly rare).:setns— couldn't enter one of the target namespaces (typicallyEPERMin the rootless case).:thread— couldn't create the worker thread.
Summary
Functions
Recursively walks the directory tree rooted at root from inside
the target namespace stack named by ns_paths, returning every
readable regular file as a {path_binary, value_binary} tuple.
Reads the procfs file at path from inside the target namespace
stack named by ns_paths.
Returns the NIF identifier string.
Writes data to the procfs file at path from inside the target
namespace stack named by ns_paths. One write call; no \n is
appended.
Types
@type error() :: {:error, {stage(), atom() | pos_integer()}}
@type stage() :: :read | :write | :list | :open_ns | :unshare | :setns | :thread
Native error shape: {stage_atom, errno_atom_or_int}.
Functions
Recursively walks the directory tree rooted at root from inside
the target namespace stack named by ns_paths, returning every
readable regular file as a {path_binary, value_binary} tuple.
Unreadable directories and unreadable files are silently skipped
(matches the pure-Elixir walker behaviour). A non-existent or
non-directory root returns {:error, {:list, errno}}.
The returned list is in walker-discovery order; callers sort by whatever key they want.
Reads the procfs file at path from inside the target namespace
stack named by ns_paths.
Returns {:ok, binary} with the file's untrimmed bytes (callers
trim) or {:error, {stage, errno}}.
@spec version() :: charlist()
Returns the NIF identifier string.
Writes data to the procfs file at path from inside the target
namespace stack named by ns_paths. One write call; no \n is
appended.