aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/system
diff options
context:
space:
mode:
Diffstat (limited to 'internal/system')
-rw-r--r--internal/system/dbus.go72
-rw-r--r--internal/system/op.go21
2 files changed, 20 insertions, 73 deletions
diff --git a/internal/system/dbus.go b/internal/system/dbus.go
index 42208267..fd995bb0 100644
--- a/internal/system/dbus.go
+++ b/internal/system/dbus.go
@@ -3,7 +3,6 @@ package system
import (
"bytes"
"errors"
- "os"
"strings"
"sync"
@@ -26,9 +25,6 @@ func (sys *I) MustProxyDBus(sessionPath string, session *dbus.Config, systemPath
func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath string) (func(), error) {
d := new(DBus)
- // used by waiting goroutine to notify process exit
- d.done = make(chan struct{})
-
// session bus is mandatory
if session == nil {
return nil, fmsg.WrapError(ErrDBusConfig,
@@ -75,88 +71,34 @@ type DBus struct {
out *scanToFmsg
// whether system bus proxy is enabled
system bool
- // notification from goroutine waiting for dbus.Proxy
- done chan struct{}
}
func (d *DBus) Type() Enablement {
return Process
}
-func (d *DBus) apply(_ *I) error {
+func (d *DBus) apply(sys *I) error {
fmsg.VPrintf("session bus proxy on %q for upstream %q", d.proxy.Session()[1], d.proxy.Session()[0])
if d.system {
fmsg.VPrintf("system bus proxy on %q for upstream %q", d.proxy.System()[1], d.proxy.System()[0])
}
- // ready channel passed to dbus package
- ready := make(chan error, 1)
-
- // background dbus proxy start
- if err := d.proxy.Start(ready, d.out, true, true); err != nil {
+ // this starts the process and blocks until ready
+ if err := d.proxy.Start(sys.ctx, d.out, true); err != nil {
+ d.out.Dump()
return fmsg.WrapErrorSuffix(err,
"cannot start message bus proxy:")
}
fmsg.VPrintln("starting message bus proxy:", d.proxy)
- if fmsg.Verbose() { // save the extra bwrap arg build when verbose logging is off
- fmsg.VPrintln("message bus proxy bwrap args:", d.proxy.BwrapStatic())
- }
-
- // background wait for proxy instance and notify completion
- go func() {
- if err := d.proxy.Wait(); err != nil {
- fmsg.Println("message bus proxy exited with error:", err)
- go func() { ready <- err }()
- } else {
- fmsg.VPrintln("message bus proxy exit")
- }
-
- // ensure socket removal so ephemeral directory is empty at revert
- if err := os.Remove(d.proxy.Session()[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmsg.Println("cannot remove dangling session bus socket:", err)
- }
- if d.system {
- if err := os.Remove(d.proxy.System()[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmsg.Println("cannot remove dangling system bus socket:", err)
- }
- }
-
- // notify proxy completion
- close(d.done)
- }()
-
- // ready is not nil if the proxy process faulted
- if err := <-ready; err != nil {
- // dump message buffer as caller does not dump this
- // in an early fault condition
- d.out.Dump()
-
- // note that err here is either an I/O error or a predetermined unexpected behaviour error
- return fmsg.WrapErrorSuffix(err,
- "message bus proxy fault after start:")
- }
- fmsg.VPrintln("message bus proxy ready")
-
return nil
}
func (d *DBus) revert(_ *I, _ *Criteria) error {
// criteria ignored here since dbus is always process-scoped
fmsg.VPrintln("terminating message bus proxy")
-
- if err := d.proxy.Close(); err != nil {
- if errors.Is(err, os.ErrClosed) {
- return fmsg.WrapError(err,
- "message bus proxy already closed")
- } else {
- return fmsg.WrapErrorSuffix(err,
- "cannot stop message bus proxy:")
- }
- }
-
- // block until proxy wait returns
- <-d.done
- return nil
+ d.proxy.Close()
+ defer fmsg.VPrintln("message bus proxy exit")
+ return fmsg.WrapErrorSuffix(d.proxy.Wait(), "message bus proxy error:")
}
func (d *DBus) Is(o Op) bool {
diff --git a/internal/system/op.go b/internal/system/op.go
index d8479c7c..8a98fa78 100644
--- a/internal/system/op.go
+++ b/internal/system/op.go
@@ -1,6 +1,7 @@
package system
import (
+ "context"
"errors"
"os"
"sync"
@@ -57,10 +58,14 @@ func TypeString(e Enablement) string {
type I struct {
uid int
ops []Op
- sp *os.File
+ ctx context.Context
+ // sync fd passed to bwrap
+ sp *os.File
- state [2]bool
- lock sync.Mutex
+ // whether sys has been reverted
+ state bool
+
+ lock sync.Mutex
}
func (sys *I) UID() int {
@@ -85,14 +90,14 @@ func (sys *I) Equal(v *I) bool {
return true
}
-func (sys *I) Commit() error {
+func (sys *I) Commit(ctx context.Context) error {
sys.lock.Lock()
defer sys.lock.Unlock()
- if sys.state[0] {
+ if sys.ctx != nil {
panic("sys instance committed twice")
}
- sys.state[0] = true
+ sys.ctx = ctx
sp := New(sys.uid)
sp.ops = make([]Op, 0, len(sys.ops)) // prevent copies during commits
@@ -125,10 +130,10 @@ func (sys *I) Revert(ec *Criteria) error {
sys.lock.Lock()
defer sys.lock.Unlock()
- if sys.state[1] {
+ if sys.state {
panic("sys instance reverted twice")
}
- sys.state[1] = true
+ sys.state = true
// collect errors
errs := make([]error, len(sys.ops))