From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 21/23] libxl: suspend: Fix suspend wait corner cases Date: Tue, 17 Dec 2013 18:35:35 +0000 Message-ID: <1387305337-15355-22-git-send-email-ian.jackson@eu.citrix.com> References: <1387305337-15355-1-git-send-email-ian.jackson@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1387305337-15355-1-git-send-email-ian.jackson@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: Shriram Rajagopalan , George Dunlap , Ian Jackson , Ian Campbell , Stefano Stabellini List-Id: xen-devel@lists.xenproject.org When we are waiting for a guest to suspend, this suspend operation would continue to wait (until the timeout) if the guest was destroyed or shut down for another reason, or if xc_domain_getinfolist failed. Handle these cases correctly, as errors. Signed-off-by: Ian Jackson CC: Stefano Stabellini CC: Ian Campbell --- tools/libxl/libxl_dom.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 6291115..88700ee 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -1208,24 +1208,42 @@ static void suspend_common_wait_guest_watch(libxl__egc *egc, STATE_AO_GC(dss->ao); xc_domaininfo_t info; int ret; + int shutdown_reason; /* Convenience aliases */ const uint32_t domid = dss->domid; ret = xc_domain_getinfolist(CTX->xch, domid, 1, &info); - if (ret == 1 && info.domain == domid && - (info.flags & XEN_DOMINF_shutdown)) { - int shutdown_reason; - - shutdown_reason = (info.flags >> XEN_DOMINF_shutdownshift) - & XEN_DOMINF_shutdownmask; - if (shutdown_reason == SHUTDOWN_suspend) { - LOG(DEBUG, "guest has suspended"); - domain_suspend_common_guest_suspended(egc, dss); - return; - } + if (ret < 0) { + LOGE(ERROR, "unable to check for status of guest %"PRId32"", domid); + goto err; + domain_suspend_common_failed(egc, dss); + } + + if (!(ret == 1 && info.domain == domid)) { + LOGE(ERROR, "guest %"PRId32" we were suspending has been destroyed", + domid); + goto err; + } + + if (!(info.flags & XEN_DOMINF_shutdown)) + /* keep waiting */ + return; + + shutdown_reason = (info.flags >> XEN_DOMINF_shutdownshift) + & XEN_DOMINF_shutdownmask; + if (shutdown_reason != SHUTDOWN_suspend) { + LOG(DEBUG, "guest %"PRId32" we were suspending has shut down" + " with unexpected reason code %d", domid, shutdown_reason); + goto err; } - /* otherwise, keep waiting */ + + LOG(DEBUG, "guest has suspended"); + domain_suspend_common_guest_suspended(egc, dss); + return; + + err: + domain_suspend_common_failed(egc, dss); } static void suspend_common_wait_guest_timeout(libxl__egc *egc, -- 1.7.10.4