The following patch adds a --force option to detach operations. It
avoids the device being held forever when frontend fails.
Comments welcome,
--
Glauber de Oliveira Costa
Red Hat Inc.
"Free as in Freedom"
# HG changeset patch
# User gcosta@xxxxxxxxxx
# Date 1166052970 18000
# Node ID 0c146c72637357ed3011f248c3e6952fface55a6
# Parent 360eb996fa38319867a74bf581c734a80bf6839d
[Xend] Add a --force option to detach operations
In some situations triggered by errors found on guest side,
the device will be held forever, due to the online flag being still on.
Detach operations mostly fails from this point on, as the backend
will not see frontend's state change anymore.
We have to take care about the possibility of of leaking if we drop
entries too early (mostly netfront), or not forcing if for any reason
frontend refused to disconnect device (mostly blkfront)
Signed-off-by Glauber de Oliveira Costa <gcosta@xxxxxxxxxx>
diff -r 360eb996fa38 -r 0c146c726373 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Dec 13 16:13:26 2006 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Dec 13 18:36:10 2006 -0500
@@ -563,7 +563,7 @@ class XendDomainInfo:
for devclass in XendDevices.valid_devices():
self.getDeviceController(devclass).waitForDevices()
- def destroyDevice(self, deviceClass, devid):
+ def destroyDevice(self, deviceClass, devid, force=None):
try:
devid = int(devid)
except ValueError:
@@ -578,7 +578,7 @@ class XendDomainInfo:
devid = entry
break
- return self.getDeviceController(deviceClass).destroyDevice(devid)
+ return self.getDeviceController(deviceClass).destroyDevice(devid,
force)
diff -r 360eb996fa38 -r 0c146c726373
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Wed Dec 13 16:13:26
2006 +0000
+++ b/tools/python/xen/xend/server/DevController.py Wed Dec 13 18:36:10
2006 -0500
@@ -191,7 +191,7 @@ class DevController:
raise VmError('%s devices may not be reconfigured' % self.deviceClass)
- def destroyDevice(self, devid):
+ def destroyDevice(self, devid, force):
"""Destroy the specified device.
@param devid The device ID, or something device-specific from which
@@ -211,6 +211,26 @@ class DevController:
# drivers, so this ordering avoids a race).
self.writeBackend(devid, 'online', "0")
self.writeBackend(devid, 'state', str(xenbusState['Closing']))
+
+ if force:
+ frontpath = self.frontendPath(devid)
+ backpath = xstransact.Read(frontpath, "backend")
+ # give frontend its last chance
+ if not backpath:
+ # we're done
+ return
+ ev = Event()
+ # leave a reasonable time for cleanups that may rely upon
+ # xenstore entries
+ ev.wait(2)
+
+ fstate = xstransact.Read(frontpath,"state")
+ # It is not safe to force anything if guest is in connected
+ # state, as it may cause it to leak.
+ if fstate == str(xenbusState['Connected']):
+ raise VmError("Device %d still connected"%(devid))
+ xstransact.Remove(backpath)
+ xstransact.Remove(frontpath)
def configurations(self):
diff -r 360eb996fa38 -r 0c146c726373 tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py Wed Dec 13 16:13:26 2006 +0000
+++ b/tools/python/xen/xend/server/blkif.py Wed Dec 13 18:36:10 2006 -0500
@@ -133,7 +133,7 @@ class BlkifController(DevController):
return config
- def destroyDevice(self, devid):
+ def destroyDevice(self, devid, force):
"""@see DevController.destroyDevice"""
# If we are given a device name, then look up the device ID from it,
@@ -142,13 +142,13 @@ class BlkifController(DevController):
# superclass's method.
try:
- DevController.destroyDevice(self, int(devid))
+ DevController.destroyDevice(self, int(devid), force)
except ValueError:
devid_end = type(devid) is str and devid.split('/')[-1] or None
for i in self.deviceIDs():
d = self.readBackend(i, 'dev')
if d == devid or (devid_end and d == devid_end):
- DevController.destroyDevice(self, i)
+ DevController.destroyDevice(self, i, force)
return
raise VmError("Device %s not connected" % devid)
diff -r 360eb996fa38 -r 0c146c726373 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Wed Dec 13 16:13:26 2006 +0000
+++ b/tools/python/xen/xm/main.py Wed Dec 13 18:36:10 2006 -0500
@@ -142,14 +142,14 @@ SUBCOMMAND_HELP = {
'Create a new virtual block device.'),
'block-configure': ('<Domain> <BackDev> <FrontDev> <Mode> [BackDomain]',
'Change block device configuration'),
- 'block-detach' : ('<Domain> <DevId>',
+ 'block-detach' : ('<Domain> <DevId> [-f|--force]',
'Destroy a domain\'s virtual block device.'),
'block-list' : ('<Domain> [--long]',
'List virtual block devices for a domain.'),
'network-attach': ('<Domain> [--script=<script>] [--ip=<ip>] '
'[--mac=<mac>]',
'Create a new virtual network device.'),
- 'network-detach': ('<Domain> <DevId>',
+ 'network-detach': ('<Domain> <DevId> [-f|--force]',
'Destroy a domain\'s virtual network device.'),
'network-list' : ('<Domain> [--long]',
'List virtual network interfaces for a domain.'),
@@ -1493,12 +1493,19 @@ def xm_network_attach(args):
def detach(args, command, deviceClass):
- arg_check(args, command, 2)
+ arg_check(args, command, 2, 3)
dom = args[0]
dev = args[1]
-
- server.xend.domain.destroyDevice(dom, deviceClass, dev)
+ try:
+ force = args[2]
+ if (force != "--force") and (force != "-f"):
+ print "Ignoring option %s"%(force)
+ force = None
+ except IndexError:
+ force = None
+
+ server.xend.domain.destroyDevice(dom, deviceClass, dev, force)
def xm_block_detach(args):
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|