[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] libxl: treat "dying" domains as destroyed
# HG changeset patch # User Ian Jackson <ian.jackson@xxxxxxxxxxxxx> # Date 1327937019 0 # Node ID f31d8d1b534eab54178c2a73112562d46bbd6fcb # Parent fe766513739e4b7af461dc042ab90be222956282 libxl: treat "dying" domains as destroyed Rename the DOMAIN_DESTROY event to DOMAIN_DEATH and have it trigger when the domain goes into the state indicated by the domaininfo flag "dying". This fixes a race which could leak a daemonised xl process, which would have ignored the domain becoming "dying" and would then wait forever to be told the domain was destroyed. After the domain becomes "dying" we can't generate an event when it is actually destroyed because xenstored will eat the relevant VIRT_DOM_EXC virq and not generate an @releaseDomain, since xenstored discards its own record of the domain's existence as soon as it sees the domain "dying" and will not trigger @releaseDomain watches for domains it knows nothing about. Arguably this is a bug in xenstored, and the whole @releaseDomain machinery is rather poor, but let us not fix that now. Anyway, xl does not really want to know when the domain is ultimately destroyed. It is enough for xl to know that it is on the way out, in the "dying" state (which leads later to destruction by Xen). Also fix a bug where domain_death_xswatch_callback might read one domain beyond the valid data in its domaininfos array, by correctly ordering the checks for empty domain list, end of domain list, and our domain being missing. Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Tested-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Committed-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> --- diff -r fe766513739e -r f31d8d1b534e tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jan 30 15:23:38 2012 +0000 +++ b/tools/libxl/libxl.c Mon Jan 30 15:23:39 2012 +0000 @@ -685,6 +685,30 @@ return ret; } +static void domain_death_occurred(libxl__egc *egc, + libxl_evgen_domain_death **evg_upd, + const char *why) { + /* Removes **evg_upd from death_list and puts it on death_reported + * and advances *evg_upd to the next entry. + * Call sites in domain_death_xswatch_callback must use "continue". */ + EGC_GC; + libxl_evgen_domain_death *const evg = *evg_upd; + + LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, "%s", why); + + libxl_evgen_domain_death *evg_next = LIBXL_TAILQ_NEXT(evg, entry); + *evg_upd = evg_next; + + libxl_event *ev = NEW_EVENT(egc, DOMAIN_DEATH, evg->domid); + if (!ev) return; + + libxl__event_occurred(egc, ev); + + evg->death_reported = 1; + LIBXL_TAILQ_REMOVE(&CTX->death_list, evg, entry); + LIBXL_TAILQ_INSERT_HEAD(&CTX->death_reported, evg, entry); +} + static void domain_death_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *w, const char *wpath, const char *epath) { EGC_GC; @@ -728,32 +752,23 @@ evg, evg->domid, (int)(got - domaininfos), got < gotend ? (long)got->domain : -1L); - if (!rc || got->domain > evg->domid) { - /* ie, the list doesn't contain evg->domid any more so - * the domain has been destroyed */ - libxl_evgen_domain_death *evg_next; - - LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, " destroyed"); - - libxl_event *ev = NEW_EVENT(egc, DOMAIN_DESTROY, evg->domid); - if (!ev) goto out; - - libxl__event_occurred(egc, ev); - - evg->death_reported = 1; - evg_next = LIBXL_TAILQ_NEXT(evg, entry); - LIBXL_TAILQ_REMOVE(&CTX->death_list, evg, entry); - LIBXL_TAILQ_INSERT_HEAD(&CTX->death_reported, evg, entry); - evg = evg_next; - + if (!rc) { + domain_death_occurred(egc, &evg, "empty list"); continue; } - + if (got == gotend) { LIBXL__LOG(CTX, LIBXL__LOG_DEBUG, " got==gotend"); break; } + if (got->domain > evg->domid) { + /* ie, the list doesn't contain evg->domid any more so + * the domain has been destroyed */ + domain_death_occurred(egc, &evg, "missing from list"); + continue; + } + if (got->domain < evg->domid) { got++; continue; @@ -764,6 +779,11 @@ " dominf.flags=%x", evg->shutdown_reported, got->flags); + if (got->flags & XEN_DOMINF_dying) { + domain_death_occurred(egc, &evg, "dying"); + continue; + } + if (!evg->shutdown_reported && (got->flags & XEN_DOMINF_shutdown)) { libxl_event *ev = NEW_EVENT(egc, DOMAIN_SHUTDOWN, got->domain); diff -r fe766513739e -r f31d8d1b534e tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Mon Jan 30 15:23:38 2012 +0000 +++ b/tools/libxl/libxl_types.idl Mon Jan 30 15:23:39 2012 +0000 @@ -396,7 +396,7 @@ libxl_event_type = Enumeration("event_type", [ (1, "DOMAIN_SHUTDOWN"), - (2, "DOMAIN_DESTROY"), + (2, "DOMAIN_DEATH"), (3, "DISK_EJECT"), (4, "OPERATION_COMPLETE"), ]) @@ -417,7 +417,7 @@ [("domain_shutdown", Struct(None, [ ("shutdown_reason", uint8), ])), - ("domain_destroy", Struct(None, [])), + ("domain_death", Struct(None, [])), ("disk_eject", Struct(None, [ ("vdev", string), ("disk", libxl_device_disk), diff -r fe766513739e -r f31d8d1b534e tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Mon Jan 30 15:23:38 2012 +0000 +++ b/tools/libxl/xl_cmdimpl.c Mon Jan 30 15:23:39 2012 +0000 @@ -1909,7 +1909,7 @@ abort(); } - case LIBXL_EVENT_TYPE_DOMAIN_DESTROY: + case LIBXL_EVENT_TYPE_DOMAIN_DEATH: LOG("Domain %d has been destroyed.", domid); ret = 0; goto out; @@ -2445,7 +2445,7 @@ switch (event->type) { - case LIBXL_EVENT_TYPE_DOMAIN_DESTROY: + case LIBXL_EVENT_TYPE_DOMAIN_DEATH: LOG("Domain %d has been destroyed", domid); goto done; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |