[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Add VBD.runtime_properties dictionary, and use that to implement xm block-list



# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Date 1174391144 0
# Node ID e2f302488983548285f25f4e8927f1a456188c31
# Parent  dace880e871a22883f61a3fdaeafae7fdd51ba58
Add VBD.runtime_properties dictionary, and use that to implement xm block-list
through the Xen-API.  Implement xm block-attach and xm block-detach also.

Signed-off-by: Tom Wilkie <tom.wilkie@xxxxxxxxx>
---
 tools/python/xen/xend/XendAPI.py     |   61 ++++++++++++++++-----
 tools/python/xen/xend/XendVDI.py     |   10 +++
 tools/python/xen/xm/main.py          |  101 +++++++++++++++++++++++++++++------
 tools/python/xen/xm/xenapi_create.py |    6 --
 4 files changed, 145 insertions(+), 33 deletions(-)

diff -r dace880e871a -r e2f302488983 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Tue Mar 20 11:45:44 2007 +0000
@@ -35,6 +35,9 @@ from xen.xend.XendVMMetrics import XendV
 
 from xen.xend.XendAPIConstants import *
 from xen.util.xmlrpclib2 import stringify
+
+from xen.util.blkif import blkdev_name_to_number
+
 
 AUTH_NONE = 'none'
 AUTH_PAM = 'pam'
@@ -1555,7 +1558,8 @@ class XendAPI(object):
     # Xen API: Class VBD
     # ----------------------------------------------------------------
 
-    VBD_attr_ro = ['metrics']
+    VBD_attr_ro = ['metrics',
+                   'runtime_properties']
     VBD_attr_rw = ['VM',
                    'VDI',
                    'device',
@@ -1596,23 +1600,28 @@ class XendAPI(object):
     # class methods
     def VBD_create(self, session, vbd_struct):
         xendom = XendDomain.instance()
+        xennode = XendNode.instance()
+        
         if not xendom.is_valid_vm(vbd_struct['VM']):
             return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
         
         dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
-        vbd_ref = ''
+        vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
+        if not vdi:
+            return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
+
+        # new VBD via VDI/SR
+        vdi_image = vdi.get_location()
+
         try:
-            # new VBD via VDI/SR
-            vdi_ref = vbd_struct.get('VDI')
-            vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
-            if not vdi:
-                return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
-            vdi_image = vdi.get_location()
             vbd_ref = XendTask.log_progress(0, 100,
                                             dom.create_vbd,
                                             vbd_struct, vdi_image)
-        except XendError:
-            return xen_api_todo()
+        except XendError, e:
+            log.exception("Error in VBD_create")
+            return xen_api_error(['INTERNAL_ERROR', str(e)]) 
+            
+        vdi.addVBD(vbd_ref)
 
         xendom.managed_config_save(dom)
         return xen_api_success(vbd_ref)
@@ -1624,7 +1633,14 @@ class XendAPI(object):
         if not vm:
             return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
 
+        vdi_ref = XendDomain.instance()\
+                  .get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
+        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
+
         XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
+
+        vdi.removeVBD(vbd_ref)
+        
         return xen_api_success_void()
 
     def _VBD_get(self, vbd_ref, prop):
@@ -1635,6 +1651,26 @@ class XendAPI(object):
     # attributes (ro)
     def VBD_get_metrics(self, _, vbd_ref):
         return xen_api_success(vbd_ref)
+
+    def VBD_get_runtime_properties(self, _, vbd_ref):
+        xendom = XendDomain.instance()
+        dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
+        device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
+        devid = int(device['id'])
+        device_sxps = dominfo.getDeviceSxprs('vbd')
+
+        log.debug("VBD_get_runtime_properties devid: %i device_sxps: %s",
+                  devid, device_sxps)
+        
+        device_dicts  = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
+
+        device_dict = [device_dict
+                       for device_dict in device_dicts
+                       if int(device_dict['virtual-device']) == devid][0]
+
+        log.debug("VBD_get_runtime_properties device_dict: %s", device_dict)
+
+        return xen_api_success(device_dict)
 
     # attributes (rw)
     def VBD_get_VM(self, session, vbd_ref):
@@ -1828,7 +1864,8 @@ class XendAPI(object):
         return XendNode.instance().get_vdi_by_uuid(ref)
     
     def VDI_get_VBDs(self, session, vdi_ref):
-        return xen_api_todo()
+        vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
+        return xen_api_success(vdi.getVBDs())
     
     def VDI_get_physical_utilisation(self, session, vdi_ref):
         return xen_api_success(self._get_VDI(vdi_ref).
@@ -1898,7 +1935,7 @@ class XendAPI(object):
             'name_label': image.name_label,
             'name_description': image.name_description,
             'SR': image.sr_uuid,
-            'VBDs': [], # TODO
+            'VBDs': image.getVBDs(),
             'virtual_size': image.virtual_size,
             'physical_utilisation': image.physical_utilisation,
             'type': image.type,
diff -r dace880e871a -r e2f302488983 tools/python/xen/xend/XendVDI.py
--- a/tools/python/xen/xend/XendVDI.py  Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xend/XendVDI.py  Tue Mar 20 11:45:44 2007 +0000
@@ -72,6 +72,16 @@ class XendVDI(AutoSaveObject):
         self.read_only = False
         self.type = "system"
         self.other_config = {}
+        self.vbds = []
+
+    def addVBD(self, vbd_ref):
+        self.vbds.append(vbd_ref)
+
+    def removeVBD(self, vbd_ref):
+        self.vbds.remove(vbd_ref)
+
+    def getVBDs(self):
+        return self.vbds
 
     def load_config_dict(self, cfg):
         """Loads configuration into the object from a dict.
diff -r dace880e871a -r e2f302488983 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xm/main.py       Tue Mar 20 11:45:44 2007 +0000
@@ -33,7 +33,6 @@ import socket
 import socket
 import traceback
 import xmlrpclib
-import traceback
 import time
 import datetime
 from select import select
@@ -50,6 +49,7 @@ from xen.xm.opts import OptionError, Opt
 from xen.xm.opts import OptionError, Opts, wrap, set_true
 from xen.xm import console
 from xen.util.xmlrpclib2 import ServerProxy
+
 import XenAPI
 
 
@@ -492,6 +492,14 @@ def usage(cmd = None):
 #
 ####################################################################
 
+def get_default_SR():
+    return [sr_ref
+            for sr_ref in server.xenapi.SR.get_all()
+            if server.xenapi.SR.get_type(sr_ref) == "local"][0]
+
+def map2sxp(m):
+    return [[k, m[k]] for k in m.keys()]
+
 def arg_check(args, name, lo, hi = -1):
     n = len([i for i in args if i != '--'])
     
@@ -675,9 +683,6 @@ def xm_restore(args):
 
 def getDomains(domain_names, state, full = 0):
     if serverType == SERVER_XEN_API:
-        def map2sxp(m):
-            return ["domain"] + [[k, m[k]] for k in m.keys()]
-        
         doms_sxp = []
         doms_dict = []
         dom_refs = server.xenapi.VM.get_all()
@@ -691,11 +696,11 @@ def getDomains(domain_names, state, full
                             'state':    '-----',
                             'cpu_time': dom_metrics['vcpus_utilisation']})
                        
-            doms_sxp.append(map2sxp(dom_rec))
+            doms_sxp.append(['domain'] + map2sxp(dom_rec))
             doms_dict.append(dom_rec)
             
         if domain_names:
-            doms = [map2sxp(dom) for dom in doms_dict
+            doms = [['domain'] + map2sxp(dom) for dom in doms_dict
                     if dom["name"] in domain_names]
             
             if len(doms) > 0:
@@ -1689,12 +1694,20 @@ def xm_block_list(args):
     (use_long, params) = arg_check_for_resource_list(args, "block-list")
 
     dom = params[0]
+
+    if serverType == SERVER_XEN_API:
+        vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
+        vbd_properties = \
+            map(server.xenapi.VBD.get_runtime_properties, vbd_refs)
+        devs = map(lambda x: [x['virtual-device'], map2sxp(x)], vbd_properties)
+    else:
+        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
+
     if use_long:
-        devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
         map(PrettyPrint.prettyprint, devs)
     else:
         hdr = 0
-        for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
+        for x in devs:
             if hdr == 0:
                 print 'Vdev  BE handle state evt-ch ring-ref BE-path'
                 hdr = 1
@@ -1767,8 +1780,45 @@ def xm_block_attach(args):
 def xm_block_attach(args):
     arg_check(args, 'block-attach', 4, 5)
 
-    (dom, vbd) = parse_block_configuration(args)
-    server.xend.domain.device_create(dom, vbd)
+    if serverType == SERVER_XEN_API:
+        dom   = args[0]
+        uname = args[1]
+        dev   = args[2]
+        mode  = args[3]
+
+        # First create new VDI
+        vdi_record = {
+            "name_label":       "vdi" + str(uname.__hash__()),   
+            "name_description": "",
+            "SR":               get_default_SR(),
+            "virtual_size":     0,
+            "sector_size":      512,
+            "type":             "system",
+            "sharable":         False,
+            "read_only":        mode!="w",
+            "other_config":     {"location": uname}
+        }
+
+        vdi_ref = server.xenapi.VDI.create(vdi_record)
+
+        # Now create new VBD
+
+        vbd_record = {
+            "VM":               get_single_vm(dom),
+            "VDI":              vdi_ref,
+            "device":           dev,
+            "bootable":         True,
+            "mode":             mode=="w" and "RW" or "RO",
+            "type":             "Disk",
+            "qos_algorithm_type": "",
+            "qos_algorithm_params": {}
+        }
+
+        server.xenapi.VBD.create(vbd_record)
+        
+    else:
+        (dom, vbd) = parse_block_configuration(args)
+        server.xend.domain.device_create(dom, vbd)
 
 
 def xm_block_configure(args):
@@ -1814,13 +1864,30 @@ def detach(args, command, deviceClass):
 
 
 def xm_block_detach(args):
-    try:
-        detach(args, 'block-detach', 'vbd')
-        return
-    except:
-        pass
-    detach(args, 'block-detach', 'tap')
-
+    if serverType == SERVER_XEN_API:
+        arg_check(args, "xm_block_detach", 2, 3)
+        dom = args[0]
+        dev = args[1]
+        vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
+        vbd_refs = [vbd_ref for vbd_ref in vbd_refs
+                    if server.xenapi.VBD.get_device(vbd_ref) == dev]
+        if len(vbd_refs) > 0:
+            vbd_ref = vbd_refs[0]
+            vdi_ref = server.xenapi.VBD.get_VDI(vbd_ref)
+
+            server.xenapi.VBD.destroy(vbd_ref)
+
+            if len(server.xenapi.VDI.get_VBDs(vdi_ref)) <= 0:
+                server.xenapi.VDI.destroy(vdi_ref)
+        else:
+            print "Cannot find device '%s' in domain '%s'" % (dev,dom)
+    else:
+        try:
+            detach(args, 'block-detach', 'vbd')
+            return
+        except:
+            pass
+        detach(args, 'block-detach', 'tap')
 
 def xm_network_detach(args):
     detach(args, 'network-detach', 'vif')
diff -r dace880e871a -r e2f302488983 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Tue Mar 20 11:44:13 2007 +0000
+++ b/tools/python/xen/xm/xenapi_create.py      Tue Mar 20 11:45:44 2007 +0000
@@ -18,7 +18,7 @@
 """Domain creation using new XenAPI
 """
 
-from xen.xm.main import server
+from xen.xm.main import server, get_default_SR
 from xml.dom.minidom import parse, getDOMImplementation
 from xml.dom.ext import PrettyPrint
 from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
@@ -71,9 +71,7 @@ class xenapi_create:
 class xenapi_create:
 
     def __init__(self):
-        self.DEFAULT_STORAGE_REPOSITORY = [sr_ref
-                  for sr_ref in server.xenapi.SR.get_all()
-                  if server.xenapi.SR.get_type(sr_ref) == "local"][0]
+        self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
 
         self.dtd = "/usr/lib/python/xen/xm/create.dtd"
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.