lunatikModule
Manages Lunatik runtimes — isolated Lua states running in the kernel.
In a softirq or hardirq runtime the module holds only cpu and _ENV: runtime and percpu exist in a process runtime alone, and the io library is not opened there and require refuses it.lunatik
| _ENV | Shared rcu.table through which scripts exchange objects. |
| cpu () | Returns the CPU id a percpu runtime serves. |
| percpu (script[, context="process"]) | Creates one runtime per CPU id, each loading the given script in the calling context. |
| runtime (script[, context="process"]) | Creates a new Lunatik runtime executing the given script. |
Class runtime
| runtime:resume (...) | Resumes a runtime as the function coroutine.wrap returns resumes a coroutine: an error is raised, not returned. |
| runtime:stop () | Stops the runtime and releases all associated kernel resources. |
Class percpu
| percpu:resume (...) | Resumes every runtime, as runtime:resume does, delivering the same objects to each. |
| percpu:stop () | Closes the objects the runtimes share, then every runtime, releasing their Lua states. |
lunatik in detail
- _ENV
-
Shared rcu.table through which scripts exchange objects. Its keys
runtimesandthreadsare reserved for lunatik.runner, which records there the scripts it runs and spawns. It is present in a runtime created while thelunatik_runmodule is loaded.Parameters
- _ENV
- cpu ()
-
Returns the CPU id a percpu runtime serves.
Ranges from
0tocpu.maxid(); seerunner.run.Returns
-
integer
CPU id, or
nilon a plain runtime - percpu (script[, context="process"])
-
Creates one runtime per CPU id, each loading the given script in the calling context.
The runtimes are dispatched by CPU: see lunatik.cpu and
runner.run. They close onstop(), when a to-be-closed variable holding the set goes out of scope, or when the last reference to the set is dropped. A hook its script registers with the kernel is one the runtimes share, and it holds the set untilstop(), so dropping the handle does not close a set whose script registered one, andstop()cannot be called once its last handle is gone. A script stops the sets it creates, as it stops a runtime: see lunatik.runtime. Only a process runtime’s lunatik module has it.Parameters
- script
string
script name (e.g.,
"mymod"loads/lib/modules/lua/mymod.lua) - context string execution context, as in lunatik.runtime (default "process")
Returns
Raises
if allocation fails or the script errors on load, after releasing the runtimes already created - script
string
script name (e.g.,
- runtime (script[, context="process"])
-
Creates a new Lunatik runtime executing the given script.
The runtime closes on
stop(), when a to-be-closed variable holding it goes out of scope, or when its last reference is dropped. A hook its script registers with the kernel holds a reference to the runtime, so dropping the handle does not close a runtime a hook still holds: it stays open, its hooks in place and the modules its script required loaded, untilstop(), which cannot be called once its last handle is gone. A script stops the runtimes it creates. A sentinel stops a child with its creator: a table whose__gcstops the child, reachable from what the creator’s runtime keeps until it closes, as the driver table device.new keeps inexamples/systrack/device.lua, since what only a local of the script body references can be collected once the body returns. The close runs the script’s finalizers, the sentinel’s among them: an object one creates or reads is released by the end of the close, and a registration raisesnot allowed while the runtime closes. A last reference dropped with bottom halves or IRQs off, as a softirq or hardirq runtime’s rcu.table write drops an entry’s, closes it on a kernel worker after the drop, where its finalizers may sleep. Only a process runtime’s lunatik module has it.Parameters
- script
string
script name (e.g.,
"mymod"loads/lib/modules/lua/mymod.lua) - context
string
execution context:
"process"(sleepable, GFP_KERNEL, mutex),"softirq"(atomic, GFP_ATOMIC, spinlock), or"hardirq"(atomic, GFP_ATOMIC, spinlock with IRQs disabled). Use"softirq"for hooks that fire in softirq context (netfilter, XDP). Use"hardirq"for hooks that can fire inside an interrupt handler or with interrupts off (kprobes), since only a lock that turns interrupts off cannot be taken again by an interrupt on the CPU that holds it. (default "process")
Returns
Raises
if allocation fails or the script errors on load - script
string
script name (e.g.,
Class runtime in detail
Isolated Lua state running within the Linux kernel.
- runtime:resume (...)
-
Resumes a runtime as the function coroutine.wrap returns resumes a coroutine: an error is
raised, not returned.
The runtime’s script returns a function: the first resume calls it with the objects as its
arguments, and each later one delivers them as the return values of the
coroutine.yield()it is suspended in. Only Lunatik objects cross between the runtimes, in either direction.Parameters
- ...
objects passed to the function, or returned by its
coroutine.yield()
Returns
-
vararg
objects passed to the next
coroutine.yield(), or returned by the functionRaises
“closed object” if the runtime has been stopped; “invalid object” or “cannot share SINGLE object” if a value cannot cross, numbering the arguments on the way in and the yielded values on the way back, or the error raised on resumption; “not allowed from the runtime itself” from under the runtime’s own lock, the contexts stop names, where the resumption would wait on it; “EINTR” if the stop of the calling kernel thread, or a fatal signal to any other task, ends its wait for the runtime’s lockUsage
-- echo.lua, a runtime that hands back what it receives local function echo(object) while true do object = coroutine.yield(object) end end return echo -- the script that drives it local lunatik = require("lunatik") local data = require("data") local runtime <close> = lunatik.runtime("echo") local back = runtime:resume(data.new(4)) -- calls echo, which yields the object back
- ...
objects passed to the function, or returned by its
- runtime:stop ()
-
Stops the runtime and releases all associated kernel resources.
Raises
“not allowed from the runtime itself” from the runtime’s own callback, a device file operation, a thread body or a resumed body, where the close would wait on the lock that task holds; “EINTR” if the stop of the calling kernel thread, or a fatal signal to any other task, ends its wait for the runtime’s lock
Class percpu in detail
Set of runtimes, one per CPU id, running the same script. A callback dispatched
through it reaches the runtime of the CPU it fired on.
- percpu:resume (...)
-
Resumes every runtime, as runtime:resume does, delivering the same objects to each.
The first resume calls the function each runtime’s script returned with them as its arguments,
and each later one returns them from the
coroutine.yield()it is suspended in. Nothing comes back: a broadcast has no single set of values to return, so what a runtime yields is dropped.Parameters
- ...
objects passed to each runtime’s function, or returned by its
coroutine.yield()
Raises
“closed object” if the object has been stopped; otherwise the error of the first runtime that refuses a value it cannot carry or raises on resumption, naming its CPU, with the runtimes after it not resumed. A runtime that refuses a value stays where it yielded; one that raises is dead, so every later resume delivers to the CPUs before it again and fails on it again; “not allowed from the runtime itself” from under the lock of one of the set’s runtimes, the contexts stop names, where its resumption would wait on that lock; “EINTR” if the stop of the calling kernel thread, or a fatal signal to any other task, ends its wait for the lock of one of the set’s runtimes, the runtimes after it not resumed - ...
objects passed to each runtime’s function, or returned by its
- percpu:stop ()
-
Closes the objects the runtimes share, then every runtime, releasing their Lua states.
Raises
“not allowed from the runtime itself” from a callback or a resumed body of one of the set’s runtimes, where its close would wait on the lock that task holds; “EINTR” if the stop of the calling kernel thread, or a fatal signal to any other task, ends its wait for the lock of one of the set’s runtimes, the runtimes before it closed