MCP/Runtime split #107

Closed
wants to merge 27 commits into
from

Conversation

Projects
None yet
3 participants
@extremeshok

This is a substantial internal refactor of the outer
daemonization/startup parts of the code with further commits to introduce better reload/restart -type
behaviors which work consistently and more-seamlessly regardless of traditional *nix daemonization/sysvinit vs systemd.

@blblack

This comment has been minimized.

Show comment
Hide comment
@blblack

blblack Mar 22, 2016

Member

I'd love to, but this branch isn't quite ready yet. Probably this along with some further work will become gdnsd 3.x eventually.

Member

blblack commented Mar 22, 2016

I'd love to, but this branch isn't quite ready yet. Probably this along with some further work will become gdnsd 3.x eventually.

blblack added some commits Nov 26, 2014

Initial MCP/Runtime split
This is a substantial internal refactor of the outer
daemonization/startup parts of the code with an eye towards
allowing further commits to introduce better reload/restart -type
behaviors which work consistently and more-seamlessly regardless
of traditional *nix daemonization/sysvinit vs systemd.

Notes on what's happened in this unfortunately-huge commit:

 * The dmn_* daemonization API has been substantially refactored
   and simplified from the temporarily somewhat-crazy form it has
   had for the past several versions.
 * The deprecated option 'listen => scan' has been removed.
 * Socket binding has been simplified with regard to SO_REUSEPORT:
   We no longer attempt binding at two different times to
   accomodate seamlessly restarting-on-upgrade from older gdnsd
   versions which lacked SO_REUSEPORT support.
 * The statio and monitoring code previously shared a separate
   thread and libev loop, but now they're back inside the primary
   thread/loop
 * main.c has been split into mcp.c and runtime.c, and the main
   process has been split into two processes called "mcp" and "runtime":
   * mcp is the outer daemon process from the system or
     administrator point-of-view, while runtime is a child process
     managed by mcp.
   * mcp handles daemonization, pidfiles, signals, initial
     security/privdrop, etc.  It also handles the (often
     privileged) task of socket binding for the runtime process
     after it has completed other initialization tasks.
     Eventually it will also host a control socket for synchronous
     "reload" via re-execution of itself with overlap and re-use
     of common listening sockets, allowing a seamless "reload"
     without loss of network service that can cover any config
     change and can also handle daemon binary code updates.
   * The previous overlapped-restart behavior is gone, to be
     replaced by the above.
   * mcp retains root privileges, but does very little at runtime
     aside from managing "reload" and "stop" behaviors, and does
     not speak to any network sockets.
   * runtime is a subprocess which does all of the actual runtime
     work (dns, zonefiles, stats, etc).  It will have its own
     control socket for handling on-demand stats output and
     synchronous zone data reloads and such.
   * runtime runs under reduced privileges from the get-go,
     enforced by mcp.
   * the two are connected by an anonymous socketpair() and are
     considered an inseparable team of processes that don't
     survive without each other: if either one exits or
     closes the socket, the other will also do so shortly.

Other side-effects:
 * gdnsd's action parameters are now just "start" and
   "checkconfig".  All other functionality will be moved to a new
   "gdnsdctl" binary.
 * When log_foo() outputs are sent to stdio, they now always go to
   stderr (previously, info and debug level messages went to
   stdout instead)
 * The max_http_clients setting is now per-address rather than
   global to all addresses. (but the HTTP listener will be removed
   in a later commit anyways...)
Add control sockets to runtime + mcp
These don't have any specific functionality yet, but they now
exist at defined paths and have the built-in ping and getpid
functionalities.
Add preliminary gdnsdctl binary
The intent is that gdnsdctl will use the control sockets where
possible and handle all of the simple query and control actions on
a running daemon.

At present only "stop" and "status" work.  "stop" uses the legacy
signal, whereas "status" does the existing fcntl-based pidfile
check, then exercises both control sockets by doing "ping" on the
runtime socket, and then validating "getpid" on the MCP socket
matches the fcntl results.
statio: replace http with file + socket JSON outputs
* Removes the awful embedded HTTP listener completely
* Removes HTML and CSV as output formats (JSON only now)
* Adds periodic JSON stats file output, defaults to writing
  $RUNDIR/stats.json every 15 seconds, configurable
* Adds an example html file at docs/stats_example.html, which can
  be served (along with the configured stats file path) by a
  normal external HTTP server and periodically reloads the JSON
  stats file via XMLHTTPRequest and uses it to place the values
  into some styled HTML that closely resembles the output of the
  old built-in HTTP server.
* Adds control socket JSON stats output on-demand, accessible via
  "gdnsdctl stats" or any custom client of the control socket
* Switches testsuite stats checks from HTTP to control socket
  (which removes our dependency on perl's LWP::UserAgent)
Bring docs into better sync with recent code changes
(also, update the sytemd unit template to match)
switch to single controlsock with proxy
This replaces "mcp.sock" and "rt.sock" with a single socket named
"cs" attached to the MCP.  MCP proxies requests to the runtime
process when applicable over their existing anonymous socketpair.
This simplifies some related behaviors for the future "reload"
functionality.  As a side-effect, simplified runtime.c's state and
communications code.
Revert "csock server: support for fork->execve without dropping liste…
…n fd"

This complexity turned out to be unnecessary for the reload work.

This reverts commit bdf84b0.
require existence of config dir on startup
With an execve reload, if we don't get an absolute configdir path
before the daemon's chdir("/"), we lose the ability to ever find
it again, and without it existing we can't use realpath() either
(and anything less is suspect, really).  This was always a
potential corner-case issue for other existing runtime-reload uses
anyways.  It's better to simply require the directory's existence.
Revert "csock server: allow caller stop->start of accepting new conns"
This complexity turned out to be unnecessary for the reload work.

This reverts commit e3b05ec.
runtime: start DNS threads slightly later
This makes no dependency difference, but delays listening for
requests until we've gotten past a few more potential fatal error
checkpoints.
gdnsdctl: implement "reload" request
note that the mcp side of this is still not yet implemented...
@coveralls

This comment has been minimized.

Show comment
Hide comment
@coveralls

coveralls Jun 28, 2016

Coverage Status

Coverage increased (+0.4%) to 80.471% when pulling 99d5e01 on blblack:mcp into b08e3e9 on gdnsd:master.

Coverage Status

Coverage increased (+0.4%) to 80.471% when pulling 99d5e01 on blblack:mcp into b08e3e9 on gdnsd:master.

@blblack

This comment has been minimized.

Show comment
Hide comment
@blblack

blblack Dec 29, 2017

Member

I ended up not really liking where this branch was going. Some of its better ideas were salvaged into another proto-3.x branch, to be uploaded Soon.

Member

blblack commented Dec 29, 2017

I ended up not really liking where this branch was going. Some of its better ideas were salvaged into another proto-3.x branch, to be uploaded Soon.

@blblack blblack closed this Dec 29, 2017

@blblack blblack deleted the blblack:mcp branch Dec 29, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment