ia64/xen-unstable

changeset 2707:41e31d1ac03f

bitkeeper revision 1.1159.128.1 (41780f0dzQjdvnhFtMuVv1YAmVoQ8Q)

Merge ssh://xenbk@gandalf.hpl.hp.com//var/bk/xeno-unstable.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Thu Oct 21 19:33:33 2004 +0000 (2004-10-21)
parents bffd969a5a07 4b6dc2da0d4c
children 5233708cfa46
files tools/libxc/xc_io.h tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/netif.py tools/python/xen/xm/migrate.py tools/xfrd/xen_domain.c tools/xfrd/xen_domain.h tools/xfrd/xfrd.c
line diff
     1.1 --- a/tools/libxc/xc_io.h	Thu Oct 21 17:12:07 2004 +0000
     1.2 +++ b/tools/libxc/xc_io.h	Thu Oct 21 19:33:33 2004 +0000
     1.3 @@ -8,6 +8,7 @@
     1.4  typedef struct XcIOContext {
     1.5      u32 domain;
     1.6      unsigned flags;
     1.7 +    int resource;
     1.8      IOStream *io;
     1.9      IOStream *info;
    1.10      IOStream *err;
     2.1 --- a/tools/python/xen/xend/XendClient.py	Thu Oct 21 17:12:07 2004 +0000
     2.2 +++ b/tools/python/xen/xend/XendClient.py	Thu Oct 21 19:33:33 2004 +0000
     2.3 @@ -239,11 +239,12 @@ class Xend:
     2.4                               {'op'      : 'save',
     2.5                                'file'    : filename })
     2.6  
     2.7 -    def xend_domain_migrate(self, id, dst, live=0):
     2.8 +    def xend_domain_migrate(self, id, dst, live=0, resource=0):
     2.9          return self.xendPost(self.domainurl(id),
    2.10                               {'op'         : 'migrate',
    2.11                                'destination': dst,
    2.12 -                              'live'       : live })
    2.13 +                              'live'       : live,
    2.14 +                              'resource'   : resource })
    2.15  
    2.16      def xend_domain_pincpu(self, id, cpu):
    2.17          return self.xendPost(self.domainurl(id),
     3.1 --- a/tools/python/xen/xend/XendDomain.py	Thu Oct 21 17:12:07 2004 +0000
     3.2 +++ b/tools/python/xen/xend/XendDomain.py	Thu Oct 21 19:33:33 2004 +0000
     3.3 @@ -585,7 +585,7 @@ class XendDomain:
     3.4          self.refresh_schedule()
     3.5          return val
     3.6  
     3.7 -    def domain_migrate(self, id, dst, live):
     3.8 +    def domain_migrate(self, id, dst, live=0, resource=0):
     3.9          """Start domain migration.
    3.10  
    3.11          @param id: domain id
    3.12 @@ -595,7 +595,7 @@ class XendDomain:
    3.13          # Don't forget to cancel restart for it.
    3.14          dominfo = self.domain_lookup(id)
    3.15          xmigrate = XendMigrate.instance()
    3.16 -        val = xmigrate.migrate_begin(dominfo, dst, live=live)
    3.17 +        val = xmigrate.migrate_begin(dominfo, dst, live=live, resource=resource)
    3.18          return val
    3.19  
    3.20      def domain_save(self, id, dst, progress=0):
     4.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Oct 21 17:12:07 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Oct 21 19:33:33 2004 +0000
     4.3 @@ -33,8 +33,6 @@ xend = server.SrvDaemon.instance()
     4.4  
     4.5  from XendError import VmError
     4.6  
     4.7 -from server.blkif import blkdev_name_to_number
     4.8 -
     4.9  """The length of domain names that Xen can handle.
    4.10  The names stored in Xen itself are not used for much, and
    4.11  xend can handle domain names of any length.
    4.12 @@ -92,24 +90,6 @@ def shutdown_reason(code):
    4.13      """
    4.14      return shutdown_reasons.get(code, "?")
    4.15  
    4.16 -def make_disk(vm, config, uname, dev, mode, recreate=0):
    4.17 -    """Create a virtual disk device for a domain.
    4.18 -
    4.19 -    @param vm:       vm
    4.20 -    @param uname:    device to export
    4.21 -    @param dev:      device name in domain
    4.22 -    @param mode:     read/write mode
    4.23 -    @param recreate: recreate flag (after xend restart)
    4.24 -    @return: deferred
    4.25 -    """
    4.26 -    idx = vm.next_device_index('vbd')
    4.27 -    # todo: The 'dev' should be looked up in the context of the domain.
    4.28 -    vdev = blkdev_name_to_number(dev)
    4.29 -    if not vdev:
    4.30 -        raise VmError("vbd: Device not found: uname=%s dev=%s" % (uname, dev))
    4.31 -    ctrl = xend.blkif_create(vm.dom, recreate=recreate)
    4.32 -    return ctrl.attachDevice(idx, config, uname, vdev, mode, recreate=recreate)
    4.33 -        
    4.34  def vif_up(iplist):
    4.35      """send an unsolicited ARP reply for all non link-local IP addresses.
    4.36  
    4.37 @@ -222,6 +202,7 @@ def vm_recreate(savedinfo, info):
    4.38      """
    4.39      vm = XendDomainInfo()
    4.40      vm.recreate = 1
    4.41 +    vm.savedinfo = savedinfo
    4.42      vm.setdom(info['dom'])
    4.43      #vm.name = info['name']
    4.44      vm.memory = info['mem_kb']/1024
    4.45 @@ -239,6 +220,7 @@ def vm_recreate(savedinfo, info):
    4.46          vm.name = sxp.child_value(savedinfo, 'name')
    4.47          d = defer.succeed(vm)
    4.48      vm.recreate = 0
    4.49 +    vm.savedinfo = None
    4.50      return d
    4.51  
    4.52  def vm_restore(src, progress=0):
    4.53 @@ -288,6 +270,18 @@ def append_deferred(dlist, v):
    4.54      if isinstance(v, defer.Deferred):
    4.55          dlist.append(v)
    4.56  
    4.57 +def dlist_err(val):
    4.58 +    """Error callback suitable for a deferred list.
    4.59 +    In a deferred list the error callback is called with with Failure((error, index)).
    4.60 +    This callback extracts the error and returns it.
    4.61 +
    4.62 +    @param val: Failure containing (error, index)
    4.63 +    @type val: twisted.internet.failure.Failure 
    4.64 +    """
    4.65 +    
    4.66 +    (error, index) = val.value
    4.67 +    return error
    4.68 +
    4.69  class XendDomainInfo:
    4.70      """Virtual machine object."""
    4.71  
    4.72 @@ -324,6 +318,7 @@ class XendDomainInfo:
    4.73          self.restart_state = None
    4.74          self.restart_time = None
    4.75          self.console_port = None
    4.76 +        self.savedinfo = None
    4.77  
    4.78      def setdom(self, dom):
    4.79          """Set the domain id.
    4.80 @@ -385,10 +380,21 @@ class XendDomainInfo:
    4.81              sxpr.append(['restart_state', self.restart_state])
    4.82          if self.restart_time:
    4.83              sxpr.append(['restart_time', str(self.restart_time)])
    4.84 +        devs = self.sxpr_devices()
    4.85 +        if devs:
    4.86 +            sxpr.append(devs)
    4.87          if self.config:
    4.88              sxpr.append(['config', self.config])
    4.89          return sxpr
    4.90  
    4.91 +    def sxpr_devices(self):
    4.92 +        sxpr = ['devices']
    4.93 +        for devs in self.devices.values():
    4.94 +            for dev in devs:
    4.95 +                if hasattr(dev, 'sxpr'):
    4.96 +                    sxpr.append(dev.sxpr())
    4.97 +        return sxpr
    4.98 +
    4.99      def check_name(self, name):
   4.100          """Check if a vm name is valid. Valid names start with a non-digit
   4.101          and contain alphabetic characters, digits, or characters in '_-.:/+'.
   4.102 @@ -572,6 +578,25 @@ class XendDomainInfo:
   4.103                  return d
   4.104          return None
   4.105  
   4.106 +    def get_device_savedinfo(self, type, index):
   4.107 +        val = None
   4.108 +        if self.savedinfo is None:
   4.109 +            return val
   4.110 +        index = str(index)
   4.111 +        devinfo = sxp.child(self.savedinfo, 'devices')
   4.112 +        if devinfo is None:
   4.113 +            return val
   4.114 +        for d in sxp.children(devinfo, type):
   4.115 +            dindex = sxp.child_value(d, 'index')
   4.116 +            if dindex is None: continue
   4.117 +            if str(dindex) == index:
   4.118 +                val = d
   4.119 +                break
   4.120 +        return val
   4.121 +
   4.122 +    def get_device_recreate(self, type, index):
   4.123 +        return self.get_device_savedinfo(type, index) or self.recreate
   4.124 +
   4.125      def add_config(self, val):
   4.126          """Add configuration data to a virtual machine.
   4.127  
   4.128 @@ -699,6 +724,10 @@ class XendDomainInfo:
   4.129          """Build the domain boot image.
   4.130          """
   4.131          if self.recreate or self.restore: return
   4.132 +        if not os.path.isfile(kernel):
   4.133 +            raise VmError('Kernel image does not exist: %s' % kernel)
   4.134 +        if ramdisk and not os.path.isfile(ramdisk):
   4.135 +            raise VmError('Kernel ramdisk does not exist: %s' % ramdisk)
   4.136          if len(cmdline) >= 256:
   4.137              log.warning('kernel cmdline too long, domain %d', self.dom)
   4.138          dom = self.dom
   4.139 @@ -724,11 +753,6 @@ class XendDomainInfo:
   4.140          @param ramdisk: kernel ramdisk
   4.141          @param cmdline: kernel commandline
   4.142          """
   4.143 -        if not self.recreate:
   4.144 -            if not os.path.isfile(kernel):
   4.145 -                raise VmError('Kernel image does not exist: %s' % kernel)
   4.146 -            if ramdisk and not os.path.isfile(ramdisk):
   4.147 -                raise VmError('Kernel ramdisk does not exist: %s' % ramdisk)
   4.148          #self.init_domain()
   4.149          if self.console:
   4.150              self.console.registerChannel()
   4.151 @@ -761,6 +785,7 @@ class XendDomainInfo:
   4.152              append_deferred(dlist, v)
   4.153              index[dev_name] = dev_index + 1
   4.154          deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
   4.155 +        deferred.addErrback(dlist_err)
   4.156          return deferred
   4.157  
   4.158      def device_create(self, dev_config):
   4.159 @@ -826,7 +851,7 @@ class XendDomainInfo:
   4.160      def configure_memory(self):
   4.161          """Configure vm memory limit.
   4.162          """
   4.163 -        maxmem = sxp.get_child_value(self.config, "maxmem")
   4.164 +        maxmem = sxp.child_value(self.config, "maxmem")
   4.165          if maxmem is None:
   4.166              maxmem = self.memory
   4.167          xc.domain_setmaxmem(self.dom, maxmem_kb = maxmem * 1024)
   4.168 @@ -992,6 +1017,7 @@ class XendDomainInfo:
   4.169                  log.warning("Unknown config field %s", field_name)
   4.170              index[field_name] = field_index + 1
   4.171          d = defer.DeferredList(dlist, fireOnOneErrback=1)
   4.172 +        d.addErrback(dlist_err)
   4.173          return d
   4.174  
   4.175  
   4.176 @@ -1005,7 +1031,7 @@ def vm_image_linux(vm, image):
   4.177      """
   4.178      kernel = sxp.child_value(image, "kernel")
   4.179      cmdline = ""
   4.180 -    ip = sxp.child_value(image, "ip", "dhcp")
   4.181 +    ip = sxp.child_value(image, "ip", None)
   4.182      if ip:
   4.183          cmdline += " ip=" + ip
   4.184      root = sxp.child_value(image, "root")
   4.185 @@ -1030,9 +1056,11 @@ def vm_dev_vif(vm, val, index, change=0)
   4.186      vmac = sxp.child_value(val, "mac")
   4.187      ctrl = xend.netif_create(vm.dom, recreate=vm.recreate)
   4.188      log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
   4.189 -    defer = ctrl.attachDevice(vif, val, recreate=vm.recreate)
   4.190 +    recreate = vm.get_device_recreate('vif', index)
   4.191 +    defer = ctrl.attachDevice(vif, val, recreate=recreate)
   4.192      def cbok(dev):
   4.193          dev.vifctl('up', vmname=vm.name)
   4.194 +        dev.setIndex(index)
   4.195          vm.add_device('vif', dev)
   4.196          if change:
   4.197              dev.interfaceChanged()
   4.198 @@ -1048,23 +1076,19 @@ def vm_dev_vbd(vm, val, index, change=0)
   4.199      @param index:     vbd index
   4.200      @return: deferred
   4.201      """
   4.202 +    idx = vm.next_device_index('vbd')
   4.203      uname = sxp.child_value(val, 'uname')
   4.204 -    if not uname:
   4.205 -        raise VmError('vbd: Missing uname')
   4.206 -    dev = sxp.child_value(val, 'dev')
   4.207 -    if not dev:
   4.208 -        raise VmError('vbd: Missing dev')
   4.209 -    mode = sxp.child_value(val, 'mode', 'r')
   4.210 -    log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
   4.211 -    defer = make_disk(vm, val, uname, dev, mode, vm.recreate)
   4.212 -    def fn(vbd):
   4.213 -        vbd.dev = dev
   4.214 -        vbd.uname = uname
   4.215 -        vm.add_device('vbd', vbd)
   4.216 +    log.debug("Creating vbd dom=%d uname=%s", vm.dom, uname)
   4.217 +    ctrl = xend.blkif_create(vm.dom, recreate=vm.recreate)
   4.218 +    recreate = vm.get_device_recreate('vbd', index)
   4.219 +    defer = ctrl.attachDevice(idx, val, recreate=recreate)
   4.220 +    def cbok(dev):
   4.221 +        dev.setIndex(index)
   4.222 +        vm.add_device('vbd', dev)
   4.223          if change:
   4.224 -            vbd.interfaceChanged()
   4.225 -        return vbd
   4.226 -    defer.addCallback(fn)
   4.227 +            dev.interfaceChanged()
   4.228 +        return dev
   4.229 +    defer.addCallback(cbok)
   4.230      return defer
   4.231  
   4.232  def parse_pci(val):
     5.1 --- a/tools/python/xen/xend/XendMigrate.py	Thu Oct 21 17:12:07 2004 +0000
     5.2 +++ b/tools/python/xen/xend/XendMigrate.py	Thu Oct 21 19:33:33 2004 +0000
     5.3 @@ -260,7 +260,7 @@ class XendMigrateInfo(XfrdInfo):
     5.4      """Representation of a migrate in-progress and its interaction with xfrd.
     5.5      """
     5.6  
     5.7 -    def __init__(self, xid, dominfo, host, port, live):
     5.8 +    def __init__(self, xid, dominfo, host, port, live=0, resource=0):
     5.9          XfrdInfo.__init__(self)
    5.10          self.xid = xid
    5.11          self.dominfo = dominfo
    5.12 @@ -271,13 +271,15 @@ class XendMigrateInfo(XfrdInfo):
    5.13          self.dst_port = port
    5.14          self.dst_dom = None
    5.15          self.live = live
    5.16 +        self.resource = resource
    5.17          self.start = 0
    5.18          
    5.19      def sxpr(self):
    5.20          sxpr = ['migrate',
    5.21                  ['id',    self.xid   ],
    5.22                  ['state', self.state ],
    5.23 -                ['live',  self.live  ] ]
    5.24 +                ['live',  self.live  ],
    5.25 +                ['resource', self.resource] ]
    5.26          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
    5.27          sxpr.append(sxpr_src)
    5.28          sxpr_dst = ['dst', ['host', self.dst_host] ]
    5.29 @@ -300,7 +302,8 @@ class XendMigrateInfo(XfrdInfo):
    5.30                        vmconfig,
    5.31                        self.dst_host,
    5.32                        self.dst_port,
    5.33 -                      self.live ])
    5.34 +                      self.live,
    5.35 +                      self.resource ])
    5.36          
    5.37  ##     def xfr_vm_suspend(self, xfrd, val):
    5.38  ##         def cbok(val):
    5.39 @@ -490,7 +493,7 @@ class XendMigrate:
    5.40          reactor.connectTCP('localhost', XFRD_PORT, xcf)
    5.41          return info.deferred
    5.42      
    5.43 -    def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0):
    5.44 +    def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0):
    5.45          """Begin to migrate a domain to another host.
    5.46  
    5.47          @param dominfo:  domain info
    5.48 @@ -499,7 +502,7 @@ class XendMigrate:
    5.49          @return: deferred
    5.50          """
    5.51          xid = self.nextid()
    5.52 -        info = XendMigrateInfo(xid, dominfo, host, port, live)
    5.53 +        info = XendMigrateInfo(xid, dominfo, host, port, live, resource)
    5.54          return self.session_begin(info)
    5.55  
    5.56      def save_begin(self, dominfo, file):
     6.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Thu Oct 21 17:12:07 2004 +0000
     6.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Thu Oct 21 19:33:33 2004 +0000
     6.3 @@ -81,7 +81,8 @@ class SrvDomain(SrvDir):
     6.4          fn = FormFn(self.xd.domain_migrate,
     6.5                      [['dom', 'str'],
     6.6                       ['destination', 'str'],
     6.7 -                     ['live', 'int']])
     6.8 +                     ['live', 'int'],
     6.9 +                     ['resource', 'int']])
    6.10          deferred = fn(req.args, {'dom': self.dom.id})
    6.11          print 'op_migrate>', deferred
    6.12          deferred.addCallback(self._op_migrate_cb, req)
     7.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Thu Oct 21 17:12:07 2004 +0000
     7.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Thu Oct 21 19:33:33 2004 +0000
     7.3 @@ -5,6 +5,7 @@ from StringIO import StringIO
     7.4  
     7.5  from twisted.protocols import http
     7.6  from twisted.web import error
     7.7 +from twisted.python.failure import Failure
     7.8  
     7.9  from xen.xend import sxp
    7.10  from xen.xend import XendDomain
    7.11 @@ -94,7 +95,10 @@ class SrvDomainDir(SrvDir):
    7.12      def _op_create_err(self, err, req):
    7.13          """Callback to handle errors in deferred domain creation.
    7.14          """
    7.15 +        if isinstance(err, Failure):
    7.16 +            err = err.getErrorMessage()
    7.17          print 'op_create> Deferred Exception creating domain:', err
    7.18 +        traceback.print_exc()
    7.19          req.setResponseCode(http.BAD_REQUEST, "Error creating domain: " + str(err))
    7.20          return str(err)
    7.21  
    7.22 @@ -127,6 +131,8 @@ class SrvDomainDir(SrvDir):
    7.23              return val
    7.24  
    7.25      def _op_restore_err(self, err, req):
    7.26 +        if isinstance(err, Failure):
    7.27 +            err = err.getErrorMessage()
    7.28          print 'op_create> Deferred Exception restoring domain:', err
    7.29          req.setResponseCode(http.BAD_REQUEST, "Error restoring domain: "+ str(err))
    7.30          return str(err)
     8.1 --- a/tools/python/xen/xend/server/blkif.py	Thu Oct 21 17:12:07 2004 +0000
     8.2 +++ b/tools/python/xen/xend/server/blkif.py	Thu Oct 21 19:33:33 2004 +0000
     8.3 @@ -16,6 +16,46 @@ import channel
     8.4  import controller
     8.5  from messages import *
     8.6  
     8.7 +
     8.8 +def blkdev_name_to_number(name):
     8.9 +    """Take the given textual block-device name (e.g., '/dev/sda1',
    8.10 +    'hda') and return the device number used by the OS. """
    8.11 +
    8.12 +    if re.match( '^/dev/', name ):
    8.13 +	n = name
    8.14 +    else:
    8.15 +	n = '/dev/' + name
    8.16 +    
    8.17 +    try:
    8.18 +	return os.stat(n).st_rdev
    8.19 +    except Exception, ex:
    8.20 +        log.debug("exception looking up device number for %s: %s", name, ex)
    8.21 +	pass
    8.22 +
    8.23 +    # see if this is a hex device number
    8.24 +    if re.match( '^(0x)?[0-9a-fA-F]+$', name ):
    8.25 +	return string.atoi(name,16)
    8.26 +	
    8.27 +    return None
    8.28 +
    8.29 +def blkdev_segment(name):
    8.30 +    """Take the given block-device name (e.g. '/dev/sda1', 'hda')
    8.31 +    and return a dictionary { device, start_sector,
    8.32 +    nr_sectors, type }
    8.33 +        device:       Device number of the given partition
    8.34 +        start_sector: Index of first sector of the partition
    8.35 +        nr_sectors:   Number of sectors comprising this partition
    8.36 +        type:         'Disk' or identifying name for partition type
    8.37 +    """
    8.38 +    val = None
    8.39 +    n = blkdev_name_to_number(name)
    8.40 +    if n:
    8.41 +	val = { 'device' : n,
    8.42 +                'start_sector' : long(0),
    8.43 +                'nr_sectors' : long(1L<<63),
    8.44 +                'type' : 'Disk' }
    8.45 +    return val
    8.46 +
    8.47  class BlkifBackendController(controller.BackendController):
    8.48      """ Handler for the 'back-end' channel to a block device driver domain.
    8.49      """
    8.50 @@ -231,26 +271,70 @@ class BlkDev(controller.SplitDev):
    8.51      """Info record for a block device.
    8.52      """
    8.53  
    8.54 -    def __init__(self, idx, ctrl, config, vdev, mode, segment):
    8.55 +    def __init__(self, idx, ctrl, config):
    8.56          controller.SplitDev.__init__(self, idx, ctrl)
    8.57 -        self.config = config
    8.58          self.dev = None
    8.59          self.uname = None
    8.60 -        self.vdev = vdev
    8.61 -        self.mode = mode
    8.62 -        self.device = segment['device']
    8.63 -        self.start_sector = segment['start_sector']
    8.64 -        self.nr_sectors = segment['nr_sectors']
    8.65 +        self.vdev = None
    8.66 +        self.mode = None
    8.67 +        self.type = None
    8.68 +        self.params = None
    8.69 +        self.node = None
    8.70 +        self.device = None
    8.71 +        self.start_sector = None
    8.72 +        self.nr_sectors = None
    8.73 +        self.configure(config)
    8.74 +
    8.75 +    def configure(self, config):
    8.76 +        self.config = config
    8.77 +        self.uname = sxp.child_value(config, 'uname')
    8.78 +        if not self.uname:
    8.79 +            raise VmError('vbd: Missing uname')
    8.80 +        # Split into type and type-specific params (which are passed to the
    8.81 +        # type-specific control script).
    8.82 +        (self.type, self.params) = string.split(self.uname, ':', 1)
    8.83 +        self.dev = sxp.child_value(config, 'dev')
    8.84 +        if not self.dev:
    8.85 +            raise VmError('vbd: Missing dev')
    8.86 +        self.mode = sxp.child_value(config, 'mode', 'r')
    8.87 +        # todo: The 'dev' should be looked up in the context of the domain.
    8.88 +        self.vdev = blkdev_name_to_number(self.dev)
    8.89 +        if not self.vdev:
    8.90 +            raise VmError('vbd: Device not found: %s' % self.dev)
    8.91          try:
    8.92              self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
    8.93          except:
    8.94              raise XendError('invalid backend domain')
    8.95  
    8.96 +    def recreate(self, savedinfo):
    8.97 +        node = sxp.child_value(savedinfo, 'node')
    8.98 +        self.setNode(node)
    8.99 +
   8.100 +    def attach(self):
   8.101 +        node = Blkctl.block('bind', self.type, self.params)
   8.102 +        self.setNode(node)
   8.103 +        return self.attachBackend()
   8.104 +
   8.105 +    def unbind(self):
   8.106 +        if self.node is None: return
   8.107 +        log.debug("Unbinding vbd (type %s) from %s"
   8.108 +                  % (self.type, self.node))
   8.109 +        Blkctl.block('unbind', self.type, self.node)
   8.110 +
   8.111 +    def setNode(self, node):
   8.112 +        segment = blkdev_segment(node)
   8.113 +        if not segment:
   8.114 +            raise VmError("vbd: Segment not found: uname=%s" % self.uname)
   8.115 +        self.node = node
   8.116 +        self.device = segment['device']
   8.117 +        self.start_sector = segment['start_sector']
   8.118 +        self.nr_sectors = segment['nr_sectors']
   8.119 +
   8.120      def readonly(self):
   8.121          return 'w' not in self.mode
   8.122  
   8.123      def sxpr(self):
   8.124 -        val = ['blkdev',
   8.125 +        val = ['vbd',
   8.126                 ['idx', self.idx],
   8.127                 ['vdev', self.vdev],
   8.128                 ['device', self.device],
   8.129 @@ -259,13 +343,12 @@ class BlkDev(controller.SplitDev):
   8.130              val.append(['dev', self.dev])
   8.131          if self.uname:
   8.132              val.append(['uname', self.uname])
   8.133 +        if self.node:
   8.134 +            val.append(['node', self.node])
   8.135 +        if self.index is not None:
   8.136 +            val.append(['index', self.index])
   8.137          return val
   8.138  
   8.139 -    def unbind(self):
   8.140 -        log.debug("Unbinding block dev (type %s) from %s"
   8.141 -                  % (self.type, self.node))
   8.142 -        Blkctl.block('unbind', self.type, self.node)
   8.143 -
   8.144      def destroy(self, change=0):
   8.145          """Destroy the device. If 'change' is true notify the front-end interface.
   8.146  
   8.147 @@ -283,7 +366,7 @@ class BlkDev(controller.SplitDev):
   8.148          """
   8.149          self.getBackendInterface().interfaceChanged()
   8.150  
   8.151 -    def attach(self):
   8.152 +    def attachBackend(self):
   8.153          """Attach the device to its controller.
   8.154  
   8.155          """
   8.156 @@ -340,8 +423,8 @@ class BlkDev(controller.SplitDev):
   8.157          val = unpackMsg('blkif_be_vbd_grow_t', msg)
   8.158  	status = val['status']
   8.159  	if status != BLKIF_BE_STATUS_OKAY:
   8.160 -            raise XendError("Adding extent to vbd failed: device %d, error %d"
   8.161 -                            % (self.vdev, status))
   8.162 +            raise XendError("Adding extent to vbd failed: device %s, error %d"
   8.163 +                            % (sxp.to_string(self.config), status))
   8.164          return self
   8.165  
   8.166      def send_be_vbd_destroy(self):
   8.167 @@ -356,46 +439,6 @@ class BlkDev(controller.SplitDev):
   8.168          return d
   8.169          
   8.170  
   8.171 -def blkdev_name_to_number(name):
   8.172 -    """Take the given textual block-device name (e.g., '/dev/sda1',
   8.173 -    'hda') and return the device number used by the OS. """
   8.174 -
   8.175 -    if not re.match( '^/dev/', name ):
   8.176 -	n = '/dev/' + name
   8.177 -    else:
   8.178 -	n = name
   8.179 -    
   8.180 -    try:
   8.181 -	return os.stat(n).st_rdev
   8.182 -    except Exception, e:
   8.183 -        print "blkdev_name_to_number> exception looking up device number for %s: %s" % (name, e)
   8.184 -	pass
   8.185 -
   8.186 -    # see if this is a hex device number
   8.187 -    if re.match( '^(0x)?[0-9a-fA-F]+$', name ):
   8.188 -	return string.atoi(name,16)
   8.189 -	
   8.190 -    return None
   8.191 -
   8.192 -def lookup_raw_partn(name):
   8.193 -    """Take the given block-device name (e.g., '/dev/sda1', 'hda')
   8.194 -    and return a dictionary { device, start_sector,
   8.195 -    nr_sectors, type }
   8.196 -        device:       Device number of the given partition
   8.197 -        start_sector: Index of first sector of the partition
   8.198 -        nr_sectors:   Number of sectors comprising this partition
   8.199 -        type:         'Disk' or identifying name for partition type
   8.200 -    """
   8.201 -
   8.202 -    n = blkdev_name_to_number(name)
   8.203 -    if n:
   8.204 -	return [ { 'device' : n,
   8.205 -		   'start_sector' : long(0),
   8.206 -		   'nr_sectors' : long(1L<<63),
   8.207 -		   'type' : 'Disk' } ]
   8.208 -    else:
   8.209 -	return None
   8.210 -
   8.211  class BlkifController(controller.SplitController):
   8.212      """Block device interface controller. Handles all block devices
   8.213      for a domain.
   8.214 @@ -418,65 +461,37 @@ class BlkifController(controller.SplitCo
   8.215          val = ['blkif', ['dom', self.dom]]
   8.216          return val
   8.217  
   8.218 -    def addDevice(self, idx, config, vdev, mode, segment):
   8.219 +    def addDevice(self, idx, config):
   8.220          """Add a device to the device table.
   8.221  
   8.222          @param vdev:     device index
   8.223          @type  vdev:     int
   8.224 -        @param mode:     read/write mode
   8.225 -        @type  mode:     string
   8.226 -        @param segment:  segment
   8.227 -        @type  segment:  int
   8.228 +        @param config: device configuration
   8.229          @return: device
   8.230          @rtype:  BlkDev
   8.231          """
   8.232          if idx in self.devices:
   8.233              raise XendError('device exists: ' + str(idx))
   8.234 -        dev = BlkDev(idx, self, config, vdev, mode, segment)
   8.235 +        dev = BlkDev(idx, self, config )
   8.236          self.devices[idx] = dev
   8.237          return dev
   8.238  
   8.239 -    def attachDevice(self, idx, config, uname, vdev, mode, recreate=0):
   8.240 +    def attachDevice(self, idx, config, recreate=0):
   8.241          """Attach a device to the specified interface.
   8.242          On success the returned deferred will be called with the device.
   8.243  
   8.244          @param idx:      device id
   8.245          @param config:   device configuration
   8.246 -        @param vdev:     device index
   8.247 -        @type  vdev:     int
   8.248 -        @param mode:     read/write mode
   8.249 -        @type  mode:     string
   8.250 -        @param segment:  segment
   8.251 -        @type  segment:  int
   8.252          @param recreate: if true it's being recreated (after xend restart)
   8.253          @type  recreate: bool
   8.254          @return: deferred
   8.255          @rtype:  Deferred
   8.256          """
   8.257 -        if not recreate:
   8.258 -            # Split into type and type-specific details (which are passed to the
   8.259 -            # type-specific control script).
   8.260 -            type, dets = string.split(uname, ':', 1)
   8.261 -            # Special case: don't bother calling a script for phy.  Could
   8.262 -            # alternatively provide a "do nothing" script for phy devices...
   8.263 -            node = Blkctl.block('bind', type, dets)
   8.264 -
   8.265 -        segments = lookup_raw_partn(node)
   8.266 -
   8.267 -        if not segments:
   8.268 -            raise VmError("vbd: Segments not found: uname=%s" % uname)
   8.269 -        if len(segments) > 1:
   8.270 -            raise VmError("vbd: Multi-segment vdisk: uname=%s" % uname)
   8.271 -
   8.272 -        segment = segments[0]            
   8.273 -
   8.274 -        dev = self.addDevice(idx, config, vdev, mode, segment)
   8.275 -            
   8.276 +        dev = self.addDevice(idx, config)
   8.277          if recreate:
   8.278 +            dev.recreate(recreate)
   8.279              d = defer.succeed(dev)
   8.280          else:
   8.281 -            dev.node = node
   8.282 -            dev.type = type
   8.283              d = dev.attach()
   8.284          return d
   8.285  
     9.1 --- a/tools/python/xen/xend/server/controller.py	Thu Oct 21 17:12:07 2004 +0000
     9.2 +++ b/tools/python/xen/xend/server/controller.py	Thu Oct 21 19:33:33 2004 +0000
     9.3 @@ -682,10 +682,17 @@ class SplitDev(Dev):
     9.4      def __init__(self, idx, controller):
     9.5          Dev.__init__(self, idx, controller)
     9.6          self.backendDomain = 0
     9.7 +        self.index = None
     9.8  
     9.9      def getBackendInterface(self):
    9.10          return self.controller.getBackendInterface(self.backendDomain)
    9.11  
    9.12 +    def getIndex(self):
    9.13 +        return self.index
    9.14 +
    9.15 +    def setIndex(self, index):
    9.16 +        self.index = index
    9.17 +
    9.18  
    9.19  
    9.20      
    10.1 --- a/tools/python/xen/xend/server/netif.py	Thu Oct 21 17:12:07 2004 +0000
    10.2 +++ b/tools/python/xen/xend/server/netif.py	Thu Oct 21 19:33:33 2004 +0000
    10.3 @@ -198,6 +198,8 @@ class NetDev(controller.SplitDev):
    10.4              val.append(['evtchn',
    10.5                          self.evtchn['port1'],
    10.6                          self.evtchn['port2']])
    10.7 +        if self.index is not None:
    10.8 +            val.append(['index', self.index])
    10.9          return val
   10.10  
   10.11      def get_vifname(self):
    11.1 --- a/tools/python/xen/xm/migrate.py	Thu Oct 21 17:12:07 2004 +0000
    11.2 +++ b/tools/python/xen/xm/migrate.py	Thu Oct 21 19:33:33 2004 +0000
    11.3 @@ -26,6 +26,10 @@ gopts.opt('live', short='l',
    11.4            fn=set_true, default=0,
    11.5            use="Use live migration.")
    11.6  
    11.7 +gopts.opt('resource', short='r',
    11.8 +          fn=set_int, default=0,
    11.9 +          use="Set level of resource usage for migration.")
   11.10 +
   11.11  def help(argv):
   11.12      gopts.argv = argv
   11.13      gopts.usage()
   11.14 @@ -42,5 +46,5 @@ def main(argv):
   11.15      dst = args[1]
   11.16      if dom in [DOM0_NAME, DOM0_ID]:
   11.17          opts.err('Cannot migrate ' + dom)
   11.18 -    server.xend_domain_migrate(dom, dst, opts.vals.live)
   11.19 +    server.xend_domain_migrate(dom, dst, opts.vals.live, opts.vals.resource)
   11.20          
    12.1 --- a/tools/xfrd/xen_domain.c	Thu Oct 21 17:12:07 2004 +0000
    12.2 +++ b/tools/xfrd/xen_domain.c	Thu Oct 21 19:33:33 2004 +0000
    12.3 @@ -60,7 +60,7 @@ void xcfini(void){
    12.4  int xen_domain_snd(Conn *xend, IOStream *io,
    12.5                     uint32_t dom,
    12.6                     char *vmconfig, int vmconfig_n,
    12.7 -                   int live){
    12.8 +                   int live, int resource){
    12.9      int err = 0;
   12.10  #ifdef _XEN_XFR_STUB_
   12.11      char buf[1024];
   12.12 @@ -99,6 +99,7 @@ int xen_domain_snd(Conn *xend, IOStream 
   12.13      if(live){
   12.14          ioctxt->flags |= XCFLAGS_LIVE;
   12.15      }
   12.16 +    ioctxt->resource = resource;
   12.17      err = xc_linux_save(xcinit(), ioctxt);
   12.18  #endif   
   12.19      dprintf("< err=%d\n", err);
    13.1 --- a/tools/xfrd/xen_domain.h	Thu Oct 21 17:12:07 2004 +0000
    13.2 +++ b/tools/xfrd/xen_domain.h	Thu Oct 21 19:33:33 2004 +0000
    13.3 @@ -10,7 +10,7 @@
    13.4  extern int xen_domain_snd(Conn *xend, IOStream *io,
    13.5                            uint32_t dom,
    13.6                            char *vmconfig, int vmconfig_n,
    13.7 -                          int live);
    13.8 +                          int live, int resource);
    13.9  extern int xen_domain_rcv(IOStream *io,
   13.10                            uint32_t *dom,
   13.11                            char **vmconfig, int *vmconfig_n,
    14.1 --- a/tools/xfrd/xfrd.c	Thu Oct 21 17:12:07 2004 +0000
    14.2 +++ b/tools/xfrd/xfrd.c	Thu Oct 21 19:33:33 2004 +0000
    14.3 @@ -96,7 +96,7 @@ receiver:
    14.4  Sxpr oxfr_configure; // (xfr.configure <vmid> <vmconfig>)
    14.5  Sxpr oxfr_err;       // (xfr.err <code>)
    14.6  Sxpr oxfr_hello;     // (xfr.hello <major> <minor>)
    14.7 -Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port> <live>)
    14.8 +Sxpr oxfr_migrate;   // (xfr.migrate <vmid> <vmconfig> <host> <port> <live> <resource>)
    14.9  Sxpr oxfr_migrate_ok;// (xfr.migrate.ok <value>)
   14.10  Sxpr oxfr_progress;  // (xfr.progress <percent> <rate: kb/s>)
   14.11  Sxpr oxfr_restore;   // (xfr.restore <file>)
   14.12 @@ -241,6 +241,7 @@ typedef struct XfrState {
   14.13      char *xfr_host;
   14.14      uint32_t vmid_new;
   14.15      int live;
   14.16 +    int resource;
   14.17  } XfrState;
   14.18  
   14.19  /** Get the name of a transfer state.
   14.20 @@ -623,7 +624,7 @@ int xfr_send_state(XfrState *state, Conn
   14.21      err = xen_domain_snd(xend, peer->out,
   14.22                           state->vmid,
   14.23                           state->vmconfig, state->vmconfig_n,
   14.24 -                         state->live);
   14.25 +                         state->live, state->resource);
   14.26      dprintf(">*** Sent domain %u\n", state->vmid);
   14.27      if(err) goto exit;
   14.28      // Sending the domain suspends it, and there's no way back.
   14.29 @@ -771,7 +772,7 @@ int xfr_save(Args *args, XfrState *state
   14.30      err = xen_domain_snd(xend, io,
   14.31                           state->vmid,
   14.32                           state->vmconfig, state->vmconfig_n,
   14.33 -                         0);
   14.34 +                         0, 0);
   14.35      if(err){
   14.36          err = xfr_error(xend, err);
   14.37      } else {
   14.38 @@ -926,6 +927,8 @@ int xfrd_service(Args *args, int peersoc
   14.39          if(err) goto exit;
   14.40          err = intof(sxpr_childN(sxpr, n++, ONONE), &state->live);
   14.41          if(err) goto exit;
   14.42 +        err = intof(sxpr_childN(sxpr, n++, ONONE), &state->resource);
   14.43 +        if(err) goto exit;
   14.44          err = xfr_send(args, state, conn, addr, port);
   14.45  
   14.46      } else if(sxpr_elementp(sxpr, oxfr_save)){