|
[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 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.
-George
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |