aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/examples/Makefile8
-rw-r--r--tools/examples/xmexample.vmx.in (renamed from tools/examples/xmexample.vmx)6
-rw-r--r--tools/ioemu/target-i386-dm/Makefile2
-rw-r--r--tools/python/Makefile3
-rw-r--r--tools/python/pylintrc307
-rwxr-xr-xtools/python/xen/sv/DomInfo.py16
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py139
-rw-r--r--tools/python/xen/xend/XendVnet.py2
-rw-r--r--tools/python/xen/xend/scheduler.py6
-rwxr-xr-xtools/python/xen/xend/server/controller.py7
-rw-r--r--tools/xenstore/xenstore_client.c2
11 files changed, 388 insertions, 110 deletions
diff --git a/tools/examples/Makefile b/tools/examples/Makefile
index 36edb8789f..5bfa67fd9f 100644
--- a/tools/examples/Makefile
+++ b/tools/examples/Makefile
@@ -25,7 +25,7 @@ XEN_SCRIPTS += block-phy
XEN_SCRIPTS += block-file
XEN_SCRIPTS += block-enbd
-XEN_BOOT_DIR = /usr/lib/xen/boot
+XEN_BOOT_DIR = /usr/$(LIBDIR)/xen/boot
XEN_BOOT = mem-map.sxp
XEN_HOTPLUG_DIR = /etc/hotplug
@@ -37,12 +37,15 @@ build:
install: all install-initd install-configs install-scripts install-boot \
install-hotplug
+xmexample.vmx: xmexample.vmx.in
+ sed -e 's/@@LIBDIR@@/$(LIBDIR)/' < $< > $@
+
install-initd:
[ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
-install-configs:
+install-configs: $(XEN_CONFIGS)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR)/auto ] || \
@@ -77,3 +80,4 @@ install-hotplug:
done
clean:
+ $(RM) xmexample.vmx
diff --git a/tools/examples/xmexample.vmx b/tools/examples/xmexample.vmx.in
index 1c338beca4..c45a237033 100644
--- a/tools/examples/xmexample.vmx
+++ b/tools/examples/xmexample.vmx.in
@@ -8,7 +8,7 @@
#----------------------------------------------------------------------------
# Kernel image file.
-kernel = "/usr/lib/xen/boot/vmxloader"
+kernel = "/usr/@@LIBDIR@@/xen/boot/vmxloader"
# The domain build function. VMX domain uses 'vmx'.
builder='vmx'
@@ -48,10 +48,10 @@ disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
# New stuff
-device_model = '/usr/lib/xen/bin/qemu-dm'
+device_model = '/usr/@@LIBDIR@@/xen/bin/qemu-dm'
# Advanced users only. Don't touch if you don't know what you're doing
-memmap = '/usr/lib/xen/boot/mem-map.sxp'
+memmap = '/usr/@@LIBDIR@@/xen/boot/mem-map.sxp'
#-----------------------------------------------------------------------------
# Disk image for
diff --git a/tools/ioemu/target-i386-dm/Makefile b/tools/ioemu/target-i386-dm/Makefile
index 67dcb2e99e..856be8fe87 100644
--- a/tools/ioemu/target-i386-dm/Makefile
+++ b/tools/ioemu/target-i386-dm/Makefile
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
include config.mak
override TARGET_ARCH=i386
-INSTALL_DIR := $(DESTDIR)/usr/lib/xen/bin
+INSTALL_DIR := $(DESTDIR)/usr/$(LIBDIR)/xen/bin
TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH) -I$(XEN_ROOT)/xen/include/public
diff --git a/tools/python/Makefile b/tools/python/Makefile
index a676cdf0e9..ea8040d512 100644
--- a/tools/python/Makefile
+++ b/tools/python/Makefile
@@ -1,7 +1,8 @@
-
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk
+.PHONY: all build install clean
+
all: build
build:
CFLAGS="$(CFLAGS)" python setup.py build
diff --git a/tools/python/pylintrc b/tools/python/pylintrc
new file mode 100644
index 0000000000..7d207d1b95
--- /dev/null
+++ b/tools/python/pylintrc
@@ -0,0 +1,307 @@
+# lint Python modules using external checkers.
+#
+# This is the main checker controling the other ones and the reports
+# generation. It is itself both a raw checker and an astng checker in order
+# to:
+# * handle message activation / deactivation at the module level
+# * handle some basic but necessary stats'data (number of classes, methods...)
+#
+# This checker also defines the following reports:
+# * R0001: Total errors / warnings
+# * R0002: % errors / warnings by module
+# * R0003: Messages
+# * R0004: Global evaluation
+#
+[MASTER]
+# Add <file or directory> to the black list. It should be a base name, not a
+# path. You may set this option multiple times.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Set the cache size for astng objects.
+cache-size=500
+
+
+
+[REPORTS]
+# Tells wether to display a full report or only the messages
+reports=yes
+
+# Use HTML as output format instead of text
+html=no
+
+# Use a parseable text output format, so your favorite text editor will be able
+# to jump to the line corresponding to a message.
+parseable=no
+
+# Colorizes text output using ansi escape codes
+color=no
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note).You have access to the variables errors warning, statement which
+# respectivly contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (R0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (R0004).
+comment=no
+
+# Include message's id in output
+include-ids=yes
+
+
+
+# checks for
+# * unused variables / imports
+# * undefined variables
+# * redefinition of variable from builtins or from an outer scope
+# * use of variable before assigment
+#
+[VARIABLES]
+# Enable / disable this checker
+enable-variables=yes
+
+# Tells wether we should check for unused import in __init__ files.
+init-import=no
+
+# List of variable names used for dummy variables (i.e. not used).
+dummy-variables=_,dummy
+
+
+
+# checks for :
+# * doc strings
+# * modules / classes / functions / methods / arguments / variables name
+# * number of arguments, local variables, branchs, returns and statements in
+# functions, methods
+# * required module attributes
+# * dangerous default values as arguments
+# * redefinition of function / method / class
+# * uses of the global statement
+#
+# This checker also defines the following reports:
+# * R0101: Statistics by type
+#
+[BASIC]
+# Enable / disable this checker
+enable-basic=yes
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=.*
+
+# Minimal length for module / class / function / method / argument / variable
+# names
+min-name-length=1
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+
+
+# checks for sign of poor/misdesign:
+# * number of methods, attributes, local variables...
+# * size, complexity of functions, methods
+#
+[DESIGN]
+# Enable / disable this checker
+enable-design=yes
+
+# Maximum number of arguments for function / method
+max-args=15
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+
+# checks for :
+# * methods without self as first argument
+# * overriden methods signature
+# * access only to existant members via self
+# * attributes not defined in the __init__ method
+# * supported interfaces implementation
+# * unreachable code
+#
+[CLASSES]
+# Enable / disable this checker
+enable-classes=yes
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# Tells wether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+
+
+# checks for
+# * external modules dependencies
+# * relative / wildcard imports
+# * cyclic imports
+# * uses of deprecated modules
+#
+# This checker also defines the following reports:
+# * R0401: External dependencies
+# * R0402: Modules dependencies graph
+#
+[IMPORTS]
+# Enable / disable this checker
+enable-imports=no
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the given
+# file (report R0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report R0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report R0402 must
+# not be disabled)
+int-import-graph=
+
+
+
+# checks for
+# * excepts without exception filter
+# * string exceptions
+#
+[EXCEPTIONS]
+# Enable / disable this checker
+enable-exceptions=yes
+
+
+
+# checks for :
+# * unauthorized constructions
+# * strict indentation
+# * line length
+# * use of <> instead of !=
+#
+[FORMAT]
+# Enable / disable this checker
+enable-format=no
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 tab).
+indent-string=' '
+
+
+
+# does not check anything but gives some raw metrics :
+# * total number of lines
+# * total number of code lines
+# * total number of docstring lines
+# * total number of comments lines
+# * total number of empty lines
+#
+# This checker also defines the following reports:
+# * R0701: Raw metrics
+#
+[METRICS]
+# Enable / disable this checker
+enable-metrics=yes
+
+
+
+# checks for:
+# * warning notes in the code like FIXME, XXX
+# * PEP 263: source code with non ascii character but no encoding declaration
+#
+[MISCELLANEOUS]
+# Enable / disable this checker
+enable-miscellaneous=yes
+
+# List of note tags to take in consideration, separated by a comma. Default to
+# FIXME, XXX, TODO
+notes=FIXME,XXX,TODO
+
+
+
+# checks for similarities and duplicated code. This computation may be
+# memory / CPU intensive, so you should disable it if you experiments some
+# problems.
+#
+# This checker also defines the following reports:
+# * R0801: Duplication
+#
+[SIMILARITIES]
+# Enable / disable this checker
+enable-similarities=yes
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+
+
diff --git a/tools/python/xen/sv/DomInfo.py b/tools/python/xen/sv/DomInfo.py
index 0f7a8ab486..12135cd4fb 100755
--- a/tools/python/xen/sv/DomInfo.py
+++ b/tools/python/xen/sv/DomInfo.py
@@ -75,7 +75,7 @@ class DomGeneralTab( CompositeTab ):
class DomGenTab( GeneralTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
titles = {}
@@ -103,7 +103,7 @@ class DomGenTab( GeneralTab ):
class DomSXPTab( PreTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
self.dom = 0
PreTab.__init__( self, "" )
@@ -126,7 +126,7 @@ class DomSXPTab( PreTab ):
class DomActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "shutdown" : "Shutdown",
"reboot" : "Reboot",
"pause" : "Pause",
@@ -188,19 +188,19 @@ class DomDeviceListTab( NullTab ):
title = "Device List"
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
pass
class DomDeviceOptionsTab( NullTab ):
title = "Device Options"
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
pass
class DomDeviceActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
ActionTab.__init__( self, { "addvcpu" : "Add VCPU", "addvbd" : "Add VBD", "addvif" : "Add VIF" } )
class DomMigrateTab( CompositeTab ):
@@ -218,7 +218,7 @@ class DomMigrateExtraTab( Sheet ):
class DomMigrateActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "migrate" : "Migrate" }
ActionTab.__init__( self, actions )
@@ -249,7 +249,7 @@ class DomSaveExtraTab( Sheet ):
class DomSaveActionTab( ActionTab ):
- def __init__( self, urlWriter ):
+ def __init__( self, _ ):
actions = { "save" : "Save" }
ActionTab.__init__( self, actions )
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index 8209ef9588..7251239bad 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -103,34 +103,6 @@ def shutdown_reason(code):
"""
return shutdown_reasons.get(code, "?")
-config_handlers = {}
-
-def add_config_handler(name, h):
- """Add a handler for a config field.
-
- @param name: field name
- @param h: handler: fn(vm, config, field, index)
- """
- config_handlers[name] = h
-
-def get_config_handler(name):
- """Get a handler for a config field.
-
- returns handler or None
- """
- return config_handlers.get(name)
-
-"""Table of handlers for devices.
-Indexed by device type.
-"""
-device_handlers = {}
-
-def add_device_handler(name, type):
- device_handlers[name] = type
-
-def get_device_handler(name):
- return device_handlers[name]
-
def dom_get(dom):
"""Get info from xen for an existing domain.
@@ -382,12 +354,6 @@ class XendDomainInfo:
__repr__ = __str__
- def getDeviceTypes(self):
- return self.controllers.keys()
-
- def getDeviceControllers(self):
- return self.controllers.values()
-
def getDeviceController(self, type, error=True):
ctrl = self.controllers.get(type)
if not ctrl and error:
@@ -596,7 +562,7 @@ class XendDomainInfo:
def sxpr_devices(self):
sxpr = []
- for ty in self.getDeviceTypes():
+ for ty in self.controllers.keys():
devs = self.getDeviceSxprs(ty)
sxpr += devs
if sxpr:
@@ -787,7 +753,7 @@ class XendDomainInfo:
"""Release all vm devices.
"""
reboot = self.restart_pending()
- for ctrl in self.getDeviceControllers():
+ for ctrl in self.controllers.values():
if ctrl.isDestroyed(): continue
ctrl.destroyController(reboot=reboot)
t = xstransact("%s/device" % self.path)
@@ -845,6 +811,7 @@ class XendDomainInfo:
self.store_channel = self.eventChannel("store/port")
self.console_channel = self.eventChannel("console/port")
+
def create_configured_devices(self):
devices = sxp.children(self.config, 'device')
for d in devices:
@@ -852,18 +819,20 @@ class XendDomainInfo:
if dev_config is None:
raise VmError('invalid device')
dev_type = sxp.name(dev_config)
- ctrl_type = get_device_handler(dev_type)
- if ctrl_type is None:
+
+ if not controller.isDevControllerClass(dev_type):
raise VmError('unknown device type: ' + dev_type)
- self.createDevice(ctrl_type, dev_config)
-
+
+ self.createDevice(dev_type, dev_config)
+
+
def create_devices(self):
"""Create the devices for a vm.
@raise: VmError for invalid devices
"""
if self.rebooting():
- for ctrl in self.getDeviceControllers():
+ for ctrl in self.controllers.values():
ctrl.initController(reboot=True)
else:
self.create_configured_devices()
@@ -1014,7 +983,7 @@ class XendDomainInfo:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
- config = sxp.merge(['vm', blconfig ], self.config)
+ config = sxp.merge(['vm', blcfg ], self.config)
return config
def configure_backends(self):
@@ -1063,7 +1032,7 @@ class XendDomainInfo:
for field in sxp.children(self.config):
field_name = sxp.name(field)
field_index = index.get(field_name, 0)
- field_handler = get_config_handler(field_name)
+ field_handler = config_handlers.get(field_name)
# Ignore unknown fields. Warn?
if field_handler:
v = field_handler(self, self.config, field, field_index)
@@ -1133,23 +1102,17 @@ class XendDomainInfo:
# get run-time value of vcpus and update store
self.exportVCPUSToDB(dom_get(self.id)['vcpus'])
-def vm_field_ignore(vm, config, val, index):
- """Dummy config field handler used for fields with built-in handling.
- @param vm: virtual machine
- @param config: vm config
- @param val: config field
- @param index: field index
+def vm_field_ignore(_, _1, _2, _3):
+ """Dummy config field handler used for fields with built-in handling.
+ Matches the signature required by config_handlers.
"""
pass
-def vm_field_maxmem(vm, config, val, index):
- """Configure vm memory limit.
- @param vm: virtual machine
- @param config: vm config
- @param val: config field
- @param index: field index
+def vm_field_maxmem(vm, _1, val, _2):
+ """Config field handler to configure vm memory limit. Matches the
+ signature required by config_handlers.
"""
maxmem = sxp.child0(val)
if maxmem is None:
@@ -1160,8 +1123,10 @@ def vm_field_maxmem(vm, config, val, index):
raise VmError("invalid maxmem: " + str(maxmem))
xc.domain_setmaxmem(vm.id, maxmem_kb = maxmem * 1024)
+
#============================================================================
# Register image handlers.
+
from image import \
addImageHandlerClass, \
ImageHandler, \
@@ -1171,43 +1136,37 @@ from image import \
addImageHandlerClass(LinuxImageHandler)
addImageHandlerClass(VmxImageHandler)
-# Ignore the fields we already handle.
-add_config_handler('name', vm_field_ignore)
-add_config_handler('memory', vm_field_ignore)
-add_config_handler('ssidref', vm_field_ignore)
-add_config_handler('cpu', vm_field_ignore)
-add_config_handler('cpu_weight', vm_field_ignore)
-add_config_handler('restart', vm_field_ignore)
-add_config_handler('image', vm_field_ignore)
-add_config_handler('device', vm_field_ignore)
-add_config_handler('backend', vm_field_ignore)
-add_config_handler('vcpus', vm_field_ignore)
-add_config_handler('bootloader', vm_field_ignore)
-
-# Register other config handlers.
-add_config_handler('maxmem', vm_field_maxmem)
-
-#============================================================================
-# Register device controllers and their device config types.
-
-from server import blkif
-controller.addDevControllerClass("vbd", blkif.BlkifController)
-add_device_handler("vbd", "vbd")
-from server import netif
-controller.addDevControllerClass("vif", netif.NetifController)
-add_device_handler("vif", "vif")
+"""Table of handlers for field configuration.
-from server import tpmif
-controller.addDevControllerClass("vtpm", tpmif.TPMifController)
-add_device_handler("vtpm", "vtpm")
-
-from server import pciif
-controller.addDevControllerClass("pci", pciif.PciController)
-add_device_handler("pci", "pci")
+field_name[String]: fn(vm, config, field, index) -> value(ignored)
+"""
+config_handlers = {
+
+ # Ignore the fields we already handle.
+
+ 'name': vm_field_ignore,
+ 'memory': vm_field_ignore,
+ 'ssidref': vm_field_ignore,
+ 'cpu': vm_field_ignore,
+ 'cpu_weight': vm_field_ignore,
+ 'restart': vm_field_ignore,
+ 'image': vm_field_ignore,
+ 'device': vm_field_ignore,
+ 'backend': vm_field_ignore,
+ 'vcpus': vm_field_ignore,
+ 'bootloader': vm_field_ignore,
+
+ # Register other config handlers.
+ 'maxmem': vm_field_maxmem
+ }
-from xen.xend.server import usbif
-controller.addDevControllerClass("usb", usbif.UsbifController)
-add_device_handler("usb", "usb")
#============================================================================
+# Register device controllers and their device config types.
+
+controller.addDevControllerClass("vbd", server.blkif.BlkifController)
+controller.addDevControllerClass("vif", server.netif.NetifController)
+controller.addDevControllerClass("vtpm", server.tpmif.TPMifController)
+controller.addDevControllerClass("pci", server.pciif.PciController)
+controller.addDevControllerClass("usb", server.usbif.UsbifController)
diff --git a/tools/python/xen/xend/XendVnet.py b/tools/python/xen/xend/XendVnet.py
index 5ed7ee1d64..2308e391ee 100644
--- a/tools/python/xen/xend/XendVnet.py
+++ b/tools/python/xen/xend/XendVnet.py
@@ -145,7 +145,7 @@ class XendVnet:
def vnet_get(self, id):
"""Get a vnet.
- @param id: vnet id
+ @param id vnet id
"""
id = str(id)
return self.vnet.get(id)
diff --git a/tools/python/xen/xend/scheduler.py b/tools/python/xen/xend/scheduler.py
index a99dc007b7..dc44765522 100644
--- a/tools/python/xen/xend/scheduler.py
+++ b/tools/python/xen/xend/scheduler.py
@@ -20,8 +20,8 @@ import threading
def later(delay, fn, args=(), kwargs={}):
"""Schedule a function to be called later.
- @param _delay: delay in seconds
- @param _fn: function
+ @param delay: delay in seconds
+ @param fn: function
@param args: arguments (list)
@param kwargs keyword arguments (map)
"""
@@ -32,7 +32,7 @@ def later(delay, fn, args=(), kwargs={}):
def now(fn, args=(), kwargs={}):
"""Schedule a function to be called now.
- @param _fn: function
+ @param fn: function
@param args: arguments (list)
@param kwargs keyword arguments (map)
"""
diff --git a/tools/python/xen/xend/server/controller.py b/tools/python/xen/xend/server/controller.py
index ab531789d8..5a4f67cd5a 100755
--- a/tools/python/xen/xend/server/controller.py
+++ b/tools/python/xen/xend/server/controller.py
@@ -63,6 +63,13 @@ def addDevControllerClass(name, cls):
cls.type = name
getDevControllerTable().addDevControllerClass(cls)
+
+def isDevControllerClass(name):
+ """@return True if a device controller class has been registered with
+ the controller table under the given name."""
+ return name in getDevControllerTable().controllerClasses
+
+
def createDevController(name, vm, recreate=False):
return getDevControllerTable().createDevController(name, vm, recreate=recreate)
diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c
index 50a774d296..079d988871 100644
--- a/tools/xenstore/xenstore_client.c
+++ b/tools/xenstore/xenstore_client.c
@@ -76,7 +76,7 @@ main(int argc, char **argv)
/* NOTREACHED */
}
#if defined(CLIENT_write)
- if ((argc - optind) % 1) {
+ if ((argc - optind) % 2 == 1) {
usage(argv[0]);
/* NOTREACHED */
}