mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Merge branch 'ticket32211'
This commit is contained in:
commit
97b5ff2b1d
@ -258,6 +258,8 @@ ALIASES =
|
||||
|
||||
ALIASES += refdir{1}="\ref src/\1 \"\1\""
|
||||
|
||||
ALIASES += ticket{1}="[ticket \1](https://bugs.torproject.org/\1)"
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
77
src/lib/subsys/initialization.dox
Normal file
77
src/lib/subsys/initialization.dox
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
|
||||
@page initialization Initialization and shutdown
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@section overview Overview
|
||||
|
||||
Tor has a single entry point: tor_run_main() in main.c. All the ways of
|
||||
starting a Tor process (ntmain.c, tor_main.c, and tor_api.c) work by invoking tor_run_main().
|
||||
|
||||
The tor_run_main() function normally exits (@ref init_exceptwhen "1") by
|
||||
returning: not by calling abort() or exit(). Before it returns, it calls
|
||||
tor_cleanup() in shutdown.c.
|
||||
|
||||
Conceptually, there are several stages in running Tor.
|
||||
|
||||
1. First, we initialize those modules that do not depend on the
|
||||
configuration. This happens in the first half of tor_run_main(), and the
|
||||
first half of tor_init(). (@ref init_pending_refactor "2")
|
||||
|
||||
2. Second, we parse the command line and our configuration, and configure
|
||||
systems that depend on our configuration or state. This configuration
|
||||
happens midway through tor_init(), which invokes
|
||||
options_init_from_torrc(). We then initialize more systems from the
|
||||
second half of tor_init().
|
||||
|
||||
3. At this point we may exit early if we have been asked to do something
|
||||
requiring no further initialization, like printing our version number or
|
||||
creating a new signing key. Otherwise, we proceed to run_tor_main_loop(),
|
||||
which initializes some network-specific parts of Tor, grabs some
|
||||
daemon-only resources (like the data directory lock) and starts Tor itself
|
||||
running.
|
||||
|
||||
|
||||
> @anchor init_exceptwhen 1. tor_run_main() _can_ terminate with a call to
|
||||
> abort() or exit(), but only when crashing due to a bug, or when forking to
|
||||
> run as a daemon.
|
||||
|
||||
> @anchor init_pending_refactor 2. The pieces of code that I'm describing as
|
||||
> "the first part of tor_init()" and so on deserve to be functions with their
|
||||
> own name. I'd like to refactor them, but before I do so, there is some
|
||||
> slight reorganization that needs to happen. Notably, the
|
||||
> nt_service_parse_options() call ought logically to be later in our
|
||||
> initialization sequence. See @ticket{32447} for our refactoring progress.
|
||||
|
||||
|
||||
@section subsys Subsystems and initialization
|
||||
|
||||
Our current convention is to use the subsystem mechanism to initialize and
|
||||
clean up pieces of Tor. The more recently updated pieces of Tor will use
|
||||
this mechanism. For examples, see e.g. time_sys.c or log_sys.c.
|
||||
|
||||
In simplest terms, a **subsytem** is a logically separate part of Tor that
|
||||
can be initialized, shut down, managed, and configured somewhat independently
|
||||
of the rest of the program.
|
||||
|
||||
The subsys_fns_t type describes a subsystem and a set of functions that
|
||||
initialize it, desconstruct it, and so on. To define a subsystem, we declare
|
||||
a `const` instance of subsys_fns_t. See the documentation for subsys_fns_t
|
||||
for a full list of these functions.
|
||||
|
||||
After defining a subsytem, it must be inserted in subsystem_list.c. At that
|
||||
point, table-driven mechanisms in subsysmgr.c will invoke its functions when
|
||||
appropriate.
|
||||
|
||||
@subsection vsconfig Initialization versus configuration
|
||||
|
||||
We note that the initialization phase of Tor occurs before any configuration
|
||||
is read from disk -- and therefore before any other files are read from
|
||||
disk. Therefore, any behavior that depends on Tor's configuration or state
|
||||
must occur _after_ the initialization process, during configuration.
|
||||
|
||||
|
||||
|
||||
|
||||
**/
|
@ -23,8 +23,16 @@ struct config_format_t;
|
||||
* All callbacks are optional -- if a callback is set to NULL, the subsystem
|
||||
* manager will treat it as a no-op.
|
||||
*
|
||||
* You should use c99 named-field initializers with this structure: we
|
||||
* will be adding more fields, often in the middle of the structure.
|
||||
* You should use c99 named-field initializers with this structure, for
|
||||
* readability and safety. (There are a lot of functions here, all of them
|
||||
* optional, and many of them with similar signatures.)
|
||||
*
|
||||
* See @ref initialization for more information about initialization and
|
||||
* shutdown in Tor.
|
||||
*
|
||||
* To make a new subsystem, you declare a const instance of this type, and
|
||||
* include it on the list in subsystem_list.c. The code that manages these
|
||||
* subsystems is in subsysmgr.c.
|
||||
**/
|
||||
typedef struct subsys_fns_t {
|
||||
/**
|
||||
@ -55,7 +63,7 @@ typedef struct subsys_fns_t {
|
||||
* it is only for global state or pre-configuration state.
|
||||
*
|
||||
* (If you need to do any setup that depends on configuration, you'll need
|
||||
* to declare a configuration callback. (Not yet designed))
|
||||
* to declare a configuration callback instead. (Not yet designed))
|
||||
*
|
||||
* This function MUST NOT have any parts that can fail.
|
||||
**/
|
||||
@ -63,22 +71,49 @@ typedef struct subsys_fns_t {
|
||||
|
||||
/**
|
||||
* Connect a subsystem to the message dispatch system.
|
||||
*
|
||||
* This function should use the macros in @refdir{lib/pubsub} to register a
|
||||
* set of messages that this subsystem may publish, and may subscribe to.
|
||||
*
|
||||
* See pubsub_macros.h for more information, and for examples.
|
||||
**/
|
||||
int (*add_pubsub)(struct pubsub_connector_t *);
|
||||
|
||||
/**
|
||||
* Perform any necessary pre-fork cleanup. This function may not fail.
|
||||
*
|
||||
* On Windows (and any other platforms without fork()), this function will
|
||||
* never be invoked. Otherwise it is used when we are about to start
|
||||
* running as a background daemon, or when we are about to run a unit test
|
||||
* in a subprocess. Unlike the subsys_fns_t.postfork callback, it is run
|
||||
* from the parent process.
|
||||
*
|
||||
* Note that we do not invoke this function when the child process's only
|
||||
* purpose is to call exec() and run another program.
|
||||
*/
|
||||
void (*prefork)(void);
|
||||
|
||||
/**
|
||||
* Perform any necessary post-fork setup. This function may not fail.
|
||||
*
|
||||
* On Windows (and any other platforms without fork()), this function will
|
||||
* never be invoked. Otherwise it is used when we are about to start
|
||||
* running as a background daemon, or when we are about to run a unit test
|
||||
* in a subprocess. Unlike the subsys_fns_t.prefork callback, it is run
|
||||
* from the child process.
|
||||
*
|
||||
* Note that we do not invoke this function when the child process's only
|
||||
* purpose is to call exec() and run another program.
|
||||
*/
|
||||
void (*postfork)(void);
|
||||
|
||||
/**
|
||||
* Free any thread-local resources held by this subsystem. Called before
|
||||
* the thread exits.
|
||||
*
|
||||
* This function is not allowed to fail.
|
||||
*
|
||||
* \bug Note that this callback is currently buggy: See \ticket{32103}.
|
||||
*/
|
||||
void (*thread_cleanup)(void);
|
||||
|
||||
@ -86,18 +121,28 @@ typedef struct subsys_fns_t {
|
||||
* Free all resources held by this subsystem.
|
||||
*
|
||||
* This function is not allowed to fail.
|
||||
*
|
||||
* Subsystems are shut down when Tor is about to exit or return control to
|
||||
* an embedding program. This callback must return the process to a state
|
||||
* such that subsys_fns_t.init will succeed if invoked again.
|
||||
**/
|
||||
void (*shutdown)(void);
|
||||
|
||||
/**
|
||||
* A config_format_t describing all of the torrc fields owned by this
|
||||
* subsystem.
|
||||
*
|
||||
* This object, if present, is registered in a confmgr_t for Tor's options,
|
||||
* and used to parse option fields from the command line and torrc file.
|
||||
**/
|
||||
const struct config_format_t *options_format;
|
||||
|
||||
/**
|
||||
* A config_format_t describing all of the DataDir/state fields owned by
|
||||
* this subsystem.
|
||||
*
|
||||
* This object, if present, is registered in a confmgr_t for Tor's state,
|
||||
* and used to parse state fields from the DataDir/state file.
|
||||
**/
|
||||
const struct config_format_t *state_format;
|
||||
|
||||
@ -106,7 +151,11 @@ typedef struct subsys_fns_t {
|
||||
* on success, -1 on failure.
|
||||
*
|
||||
* It is safe to store the pointer to the object until set_options()
|
||||
* is called again. */
|
||||
* is called again.
|
||||
*
|
||||
* This function is only called after all the validation code defined
|
||||
* by subsys_fns_t.options_format has passed.
|
||||
**/
|
||||
int (*set_options)(void *);
|
||||
|
||||
/* XXXX Add an implementation for options_act_reversible() later in this
|
||||
@ -118,6 +167,12 @@ typedef struct subsys_fns_t {
|
||||
*
|
||||
* It is safe to store the pointer to the object; set_state() is only
|
||||
* called on startup.
|
||||
*
|
||||
* This function is only called after all the validation code defined
|
||||
* by subsys_fns_t.state_format has passed.
|
||||
*
|
||||
* This function will only be called once per invocation of Tor, since
|
||||
* Tor does not reload its state while it is running.
|
||||
**/
|
||||
int (*set_state)(void *);
|
||||
|
||||
|
@ -30,6 +30,8 @@ Tor repository.
|
||||
|
||||
@subpage intro
|
||||
|
||||
@subpage initialization
|
||||
|
||||
@subpage dataflow
|
||||
|
||||
@subpage certificates
|
||||
|
Loading…
Reference in New Issue
Block a user