WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Added network.{create, destroy}, and PIF.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Added network.{create, destroy}, and PIF.{create, create_VLAN, destroy}, and
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 29 Dec 2006 14:20:09 -0800
Delivery-date: Fri, 29 Dec 2006 14:21:35 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Date 1167234176 0
# Node ID a8e853aecb3ef24b7a77bb9022f475bfee564c37
# Parent  069d1364af539b78d89cbeaa7c898c0cda3ed0af
Added network.{create,destroy}, and PIF.{create,create_VLAN,destroy}, and
a first blush at support for VLANs through Xen-API.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
---
 tools/python/xen/xend/XendAPI.py          |   58 ++++++++++++++----
 tools/python/xen/xend/XendNode.py         |   92 +++++++++++++++++++++-------
 tools/python/xen/xend/XendPIF.py          |   96 +++++++++++++++++++++++-------
 tools/python/xen/xend/server/SrvServer.py |    4 -
 4 files changed, 193 insertions(+), 57 deletions(-)

diff -r 069d1364af53 -r a8e853aecb3e tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Dec 27 15:39:32 2006 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Wed Dec 27 15:42:56 2006 +0000
@@ -469,13 +469,23 @@ class XendAPI:
                        'default_gateway',
                        'default_netmask']
 
+    def network_create(self, _, name_label, name_description,
+                       default_gateway, default_netmask):
+        return xen_api_success(
+            XendNode.instance().network_create(name_label, name_description,
+                                               default_gateway,
+                                               default_netmask))
+
+    def network_destroy(self, _, ref):
+        return xen_api_success(XendNode.instance().network_destroy(ref))
+
     def _get_network(self, ref):
         return XendNode.instance().get_network(ref)
 
-    def network_get_all(self, session):
+    def network_get_all(self, _):
         return xen_api_success(XendNode.instance().get_network_refs())
 
-    def network_get_record(self, session, ref):
+    def network_get_record(self, _, ref):
         return xen_api_success(
             XendNode.instance().get_network(ref).get_record())
 
@@ -524,8 +534,25 @@ class XendAPI:
 
     PIF_attr_inst = PIF_attr_rw
 
+    PIF_methods = ['create_VLAN']
+
     def _get_PIF(self, ref):
         return XendNode.instance().pifs[ref]
+
+    def PIF_create(self, _, name, network_uuid, host_uuid, mac, mtu, vlan):
+        node = XendNode.instance()
+        if host_uuid != node.uuid:
+            return xen_api_error([HOST_HANDLE_INVALID, host_uuid])
+
+        elif _is_valid_ref(network_uuid, node.is_valid_network):
+            network = node.get_network(network_uuid)
+            return xen_api_success(node.PIF_create(name, mtu, vlan, mac,
+                                                   network))
+        else:
+            return xen_api_error([NETWORK_HANDLE_INVALID, network_uuid])
+
+    def PIF_destroy(self, _, ref):
+        return xen_api_success(XendNode.instance().PIF_destroy(ref))
 
     # object methods
     def PIF_get_record(self, _, ref):
@@ -534,38 +561,45 @@ class XendAPI:
     def PIF_get_all(self, _):
         return xen_api_success(XendNode.instance().pifs.keys())
 
-    def PIF_get_name(self, session, ref):
+    def PIF_get_name(self, _, ref):
         return xen_api_success(self._get_PIF(ref).name)
 
-    def PIF_get_network(self, session, ref):
+    def PIF_get_network(self, _, ref):
         return xen_api_success(self._get_PIF(ref).network.uuid)
 
-    def PIF_get_host(self, session, ref):
+    def PIF_get_host(self, _, ref):
         return xen_api_success(self._get_PIF(ref).host.uuid)
 
-    def PIF_get_MAC(self, session, ref):
+    def PIF_get_MAC(self, _, ref):
         return xen_api_success(self._get_PIF(ref).mac)
 
-    def PIF_get_MTU(self, session, ref):
+    def PIF_get_MTU(self, _, ref):
         return xen_api_success(self._get_PIF(ref).mtu)
 
-    def PIF_get_VLAN(self, session, ref):
+    def PIF_get_VLAN(self, _, ref):
         return xen_api_success(self._get_PIF(ref).vlan)
 
-    def PIF_get_io_read_kbs(self, session, ref):
+    def PIF_get_io_read_kbs(self, _, ref):
         return xen_api_success(self._get_PIF(ref).get_io_read_kbs())
 
-    def PIF_get_io_write_kbs(self, session, ref):
+    def PIF_get_io_write_kbs(self, _, ref):
         return xen_api_success(self._get_PIF(ref).get_io_write_kbs())
     
     def PIF_set_name(self, _, ref, name):
         return xen_api_success(self._get_PIF(ref).set_name(name))
 
-    def PIF_set_MAC(self, session, ref, mac):
+    def PIF_set_MAC(self, _, ref, mac):
         return xen_api_success(self._get_PIF(ref).set_mac(name))
 
-    def PIF_set_MTU(self, session, ref, mtu):
+    def PIF_set_MTU(self, _, ref, mtu):
         return xen_api_success(self._get_PIF(ref).set_mtu(name))
+
+    def PIF_create_VLAN(self, _, ref, network, vlan):
+        if _is_valid_ref(network, XendNode.instance().is_valid_network):
+            return xen_api_success(XendNode.instance().PIF_create_VLAN(
+                ref, network, vlan))
+        else:
+            return xen_api_error([NETWORK_HANDLE_INVALID, network_uuid])
 
 
     # Xen API: Class VM
diff -r 069d1364af53 -r a8e853aecb3e tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Dec 27 15:39:32 2006 +0000
+++ b/tools/python/xen/xend/XendNode.py Wed Dec 27 15:42:56 2006 +0000
@@ -19,6 +19,9 @@ import os
 import os
 import socket
 import xen.lowlevel.xc
+
+from xen.util import Brctl
+
 from xen.xend import uuid
 from xen.xend.XendError import XendError
 from xen.xend.XendRoot import instance as xendroot
@@ -87,16 +90,14 @@ class XendNode:
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.networks[net_uuid] = XendNetwork(net_uuid,
-                                network.get('name_label'),
-                                network.get('name_description', ''),
-                                network.get('default_gateway', ''),
-                                network.get('default_netmask', ''))
+                self.network_create(network.get('name_label'),
+                                    network.get('name_description', ''),
+                                    network.get('default_gateway', ''),
+                                    network.get('default_netmask', ''),
+                                    False, net_uuid)
         else:
             gateway, netmask = linux_get_default_network()
-            net_uuid = uuid.createString()
-            net = XendNetwork(net_uuid, 'net0', '', gateway, netmask)
-            self.networks[net_uuid] = net
+            self.network_create('net0', '', gateway, netmask, False)
 
         # initialise PIFs
         saved_pifs = self.state_store.load_state('pif')
@@ -104,19 +105,12 @@ class XendNode:
             for pif_uuid, pif in saved_pifs.items():
                 if pif['network'] in self.networks:
                     network = self.networks[pif['network']]
-                    self.pifs[pif_uuid] = XendPIF(pif_uuid,
-                                                  pif['name'],
-                                                  pif['MTU'],
-                                                  pif['VLAN'],
-                                                  pif['MAC'],
-                                                  network,
-                                                  self)
+                    self.PIF_create(pif['name'], pif['MTU'], pif['VLAN'],
+                                    pif['MAC'], network, False, pif_uuid)
         else:
             for name, mtu, mac in linux_get_phy_ifaces():
                 network = self.networks.values()[0]
-                pif_uuid = uuid.createString()
-                pif = XendPIF(pif_uuid, name, mtu, '', mac, network, self)
-                self.pifs[pif_uuid] = pif
+                self.PIF_create(name, mtu, '', mac, network, False)
 
         # initialise storage
         saved_sr = self.state_store.load_state('sr')
@@ -126,6 +120,49 @@ class XendNode:
         else:
             sr_uuid = uuid.createString()
             self.sr = XendStorageRepository(sr_uuid)
+
+
+    def network_create(self, name_label, name_description,
+                       default_gateway, default_netmask, persist = True,
+                       net_uuid = None):
+        if net_uuid is None:
+            net_uuid = uuid.createString()
+        self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
+                                              name_description,
+                                              default_gateway,
+                                              default_netmask)
+        if persist:
+            self.save_networks()
+        return net_uuid
+
+
+    def network_destroy(self, net_uuid):
+        del self.networks[net_uuid]
+        self.save_networks()
+
+
+    def PIF_create(self, name, mtu, vlan, mac, network, persist = True,
+                   pif_uuid = None):
+        if pif_uuid is None:
+            pif_uuid = uuid.createString()
+        self.pifs[pif_uuid] = XendPIF(pif_uuid, name, mtu, vlan, mac, network,
+                                      self)
+        if persist:
+            self.save_PIFs()
+            self.refreshBridges()
+        return pif_uuid
+
+
+    def PIF_create_VLAN(self, pif_uuid, network_uuid, vlan):
+        pif = self.pifs[pif_uuid]
+        network = self.networks[network_uuid]
+        return self.PIF_create(pif.name, pif.mtu, vlan, pif.mac, network)
+
+
+    def PIF_destroy(self, pif_uuid):
+        del self.pifs[pif_uuid]
+        self.save_PIFs()
+
 
     def save(self):
         # save state
@@ -133,14 +170,16 @@ class XendNode:
                                    'name_description':self.desc}}
         self.state_store.save_state('host',host_record)
         self.state_store.save_state('cpu', self.cpus)
+        self.save_PIFs()
+        self.save_networks()
+
+        sr_record = {self.sr.uuid: self.sr.get_record()}
+        self.state_store.save_state('sr', sr_record)
+
+    def save_PIFs(self):
         pif_records = dict([(k, v.get_record(transient = False))
                             for k, v in self.pifs.items()])
         self.state_store.save_state('pif', pif_records)
-
-        self.save_networks()
-
-        sr_record = {self.sr.uuid: self.sr.get_record()}
-        self.state_store.save_state('sr', sr_record)
 
     def save_networks(self):
         net_records = dict([(k, v.get_record(transient = False))
@@ -326,7 +365,12 @@ class XendNode:
         return dict(self.physinfo())
     def info_dict(self):
         return dict(self.info())
-    
+
+
+    def refreshBridges(self):
+        for pif in self.pifs.values():
+            pif.refresh(Brctl.get_state())
+
 
 def instance():
     global inst
diff -r 069d1364af53 -r a8e853aecb3e tools/python/xen/xend/XendPIF.py
--- a/tools/python/xen/xend/XendPIF.py  Wed Dec 27 15:39:32 2006 +0000
+++ b/tools/python/xen/xend/XendPIF.py  Wed Dec 27 15:42:56 2006 +0000
@@ -15,16 +15,18 @@
 # Copyright (c) 2006 Xensource Inc.
 #============================================================================
 
+import commands
+import logging
 import os
-import commands
 import re
-import socket
 
-from xen.xend.XendRoot import instance as xendroot
-from xen.xend.XendLogging import log
 
-MAC_RE = ':'.join(['[0-9a-f]{2}'] * 6)
-IP_IFACE_RE = r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)'
+log = logging.getLogger("xend.XendPIF")
+log.setLevel(logging.TRACE)
+
+
+MAC_RE = re.compile(':'.join(['[0-9a-f]{2}'] * 6))
+IP_IFACE_RE = re.compile(r'^\d+: (\w+):.*mtu (\d+) .* link/\w+ ([0-9a-f:]+)')
 
 def linux_phy_to_virt(pif_name):
     return 'eth' + re.sub(r'^[a-z]+', '', pif_name)
@@ -40,7 +42,7 @@ def linux_get_phy_ifaces():
     @rtype: array of 3-element tuple (name, mtu, mac)
     """
     
-    ip_cmd = '/sbin/ip -o link show'
+    ip_cmd = 'ip -o link show'
     rc, output = commands.getstatusoutput(ip_cmd)
     ifaces = {}
     phy_ifaces = []
@@ -66,7 +68,7 @@ def linux_set_mac(iface, mac):
     if not re.search(MAC_RE, mac):
         return False
 
-    ip_mac_cmd = '/sbin/ip link set %s addr %s' % \
+    ip_mac_cmd = 'ip link set %s addr %s' % \
                  (linux_phy_to_virt(iface), mac)
     rc, output = commands.getstatusoutput(ip_mac_cmd)
     if rc == 0:
@@ -76,7 +78,7 @@ def linux_set_mac(iface, mac):
 
 def linux_set_mtu(iface, mtu):
     try:
-        ip_mtu_cmd = '/sbin/ip link set %s mtu %d' % \
+        ip_mtu_cmd = 'ip link set %s mtu %d' % \
                      (linux_phy_to_virt(iface), int(mtu))
         rc, output = commands.getstatusoutput(ip_mtu_cmd)
         if rc == 0:
@@ -84,17 +86,6 @@ def linux_set_mtu(iface, mtu):
         return False
     except ValueError:
         return False
-
-def same_dir_rename(old_path, new_path):
-    """Ensure that the old_path and new_path refer to files in the same
-    directory."""
-    old_abs = os.path.normpath(old_path)
-    new_abs = os.path.normpath(new_path)
-    if os.path.dirname(old_abs) == os.path.dirname(new_abs):
-        os.rename(old_abs, new_abs)
-    else:
-        log.warning("Unable to ensure name is new name is safe: %s" % new_abs)
-    
 
 class XendPIF:
     """Representation of a Physical Network Interface."""
@@ -140,3 +131,68 @@ class XendPIF:
             result['io_read_kbs'] = str(self.get_io_read_kbs())
             result['io_write_kbs'] = str(self.get_io_write_kbs())
         return result
+
+
+    def refresh(self, bridges):
+        ifname = self._ifname()
+        rc, _ = _cmd('ip link show %s', ifname)
+        if rc != 0:
+            # Interface does not exist.  If it's a physical interface, then
+            # there's nothing we can do -- this should have been set up with
+            # the network script.  Otherwise, we can use vconfig to derive
+            # a subinterface.
+            if not self.vlan:
+                return
+            
+            rc, _ = _cmd('vconfig add %s %s', self.name, self.vlan)
+            if rc != 0:
+                log.error('Could not refresh %s', ifname)
+                return
+            log.info('Created network interface %s', ifname)
+
+        for brname, nics in bridges.items():
+            if ifname in nics:
+                log.debug('%s is already attached to %s', ifname, brname)
+                return
+
+        # The interface is not attached to a bridge.  Create one, and attach
+        # the interface to it.
+        brname = _new_bridge_name(bridges)
+        rc, _ = _cmd('brctl addbr %s', brname)
+        if rc != 0:
+            log.error('Could not create bridge %s for interface %s', brname,
+                      ifname)
+            return
+        log.info('Created network bridge %s', brname)
+        
+        rc, _ = _cmd('brctl addif %s %s', brname, ifname)
+        if rc != 0:
+            log.error('Could not add %s to %s', ifname, brname)
+            return
+        log.info('Added network interface %s to bridge %s', ifname, brname)
+
+
+    def _ifname(self):
+        if self.vlan:
+            return '%s.%s' % (self.name, self.vlan)
+        else:
+            return self.name
+
+
+def _cmd(cmd, *args):
+    if len(args) > 0:
+        cmd = cmd % args
+    rc, output = commands.getstatusoutput(cmd)
+    if rc != 0:
+        log.debug('%s failed with code %d' % (cmd, rc))
+    log.trace('%s: %s' % (cmd, output))
+    return rc, output
+
+
+def _new_bridge_name(bridges):
+    n = 0
+    while True:
+        brname = 'xenbr%d' % n
+        if brname not in bridges:
+            return brname
+        n += 1
diff -r 069d1364af53 -r a8e853aecb3e tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Wed Dec 27 15:39:32 2006 +0000
+++ b/tools/python/xen/xend/server/SrvServer.py Wed Dec 27 15:42:56 2006 +0000
@@ -48,7 +48,7 @@ from threading import Thread
 
 from xen.web.httpserver import HttpServer, UnixHttpServer
 
-from xen.xend import XendRoot, XendAPI
+from xen.xend import XendNode, XendRoot, XendAPI
 from xen.xend import Vifctl
 from xen.xend.XendLogging import log
 from xen.xend.XendClient import XEN_API_SOCKET
@@ -100,6 +100,8 @@ class XendServers:
         signal.signal(signal.SIGHUP, self.reloadConfig)
 
         while True:
+            XendNode.instance().refreshBridges()
+
             threads = []
             for server in self.servers:
                 if server.ready:

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Added network.{create, destroy}, and PIF.{create, create_VLAN, destroy}, and, Xen patchbot-unstable <=