diff options
Diffstat (limited to 'tools/xenmgr/lib/server')
-rw-r--r-- | tools/xenmgr/lib/server/SrvConsoleServer.py | 30 | ||||
-rw-r--r-- | tools/xenmgr/lib/server/SrvDomain.py | 6 | ||||
-rwxr-xr-x | tools/xenmgr/lib/server/blkif.py | 118 | ||||
-rwxr-xr-x | tools/xenmgr/lib/server/controller.py | 29 | ||||
-rw-r--r-- | tools/xenmgr/lib/server/messages.py | 3 | ||||
-rwxr-xr-x | tools/xenmgr/lib/server/netif.py | 59 |
6 files changed, 180 insertions, 65 deletions
diff --git a/tools/xenmgr/lib/server/SrvConsoleServer.py b/tools/xenmgr/lib/server/SrvConsoleServer.py index 7179a0d1d4..94b7c8e6c8 100644 --- a/tools/xenmgr/lib/server/SrvConsoleServer.py +++ b/tools/xenmgr/lib/server/SrvConsoleServer.py @@ -584,28 +584,31 @@ class Daemon: reactor.diconnectAll() sys.exit(0) - def blkif_set_control_domain(self, dom): + def blkif_set_control_domain(self, dom, recreate=0): """Set the block device backend control domain. """ - return self.blkifCF.setControlDomain(dom) + return self.blkifCF.setControlDomain(dom, recreate=recreate) def blkif_get_control_domain(self, dom): """Get the block device backend control domain. """ return self.blkifCF.getControlDomain() - def blkif_create(self, dom): + def blkif_create(self, dom, recreate=0): """Create a block device interface controller. Returns Deferred """ - d = self.blkifCF.createInstance(dom) + d = self.blkifCF.createInstance(dom, recreate=recreate) return d + def blkif_get(self, dom): + return self.blkifCF.getInstanceByDom(dom) + def blkif_dev(self, dom, vdev): return self.blkifCF.getDomainDevice(dom, vdev) - def blkif_dev_create(self, dom, vdev, mode, segment): + def blkif_dev_create(self, dom, vdev, mode, segment, recreate=0): """Create a block device. Returns Deferred @@ -614,26 +617,29 @@ class Daemon: if not ctrl: raise ValueError('No blkif controller: %d' % dom) print 'blkif_dev_create>', dom, vdev, mode, segment - d = ctrl.attach_device(vdev, mode, segment) + d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate) return d - def netif_set_control_domain(self, dom): + def netif_set_control_domain(self, dom, recreate=0): """Set the network interface backend control domain. """ - return self.netifCF.setControlDomain(dom) + return self.netifCF.setControlDomain(dom, recreate=recreate) def netif_get_control_domain(self, dom): """Get the network interface backend control domain. """ return self.netifCF.getControlDomain() - def netif_create(self, dom): + def netif_create(self, dom, recreate=0): """Create a network interface controller. """ - return self.netifCF.createInstance(dom) + return self.netifCF.createInstance(dom, recreate=recreate) + + def netif_get(self, dom): + return self.netifCF.getInstanceByDom(dom) - def netif_dev_create(self, dom, vif, vmac): + def netif_dev_create(self, dom, vif, vmac, recreate=0): """Create a network device. todo @@ -641,7 +647,7 @@ class Daemon: ctrl = self.netifCF.getInstanceByDom(dom) if not ctrl: raise ValueError('No netif controller: %d' % dom) - d = ctrl.attach_device(vif, vmac) + d = ctrl.attachDevice(vif, vmac, recreate=recreate) return d def netif_dev(self, dom, vif): diff --git a/tools/xenmgr/lib/server/SrvDomain.py b/tools/xenmgr/lib/server/SrvDomain.py index 5034869e63..d8287e05ea 100644 --- a/tools/xenmgr/lib/server/SrvDomain.py +++ b/tools/xenmgr/lib/server/SrvDomain.py @@ -32,8 +32,8 @@ class SrvDomain(SrvDir): req.setHeader("Location", "%s/.." % req.prePathURL()) return val - def op_halt(self, op, req): - val = self.xd.domain_halt(self.dom.id) + def op_destroy(self, op, req): + val = self.xd.domain_destroy(self.dom.id) req.setHeader("Location", "%s/.." % req.prePathURL()) return val @@ -196,7 +196,7 @@ class SrvDomain(SrvDir): req.write('<input type="submit" name="op" value="unpause">') req.write('<input type="submit" name="op" value="pause">') req.write('<input type="submit" name="op" value="shutdown">') - req.write('<input type="submit" name="op" value="halt">') + req.write('<input type="submit" name="op" value="destroy">') req.write('<br><input type="submit" name="op" value="migrate">') req.write('To: <input type="text" name="destination">') req.write('</form>') diff --git a/tools/xenmgr/lib/server/blkif.py b/tools/xenmgr/lib/server/blkif.py index 8da827baa9..92706316b1 100755 --- a/tools/xenmgr/lib/server/blkif.py +++ b/tools/xenmgr/lib/server/blkif.py @@ -1,3 +1,5 @@ +from twisted.internet import defer + import channel import controller from messages import * @@ -22,7 +24,7 @@ class BlkifControllerFactory(controller.ControllerFactory): self.attached = 1 self.registerChannel() - def createInstance(self, dom): + def createInstance(self, dom, recreate=0): d = self.addDeferred() blkif = self.getInstanceByDom(dom) if blkif: @@ -30,7 +32,10 @@ class BlkifControllerFactory(controller.ControllerFactory): else: blkif = BlkifController(self, dom) self.addInstance(blkif) - blkif.send_be_create() + if recreate: + self.callDeferred(blkif) + else: + blkif.send_be_create() return d def getDomainDevices(self, dom): @@ -41,10 +46,11 @@ class BlkifControllerFactory(controller.ControllerFactory): blkif = self.getInstanceByDom(dom) return (blkif and blkif.getDevice(vdev)) or None - def setControlDomain(self, dom): + def setControlDomain(self, dom, recreate=0): if self.dom == dom: return self.deregisterChannel() - self.attached = 0 + if not recreate: + self.attached = 0 self.dom = dom self.registerChannel() # @@ -55,6 +61,28 @@ class BlkifControllerFactory(controller.ControllerFactory): def getControlDomain(self): return self.dom + def reattachDevice(self, dom, vdev): + blkif = self.getInstanceByDom(dom) + if blkif: + blkif.reattachDevice(vdev) + self.attached = self.devicesAttached() + if self.attached: + self.reattached() + + def devicesAttached(self): + """Check if all devices are attached. + """ + attached = 1 + for blkif in self.getInstances(): + if not blkif.attached: + attached = 0 + break + return attached + + def reattached(self): + for blkif in self.getInstances(): + blkif.reattached() + def recv_be_create(self, msg, req): #print 'recv_be_create>' val = unpackMsg('blkif_be_create_t', msg) @@ -86,29 +114,7 @@ class BlkifControllerFactory(controller.ControllerFactory): if self.attached: self.callDeferred(0) else: - self.reattach_device(val['domid'], val['vdevice']) - - def reattach_device(self, dom, vdev): - blkif = self.getInstanceByDom(dom) - if blkif: - blkif.reattach_device(vdev) - self.attached = self.devices_attached() - if self.attached: - self.reattached() - - def devices_attached(self): - """Check if all devices are attached. - """ - attached = 1 - for blkif in self.getInstances(): - if not blkif.attached: - attached = 0 - break - return attached - - def reattached(self): - for blkif in self.getInstances(): - blkif.reattached() + self.reattachDevice(val['domid'], val['vdevice']) def recv_be_driver_status_changed(self, msg, req): val = unpackMsg('blkif_be_driver_status_changed_t', msg) @@ -117,11 +123,12 @@ class BlkifControllerFactory(controller.ControllerFactory): for blkif in self.getInstances(): blkif.detach() -class BlkDev: +class BlkDev(controller.Dev): """Info record for a block device. """ - def __init__(self, vdev, mode, segment): + def __init__(self, ctrl, vdev, mode, segment): + controller.Dev.__init__(self, ctrl) self.vdev = vdev self.mode = mode self.device = segment['device'] @@ -131,6 +138,14 @@ class BlkDev: def readonly(self): return 'w' not in self.mode + + def sxpr(self): + print 'BlkDev>sxpr>', vars(self) + val = ['blkif', ['vdev', self.vdev], ['mode', self.mode] ] + return val + + def destroy(self): + self.controller.send_be_vbd_destroy(self.vdev) class BlkifController(controller.Controller): """Block device interface controller. Handles all block devices @@ -154,21 +169,43 @@ class BlkifController(controller.Controller): self.registerChannel() #print 'BlkifController<', 'dom=', self.dom, 'idx=', self.idx + def lostChannel(self): + print 'BlkifController>lostChannel>', 'dom=', self.dom + #self.destroyDevices() + controller.Controller.lostChannel(self) + def getDevices(self): return self.devices.values() def getDevice(self, vdev): return self.devices.get(vdev) - def attach_device(self, vdev, mode, segment): + def addDevice(self, vdev, mode, segment): + if vdev in self.devices: return None + dev = BlkDev(self, vdev, mode, segment) + self.devices[vdev] = dev + return dev + + def attachDevice(self, vdev, mode, segment, recreate=0): """Attach a device to the specified interface. """ #print 'BlkifController>attach_device>', self.dom, vdev, mode, segment - if vdev in self.devices: return -1 - dev = BlkDev(vdev, mode, segment) - self.devices[vdev] = dev - self.send_be_vbd_create(vdev) - return self.factory.addDeferred() + dev = self.addDevice(vdev, mode, segment) + if not dev: return -1 + if recreate: + d = defer.Deferred() + d.callback(self) + else: + self.send_be_vbd_create(vdev) + d = self.factory.addDeferred() + return d + + def destroy(self): + self.destroyDevices() + + def destroyDevices(self): + for dev in self.getDevices(): + dev.destroy() def detach(self): """Detach all devices, when the back-end control domain has changed. @@ -178,7 +215,7 @@ class BlkifController(controller.Controller): dev.attached = 0 self.send_be_vbd_create(vdev) - def reattach_device(self, vdev): + def reattachDevice(self, vdev): """Reattach a device, when the back-end control domain has changed. """ dev = self.devices[vdev] @@ -254,4 +291,13 @@ class BlkifController(controller.Controller): 'extent.sector_start' : dev.start_sector, 'extent.sector_length' : dev.nr_sectors }) self.factory.writeRequest(msg) + + def send_be_vbd_destroy(self, vdev): + dev = self.devices[vdev] + msg = packMsg('blkif_be_vbd_destroy_t', + { 'domid' : self.dom, + 'blkif_handle' : 0, + 'vdevice' : dev.vdev }) + del self.devices[vdev] + self.factory.writeRequest(msg) diff --git a/tools/xenmgr/lib/server/controller.py b/tools/xenmgr/lib/server/controller.py index 791e987511..cb543fa57c 100755 --- a/tools/xenmgr/lib/server/controller.py +++ b/tools/xenmgr/lib/server/controller.py @@ -95,7 +95,7 @@ class ControllerFactory(CtrlMsgRcvr): if instance.idx in self.instances: del self.instances[instance.idx] - def createInstance(self, dom): + def createInstance(self, dom, recreate=0): raise NotImplementedError() def instanceClosed(self, instance): @@ -136,3 +136,30 @@ class Controller(CtrlMsgRcvr): def lostChannel(self): self.factory.instanceClosed(self) + +class Dev: + + def __init__(self, controller): + self.controller = controller + self.props = {} + + def setprop(self, k, v): + self.props[k] = v + + def getprop(self, k, v=None): + return self.props.get(k, v) + + def hasprop(self, k): + return k in self.props + + def delprop(self, k): + if k in self.props: + del self.props[k] + + #def __repr__(self): + # return str(self.sxpr()) + + def sxpr(self): + raise NotImplementedError() + + diff --git a/tools/xenmgr/lib/server/messages.py b/tools/xenmgr/lib/server/messages.py index 78bc24526f..0313670279 100644 --- a/tools/xenmgr/lib/server/messages.py +++ b/tools/xenmgr/lib/server/messages.py @@ -76,6 +76,9 @@ blkif_formats = { 'blkif_be_vbd_grow_t': (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW), + 'blkif_be_vbd_destroy_t': + (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY), + 'blkif_fe_interface_status_changed_t': (CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED), diff --git a/tools/xenmgr/lib/server/netif.py b/tools/xenmgr/lib/server/netif.py index f3da86ba82..d2a6a53860 100755 --- a/tools/xenmgr/lib/server/netif.py +++ b/tools/xenmgr/lib/server/netif.py @@ -1,5 +1,9 @@ import random +from twisted.internet import defer + +from xenmgr import XendBridge + import channel import controller from messages import * @@ -22,7 +26,7 @@ class NetifControllerFactory(controller.ControllerFactory): self.attached = 1 self.registerChannel() - def createInstance(self, dom): + def createInstance(self, dom, recreate=0): """Create or find the network interface controller for a domain. """ #print 'netif>createInstance> dom=', dom @@ -40,12 +44,13 @@ class NetifControllerFactory(controller.ControllerFactory): netif = self.getInstanceByDom(dom) return (netif and netif.getDevice(vif)) or None - def setControlDomain(self, dom): + def setControlDomain(self, dom, recreate=0): """Set the 'back-end' device driver domain. """ if self.dom == dom: return self.deregisterChannel() - self.attached = 0 + if not recreate: + self.attached = 0 self.dom = dom self.registerChannel() # @@ -98,20 +103,38 @@ class NetifControllerFactory(controller.ControllerFactory): ## print "Done notifying guests" ## recovery = False -class NetDev: +class NetDev(controller.Dev): """Info record for a network device. """ - def __init__(self, vif, mac): + def __init__(self, ctrl, vif, mac): + controller.Dev.__init__(self, ctrl) self.vif = vif self.mac = mac self.evtchn = None + self.bridge = None def sxpr(self): vif = str(self.vif) mac = ':'.join(map(lambda x: "%x" % x, self.mac)) - return ['netif', ['vif', vif], ['mac', mac]] - + val = ['netif', ['vif', vif], ['mac', mac]] + if self.bridge: + val += ['bridge', self.bridge] + return val + + def bridge_add(self, bridge): + self.bridge = XendBridge.vif_bridge_add(self.controller.dom, self.vif, bridge) + + def bridge_rem(self): + if not self.bridge: return + XendBridge.vif_bridge_rem(self.controller.dom, self.vif, self.bridge) + self.bridge = None + + def destroy(self): + self.bridge_rem() + self.controller.send_be_destroy(self.vif) + + class NetifController(controller.Controller): """Network interface controller. Handles all network devices for a domain. """ @@ -150,8 +173,7 @@ class NetifController(controller.Controller): def lostChannel(self): print 'NetifController>lostChannel>', 'dom=', self.dom - #for vif in self.devices: - # self.send_be_destroy(vif) + #self.destroyDevices() controller.Controller.lostChannel(self) def getDevices(self): @@ -167,11 +189,18 @@ class NetifController(controller.Controller): mac = [ int(x, 16) for x in vmac.split(':') ] if len(mac) != 6: raise ValueError("invalid mac") #print "attach_device>", "vif=", vif, "mac=", mac - dev = NetDev(vif, mac) + dev = NetDev(self, vif, mac) self.devices[vif] = dev return dev - def attach_device(self, vif, vmac): + def destroy(self): + self.destroyDevices() + + def destroyDevices(self): + for dev in self.getDevices(): + dev.destroy() + + def attachDevice(self, vif, vmac, recreate=0): """Attach a network device. If vmac is None a random mac address is assigned. @@ -179,8 +208,12 @@ class NetifController(controller.Controller): @param vmac mac address (string) """ self.addDevice(vif, vmac) - d = self.factory.addDeferred() - self.send_be_create(vif) + if recreate: + d = defer.Deferred() + d.callback(self) + else: + d = self.factory.addDeferred() + self.send_be_create(vif) return d def reattach_devices(self): |