diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-17 10:40:47 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-17 10:40:47 +0000 |
commit | 27db6136ea3b03d8711a7901a437b1f76030c9d9 (patch) | |
tree | 89771cff374bb520fd302caf0e0dc2ed2c77c8ab | |
parent | 4d4d14e8e841d1d65b4399b07ad83f8cdc441347 (diff) | |
download | xen-27db6136ea3b03d8711a7901a437b1f76030c9d9.tar.gz xen-27db6136ea3b03d8711a7901a437b1f76030c9d9.tar.bz2 xen-27db6136ea3b03d8711a7901a437b1f76030c9d9.zip |
xend: Accept udev events and update physical resource information
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@ab.jp.nec.com>
-rw-r--r-- | tools/examples/xend-config.sxp | 1 | ||||
-rw-r--r-- | tools/python/xen/xend/XendNode.py | 91 | ||||
-rw-r--r-- | tools/python/xen/xend/XendOptions.py | 7 | ||||
-rw-r--r-- | tools/python/xen/xend/server/SrvDaemon.py | 2 | ||||
-rw-r--r-- | tools/python/xen/xend/server/udevevent.py | 68 |
5 files changed, 165 insertions, 4 deletions
diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 5465c39af3..7ca270661a 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -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 --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 85773032bb..61779fa77e 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -146,6 +146,18 @@ class XendNode: 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 @@ class XendNode: 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 @@ class XendNode: 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 @@ class XendNode: 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(): @@ -248,8 +263,7 @@ class XendNode: except CreateUnspecifiedAttributeError: log.warn("Error recreating PBD %s", pbd_uuid) - - # Initialise PPCIs + def _init_PPCIs(self): saved_ppcis = self.state_store.load_state('ppci') saved_ppci_table = {} if saved_ppcis: @@ -282,7 +296,7 @@ class XendNode: 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 = {} @@ -301,6 +315,75 @@ class XendNode: 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): ## del self.networks[net_uuid] ## self.save_networks() diff --git a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py index 350f20736c..b507f9b3b7 100644 --- a/tools/python/xen/xend/XendOptions.py +++ b/tools/python/xen/xend/XendOptions.py @@ -75,6 +75,9 @@ class XendOptions: """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 = '' @@ -216,6 +219,10 @@ class XendOptions: 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 --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 225b901168..0a330f15b0 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -24,6 +24,7 @@ from xen.xend import osdep from xen.util import mkdir import relocate +import udevevent import SrvServer from params import * @@ -336,6 +337,7 @@ class Daemon: del xc relocate.listenRelocation() + udevevent.listenUdevEvent() servers = SrvServer.create() servers.start(status) del servers diff --git a/tools/python/xen/xend/server/udevevent.py b/tools/python/xen/xend/server/udevevent.py new file mode 100644 index 0000000000..b7ce26f917 --- /dev/null +++ b/tools/python/xen/xend/server/udevevent.py @@ -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) + |