[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Fix bug #331
This patch adds the following checks to xend: - Make sure a block device is not attached to more than one DomU at a time - Make sure a block device is not attached to a DomU if it is mounted in Dom0 - Make sure a block device exists before even trying to attach it - Make sure files specified with "file:" actually exist and have the necessary permissions This makes tests 11_block_attach and 12_block_attach pass. In order to check if a device is attached to another DomU, I search the /local/domain/0/device/vbd/*/*/physical-device nodes to see if any DomU had the device already. Although this is ugly, I think it's the best way, so that we don't depend on any xend internal state. Comments? Signed-off-by: Dan Smith <danms@xxxxxxxxxx> # HG changeset patch # User dan@xxxxxxxxxxxxxxxxxxxxxxxxxxx # Node ID 643382df7dc8a2562cf1034250244dc6b2bdebd3 # Parent 14d733e5e1d014e302d72fb78df1428ee08e3ce3 Fix bug #331. Perform some checks before creating block device to make sure that the device is not in use by another DomU, or mounted in Dom0. Also, make a small tweak to the 12_block_attach test so that we don't leave a DomU running with a block device attached. diff -r 14d733e5e1d0 -r 643382df7dc8 tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py Wed Nov 23 13:15:35 2005 +++ b/tools/python/xen/xend/server/DevController.py Wed Nov 23 20:13:07 2005 @@ -75,6 +75,10 @@ @return The ID for the newly created device. """ + (avail, reason) = self.checkAvailability(config) + if not avail: + raise VmError("Device is unavailable: %s" % reason) + (devid, back, front) = self.getDeviceDetails(config) if devid is None: return 0 @@ -202,6 +206,18 @@ raise NotImplementedError() + def checkAvailability(self, config): + + """Determine if the device requested is available for use. + Quick checks that can be made immediately. For example, this + may be an existence, permission, or sharing check. We default + to 'available' because this may not make sense for all device + types. + + @return (isAvailable, reason) + """ + + return (True, "OK") def getDomid(self): """Stub to {@link XendDomainInfo.getDomid}, for use by our diff -r 14d733e5e1d0 -r 643382df7dc8 tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Wed Nov 23 13:15:35 2005 +++ b/tools/python/xen/xend/server/blkif.py Wed Nov 23 20:13:07 2005 @@ -19,13 +19,16 @@ import re import string +import os from xen.util import blkif from xen.xend import sxp from xen.xend.XendError import VmError from xen.xend.server.DevController import DevController +from xen.xend.xenstore.xstransact import xstransact +import xen.xend.XendDomain class BlkifController(DevController): """Block device interface controller. Handles all block devices @@ -37,6 +40,94 @@ """ DevController.__init__(self, vm) + def __phyCheckAvailability(self, device, mode): + + device = blkif.expand_dev_name(device) + + if not os.access(device, os.F_OK): + return (False, "Device %s does not exist" % device) + + if blkif.mount_mode(device) == 'w': + # It's write-mounted, so this domain can't have + # it read or write + return (False, "Device mounted in driver domain") + + return (True, "OK") + + def __fileCheckAvailability(self, file, mode): + + if mode == "r": + checkMode = os.R_OK + else: + checkMode = os.W_OK + + if not os.access(file, os.F_OK): + return (False, "File %s does not exist" % file) + if not os.access(file, checkMode): + return (False, "%s: Permission denied" % file) + + return (True, "OK") + + def __isDeviceAttached(self, backdom, type, device): + + # Utility function + # For physical devices, we compare the physical-device node to + # the major/minor device number we've been given. For files + # we compare the params node to the filename + def isSameDevice(type, value, expected): + if type == "phy": + return int(value, 16) == int(expected) + elif type == "file": + return value == expected + + dom0Devs = xstransact.ListRecursive("%s/backend/%s" + % (backdom.getDomainPath(), + self.deviceClass)) + + if type == "phy": + valToCheck = "physical-device" + device = blkif.blkdev_name_to_number(device) + if not device: + return False + else: + valToCheck = "params" + + # This is ugly + for dom, devs in dom0Devs: + for devid, vals in devs: + for name, value in vals: + if name == valToCheck: + if isSameDevice(type, value, device): + return True + else: + break + + return False + + def checkAvailability(self, config): + """@see DevController.checkAvailability""" + + xd = xen.xend.XendDomain.instance() + backdom = xd.privilegedDomain() + devid = blkif.blkdev_name_to_number(sxp.child_value(config, 'dev')) + backpath = self.backendPath(backdom, devid) + + (type, params) = string.split(sxp.child_value(config, 'uname'), ":", 1) + mode = sxp.child_value(config, 'mode', 'r') + + # Check to see if the device is in use by any other domains + if self.__isDeviceAttached(backdom, type, params): + return (False, + "Device %s is already in use by a running domain" % params) + + # Check to see if the device actually exists and that we + # can access it + if 'phy' == type: + return self.__phyCheckAvailability(params, mode) + elif 'file' == type: + return self.__fileCheckAvailability(params, mode) + else: + return (True, "OK") def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" diff -r 14d733e5e1d0 -r 643382df7dc8 tools/xm-test/tests/block-create/12_block_attach_shared_domU.py --- a/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py Wed Nov 23 13:15:35 2005 +++ b/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py Wed Nov 23 20:13:07 2005 @@ -18,7 +18,7 @@ try: dom2.start() + dom1.destroy() FAIL("Bug #331: Started a DomU with write access to an in-use block device") except DomainError, e: - pass - + dom1.destroy() -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@xxxxxxxxxx _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |