From mboxrd@z Thu Jan 1 00:00:00 1970 From: Olaf Hering Subject: [PATCH 6/6] xen kexec: reset device state to Initializing during reboot Date: Tue, 26 Jul 2011 13:52:15 +0200 Message-ID: <20110726115211.489145690@aepfle.de> References: <20110726115209.655568638@aepfle.de> Return-path: Content-Disposition: inline; filename=xen.xenbus_dev_shutdown.XenbusStateInitialising.patch List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org During kexec all devices will be shutdown, the backend drivers enter the Closed state. But in this state the kexec kernel can not connect to the backend because it expects the devices in InitWait state. After triggering the Closing event, trigger also the Initializing event and wait until the backend has changed its state. Without this waiting the kexec kernel may find a device where a state change is still in progress. Signed-off-by: Olaf Hering --- drivers/xen/xenbus/xenbus_probe.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) Index: linux-3.0/drivers/xen/xenbus/xenbus_probe.c =================================================================== --- linux-3.0.orig/drivers/xen/xenbus/xenbus_probe.c +++ linux-3.0/drivers/xen/xenbus/xenbus_probe.c @@ -192,8 +192,19 @@ void xenbus_otherend_changed(struct xenb * work that can fail e.g., when the rootfs is gone. */ if (system_state > SYSTEM_RUNNING) { - if (ignore_on_shutdown && (state == XenbusStateClosing)) - xenbus_frontend_closed(dev); + if (ignore_on_shutdown) { + switch (state) { + case XenbusStateClosing: + xenbus_frontend_closed(dev); + break; + case XenbusStateInitialising: + case XenbusStateInitWait: + complete(&dev->down); + break; + default: + break; + } + } return; } @@ -284,6 +295,14 @@ void xenbus_dev_shutdown(struct device * if (!timeout) printk(KERN_INFO "%s: %s timeout closing device\n", __func__, dev->nodename); + + if (system_state > SYSTEM_RUNNING) { + xenbus_switch_state(dev, XenbusStateInitialising); + timeout = wait_for_completion_timeout(&dev->down, timeout); + if (!timeout) + printk(KERN_INFO "%s: %s timeout initializing device\n", + __func__, dev->nodename); + } out: put_device(&dev->dev); }