зеркало из https://github.com/mozilla/mig.git
93 строки
3.9 KiB
ReStructuredText
93 строки
3.9 KiB
ReStructuredText
======================
|
|
Persistent MIG Modules
|
|
======================
|
|
|
|
.. sectnum::
|
|
.. contents:: Table of Contents
|
|
|
|
This document describes persistent modules and how they differ from standard
|
|
MIG modules.
|
|
|
|
Persistent modules are invoked when the agent starts, and run for the lifetime
|
|
of the agent. They are supervised by the main agent process, and are restarted
|
|
if a failure occurs or they are shut down. Persistent modules can be queried in
|
|
the same way an investigator would query using a standard module, however instead
|
|
of the module being invoked once for a point-in-time investigation, the persistent
|
|
module is queried. This can be useful to return collected statistics on an on-going
|
|
basis, or otherwise conduct investigations over a period of time. A persistent module
|
|
can be considered to keep state over the course of its lifetime, where as a standard
|
|
module returns results representing a given point in time.
|
|
|
|
Persistent modules are required to implement all the same functions and satisfy
|
|
the same interfaces as standard modules, but they also are required to implement
|
|
a few additional components.
|
|
|
|
For general information on modules, see the `module documentation`_. This builds off
|
|
that documentation and is specific to the implementation of persistent modules.
|
|
|
|
.. _`module documentation`: modules.rst
|
|
|
|
Module logic
|
|
============
|
|
|
|
Registration
|
|
------------
|
|
|
|
All MIG modules must satisfy the Runner interface. Persistent modules must satisfy
|
|
both the Runner interface, and the PersistRunner interface.
|
|
|
|
.. code:: go
|
|
|
|
type PersistRunner interface {
|
|
RunPersist(io.ReadCloser, io.WriteCloser)
|
|
}
|
|
|
|
Initial execution by the agent
|
|
------------------------------
|
|
|
|
When the agent starts up, any persistent modules will be started. This is done by
|
|
spawning a supervisor goroutine which will start the modules by calling
|
|
``mig-agent`` with the ``-P`` flag to indicate which persistent module to run.
|
|
|
|
The main agent process starts the module up and supervisory related communication
|
|
occurs over a pipe. Writes to and reads from the running persistent module process
|
|
occur over a pipe. From the module side, Writes to and reads from the main agent
|
|
process occur over stdout and stdin respectively.
|
|
|
|
When the persistent module is started by the agent, the modules ``RunPersist()``
|
|
function is executed. This function does not return, and is typically responsible
|
|
for starting up any tasks the module wants to execute in goroutines. Following all
|
|
this, the module will enter the ``modules.DefaultPersistHandlers()`` function which
|
|
provides a consistent entry point to the handling of supervisor messages between the
|
|
agent and the running module.
|
|
|
|
Querying persistent modules
|
|
---------------------------
|
|
|
|
When the agent receives a request to query a persistent module, the general flow
|
|
can be described as follows.
|
|
|
|
::
|
|
|
|
Agent module -m module -P
|
|
+---+ +-------+ +-------+
|
|
Parameters ------stdin->| |
|
|
| Run() -------------listener---------->|----->+
|
|
| | | Persist request handler
|
|
| | |
|
|
<---------------stdout--|<-------------------listener-----------|<-----+
|
|
|
|
* The agent calls itself with the ``-m`` flag, and sends the parameters into stdin of the new process.
|
|
* The modules Run() method is called; this connects to the socket the persistent module is listening on, and submits the same parameter set.
|
|
* The running persistent module accepts the new connection, parses the parameters and returns a result.
|
|
* The ``-m`` query process reads the result from the socket, and returns it to the agent on stdout.
|
|
|
|
Each new request entering the persistent module is handled in a new go-routine in the
|
|
running module. Care must be taken inside this module that data structures are locked or protected
|
|
as concurrent operations can occur with multiple queries hitting the module at the same time.
|
|
|
|
Additional details
|
|
==================
|
|
|
|
For additional details and examples, the examplepersist module should be reviewed.
|