ia64/xen-unstable

changeset 2768:52530182af7c

bitkeeper revision 1.1159.1.301 (41817fb7qo-OpONURmWllN-zVtSETA)

Add checks to prevent unsafe sharing of block devices between domains.
Can be overridden by adding ! to the devices mode.
author cl349@freefall.cl.cam.ac.uk
date Thu Oct 28 23:24:39 2004 +0000 (2004-10-28)
parents 12bf8c939fc7
children 1b906236acc9
files tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/blkif.py
line diff
     1.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Thu Oct 28 17:24:09 2004 +0000
     1.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Thu Oct 28 23:24:39 2004 +0000
     1.3 @@ -649,7 +649,9 @@ class Daemon:
     1.4          
     1.5          Returns controller
     1.6          """
     1.7 -        return self.blkifCF.getController(dom)
     1.8 +        blkif = self.blkifCF.getController(dom)
     1.9 +        blkif.daemon = self
    1.10 +        return blkif
    1.11  
    1.12      def blkifs(self):
    1.13          return [ x.sxpr() for x in self.blkifCF.getControllers() ]
     2.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Oct 28 17:24:09 2004 +0000
     2.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Oct 28 23:24:39 2004 +0000
     2.3 @@ -16,16 +16,45 @@ import channel
     2.4  import controller
     2.5  from messages import *
     2.6  
     2.7 +def expand_dev_name(name):
     2.8 +    if re.match( '^/dev/', name ):
     2.9 +	return name
    2.10 +    else:
    2.11 +	return '/dev/' + name
    2.12 +
    2.13 +def check_mounted(self, name):
    2.14 +    mode = None
    2.15 +    name = expand_dev_name(name)
    2.16 +    lines = os.popen('mount 2>/dev/null').readlines()
    2.17 +    exp = re.compile('^' + name + '.*[\(,]r(?P<mode>[ow])[,\)]')
    2.18 +    for line in lines:
    2.19 +        pm = exp.match(line)
    2.20 +        if not pm: continue
    2.21 +        mode = pm.group('mode')
    2.22 +        break
    2.23 +    if mode is 'w':
    2.24 +        return mode
    2.25 +    if mode is 'o':
    2.26 +        mode = 'r'
    2.27 +    blkifs = self.ctrl.daemon.blkifs()
    2.28 +    for blkif in blkifs:
    2.29 +        if blkif[1][1] is self.ctrl.dom:
    2.30 +            continue
    2.31 +        for dev in self.ctrl.daemon.blkif_get(blkif[1][1]).getDevices():
    2.32 +            if dev.type == 'phy' and name == expand_dev_name(dev.params):
    2.33 +                mode = dev.mode
    2.34 +                if 'w' in mode:
    2.35 +                    return 'w'
    2.36 +    if mode and 'r' in mode:
    2.37 +        return 'r'
    2.38 +    return None
    2.39  
    2.40  def blkdev_name_to_number(name):
    2.41      """Take the given textual block-device name (e.g., '/dev/sda1',
    2.42      'hda') and return the device number used by the OS. """
    2.43  
    2.44 -    if re.match( '^/dev/', name ):
    2.45 -	n = name
    2.46 -    else:
    2.47 -	n = '/dev/' + name
    2.48 -    
    2.49 +    n = expand_dev_name(name)
    2.50 +
    2.51      try:
    2.52  	return os.stat(n).st_rdev
    2.53      except Exception, ex:
    2.54 @@ -283,6 +312,7 @@ class BlkDev(controller.SplitDev):
    2.55          self.device = None
    2.56          self.start_sector = None
    2.57          self.nr_sectors = None
    2.58 +        self.ctrl = ctrl
    2.59          self.configure(config)
    2.60  
    2.61      def configure(self, config):
    2.62 @@ -322,6 +352,14 @@ class BlkDev(controller.SplitDev):
    2.63          Blkctl.block('unbind', self.type, self.node)
    2.64  
    2.65      def setNode(self, node):
    2.66 +        mounted_mode = check_mounted(self, node)
    2.67 +        if not '!' in self.mode and mounted_mode:
    2.68 +            if mounted_mode is "w":
    2.69 +                raise VmError("vbd: Segment %s is in writable use" %
    2.70 +                              self.uname)
    2.71 +            elif 'w' in self.mode:
    2.72 +                raise VmError("vbd: Segment %s is in read-only use" %
    2.73 +                              self.uname)
    2.74          segment = blkdev_segment(node)
    2.75          if not segment:
    2.76              raise VmError("vbd: Segment not found: uname=%s" % self.uname)