ia64/xen-unstable

changeset 5150:fed73636e06b

bitkeeper revision 1.1550.1.1 (42947c93ScXPWqJQrSKCVoxqNJmCbw)

XendDomain.py:
Remove XendMigrate.
.del-XendMigrate.py~3921a328f4db779:
Delete: tools/python/xen/xend/XendMigrate.py
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Wed May 25 13:24:35 2005 +0000 (2005-05-25)
parents 561f71aa056d
children be7e052ce7e8
files .rootkeys tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendMigrate.py
line diff
     1.1 --- a/.rootkeys	Wed May 25 12:44:27 2005 +0000
     1.2 +++ b/.rootkeys	Wed May 25 13:24:35 2005 +0000
     1.3 @@ -838,7 +838,6 @@ 40c9c468fSl3H3IypyT0ppkbb0ZT9A tools/pyt
     1.4  40c9c4685ykq87_n1kVUbMr9flx9fg tools/python/xen/xend/XendDomainInfo.py
     1.5  40f50d99YiiaMI1fZBh1VCDFLD57qg tools/python/xen/xend/XendError.py
     1.6  40ffc44eGsgTEY355E3nN4mPLZHhMQ tools/python/xen/xend/XendLogging.py
     1.7 -40c9c46854nsHmuxHQHncKk5rAs5NA tools/python/xen/xend/XendMigrate.py
     1.8  40c9c468M96gA1EYDvNa5w5kQNYLFA tools/python/xen/xend/XendNode.py
     1.9  4151594bhib4aUerB2SMKDl-iCtc4Q tools/python/xen/xend/XendProtocol.py
    1.10  40c9c4686jruMyZIqiaZRMiMoqMJtg tools/python/xen/xend/XendRoot.py
     2.1 --- a/tools/python/xen/xend/XendDomain.py	Wed May 25 12:44:27 2005 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed May 25 13:24:35 2005 +0000
     2.3 @@ -19,7 +19,6 @@ import XendRoot; xroot = XendRoot.instan
     2.4  import XendCheckpoint
     2.5  import XendDB
     2.6  import XendDomainInfo
     2.7 -import XendMigrate
     2.8  import EventServer; eserver = EventServer.instance()
     2.9  from XendError import XendError
    2.10  from XendLogging import log
    2.11 @@ -511,8 +510,7 @@ class XendDomain:
    2.12          # Need a cancel too?
    2.13          # Don't forget to cancel restart for it.
    2.14          dominfo = self.domain_lookup(id)
    2.15 -        xmigrate = XendMigrate.instance()
    2.16 -        return xmigrate.migrate_begin(dominfo, dst, live=live, resource=resource)
    2.17 +        return None
    2.18  
    2.19      def domain_save(self, id, dst, progress=False):
    2.20          """Start saving a domain to file.
     3.1 --- a/tools/python/xen/xend/XendMigrate.py	Wed May 25 12:44:27 2005 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,585 +0,0 @@
     3.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     3.5 -
     3.6 -import traceback
     3.7 -import threading
     3.8 -
     3.9 -import errno
    3.10 -import sys
    3.11 -import socket
    3.12 -import time
    3.13 -import types
    3.14 -
    3.15 -from xen.web import reactor
    3.16 -from xen.web.protocol import Protocol, ClientFactory
    3.17 -
    3.18 -import scheduler
    3.19 -import sxp
    3.20 -import XendDB
    3.21 -import EventServer; eserver = EventServer.instance()
    3.22 -from XendError import XendError
    3.23 -from XendLogging import log
    3.24 -        
    3.25 -"""The port for the migrate/save daemon xfrd."""
    3.26 -XFRD_PORT = 8002
    3.27 -
    3.28 -"""The transfer protocol major version number."""
    3.29 -XFR_PROTO_MAJOR = 1
    3.30 -"""The transfer protocol minor version number."""
    3.31 -XFR_PROTO_MINOR = 0
    3.32 -
    3.33 -class Xfrd(Protocol):
    3.34 -    """Protocol handler for a connection to the migration/save daemon xfrd.
    3.35 -    """
    3.36 -
    3.37 -    def __init__(self, xinfo):
    3.38 -        self.parser = sxp.Parser()
    3.39 -        self.xinfo = xinfo
    3.40 -
    3.41 -    def connectionMade(self, addr=None):
    3.42 -        # Send hello.
    3.43 -        self.request(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    3.44 -        # Send request.
    3.45 -        self.xinfo.request(self)
    3.46 -        # Run the transport mainLoop which reads from the peer.
    3.47 -        self.transport.mainLoop()
    3.48 -
    3.49 -    def request(self, req):
    3.50 -        sxp.show(req, out=self.transport)
    3.51 -
    3.52 -    def loseConnection(self):
    3.53 -        self.transport.loseConnection()
    3.54 -
    3.55 -    def connectionLost(self, reason):
    3.56 -        self.xinfo.connectionLost(reason)
    3.57 -
    3.58 -    def dataReceived(self, data):
    3.59 -        self.parser.input(data)
    3.60 -        if self.parser.ready():
    3.61 -            val = self.parser.get_val()
    3.62 -            self.xinfo.dispatch(self, val)
    3.63 -        if self.parser.at_eof():
    3.64 -            self.loseConnection()
    3.65 -            
    3.66 -class XfrdClientFactory(ClientFactory):
    3.67 -    """Factory for clients of the migration/save daemon xfrd.
    3.68 -    """
    3.69 -
    3.70 -    def __init__(self, xinfo):
    3.71 -        #ClientFactory.__init__(self)
    3.72 -        self.xinfo = xinfo
    3.73 -        self.readyCond = threading.Condition()
    3.74 -        self.ready = False
    3.75 -        self.err = None
    3.76 -
    3.77 -    def start(self):
    3.78 -        print 'XfrdClientFactory>start>'
    3.79 -        reactor.connectTCP('localhost', XFRD_PORT, self)
    3.80 -        try:
    3.81 -            self.readyCond.acquire()
    3.82 -            while not self.ready:
    3.83 -                self.readyCond.wait()
    3.84 -        finally:
    3.85 -            self.readyCond.release()
    3.86 -        print 'XfrdClientFactory>start>', 'err=', self.err
    3.87 -        if self.err:
    3.88 -            raise self.err
    3.89 -        return 0
    3.90 -
    3.91 -    def notifyReady(self):
    3.92 -        try:
    3.93 -            self.readyCond.acquire()
    3.94 -            self.ready = True
    3.95 -            self.err = self.xinfo.error_summary()
    3.96 -            self.readyCond.notify()
    3.97 -        finally:
    3.98 -            self.readyCond.release()
    3.99 -            
   3.100 -    def startedConnecting(self, connector):
   3.101 -        pass
   3.102 -
   3.103 -    def buildProtocol(self, addr):
   3.104 -        return Xfrd(self.xinfo)
   3.105 -
   3.106 -    def clientConnectionLost(self, connector, reason):
   3.107 -        print "XfrdClientFactory>clientConnectionLost>", reason
   3.108 -        self.notifyReady()
   3.109 -
   3.110 -    def clientConnectionFailed(self, connector, reason):
   3.111 -        print "XfrdClientFactory>clientConnectionFailed>", reason
   3.112 -        self.xinfo.error(reason)
   3.113 -        self.notifyReady()
   3.114 -
   3.115 -class SuspendHandler:
   3.116 -
   3.117 -    def __init__(self, xinfo, vmid, timeout):
   3.118 -        self.xinfo = xinfo
   3.119 -        self.vmid = vmid
   3.120 -        self.timeout = timeout
   3.121 -        self.readyCond = threading.Condition()
   3.122 -        self.ready = False
   3.123 -        self.err = None
   3.124 -
   3.125 -    def start(self):
   3.126 -        self.subscribe(on=True)
   3.127 -        timer = scheduler.later(self.timeout, self.onTimeout)
   3.128 -        try:
   3.129 -            self.readyCond.acquire()
   3.130 -            while not self.ready:
   3.131 -                self.readyCond.wait()
   3.132 -        finally:
   3.133 -            self.readyCond.release()
   3.134 -            self.subscribe(on=False)
   3.135 -            timer.cancel()
   3.136 -        if self.err:
   3.137 -            raise XendError(self.err)
   3.138 -
   3.139 -    def notifyReady(self, err=None):
   3.140 -        try:
   3.141 -            self.readyCond.acquire()
   3.142 -            if not self.ready:
   3.143 -                self.ready = True
   3.144 -                self.err = err
   3.145 -                self.readyCond.notify()
   3.146 -        finally:
   3.147 -            self.readyCond.release()
   3.148 -
   3.149 -    def subscribe(self, on=True):
   3.150 -        # Subscribe to 'suspended' events so we can tell when the
   3.151 -        # suspend completes. Subscribe to 'died' events so we can tell if
   3.152 -        # the domain died.
   3.153 -        if on:
   3.154 -            action = eserver.subscribe
   3.155 -        else:
   3.156 -            action = eserver.unsubscribe
   3.157 -        action('xend.domain.suspended', self.onSuspended)
   3.158 -        action('xend.domain.died', self.onDied)
   3.159 -
   3.160 -    def onSuspended(self, e, v):
   3.161 -        if v[1] != self.vmid: return
   3.162 -        print 'SuspendHandler>onSuspended>', e, v
   3.163 -        self.notifyReady()
   3.164 -                
   3.165 -    def onDied(self, e, v):
   3.166 -        if v[1] != self.vmid: return
   3.167 -        print 'SuspendHandler>onDied>', e, v
   3.168 -        self.notifyReady('Domain %s died while suspending' % self.vmid)
   3.169 -
   3.170 -    def onTimeout(self):
   3.171 -         print 'SuspendHandler>onTimeout>'
   3.172 -         self.notifyReady('Domain %s suspend timed out' % self.vmid)
   3.173 -
   3.174 -class XfrdInfo:
   3.175 -    """Abstract class for info about a session with xfrd.
   3.176 -    Has subclasses for save and migrate.
   3.177 -    """
   3.178 -
   3.179 -    """Suspend timeout (seconds).
   3.180 -    We set a timeout because suspending a domain can hang."""
   3.181 -    timeout = 30
   3.182 -
   3.183 -    def __init__(self):
   3.184 -        from xen.xend import XendDomain
   3.185 -        self.xd = XendDomain.instance()
   3.186 -        self.suspended = {}
   3.187 -        self.paused = {}
   3.188 -        self.state = 'init'
   3.189 -        # List of errors encountered.
   3.190 -        self.errors = []
   3.191 -            
   3.192 -    def vmconfig(self):
   3.193 -        dominfo = self.xd.domain_get(self.src_dom)
   3.194 -        if dominfo:
   3.195 -            val = sxp.to_string(dominfo.sxpr())
   3.196 -        else:
   3.197 -            val = None
   3.198 -        return val
   3.199 -
   3.200 -    def add_error(self, err):
   3.201 -        """Add an error to the error list.
   3.202 -        Returns the error added.
   3.203 -        """
   3.204 -        if err not in self.errors:
   3.205 -            self.errors.append(err)
   3.206 -        return err
   3.207 -
   3.208 -    def error_summary(self, msg=None):
   3.209 -        """Get a XendError summarising the errors (if any).
   3.210 -        """
   3.211 -        if not self.errors:
   3.212 -            return None
   3.213 -        if msg is None:
   3.214 -            msg = "errors"
   3.215 -        if self.errors:
   3.216 -            errmsg = msg + ': ' + ', '.join(map(str, self.errors))
   3.217 -        else:
   3.218 -            errmsg = msg
   3.219 -        return XendError(errmsg)
   3.220 -
   3.221 -    def get_errors(self):
   3.222 -        """Get the list of errors.
   3.223 -        """
   3.224 -        return self.errors
   3.225 -
   3.226 -    def error(self, err):
   3.227 -        print 'XfrdInfo>error>', err
   3.228 -        self.state = 'error'
   3.229 -        self.add_error(err)
   3.230 -
   3.231 -    def dispatch(self, xfrd, val):
   3.232 -        print 'XfrdInfo>dispatch>', val
   3.233 -        op = sxp.name(val)
   3.234 -        op = op.replace('.', '_')
   3.235 -        if op.startswith('xfr_'):
   3.236 -            fn = getattr(self, op, self.unknown)
   3.237 -        else:
   3.238 -            fn = self.unknown
   3.239 -        try:
   3.240 -            val = fn(xfrd, val)
   3.241 -            if val:
   3.242 -                sxp.show(val, out=xfrd.transport)
   3.243 -        except Exception, err:
   3.244 -            print 'XfrdInfo>dispatch> error:', err
   3.245 -            val = ['xfr.err', errno.EINVAL]
   3.246 -            sxp.show(val, out=xfrd.transport)
   3.247 -            self.error(err)
   3.248 -
   3.249 -    def unknown(self, xfrd, val):
   3.250 -        xfrd.loseConnection()
   3.251 -        return None
   3.252 -
   3.253 -    def xfr_err(self, xfrd, val):
   3.254 -        # If we get an error with non-zero code the operation failed.
   3.255 -        # An error with code zero indicates hello success.
   3.256 -        print 'XfrdInfo>xfr_err>', val
   3.257 -        v = sxp.child0(val)
   3.258 -        err = int(sxp.child0(val))
   3.259 -        if not err: return
   3.260 -        self.error("transfer daemon (xfrd) error: " + str(err))
   3.261 -        xfrd.loseConnection()
   3.262 -        return None
   3.263 -
   3.264 -    def xfr_progress(self, xfrd, val):
   3.265 -        return None
   3.266 -
   3.267 -    def xfr_vm_destroy(self, xfrd, val):
   3.268 -        try:
   3.269 -            vmid = sxp.child0(val)
   3.270 -            val = self.xd.domain_destroy(vmid)
   3.271 -            if vmid in self.paused:
   3.272 -                del self.paused[vmid]
   3.273 -            if vmid in self.suspended:
   3.274 -                del self.suspended[vmid]
   3.275 -        except StandardError, err:
   3.276 -            self.add_error("vm_destroy failed")
   3.277 -            self.add_error(err)
   3.278 -            val = errno.EINVAL
   3.279 -        return ['xfr.err', val]
   3.280 -    
   3.281 -    def xfr_vm_pause(self, xfrd, val):
   3.282 -        try:
   3.283 -            vmid = sxp.child0(val)
   3.284 -            val = self.xd.domain_pause(vmid)
   3.285 -            self.paused[vmid] = 1
   3.286 -        except StandardError, err:
   3.287 -            self.add_error("vm_pause failed")
   3.288 -            self.add_error(err)
   3.289 -            val = errno.EINVAL
   3.290 -        return ['xfr.err', val]
   3.291 -
   3.292 -    def xfr_vm_unpause(self, xfrd, val):
   3.293 -        try:
   3.294 -            vmid = sxp.child0(val)
   3.295 -            val = self.xd.domain_unpause(vmid)
   3.296 -            if vmid in self.paused:
   3.297 -                del self.paused[vmid]
   3.298 -        except StandardError, err:
   3.299 -            self.add_error("vm_unpause failed")
   3.300 -            self.add_error(err)
   3.301 -            val = errno.EINVAL
   3.302 -        return ['xfr.err', val]
   3.303 -
   3.304 -    def xfr_vm_suspend(self, xfrd, val):
   3.305 -        """Suspend a domain.
   3.306 -        Suspending can hang, so we set a timeout and fail if it
   3.307 -        takes too long.
   3.308 -        """
   3.309 -        try:
   3.310 -            vmid = sxp.child0(val)
   3.311 -            h = SuspendHandler(self, vmid, self.timeout)
   3.312 -            val = self.xd.domain_shutdown(vmid, reason='suspend')
   3.313 -            self.suspended[vmid] = 1
   3.314 -            h.start()
   3.315 -            print 'xfr_vm_suspend> suspended', vmid
   3.316 -        except Exception, err:
   3.317 -            print 'xfr_vm_suspend> err', err
   3.318 -            self.add_error("suspend failed")
   3.319 -            self.add_error(err)
   3.320 -            traceback.print_exc()
   3.321 -            val = errno.EINVAL
   3.322 -        return ['xfr.err', val]
   3.323 -
   3.324 -    def connectionLost(self, reason=None):
   3.325 -        print 'XfrdInfo>connectionLost>', reason
   3.326 -        for vmid in self.suspended:
   3.327 -            try:
   3.328 -                self.xd.domain_destroy(vmid)
   3.329 -            except:
   3.330 -                pass
   3.331 -        for vmid in self.paused:
   3.332 -            try:
   3.333 -                self.xd.domain_unpause(vmid)
   3.334 -            except:
   3.335 -                pass
   3.336 -
   3.337 -class XendMigrateInfo(XfrdInfo):
   3.338 -    """Representation of a migrate in-progress and its interaction with xfrd.
   3.339 -    """
   3.340 -
   3.341 -    def __init__(self, xid, dominfo, host, port, live=0, resource=0):
   3.342 -        XfrdInfo.__init__(self)
   3.343 -        self.xid = xid
   3.344 -        self.dominfo = dominfo
   3.345 -        self.state = 'begin'
   3.346 -        self.src_host = socket.gethostname()
   3.347 -        self.src_dom = dominfo.id
   3.348 -        self.dst_host = host
   3.349 -        self.dst_port = port
   3.350 -        self.dst_dom = None
   3.351 -        self.live = live
   3.352 -        self.resource = resource
   3.353 -        self.start = 0
   3.354 -        
   3.355 -    def sxpr(self):
   3.356 -        sxpr = ['migrate',
   3.357 -                ['id',    self.xid   ],
   3.358 -                ['state', self.state ],
   3.359 -                ['live',  self.live  ],
   3.360 -                ['resource', self.resource ] ]
   3.361 -        sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
   3.362 -        sxpr.append(sxpr_src)
   3.363 -        sxpr_dst = ['dst', ['host', self.dst_host] ]
   3.364 -        if self.dst_dom:
   3.365 -            sxpr_dst.append(['domain', self.dst_dom])
   3.366 -        sxpr.append(sxpr_dst)
   3.367 -        return sxpr
   3.368 -
   3.369 -    def request(self, xfrd):
   3.370 -        vmconfig = self.vmconfig()
   3.371 -        if not vmconfig:
   3.372 -            self.error(XendError("vm config not found"))
   3.373 -            xfrd.loseConnection()
   3.374 -            return
   3.375 -        log.info('Migrate BEGIN: %s' % str(self.sxpr()))
   3.376 -        eserver.inject('xend.domain.migrate',
   3.377 -                       [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ])
   3.378 -        xfrd.request(['xfr.migrate',
   3.379 -                      self.src_dom,
   3.380 -                      vmconfig,
   3.381 -                      self.dst_host,
   3.382 -                      self.dst_port,
   3.383 -                      self.live,
   3.384 -                      self.resource ])
   3.385 -        
   3.386 -    def xfr_migrate_ok(self, xfrd, val):
   3.387 -        dom = int(sxp.child0(val))
   3.388 -        self.state = 'ok'
   3.389 -        self.dst_dom = dom
   3.390 -        self.xd.domain_destroy(self.src_dom)
   3.391 -
   3.392 -    def connectionLost(self, reason=None):
   3.393 -        print 'XendMigrateInfo>connectionLost>', reason
   3.394 -        XfrdInfo.connectionLost(self, reason)
   3.395 -        if self.state =='ok':
   3.396 -            log.info('Migrate OK: ' + str(self.sxpr()))
   3.397 -        else:
   3.398 -            self.state = 'error'
   3.399 -            self.error("migrate failed")
   3.400 -            log.info('Migrate ERROR: ' + str(self.sxpr()))
   3.401 -        eserver.inject('xend.domain.migrate',
   3.402 -                       [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ])
   3.403 -
   3.404 -class XendSaveInfo(XfrdInfo):
   3.405 -    """Representation of a save in-progress and its interaction with xfrd.
   3.406 -    """
   3.407 -    
   3.408 -    def __init__(self, xid, dominfo, file):
   3.409 -        XfrdInfo.__init__(self)
   3.410 -        self.xid = xid
   3.411 -        self.dominfo = dominfo
   3.412 -        self.state = 'begin'
   3.413 -        self.src_dom = dominfo.id
   3.414 -        self.file = file
   3.415 -        self.start = 0
   3.416 -        
   3.417 -    def sxpr(self):
   3.418 -        sxpr = ['save',
   3.419 -                ['id', self.xid],
   3.420 -                ['state', self.state],
   3.421 -                ['domain', self.src_dom],
   3.422 -                ['file', self.file] ]
   3.423 -        return sxpr
   3.424 -
   3.425 -    def request(self, xfrd):
   3.426 -        vmconfig = self.vmconfig()
   3.427 -        if not vmconfig:
   3.428 -            self.error(XendError("vm config not found"))
   3.429 -            xfrd.loseConnection()
   3.430 -            return
   3.431 -        log.info('Save BEGIN: ' + str(self.sxpr()))
   3.432 -        eserver.inject('xend.domain.save',
   3.433 -                       [ self.dominfo.name, self.dominfo.id,
   3.434 -                         "begin", self.sxpr() ])
   3.435 -        xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ])
   3.436 -        
   3.437 -    def xfr_save_ok(self, xfrd, val):
   3.438 -        self.state = 'ok'
   3.439 -        self.xd.domain_destroy(self.src_dom)
   3.440 -
   3.441 -    def connectionLost(self, reason=None):
   3.442 -        print 'XendSaveInfo>connectionLost>', reason
   3.443 -        XfrdInfo.connectionLost(self, reason)
   3.444 -        if self.state =='ok':
   3.445 -            log.info('Save OK: ' + str(self.sxpr()))
   3.446 -        else:
   3.447 -            self.state = 'error'
   3.448 -            self.error("save failed")
   3.449 -            log.info('Save ERROR: ' + str(self.sxpr()))
   3.450 -        eserver.inject('xend.domain.save',
   3.451 -                       [ self.dominfo.name, self.dominfo.id,
   3.452 -                         self.state, self.sxpr() ])
   3.453 -    
   3.454 -class XendRestoreInfo(XfrdInfo):
   3.455 -    """Representation of a restore in-progress and its interaction with xfrd.
   3.456 -    """
   3.457 -
   3.458 -    def __init__(self, xid, file):
   3.459 -        XfrdInfo.__init__(self)
   3.460 -        self.xid = xid
   3.461 -        self.state = 'begin'
   3.462 -        self.file = file
   3.463 -
   3.464 -    def sxpr(self):
   3.465 -         sxpr = ['restore',
   3.466 -                 ['id', self.xid],
   3.467 -                 ['file', self.file] ]
   3.468 -         return sxpr
   3.469 -
   3.470 -    def request(self, xfrd):
   3.471 -        log.info('restore BEGIN: ' + str(self.sxpr()))
   3.472 -        eserver.inject('xend.restore', [ 'begin', self.sxpr()])
   3.473 -                       
   3.474 -        xfrd.request(['xfr.restore', self.file ])
   3.475 -        
   3.476 -    def xfr_restore_ok(self, xfrd, val):
   3.477 -        dom = int(sxp.child0(val))
   3.478 -        dominfo = self.xd.domain_get(dom)
   3.479 -        self.state = 'ok'
   3.480 -         
   3.481 -    def connectionLost(self, reason=None):
   3.482 -        XfrdInfo.connectionLost(self, reason)
   3.483 -        if self.state =='ok':
   3.484 -            log.info('Restore OK: ' + self.file)
   3.485 -        else:
   3.486 -            self.state = 'error'
   3.487 -            self.error("restore failed")
   3.488 -            log.info('Restore ERROR: ' + str(self.sxpr()))
   3.489 -        eserver.inject('xend.restore', [ self.state,  self.sxpr()])
   3.490 -
   3.491 -class XendMigrate:
   3.492 -    """External api for interaction with xfrd for migrate and save.
   3.493 -    Singleton.
   3.494 -    """
   3.495 -    # Use log for indications of begin/end/errors?
   3.496 -    # Need logging of: domain create/halt, migrate begin/end/fail
   3.497 -    # Log via event server?
   3.498 -
   3.499 -    dbpath = "migrate"
   3.500 -    
   3.501 -    def __init__(self):
   3.502 -        self.db = XendDB.XendDB(self.dbpath)
   3.503 -        self.session = {}
   3.504 -        self.session_db = self.db.fetchall("")
   3.505 -        self.xid = 0
   3.506 -
   3.507 -    def nextid(self):
   3.508 -        self.xid += 1
   3.509 -        return "%d" % self.xid
   3.510 -
   3.511 -    def sync(self):
   3.512 -        self.db.saveall("", self.session_db)
   3.513 -
   3.514 -    def sync_session(self, xid):
   3.515 -        self.db.save(xid, self.session_db[xid])
   3.516 -
   3.517 -    def close(self):
   3.518 -        pass
   3.519 -
   3.520 -    def _add_session(self, info):
   3.521 -        xid = info.xid
   3.522 -        self.session[xid] = info
   3.523 -        self.session_db[xid] = info.sxpr()
   3.524 -        self.sync_session(xid)
   3.525 -
   3.526 -    def _delete_session(self, xid):
   3.527 -        if xid in self.session:
   3.528 -            del self.session[xid]
   3.529 -        if xid in self.session_db:
   3.530 -            del self.session_db[xid]
   3.531 -            self.db.delete(xid)
   3.532 -
   3.533 -    def session_ls(self):
   3.534 -        return self.session.keys()
   3.535 -
   3.536 -    def sessions(self):
   3.537 -        return self.session.values()
   3.538 -
   3.539 -    def session_get(self, xid):
   3.540 -        return self.session.get(xid)
   3.541 -
   3.542 -    def session_begin(self, info):
   3.543 -        """Add the session to the table and start it.
   3.544 -        Remove the session from the table when it finishes.
   3.545 -
   3.546 -        @param info: session
   3.547 -        """
   3.548 -        self._add_session(info)
   3.549 -        try:
   3.550 -            xcf = XfrdClientFactory(info)
   3.551 -            return xcf.start()
   3.552 -        finally:
   3.553 -            self._delete_session(info.xid)
   3.554 -    
   3.555 -    def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0):
   3.556 -        """Begin to migrate a domain to another host.
   3.557 -
   3.558 -        @param dominfo:  domain info
   3.559 -        @param host: destination host
   3.560 -        @param port: destination port
   3.561 -        """
   3.562 -        xid = self.nextid()
   3.563 -        info = XendMigrateInfo(xid, dominfo, host, port, live, resource)
   3.564 -        return self.session_begin(info)
   3.565 -
   3.566 -    def save_begin(self, dominfo, file):
   3.567 -        """Begin saving a domain to file.
   3.568 -
   3.569 -        @param dominfo:  domain info
   3.570 -        @param file: destination file
   3.571 -        """
   3.572 -        xid = self.nextid()
   3.573 -        info = XendSaveInfo(xid, dominfo, file)
   3.574 -        return self.session_begin(info)
   3.575 -
   3.576 -    def restore_begin(self, file):
   3.577 -        xid = self.nextid()
   3.578 -        info = XendRestoreInfo(xid, file)
   3.579 -        return self.session_begin(info)
   3.580 -        
   3.581 -
   3.582 -def instance():
   3.583 -    global inst
   3.584 -    try:
   3.585 -        inst
   3.586 -    except:
   3.587 -        inst = XendMigrate()
   3.588 -    return inst