aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenmgr/lib/server
diff options
context:
space:
mode:
Diffstat (limited to 'tools/xenmgr/lib/server')
-rw-r--r--tools/xenmgr/lib/server/SrvConsoleServer.py30
-rw-r--r--tools/xenmgr/lib/server/SrvDomain.py6
-rwxr-xr-xtools/xenmgr/lib/server/blkif.py118
-rwxr-xr-xtools/xenmgr/lib/server/controller.py29
-rw-r--r--tools/xenmgr/lib/server/messages.py3
-rwxr-xr-xtools/xenmgr/lib/server/netif.py59
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):