veyron/services/mgmt: integrate device manager with sysinit
This change adds support to the deviced binary to install/uninstall/start/stop
itself via the sysinit package (which in turn interfaces with upstart/sysinit).
In 'init mode', the install command creates a service description and registers
it with the system daemon manager. Uninstall, Start, and Stop will then also
use sysinit to perform their respective duties.
Since sysinit operations need to be run as root, we introduce a new helper
(inithelper) analogous to suidhelper, which deviced calls when it needs to do
sysinit operations.
This change also makes some necessary changes to the sysinit package:
- setting the uid to 0 when euid is 0
- adding a New() api to create the appropriate InstallSystemInit object
- removing the setup function
- adding serialization/deserialization routines for ServiceDescription
Other changes lumped up with this CL, which could have been separated out into
their own CLs if we had less time pressure:
- managing stdout/stderr output from device manager and security agent, and
ensuring we persist that in appropriate log dirs
- changing the exit code behavior of device manager to return 0 when a restart
is not desired, and to non-zero if restart is desired; in particular, Stop now
return 0 but Revert/Update/Suspend do not (nor do crashes obviously). This
makes it easier to decide if device manager is meant to be restarted or not.
- adding a 'hack' to lib/signals to treat duplicate signals received by the
process as one; this gets around the problem of deviced receiving a signal
from its parent (the security agent) in addition to the signal it gets from
e.g. a ^C or from upstart by virtue of being part of the process group lead by
the agent.
Change-Id: I9f75577abb2258600b9b58bd141002bd2e05fac7
diff --git a/services/mgmt/device/impl/dispatcher.go b/services/mgmt/device/impl/dispatcher.go
index dabfcbc..eae1fdd 100644
--- a/services/mgmt/device/impl/dispatcher.go
+++ b/services/mgmt/device/impl/dispatcher.go
@@ -32,10 +32,10 @@
// internalState wraps state shared between different device manager
// invocations.
type internalState struct {
- callback *callbackState
- updating *updatingState
- securityAgent *securityAgentState
- stopHandler func()
+ callback *callbackState
+ updating *updatingState
+ securityAgent *securityAgentState
+ restartHandler func()
}
// aclLocks provides a mutex lock for each acl file path.
@@ -85,7 +85,7 @@
)
// NewDispatcher is the device manager dispatcher factory.
-func NewDispatcher(principal security.Principal, config *config.State, stopHandler func()) (*dispatcher, error) {
+func NewDispatcher(principal security.Principal, config *config.State, restartHandler func()) (*dispatcher, error) {
if err := config.Validate(); err != nil {
return nil, fmt.Errorf("invalid config %v: %v", config, err)
}
@@ -106,9 +106,9 @@
d := &dispatcher{
etag: "default",
internal: &internalState{
- callback: newCallbackState(config.Name),
- updating: newUpdatingState(),
- stopHandler: stopHandler,
+ callback: newCallbackState(config.Name),
+ updating: newUpdatingState(),
+ restartHandler: restartHandler,
},
config: config,
uat: uat,
@@ -364,12 +364,12 @@
switch components[0] {
case deviceSuffix:
receiver := device.DeviceServer(&deviceService{
- callback: d.internal.callback,
- updating: d.internal.updating,
- stopHandler: d.internal.stopHandler,
- config: d.config,
- disp: d,
- uat: d.uat,
+ callback: d.internal.callback,
+ updating: d.internal.updating,
+ restartHandler: d.internal.restartHandler,
+ config: d.config,
+ disp: d,
+ uat: d.uat,
})
return receiver, d.auth, nil
case appsSuffix: