[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 8/9] RFC: golang/xenlight: Notify xenlight of SIGCHLD


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: George Dunlap <george.dunlap@xxxxxxxxxx>
  • Date: Fri, 27 Dec 2019 16:32:23 +0000
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=george.dunlap@xxxxxxxxxx; spf=Pass smtp.mailfrom=George.Dunlap@xxxxxxxxxx; spf=None smtp.helo=postmaster@xxxxxxxxxxxxxxx
  • Cc: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>
  • Delivery-date: Fri, 27 Dec 2019 16:32:55 +0000
  • Ironport-sdr: 4cV0c0JygSlWbcJY6IEKh+PZ3xf2hH7+1DhbJNv3f7IWVMoaHRayzduwfgp7GfIor58IUj5u4q m/gZsBZXjjB5E5g1i9SX4B7qPKgWpCZXwN1KW3m12o25WavziPh2Rw7QfyvEEaTc2u/F/X5hdw YGkW/IzrTwOKpCDrp4GUwD0fdd1Fimg4MXTApNDKXIJTYfHOKava8co7soP/9Y+ZD6I0EqB4kx P+Q7GMqv0OWYQDYRCU3G3s0hfw2ObThkYRUzdresSkMV9+LehDLjAa4QdmA2pgWkuPQq14OtGj rT8=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

libxl forks external processes and waits for them to complete; it
therefore needs to be notified when children exit.

In absence of instructions to the contrary, libxl sets up its own
SIGCHLD handlers.

Golang always unmasks and handles SIGCHLD itself.  libxl thankfully
notices this and throws an assert() rather than clobbering SIGCHLD
handlers.

Tell libxl that we'll be responsible for getting SIGCHLD notifications
to it.  Arrange for a channel in the context to receive notifications
on SIGCHLD, and set up a goroutine that will pass these on to libxl.

Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
I have no idea if this is actually the right way to go about this; in
particular, libxl_event.h's comment on this function refers to the
comment on `libxl_childproc_reaped`, which says:

 * May NOT be called from within a signal handler which might
 * interrupt any libxl operation.  The application will almost
 * certainly need to use the self-pipe trick (or a working pselect or
 * ppoll) to implement this.

I don't have a good way of knowing whether the
goproc-receiving-a-channel satisfies this requirement or not.  It
seems to work, in the sense that the pygrub process works fine.  But
it gets stuck a bit further on, looks like waiting for the disk; and a
diff of the output between `xl create` and the golang create seems to
indicate that xenstore watches aren't being delivered.  Not sure if
that's explicitly do to SIGCHLD, or due to some other side effect of
setting libxl_sigchld_owner_mainloop, or something else entirely.

CC: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx>
---
 tools/golang/xenlight/xenlight.go | 34 +++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go 
b/tools/golang/xenlight/xenlight.go
index e115592257..f70a4c6d96 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -33,6 +33,9 @@ import "C"
 
 import (
        "fmt"
+       "os"
+       "os/signal"
+       "syscall"
        "unsafe"
 )
 
@@ -77,8 +80,23 @@ func (e Error) Error() string {
 
 // Context represents a libxl_ctx.
 type Context struct {
-       ctx    *C.libxl_ctx
-       logger *C.xentoollog_logger_stdiostream
+       ctx     *C.libxl_ctx
+       logger  *C.xentoollog_logger_stdiostream
+       sigchld chan os.Signal
+}
+
+// Golang always unmasks SIGCHLD, and internally has ways of
+// distributing SIGCHLD to multiple recipients.  libxl has provision
+// for this model: just tell it when a SIGCHLD happened, and it will
+// look after its own processes.
+//
+// This should "play nicely" with other users of SIGCHLD as long as
+// they don't reap libxl's processes.
+func sigchldHandler(ctx *Context) {
+       for _ = range ctx.sigchld {
+               // Can we spin up another goroutine for this?
+               C.libxl_childproc_sigchld_occurred(ctx.ctx)
+       }
 }
 
 // NewContext returns a new Context.
@@ -93,6 +111,15 @@ func NewContext() (*Context, error) {
                return nil, Error(ret)
        }
 
+       ctx.sigchld = make(chan os.Signal, 2)
+       signal.Notify(ctx.sigchld, syscall.SIGCHLD)
+
+       go sigchldHandler(&ctx)
+
+       C.libxl_childproc_setmode(ctx.ctx,
+               &C.libxl_childproc_hooks{chldowner: 
C.libxl_sigchld_owner_mainloop},
+               nil)
+
        return &ctx, nil
 }
 
@@ -102,6 +129,9 @@ func (ctx *Context) Close() error {
        ctx.ctx = nil
        C.xtl_logger_destroy((*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
 
+       signal.Stop(ctx.sigchld)
+       close(ctx.sigchld)
+
        if ret != 0 {
                return Error(ret)
        }
-- 
2.24.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.