mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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>
This commit is contained in:
1 parent
4d4d14e8e8
commit
27db6136ea
5 files changed
+165
-4
No files matched your search
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||