Fix vnets in xm.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 26 Aug 2005 10:51:10 +0000 (10:51 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Fri, 26 Aug 2005 10:51:10 +0000 (10:51 +0000)
The removal of 'xm call' to call a xend interface function directly
made the xend vnet functions inaccessible. This patch adds those functions
to xm and fixes the persistence in XmVnet to use xenstore.
Signed-off-by: Mike Wray <mike.wray@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
tools/python/xen/util/Brctl.py
tools/python/xen/xend/XendVnet.py
tools/python/xen/xend/server/SrvVnetDir.py
tools/python/xen/xm/main.py

index 7a6f4871dfd25869353dcdf26c98835a65d0adea..28506057f2a88097484cb24384e8155cee164e82 100644 (file)
@@ -76,6 +76,7 @@ def bridge_set(bridge, hello=None, fd=None, stp=None):
 def bridge_del(bridge):
     """Delete a bridge.
     """
+    cmd(CMD_IFCONFIG, '%s down' % bridge)
     cmd(CMD_BRCTL, 'delbr %s' % bridge)
 
 def routes():
index a21e5647df3c62a7fa38d9927268b23e53bc9bd2..5ed7ee1d64afe47ec616309c518b6d9a2801a4f3 100644 (file)
@@ -22,7 +22,7 @@ from xen.util import Brctl
 from xen.xend import sxp
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
-from xen.xend.xenstore import XenNode, DBMap
+from xen.xend.xenstore import XenNode, DBMap, DBVar
 
 def vnet_cmd(cmd):
     out = None
@@ -38,17 +38,40 @@ def vnet_cmd(cmd):
 class XendVnetInfo:
     
     vifctl_ops = {'up': 'vif.add', 'down': 'vif.del'}
+
+    __exports__ = [
+        DBVar('id',     ty='str'),
+        DBVar('dbid',   ty='str'),
+        DBVar('config', ty='sxpr'),
+       ]
     
-    def __init__(self, config):
-        self.config = config
-        self.id = sxp.child_value(config, 'id')
-        self.id = str(self.id)
+    def __init__(self, db, config=None):
+        if config:
+            self.id = sxp.child_value(config, 'id')
+            self.id = str(self.id)
+            self.dbid = self.id.replace(':', '-')
+            self.db = db.addChild(self.dbid)
+            self.config = config
+        else:
+            self.db = db
+            self.importFromDB()
+            config = self.config
+            
         self.bridge = sxp.child_value(config, 'bridge')
         if not self.bridge:
             self.bridge = "vnet%s" % self.id
         self.vnetif = sxp.child_value(config, 'vnetif')
         if not self.vnetif:
-            self.vnetif = "vnetif%s" % self.id
+            self.vnetif = "vnif%s" % self.id
+
+    def saveToDB(self, save=False, sync=False):
+        self.db.saveDB(save=save, sync=sync)
+
+    def exportToDB(self, save=False, sync=False):
+        self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
+
+    def importFromDB(self):
+        self.db.importFromDB(self, fields=self.__exports__)
 
     def sxpr(self):
         return self.config
@@ -64,7 +87,9 @@ class XendVnetInfo:
         log.info("Deleting vnet %s", self.id)
         Brctl.vif_bridge_rem({'bridge': self.bridge, 'vif': self.vnetif})
         Brctl.bridge_del(self.bridge)
-        return vnet_cmd(['vnet.del', self.id])
+        val = vnet_cmd(['vnet.del', self.id])
+        self.db.delete()
+        return val
 
     def vifctl(self, op, vif, vmac):
         try:
@@ -82,16 +107,18 @@ class XendVnet:
     def __init__(self):
         # Table of vnet info indexed by vnet id.
         self.vnet = {}
-        self.dbmap = DBMap(db=XenNode(self.dbpath))
-        self.dbmap.readDB()
-        for vnetdb in self.dbmap.values():
-            config = vnetdb.config
-            info = XendVnetInfo(config)
-            self.vnet[info.id] = info
+        self.db = DBMap(db=XenNode(self.dbpath))
+        self.db.readDB()
+        for vnetdb in self.db.values():
             try:
+                info = XendVnetInfo(vnetdb)
+                self.vnet[info.id] = info
                 info.configure()
             except XendError, ex:
                 log.warning("Failed to configure vnet %s: %s", str(info.id), str(ex))
+            except Exception, ex:
+                log.exception("Vnet error")
+                vnetdb.delete()
 
     def vnet_of_bridge(self, bridge):
         """Get the vnet for a bridge (if any).
@@ -128,9 +155,9 @@ class XendVnet:
 
         @param config: config
         """
-        info = XendVnetInfo(config)
+        info = XendVnetInfo(self.db, config=config)
         self.vnet[info.id] = info
-        self.dbmap["%s/config" % info.id] = info.sxpr()
+        info.saveToDB()
         info.configure()
 
     def vnet_delete(self, id):
@@ -141,7 +168,6 @@ class XendVnet:
         info = self.vnet_get(id)
         if info:
             del self.vnet[id]
-            self.dbmap.delete(id)
             info.delete()
 
 def instance():
index f8fd807c63519387ce953d4fb0dc557ea58b25d5..5dc5b591b2e1179422e8637d74ebc19cee1786af 100644 (file)
@@ -19,6 +19,7 @@ from xen.xend import sxp
 from xen.xend.Args import FormFn
 from xen.xend import PrettyPrint
 from xen.xend import XendVnet
+from xen.xend.XendError import XendError
 
 from xen.web.SrvDir import SrvDir
 
index 6fa4bab307fd52c87225f9fba30fd043ca8685b0..5c8e4b01ff28cd4452d6b67ea6f6408097e135fb 100644 (file)
@@ -105,6 +105,11 @@ xm full list of subcommands:
         Limit the transmission rate of a virtual network interface
     network-list    <DomId>        List virtual network interfaces for a domain
 
+  Vnet commands:
+    vnet-list   [-l|--long]    list vnets
+    vnet-create <config>       create a vnet from a config file
+    vnet-delete <vnetid>       delete a vnet
+
 For a short list of subcommands run 'xm help'
 For more help on xm see the xm(1) man page
 For more help on xm create, see the xmdomain.cfg(5) man page"""
@@ -547,6 +552,47 @@ def xm_block_destroy(args):
     from xen.xend.XendClient import server
     server.xend_domain_device_destroy(dom, 'vbd', dev)
 
+def xm_vnet_list(args):
+    from xen.xend.XendClient import server
+    try:
+        (options, params) = getopt(args, 'l', ['long'])
+    except GetoptError, opterr:
+        err(opterr)
+        sys.exit(1)
+    
+    use_long = 0
+    for (k, v) in options:
+        if k in ['-l', '--long']:
+            use_long = 1
+            
+    if params:
+        use_long = 1
+        vnets = params
+    else:
+        vnets = server.xend_vnets()
+    
+    for vnet in vnets:
+        try:
+            if use_long:
+                info = server.xend_vnet(vnet)
+                PrettyPrint.prettyprint(info)
+            else:
+                print vnet
+        except Exception, ex:
+            print vnet, ex
+
+def xm_vnet_create(args):
+    arg_check(args, 1, "vnet-create")
+    conf = args[0]
+    from xen.xend.XendClient import server
+    server.xend_vnet_create(conf)
+
+def xm_vnet_delete(args):
+    arg_check(args, 1, "vnet-delete")
+    vnet = args[0]
+    from xen.xend.XendClient import server
+    server.xend_vnet_delete(vnet)
+
 commands = {
     # console commands
     "console": xm_console,
@@ -592,7 +638,11 @@ commands = {
     "block-refresh": xm_block_refresh,
     # network
     "network-limit": xm_network_limit,
-    "network-list": xm_network_list
+    "network-list": xm_network_list,
+    # vnet
+    "vnet-list": xm_vnet_list,
+    "vnet-create": xm_vnet_create,
+    "vnet-delete": xm_vnet_delete,
     }
 
 aliases = {