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

[Xen-devel] [PATCH 4/5] Accept udev events and update physical resource information



This is the main part of the patch series.
When a udev event is received, udevevent.py parses the udev data and tells
XendNode.py to update the physical resource information.
This patch also add a boolean parameter 'xend-udev-event-server', to let users
indicate whether we should enable this function or not. 

Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@xxxxxxxxxxxxx>

------

diff -r c30742011bb8 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Thu Mar 12 18:48:09 2009 +0000
+++ b/tools/examples/xend-config.sxp    Fri Mar 13 16:38:17 2009 +0900
@@ -64,6 +64,7 @@
 #(xend-relocation-server no)
 (xend-relocation-server yes)
 #(xend-relocation-ssl-server no)
+#(xend-udev-event-server no)
 
 #(xend-unix-path /var/lib/xend/xend-socket)
 
diff -r c30742011bb8 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Thu Mar 12 18:48:09 2009 +0000
+++ b/tools/python/xen/xend/XendNode.py Fri Mar 13 16:38:17 2009 +0900
@@ -146,6 +146,18 @@
 
         self.srs = {}
 
+        self._init_networks()
+        self._init_PIFs()
+
+        self._init_SRs()
+        self._init_PBDs()
+       
+        self._init_PPCIs()
+
+        self._init_PSCSIs()
+
+
+    def _init_networks(self):
         # Initialise networks
         # First configure ones off disk
         saved_networks = self.state_store.load_state('network')
@@ -179,6 +191,7 @@
             if unconfigured_bridge != 'tmpbridge':
                 XendNetwork.create_phy(unconfigured_bridge)
 
+    def _init_PIFs(self):
         # Initialise PIFs
         # First configure ones off disk
         saved_pifs = self.state_store.load_state('pif')
@@ -221,7 +234,8 @@
                     log.debug("Cannot find network for bridge %s "
                               "when configuring PIF %s",
                               (bridge_name, name))     
-        
+
+    def _init_SRs(self):
         # initialise storage
         saved_srs = self.state_store.load_state('sr')
         if saved_srs:
@@ -240,6 +254,7 @@
             qcow_sr_uuid = uuid.createString()
             self.srs[qcow_sr_uuid] = XendQCoWStorageRepo(qcow_sr_uuid)
 
+    def _init_PBDs(self):
         saved_pbds = self.state_store.load_state('pbd')
         if saved_pbds:
             for pbd_uuid, pbd_cfg in saved_pbds.items():
@@ -247,8 +262,8 @@
                     XendPBD.recreate(pbd_uuid, pbd_cfg)
                 except CreateUnspecifiedAttributeError:
                     log.warn("Error recreating PBD %s", pbd_uuid) 
-
-
+ 
+    def _init_PPCIs(self):
         # Initialise PPCIs
         saved_ppcis = self.state_store.load_state('ppci')
         saved_ppci_table = {}
@@ -282,7 +297,7 @@
             ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString())
             XendPPCI(ppci_uuid, ppci_record)
 
-
+    def _init_PSCSIs(self):
         # Initialise PSCSIs
         saved_pscsis = self.state_store.load_state('pscsi')
         saved_pscsi_table = {}
@@ -299,6 +314,75 @@
                 pscsi_uuid = saved_pscsi_table.get(pscsi_record['scsi_id'],
                                                    uuid.createString())
                 XendPSCSI(pscsi_uuid, pscsi_record)
+
+
+    def add_network(self, interface):
+        # TODO
+        log.debug("add_network(): Not implemented.")
+
+
+    def remove_network(self, interface):
+        # TODO
+        log.debug("remove_network(): Not implemented.")
+
+
+    def add_PPCI(self, pci_name):
+        # Update lspci info
+        PciUtil.create_lspci_info()
+
+        # Initialise the PPCI
+        saved_ppcis = self.state_store.load_state('ppci')
+        saved_ppci_table = {}
+        if saved_ppcis:
+            for ppci_uuid, ppci_record in saved_ppcis.items():
+                try:
+                    saved_ppci_table[ppci_record['name']] = ppci_uuid
+                except KeyError:
+                    pass
+
+        (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
+        pci_dev = PciUtil.PciDevice(domain, bus, slot, func)
+        ppci_record = {
+            'domain':                   pci_dev.domain,
+            'bus':                      pci_dev.bus,
+            'slot':                     pci_dev.slot,
+            'func':                     pci_dev.func,
+            'vendor_id':                pci_dev.vendor,
+            'vendor_name':              pci_dev.vendorname,
+            'device_id':                pci_dev.device,
+            'device_name':              pci_dev.devicename,
+            'revision_id':              pci_dev.revision,
+            'class_code':               pci_dev.classcode,
+            'class_name':               pci_dev.classname,
+            'subsystem_vendor_id':      pci_dev.subvendor,
+            'subsystem_vendor_name':    pci_dev.subvendorname,
+            'subsystem_id':             pci_dev.subdevice,
+            'subsystem_name':           pci_dev.subdevicename,
+            'driver':                   pci_dev.driver
+            }
+        # If saved uuid exists, use it. Otherwise create one.
+        ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString())
+        XendPPCI(ppci_uuid, ppci_record)
+
+
+    def remove_PPCI(self, pci_name):
+        # Update lspci info
+        PciUtil.create_lspci_info()
+
+        # Remove the PPCI
+        (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
+        ppci_ref = XendPPCI.get_by_sbdf(domain, bus, slot, func)
+        XendAPIStore.get(ppci_ref, "PPCI").destroy()
+
+
+    def add_PSCSI(self):
+        # TODO
+        log.debug("add_network(): Not implemented.")
+
+
+    def remove_PSCSI(self):
+        # TODO
+        log.debug("add_network(): Not implemented.")
 
 
 ##    def network_destroy(self, net_uuid):
diff -r c30742011bb8 tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py      Thu Mar 12 18:48:09 2009 +0000
+++ b/tools/python/xen/xend/XendOptions.py      Fri Mar 13 16:38:17 2009 +0900
@@ -75,6 +75,9 @@
     """Default for the flag indicating whether xend should run a ssl 
relocation server."""
     xend_relocation_ssl_server_default = 'no'
 
+    """Default for the flag indicating whether xend should run a udev event 
server."""
+    xend_udev_event_server_default = 'no'
+
     """Default interface address the xend relocation server listens at. """
     xend_relocation_address_default = ''
 
@@ -215,6 +218,10 @@
 
     def get_xend_relocation_server_ssl_cert_file(self):
         return self.get_config_string("xend-relocation-server-ssl-cert-file")
+
+    def get_xend_udev_event_server(self):
+        return self.get_config_bool("xend-udev-event-server",
+                                    self.xend_udev_event_server_default)
 
     def get_xend_port(self):
         """Get the port xend listens at for its HTTP interface.
diff -r c30742011bb8 tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Thu Mar 12 18:48:09 2009 +0000
+++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 13 16:38:17 2009 +0900
@@ -24,6 +24,7 @@
 from xen.util import mkdir
 
 import relocate
+import udevevent
 import SrvServer
 from params import *
 
@@ -336,6 +337,7 @@
             del xc
 
             relocate.listenRelocation()
+            udevevent.listenUdevEvent()
             servers = SrvServer.create()
             servers.start(status)
             del servers
diff -r c30742011bb8 tools/python/xen/xend/server/udevevent.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/server/udevevent.py Fri Mar 13 16:38:17 2009 +0900
@@ -0,0 +1,68 @@
+import socket
+
+from xen.web import protocol, unix
+
+from xen.xend.XendLogging import log
+from xen.xend import XendNode
+from xen.xend import XendOptions
+
+UDEV_EVENT_PATH = '\0/org/xen/xend/udev_event'
+
+class UdevEventProtocol(protocol.Protocol):
+
+    def __init__(self):
+        protocol.Protocol.__init__(self)
+
+    def dataReceived(self, data):
+        udev_event = {}
+        for entry in data.split('\0'):
+            try:
+                opt, val = entry.split("=")
+                udev_event[opt] = val
+            except (TypeError, ValueError):
+                pass
+        if udev_event.get('ACTION', None) is None:
+            log.warn("Invalid udev event received")
+            return
+
+        log.debug("udev event received: %s", udev_event)
+
+        self._process_event(udev_event)
+
+    def _process_event(self, udev_event):
+        try:
+            if (udev_event.get('SUBSYSTEM', None) == 'pci'):
+                pci_name = udev_event.get('PCI_SLOT_NAME', None)
+                if (udev_event['ACTION'] == 'add'):
+                    log.info("Adding pci device %s", pci_name)
+                    XendNode.instance().add_PPCI(pci_name)
+                elif (udev_event['ACTION'] == 'remove'):
+                    log.info("Removing pci device %s", pci_name)
+                    XendNode.instance().remove_PPCI(pci_name)
+
+            elif (udev_event.get('SUBSYSTEMS', None) == 'scsi'):
+                if (udev_event['ACTION'] == 'add'):
+                    log.info("Adding scsi device")
+                    XendNode.instance().add_PSCSI()
+                elif (udev_event['ACTION'] == 'remove'):
+                    log.info("Removing scci device")
+                    XendNode.instance().remove_PSCSI()
+
+            elif (udev_event.get('SUBSYSTEM', None) == 'net'):
+                interface = udev_event.get('INTERFACE', None)
+                if (udev_event['ACTION'] == 'add'):
+                    log.info("Adding net device %s", interface)
+                    XendNode.instance().add_network(interface)
+                elif (udev_event['ACTION'] == 'remove'):
+                    log.info("Removing net device %s", interface)
+                    XendNode.instance().remove_network(interface)
+            
+        except Exception, e:
+            log.warn("error while processing udev event(): %s" % str(e))
+
+
+def listenUdevEvent():
+    xoptions = XendOptions.instance()
+    if xoptions.get_xend_udev_event_server():
+        unix.UnixDgramListener(UDEV_EVENT_PATH, UdevEventProtocol)
+




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


 


Rackspace

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