ia64/xen-unstable

changeset 7595:286946489e5d

From Murillo Fernandes Bernardes <mfb@br.ibm.com>:

The problem is: There is no mechanism to detect block device setup failure

Network devices have the same problem, and are fixed with this too.

I handling this problem in the way suggested by aliguori:
- hotplug scripts write a "hotplug-status" node on store
- Xend DevController.createDevice() check verify this node and return success
or throw an exception on failure.
- If no changes in "hotplug-status" node after DEVICE_CREATE_TIMEOUT seconds
Xend throw an exception showing the problem with hotplug scripts.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Mon Oct 31 17:10:57 2005 +0100 (2005-10-31)
parents a7129a40f239
children 6be0d21bb863
files tools/examples/block-common.sh tools/examples/vif-bridge tools/examples/vif-nat tools/examples/vif-route tools/examples/xen-hotplug-common.sh tools/python/xen/xend/server/DevController.py
line diff
     1.1 --- a/tools/examples/block-common.sh	Mon Oct 31 17:03:13 2005 +0100
     1.2 +++ b/tools/examples/block-common.sh	Mon Oct 31 17:10:57 2005 +0100
     1.3 @@ -42,10 +42,17 @@ write_dev() {
     1.4    local major
     1.5    local minor
     1.6    local pdev
     1.7 -	
     1.8 +  
     1.9    major=$(stat -L -c %t "$1")
    1.10    minor=$(stat -L -c %T "$1")
    1.11 + 
    1.12 +  if [ -z $major  -o -z $minor ]; then
    1.13 +    fatal "Backend device does not exist"
    1.14 +  fi
    1.15 + 
    1.16    pdev=$(printf "0x%02x%02x" "0x$major" "0x$minor")
    1.17    xenstore_write "$XENBUS_PATH"/physical-device "$pdev" \
    1.18                   "$XENBUS_PATH"/node "$1"
    1.19 +
    1.20 +  success
    1.21  }
     2.1 --- a/tools/examples/vif-bridge	Mon Oct 31 17:03:13 2005 +0100
     2.2 +++ b/tools/examples/vif-bridge	Mon Oct 31 17:10:57 2005 +0100
     2.3 @@ -58,6 +58,7 @@ case "$command" in
     2.4            fatal "brctl addif $bridge $vif failed"
     2.5  
     2.6          ifconfig "$vif" up || fatal "ifconfig $vif up failed"
     2.7 +        success
     2.8          ;;
     2.9      down)
    2.10          # vifs are auto-removed from bridge.
     3.1 --- a/tools/examples/vif-nat	Mon Oct 31 17:03:13 2005 +0100
     3.2 +++ b/tools/examples/vif-nat	Mon Oct 31 17:10:57 2005 +0100
     3.3 @@ -54,3 +54,5 @@ esac
     3.4  ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip}
     3.5  
     3.6  handle_iptable()
     3.7 +
     3.8 +success
     4.1 --- a/tools/examples/vif-route	Mon Oct 31 17:03:13 2005 +0100
     4.2 +++ b/tools/examples/vif-route	Mon Oct 31 17:10:57 2005 +0100
     4.3 @@ -46,3 +46,5 @@ if [ "${ip}" ] ; then
     4.4  fi
     4.5  
     4.6  handle_iptable()
     4.7 +
     4.8 +success
     5.1 --- a/tools/examples/xen-hotplug-common.sh	Mon Oct 31 17:03:13 2005 +0100
     5.2 +++ b/tools/examples/xen-hotplug-common.sh	Mon Oct 31 17:10:57 2005 +0100
     5.3 @@ -30,10 +30,16 @@ log() {
     5.4  }
     5.5  
     5.6  fatal() {
     5.7 +  xenstore_write "$XENBUS_PATH"/hotplug-status error
     5.8    log err "$@"
     5.9    exit 1
    5.10  }
    5.11  
    5.12 +success() {
    5.13 +  # Tell DevController that backend is "connected"
    5.14 +  xenstore_write "$XENBUS_PATH"/hotplug-status connected
    5.15 +}
    5.16 +
    5.17  ##
    5.18  # xenstore_read <path>+
    5.19  #
     6.1 --- a/tools/python/xen/xend/server/DevController.py	Mon Oct 31 17:03:13 2005 +0100
     6.2 +++ b/tools/python/xen/xend/server/DevController.py	Mon Oct 31 17:10:57 2005 +0100
     6.3 @@ -16,12 +16,18 @@
     6.4  # Copyright (C) 2005 XenSource Ltd
     6.5  #============================================================================
     6.6  
     6.7 +from threading import Event
     6.8  
     6.9  from xen.xend import sxp
    6.10  from xen.xend.XendError import VmError
    6.11  from xen.xend.XendLogging import log
    6.12 +
    6.13  from xen.xend.xenstore.xstransact import xstransact
    6.14 +from xen.xend.xenstore.xswatch import xswatch
    6.15  
    6.16 +DEVICE_CREATE_TIMEOUT = 120
    6.17 +HOTPLUG_STATUS_NODE = "hotplug-status"
    6.18 +HOTPLUG_STATUS_ERROR = "error"
    6.19  
    6.20  class DevController:
    6.21      """Abstract base class for a device controller.  Device controllers create
    6.22 @@ -54,6 +60,18 @@ class DevController:
    6.23  
    6.24          self.writeDetails(config, devid, back, front)
    6.25  
    6.26 +        status, fn_ret = self.waitForBackend(devid)
    6.27 +        if status:
    6.28 +            self.destroyDevice(devid)
    6.29 +            raise VmError( ("Device %s (%s) could not be connected. "
    6.30 +                            "Hotplug scripts not working") 
    6.31 +                            % (devid, self.deviceClass))
    6.32 +
    6.33 +        elif fn_ret == HOTPLUG_STATUS_ERROR:
    6.34 +            self.destroyDevice(devid)
    6.35 +            raise VmError( ("Device %s (%s) could not be connected. "
    6.36 +                            "Backend device not found!") 
    6.37 +                            % (devid, self.deviceClass))
    6.38          return devid
    6.39  
    6.40  
    6.41 @@ -242,6 +260,29 @@ class DevController:
    6.42          xstransact.Write(frontpath, frontDetails)
    6.43          xstransact.Write(backpath, backDetails)
    6.44  
    6.45 +    def waitForBackend(self,devid):
    6.46 +        ev = Event()
    6.47 +
    6.48 +        def hotplugStatus():
    6.49 +            status = self.readBackend(devid, HOTPLUG_STATUS_NODE)
    6.50 +            if status is not None:
    6.51 +                watch.xs.unwatch(backpath, watch)
    6.52 +                hotplugStatus.value = status
    6.53 +                ev.set()
    6.54 +
    6.55 +        hotplugStatus.value = None
    6.56 +        frontpath = self.frontendPath(devid)
    6.57 +        backpath = xstransact.Read(frontpath, "backend")
    6.58 +
    6.59 +        watch = xswatch(backpath, hotplugStatus)
    6.60 +
    6.61 +        ev.wait(DEVICE_CREATE_TIMEOUT)
    6.62 +        if ev.isSet():
    6.63 +            return (0, hotplugStatus.value)
    6.64 +        else:
    6.65 +            return (-1, hotplugStatus.value)
    6.66 +
    6.67 +
    6.68  
    6.69      def backendPath(self, backdom, devid):
    6.70          """@param backdom [XendDomainInfo] The backend domain info."""