|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RESEND PATCH 12/12] golang/xenlight: add NotifyDomainDeath method to Context
On Fri, Jun 18, 2021 at 07:31:46PM +0000, George Dunlap wrote:
>
>
> > On Jun 18, 2021, at 7:28 PM, George Dunlap <george.dunlap@xxxxxxxxxx> wrote:
> >
> >
> >
> >> On May 24, 2021, at 9:36 PM, Nick Rosbrook <rosbrookn@xxxxxxxxx> wrote:
> >>
> >> Add a helper function to wait for domain death events, and then write
> >> the events to a provided channel. This handles the enabling/disabling of
> >> the event type, freeing the event, and converting it to a Go type. The
> >> caller can then handle the event however they need to. This function
> >> will run until a provided context.Context is cancelled.
> >>
> >> NotifyDomainDeath spawns two goroutines that return when the
> >> context.Context is done. The first will make sure that the domain death
> >> event is disabled, and that the corresponding event queue is cleared.
> >> The second calls libxl_event_wait, and writes the event to the provided
> >> channel.
> >>
> >> With this, callers should be able to manage a full domain life cycle.
> >> Add to the comment of DomainCreateNew so that package uses know they
> >> should use this method in conjunction with DomainCreateNew.
> >>
> >> Signed-off-by: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx>
> >> ---
> >> tools/golang/xenlight/xenlight.go | 83 ++++++++++++++++++++++++++++++-
> >> 1 file changed, 82 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/tools/golang/xenlight/xenlight.go
> >> b/tools/golang/xenlight/xenlight.go
> >> index 6fb22665cc..8406883433 100644
> >> --- a/tools/golang/xenlight/xenlight.go
> >> +++ b/tools/golang/xenlight/xenlight.go
> >> @@ -53,6 +53,7 @@ import "C"
> >> */
> >>
> >> import (
> >> + "context"
> >> "fmt"
> >> "os"
> >> "os/signal"
> >> @@ -1340,7 +1341,9 @@ func (ctx *Context) DeviceUsbdevRemove(domid Domid,
> >> usbdev *DeviceUsbdev) error
> >> return nil
> >> }
> >>
> >> -// DomainCreateNew creates a new domain.
> >> +// DomainCreateNew creates a new domain. Callers of DomainCreateNew are
> >> +// responsible for handling the death of the resulting domain. This
> >> should be
> >> +// done using NotifyDomainDeath.
> >> func (ctx *Context) DomainCreateNew(config *DomainConfig) (Domid, error) {
> >> var cdomid C.uint32_t
> >> var cconfig C.libxl_domain_config
> >> @@ -1358,6 +1361,84 @@ func (ctx *Context) DomainCreateNew(config
> >> *DomainConfig) (Domid, error) {
> >> return Domid(cdomid), nil
> >> }
> >>
> >> +// NotifyDomainDeath registers an event handler for domain death events
> >> for a
> >> +// given domnid, and writes events received to ec. NotifyDomainDeath
> >> returns an
> >> +// error if it cannot register the event handler, but other errors
> >> encountered
> >> +// are just logged. The goroutine spawned by calling NotifyDomainDeath
> >> runs
> >> +// until the provided context.Context's Done channel is closed.
> >> +func (ctx *Context) NotifyDomainDeath(c context.Context, domid Domid, ec
> >> chan<- Event) error {
> >> + var deathw *C.libxl_evgen_domain_death
> >> +
> >> + ret := C.libxl_evenable_domain_death(ctx.ctx, C.uint32_t(domid), 0,
> >> &deathw)
> >> + if ret != 0 {
> >> + return Error(ret)
> >> + }
> >> +
> >> + // Spawn a goroutine that is responsible for cleaning up when the
> >> + // passed context.Context's Done channel is closed.
> >> + go func() {
> >> + <-c.Done()
> >> +
> >> + ctx.logd("cleaning up domain death event handler for domain
> >> %d", domid)
> >> +
> >> + // Disable the event generation.
> >> + C.libxl_evdisable_domain_death(ctx.ctx, deathw)
> >> +
> >> + // Make sure any events that were generated get cleaned up so
> >> they
> >> + // do not linger in the libxl event queue.
> >> + var evc *C.libxl_event
> >> + for {
> >> + ret := C.libxl_event_check(ctx.ctx, &evc,
> >> C.LIBXL_EVENTMASK_ALL, nil, nil)
> >> + if ret != 0 {
> >> + return
> >> + }
> >> + C.libxl_event_free(ctx.ctx, evc)
> >
> > I have to admit, I don’t really understand how the libxl event stuff is
> > supposed to work. But it looks like this will drain all events of any
> > type, for any domain, associated with this context?
> >
> > So if you had two domains, and called NotifyDomainDeath() on both with
> > different contexts, and you closed the one context, you might miss events
> > from the other context?
> >
> > Or, suppose you did this:
> > * ctx.NotifyDomainDeath(ctx1, dom1, ec1)
> > * ctx.NotifyDiskEject(ctx2, dom1, ec2)
> > * ctx1CancelFunc()
> >
> > Wouldn’t there be a risk that the disk eject message would get lost?
> >
> > Ian, any suggestions for the right way to use these functions in this
> > scenario?
>
> It looks like one option would be to add a “predicate” function filter, to
> filter by type and domid.
>
> It looks like the other option would be to try to use
> libxl_event_register_callbacks(). We could have the C callback pass all the
> events to a goroutine which would act as a dispatcher.
>
After a brief look at the documentation within libxl_event.h, it seems
using predicate functions would be the easiest solution given the
current layout. Though I will look closer at using
libxl_event_register_callbacks before sending a v2.
Thanks,
NR
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |