Re: [Libvirt-cim] [PATCH] /dev/null should not be passed as source dev for cdrom device.
by Chip Vincent
For some reason this patch did not get forwarded to my email.
+1 and pushed, but I'd like to see a follow-on patch that removes
the need to strip the '/dev/null' before generating the XML. That is,
I think we need the code to simply handle a dev->source == NULL rather
than keep the 'null placeholder.'
--
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent(a)linux.vnet.ibm.com
12 years, 10 months
[PATCH] [TEST] Fix syntax errors, small tweaks
by Eduardo Lima (Etrunko)
suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py | 6 +++---
suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py | 2 +-
suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py | 8 +++++++-
suites/libvirt-cim/main.py | 2 +-
4 files changed, 12 insertions(+), 6 deletions(-)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1317410876 10800
# Node ID d8ac04bdc4806aecd1e5f28636a09ce501e36639
# Parent d9741a8b5eb7ccebf21d69f3cde72729bb60ad22
[TEST] Fix syntax errors, small tweaks
suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py:
- Unecessary virt param
suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py:
- Undefined symbols XFAIL, SKIP
suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py:
- Check for None return when ejecting media
suites/libvirt-cim/main.py
- options referenced in except block without being defined
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
@@ -47,7 +47,7 @@
new_int += 1
new_mac2 = "11:%s:22:%s:33:%s" % (new_int, new_int, new_int)
-def cleanup_env(ip, virt, cxml):
+def cleanup_env(ip, cxml):
cxml.destroy(ip)
cxml.undefine(ip)
@@ -82,13 +82,13 @@
ret = cxml.cim_define(options.ip)
if not ret:
logger.error("Failed to define the dom: %s", default_dom)
- cleanup_env(options.ip, options.virt, cxml)
+ cleanup_env(options.ip, cxml)
return FAIL
if case == "start":
ret = cxml.start(options.ip)
if not ret:
logger.error("Failed to start the dom: %s", default_dom)
- cleanup_env(options.ip, options.virt, cxml)
+ cleanup_env(options.ip, cxml)
return FAIL
status = vsms_util.mod_vcpu_res(options.ip, service, cxml, pasd, ncpu,
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
@@ -28,7 +28,7 @@
import sys
import pywbem
-from CimTest.ReturnCodes import PASS, FAIL
+from CimTest.ReturnCodes import PASS, FAIL, XFAIL, SKIP
from CimTest.Globals import logger, CIM_USER, CIM_PASS, CIM_NS
from XenKvmLib.const import do_main
from XenKvmLib.classes import get_typed_class
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
@@ -105,8 +105,12 @@
return None
inst = cim.GetInstance(ret[1]["ResultingResourceSettings"][0])
+
+ if not inst:
+ logger.error("Unable to get CDROM device instance after ModifyResourceSettings")
+ return None
+
new_addr = inst["Address"]
-
if new_addr != addr:
logger.error("New media '%s' does not match expected '%s'", new_addr, addr)
return None
@@ -204,6 +208,8 @@
# Need to eject first?
if media and old_media:
inst = modify_media(cim, inst, "")
+ if not inst:
+ return FAIL
media_path = os.path.join(_image_dir, media)
inst = modify_media(cim, inst, media_path)
diff --git a/suites/libvirt-cim/main.py b/suites/libvirt-cim/main.py
--- a/suites/libvirt-cim/main.py
+++ b/suites/libvirt-cim/main.py
@@ -306,8 +306,8 @@
if __name__ == '__main__':
ret = -1
+ options, args = parser.parse_args()
try:
- options, args = parser.parse_args()
ret = main(options, args)
except (KeyboardInterrupt, SystemExit):
print "\nKeyboardInterrupt. Cleaning up..."
12 years, 10 months
[PATCH] /dev/null should not be passed as source dev for cdrom device.
by Sharad Mishra
/dev/null should not be passed as source dev for cdrom device.
This patch verifies that source dev only has non null and
non /dev/null values for cdrom device.
Signed-off-by: Sharad Mishra <snmishra(a)us.ibm.com>
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index 343dc9e..ee20895 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -65,10 +65,12 @@ static char *disk_block_xml(xmlNodePtr root, struct
disk_device *dev)
xmlNewProp(tmp, BAD_CAST "cache", BAD_CAST dev->
cache);
}
- tmp = xmlNewChild(disk, NULL, BAD_CAST "source", NULL);
- if (tmp == NULL)
- return XML_ERROR;
- xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->source);
+ if ((dev->source != NULL) && (!XSTREQ(dev->source, "/dev/null")))
{
+ tmp = xmlNewChild(disk, NULL, BAD_CAST "source", NULL);
+ if (tmp == NULL)
+ return XML_ERROR;
+ xmlNewProp(tmp, BAD_CAST "dev", BAD_CAST dev->source);
+ }
tmp = xmlNewChild(disk, NULL, BAD_CAST "target", NULL);
if (tmp == NULL)
12 years, 10 months
[PATCH] <Incomplete> SROV support in libvirt-cim
by Sharad Mishra
> # HG changeset patch
> # User Sharad Mishra <snmishra(a)us.ibm.com>
> # Date 1318954618 25200
> # Node ID d07f99a0279030e62046bbdc3ac378f9dc6473af
> # Parent fb09136deb494008eb3aacee420ad74da7d7c294
> <Incomplete> SROV support in libvirt-cim
>
> This patch is the patch to add SRIOV support in libvirt-cim.
> This patch is not complete. Work on it was halted since the
> exploiter of this feature is not ready to consume it. And there
> are other features that need to be added which are in demand in
> near future.
>
> SRIOV support adds Enumeration of node devices to see what is
> available. Then it adds Virtual Functions (VFs), removes VFs and
> modifies VFs. It also adds support to detach a node. This link
> shows the steps -
>
> http://docs.fedoraproject.org/en-US/Fedora/13/html/
> Virtualization_Guide/sect-Para-virtualized_Windows_Drivers_Guide-
> How_SR_IOV_Libvirt_Works.html
>
> Step 6 above is for enum node devices.
> Step 8 is detach VF.
> Step 9 is add VF to guest.
> Similar to step 9 will be removeVF and modifyVF.
>
> So far, we have "sorta" implemented enum node device.
>
> Signed-off-by: Sharad Mishra <snmishra(a)us.ibm.com>
>
> diff -r fb09136deb49 -r d07f99a02790 Makefile.am
> --- a/Makefile.am Tue Aug 30 08:48:36 2011 -0700
> +++ b/Makefile.am Tue Oct 18 09:16:58 2011 -0700
> @@ -29,6 +29,7 @@
> schema/ComputerSystemIndication.mof \
> schema/ResourceAllocationSettingDataIndication.mof \
> schema/SwitchService.mof \
> + schema/VirtualSystemPCIDevice.mof \
> schema/ComputerSystemMigrationIndication.mof \
> schema/Virt_ResourceAllocationSettingData.mof \
> schema/ResourceAllocationSettingData.mof \
> @@ -116,6 +117,7 @@
> schema/ComputerSystemIndication.registration \
> schema/ResourceAllocationSettingDataIndication.registration \
> schema/SwitchService.registration \
> + schema/VirtualSystemPCIDevice.registration \
> schema/ComputerSystemMigrationIndication.registration \
> schema/ResourceAllocationSettingData.registration \
> schema/ResourcePoolConfigurationService.registration \
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/Makefile.am
> --- a/libxkutil/Makefile.am Tue Aug 30 08:48:36 2011 -0700
> +++ b/libxkutil/Makefile.am Tue Oct 18 09:16:58 2011 -0700
> @@ -5,12 +5,14 @@
> -DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE@.conf\"
>
> noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h
> infostore.h \
> - pool_parsing.h acl_parsing.h
> + pool_parsing.h acl_parsing.h node_parsing.h
>
> lib_LTLIBRARIES = libxkutil.la
>
> libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \
> - xmlgen.c infostore.c pool_parsing.c acl_parsing.c
> + xmlgen.c infostore.c pool_parsing.c acl_parsing.c
\
> + node_parsing.c
> +
> libxkutil_la_LDFLAGS = -version-info @VERSION_INFO@
> libxkutil_la_LIBADD = @LIBVIRT_LIBS@ \
> @LIBUUID_LIBS@
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/node_parsing.c
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/libxkutil/node_parsing.c Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + * Sharad Mishra <snmishra(a)us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +#include <inttypes.h>
> +#include <sys/stat.h>
> +#include <libxml/tree.h>
> +#include <libxml/parser.h>
> +#include <libxml/xpath.h>
> +#include "misc_util.h"
> +
> +#include <libcmpiutil/libcmpiutil.h>
> +
> +#include "node_parsing.h"
> +
> +static void cleanup_pci_device(struct pci_device pci) {
> +
> + free(pci.product);
> + free(pci.vendor);
> +}
> +
> +void cleanup_node_device(struct node_device **node)
> +{
> + struct node_device *_node = *node;
> +
> + if ((node == NULL) || (*node == NULL))
> + return;
> +
> + if (XSTREQ(_node->capability, "pci"))
> + cleanup_pci_device(_node->device_info.pci);
> +
> + free(_node->name);
> + free(_node->parent);
> + free(_node->capability);
> + free(_node);
> +
> + *node = NULL;
> +}
> +
> +CMPIStatus get_node_from_xml(const CMPIBroker *broker,
> + const CMPIObjectPath *reference,
> + virConnectPtr conn,
> + char *xml,
> + CMPIInstance **_inst)
> +{
> + int len;
> + xmlDoc *xmldoc;
> + xmlXPathContext *xpathctx;
> + xmlXPathObject *xpathobj;
> + const xmlChar *xpathstr = (xmlChar *)"/device";
> + CMPIStatus s = {CMPI_RC_OK, NULL};
> + CMPIInstance *inst = NULL;
> + char *val = NULL;
> + char *tmpstr = NULL;
> + xmlNode **nodes = NULL;
> + xmlNode *child;
> + uint8_t ival;
> +
> + CU_DEBUG("Node XML : %s", xml);
> + len = strlen(xml) + 1;
> +
> + inst = get_typed_instance(broker,
> + pfx_from_conn(conn),
> + "VirtualSystemPCIDevice",
> + NAMESPACE(reference));
> + if (inst == NULL) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_FAILED,
> + "Unable to init VirtualSystemPCIDevice
instance");
> + goto err1;
> + }
> +
> +
> + if ((xmldoc = xmlParseMemory(xml, len)) == NULL) {
> + CU_DEBUG("xmlParseMemory failed");
> + goto err1;
> + }
> +
> + if ((xpathctx = xmlXPathNewContext(xmldoc)) == NULL) {
> + CU_DEBUG("xmlXPathNewContext failed");
> + goto err2;
> + }
> +
> + if ((xpathobj = xmlXPathEvalExpression(xpathstr, xpathctx))==
NULL) {
> + CU_DEBUG("xmlXPathEvalExpression failed");
> + goto err3;
> + }
> +
> + nodes = xpathobj->nodesetval->nodeTab;
> +
> + for (child = nodes[0]->children; child != NULL; child =
> child->next) {
> + if (XSTREQ(child->name, "name")) {
> + val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> + if (val != NULL)
> + s = CMSetProperty(inst, "Name",
> + (CMPIValue *)val,
> + CMPI_chars);
> + } else if (XSTREQ(child->name, "capability")) {
> + child = child->children;
> +CU_DEBUG("found capabi s.rc is %d, s.msg is %s", s.rc, s.msg);
> + continue;
> + } else if (XSTREQ(child->name, "bus")) {
> +CU_DEBUG("found bus");
> + val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len is %d", ival);
> + s = CMSetProperty(inst, "BusNumber",
> + (CMPIValue *)&ival,
> + CMPI_uint8);
> + } else if (XSTREQ(child->name, "slot")) {
> +CU_DEBUG("found slot rs is %d msg is %s", s.rc, s.msg);
> + val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len is %d", ival);
> + s = CMSetProperty(inst, "DeviceNumber",
> + (CMPIValue *)&ival,
> + CMPI_uint8);
> + } else if (XSTREQ(child->name, "function")) {
> +CU_DEBUG("found function rc is %d, msg is %s", s.rc, s.msg);
> + val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len_16 is %d", ival);
> + s = CMSetProperty(inst, "FunctionNumber",
> + (CMPIValue *)&ival,
> + CMPI_uint8);
> + } else if (XSTREQ(child->name, "vendor")) {
> +CU_DEBUG("found vendor rc is %d msg is %s", s.rc, s.msg);
> + val = get_attr_value(child, "id");
> +CU_DEBUG("val is %s", val);
> +sprintf(tmpstr, "%*2s", val);
> +CU_DEBUG("tmpstr is %s", tmpstr);
> +uint16_t val16 = atoi(tmpstr);
> +CU_DEBUG("len is %d", val16);
> + s = CMSetProperty(inst, "VendorID",
> + (CMPIValue *)&val16,
> + CMPI_uint16);
> + }
> + }
> +
> + *_inst = inst;
> +
> + xmlXPathFreeObject(xpathobj);
> + err3:
> + xmlXPathFreeContext(xpathctx);
> + err2:
> + xmlFreeDoc(xmldoc);
> + err1:
> + return s;
> +}
> +
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */
> +
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/node_parsing.h
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/libxkutil/node_parsing.h Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + * Sharad Mishra <snmishra(a)us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +
> +
> +#include "cmpidt.h"
> +#include "cmpift.h"
> +#include "cmpimacs.h"
> +#include "device_parsing.h"
> +
> +struct pci_device {
> + int domain;
> + int bus;
> + int slot;
> + int function;
> + char *product;
> + char *vendor;
> +};
> +
> +/* USB and other node devices can be added later. */
> +struct node_device {
> + char *name;
> + char *parent;
> + char *capability;
> + union {
> + struct pci_device pci;
> + } device_info;
> +};
> +
> +void cleanup_node_device(struct node_device **node);
> +CMPIStatus get_node_from_xml(const CMPIBroker *broker,
> + const CMPIObjectPath *reference,
> + virConnectPtr conn,
> + char *xml,
> + CMPIInstance **_inst);
> +
> +
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff -r fb09136deb49 -r d07f99a02790 schema/VirtualSystemPCIDevice.mof
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/schema/VirtualSystemPCIDevice.mof Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,14 @@
> +// Copyright IBM Corp. 2011
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class Xen_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class KVM_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class LXC_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> diff -r fb09136deb49 -r d07f99a02790 schema/
> VirtualSystemPCIDevice.registration
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/schema/VirtualSystemPCIDevice.registration Tue Oct 18 09:16:
> 58 2011 -0700
> @@ -0,0 +1,5 @@
> +# Copyright IBM Corp. 2011
> +# Classname Namespace ProviderName ProviderModule ProviderTypes
> +Xen_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> +KVM_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> +LXC_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> diff -r fb09136deb49 -r d07f99a02790 src/Makefile.am
> --- a/src/Makefile.am Tue Aug 30 08:48:36 2011 -0700
> +++ b/src/Makefile.am Tue Oct 18 09:16:58 2011 -0700
> @@ -17,6 +17,7 @@
> Virt_VSSD.h \
> Virt_VSMigrationCapabilities.h \
> Virt_VSMigrationService.h \
> + Virt_VirtualSystemPCIDevice.h \
> Virt_AllocationCapabilities.h \
> Virt_VirtualSystemSnapshotService.h \
> Virt_VirtualSystemSnapshotServiceCapabilities.h \
> @@ -53,6 +54,7 @@
> libVirt_ComputerSystemIndication.la \
>
libVirt_ResourceAllocationSettingDataIndication.la \
> libVirt_SwitchService.la \
> + libVirt_VirtualSystemPCIDevice.la \
> libVirt_ComputerSystemMigrationIndication.la \
> libVirt_VirtualSystemManagementCapabilities.la \
> libVirt_AllocationCapabilities.la \
> @@ -105,6 +107,9 @@
> libVirt_SwitchService_la_SOURCES = Virt_SwitchService.c
> libVirt_SwitchService_la_LIBADD = -lVirt_ComputerSystem
>
> +libVirt_VirtualSystemPCIDevice = libVirt_ComputerSystem.la
> +libVirt_VirtualSystemPCIDevice_la_SOURCES =
Virt_VirtualSystemPCIDevice.c
> +
> libVirt_ComputerSystemMigrationIndication_la_DEPENDENCIES =
> libVirt_ComputerSystem.la
> libVirt_ComputerSystemMigrationIndication_la_SOURCES =
> Virt_ComputerSystemMigrationIndication.c
> libVirt_ComputerSystemMigrationIndication_la_LIBADD =
-lVirt_ComputerSystem
> diff -r fb09136deb49 -r d07f99a02790 src/Virt_VirtualSystemPCIDevice.c
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/src/Virt_VirtualSystemPCIDevice.c Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,295 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + * Sharad Mishra <snmishra(a)us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <sys/stat.h>
> +#include <signal.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include <errno.h>
> +
> +#include <uuid.h>
> +
> +#include <libvirt/libvirt.h>
> +
> +#include <cmpidt.h>
> +#include <cmpift.h>
> +#include <cmpimacs.h>
> +
> +#include <libcmpiutil/libcmpiutil.h>
> +#include "misc_util.h"
> +#include "node_parsing.h"
> +#include <libcmpiutil/std_instance.h>
> +#include <libcmpiutil/std_invokemethod.h>
> +#include <libcmpiutil/std_indication.h>
> +
> +#include "Virt_VSMigrationService.h"
> +#include "Virt_HostSystem.h"
> +#include "Virt_ComputerSystem.h"
> +#include "Virt_VSMigrationSettingData.h"
> +#include "svpc_types.h"
> +#include "libxkutil/infostore.h"
> +
> +#include "config.h"
> +
> +#include "Virt_VirtualSystemPCIDevice.h"
> +
> +const static CMPIBroker *_BROKER;
> +
> +static CMPIStatus add_sriov_vf(CMPIMethodMI *self,
> + const CMPIContext *ctx,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref,
> + const CMPIArgs *argsin,
> + CMPIArgs *argsout)
> +{
> +
> + CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> + return s;
> +}
> +
> +static CMPIStatus remove_sriov_vf(CMPIMethodMI *self,
> + const CMPIContext *ctx,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref,
> + const CMPIArgs *argsin,
> + CMPIArgs *argsout)
> +{
> +
> + CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> + return s;
> +}
> +
> +static CMPIStatus modify_sriov_vf(CMPIMethodMI *self,
> + const CMPIContext *ctx,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref,
> + const CMPIArgs *argsin,
> + CMPIArgs *argsout)
> +{
> +
> + CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> + return s;
> +}
> +
> +static struct method_handler AddSriovVf = {
> + .name = "AddSriovVf",
> + .handler = add_sriov_vf,
> + .args = {{"ComputerSystem", CMPI_ref, false},
> + {"DestinationSystem", CMPI_ref, false},
> + {"MigrationSettingData", CMPI_instance, true},
> + {"NewSystemSettingData", CMPI_instance, true},
> + {"NewResourceSettingData", CMPI_instanceA, true},
> + ARG_END
> + }
> +};
> +
> +static struct method_handler RemoveSriovVf = {
> + .name = "RemoveSriovVf",
> + .handler = remove_sriov_vf,
> + .args = {{"ComputerSystem", CMPI_ref, false},
> + {"DestinationHost", CMPI_string, false},
> + {"MigrationSettingData", CMPI_instance, true},
> + {"NewSystemSettingData", CMPI_instance, true},
> + {"NewResourceSettingData", CMPI_instanceA, true},
> + ARG_END
> + }
> +};
> +
> +static struct method_handler ModifySriovVf = {
> + .name = "ModifySriovVf",
> + .handler = modify_sriov_vf,
> + .args = {{"ComputerSystem", CMPI_ref, false},
> + {"DestinationSystem", CMPI_ref, false},
> + {"MigrationSettingData", CMPI_instance, true},
> + {"NewSystemSettingData", CMPI_instance, true},
> + {"NewResourceSettingData", CMPI_instanceA, true},
> + ARG_END
> + }
> +};
> +
> +static struct method_handler *my_handlers[] = {
> + &AddSriovVf,
> + &RemoveSriovVf,
> + &ModifySriovVf,
> + NULL
> +};
> +
> +STDIM_MethodMIStub(, Virt_VSMigrationService, _BROKER,
> + libvirt_cim_init(), my_handlers);
> +
> +
> +static CMPIStatus enum_pci(const CMPIBroker *broker,
> + const CMPIObjectPath *ref,
> + struct inst_list *instlist)
> +{
> + CMPIStatus s = {CMPI_RC_OK, NULL};
> + virConnectPtr conn = NULL;
> + char **names = NULL;
> + char *nodeXML;
> + int count;
> + int i;
> +
> + conn = connect_by_classname(broker, CLASSNAME(ref), &s);
> + if (conn == NULL) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to connect to Hypervisor");
> + goto out;
> + }
> +
> + count = virNodeNumOfDevices(conn, "pci", 0);
> + if (count < 1) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to find a PCI device");
> + goto out;
> + }
> +
> + names = calloc(count, sizeof(char *));
> + if (names == NULL) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to allocate memory");
> + goto out;
> + }
> +
> +
> + i = virNodeListDevices(conn, "pci", names, count, 0);
> + if (i == -1) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to get PCI devices");
> + goto out;
> + }
> +
> + for (i=0; i < count; i++) {
> + CMPIInstance *inst = NULL;
> +
> + virNodeDevicePtr nptr = virNodeDeviceLookupByName(conn,
> + names
[i]);
> + if (nptr == NULL) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to lookup PCI device by
name");
> + continue;
> + }
> +
> + nodeXML = virNodeDeviceGetXMLDesc(nptr, 0);
> + if (nodeXML == NULL) {
> + cu_statusf(broker, &s,
> + CMPI_RC_ERR_NOT_FOUND,
> + "Failed to get PCI Device XML
> Description");
> + continue;
> + }
> +
> + CU_DEBUG("PCI Device node xml is %s", nodeXML);
> +
> + CMPIStatus stat = get_node_from_xml(broker, ref, conn,
> + nodeXML, &inst);
> + if (stat.rc != CMPI_RC_OK)
> + continue;
> +
> + inst_list_add(instlist, inst);
> + }
> +
> + out:
> + virConnectClose(conn);
> +
> + return s;
> +}
> +
> +static CMPIStatus return_pci(const CMPIContext *context,
> + const CMPIObjectPath *ref,
> + const CMPIResult *results,
> + bool name_only,
> + bool is_get_inst)
> +{
> + struct inst_list list;
> + CMPIStatus s;
> +
> + inst_list_init(&list);
> + s = enum_pci(_BROKER, ref, &list);
> + if (s.rc != CMPI_RC_OK)
> + goto out;
> +
> + if (name_only)
> + cu_return_instance_names(results, &list);
> + else
> + cu_return_instances(results, &list);
> + out:
> + inst_list_free(&list);
> + return s;
> +}
> +
> +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
> + const CMPIContext *context,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref)
> +{
> + return return_pci(context, ref, results, true, false);
> +}
> +
> +static CMPIStatus EnumInstances(CMPIInstanceMI *self,
> + const CMPIContext *context,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref,
> + const char **properties)
> +{
> +
> + return return_pci(context, ref, results, false, false);
> +}
> +
> +
> +static CMPIStatus GetInstance(CMPIInstanceMI *self,
> + const CMPIContext *context,
> + const CMPIResult *results,
> + const CMPIObjectPath *ref,
> + const char **properties)
> +{
> + return return_pci(context, ref, results, false, true);
> +}
> +
> +DEFAULT_CI();
> +DEFAULT_MI();
> +DEFAULT_DI();
> +DEFAULT_EQ();
> +DEFAULT_INST_CLEANUP();
> +
> +STD_InstanceMIStub(,
> + Virt_VirtualSystemPCIDevice,
> + _BROKER,
> + libvirt_cim_init());
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */
12 years, 10 months
[PATCH 0 of 2] [TEST] VSMS: ModifyResourceSettings to change cdrom media
by Eduardo Lima (Etrunko)
This series introduces a new test case which covers a requirement to change the
media in the CDROM using libvirt-cim, done via a ModifyResourceSettings call.
Also changes the default domain created by cimtest to include a cdrom device.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py | 221 ++++++++++
suites/libvirt-cim/lib/XenKvmLib/const.py | 1 +
suites/libvirt-cim/lib/XenKvmLib/vxml.py | 15 +
3 files changed, 237 insertions(+), 0 deletions(-)
12 years, 10 months
[PATCH] #2 [TEST] 31_unset_netrasd.py: new test for VirtualSystemManagementService
by Eduardo Lima (Etrunko)
suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py | 193 ++++++++++
1 files changed, 193 insertions(+), 0 deletions(-)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1317153134 10800
# Node ID eac4909ac68adc28cad9cb6389ea93a053b23aec
# Parent 83921669cae17a4f0a18bb440ebec01de1a3e691
[TEST] 31_unset_netrasd.py: new test for VirtualSystemManagementService
This test case covers a recent bug found in Pegasus which makes impossible for
libvirt-cim to set a property values if the value is an empty string via a
ModifyResourceSettings call.
Link to Pegasus bug follows:
http://bugzilla.openpegasus.org/show_bug.cgi?id=9053
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
new file mode 100755
--- /dev/null
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+
+#
+# Copyright 2011 IBM Corp.
+#
+# Authors:
+# Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# ModifyResourceSettings call to set/unset NetRASD ResourceType property
+#
+
+import sys
+import pywbem
+
+from CimTest.ReturnCodes import PASS, FAIL
+from CimTest.Globals import logger, CIM_USER, CIM_PASS, CIM_NS
+from XenKvmLib.const import do_main
+from XenKvmLib.classes import get_typed_class
+from XenKvmLib.vxml import get_class
+
+supported = ['Xen', 'KVM', 'XenFV', 'LXC']
+domain = None
+
+class CIMDomain(object):
+
+ def __init__(self, name, virt, server):
+ self.name = name
+ self.server = server
+ self._domain = get_class(virt)(name)
+ #__init__
+
+ def define(self):
+ return self._domain.cim_define(self.server)
+ # define
+
+ def undefine(self):
+ return self._domain.undefine(self.server)
+ # undefine
+
+ def destroy(self):
+ return self._domain.cim_destroy(self.server)
+ #destroy
+# CIMDomain
+
+
+def resource_settings(inst, virt, resource_subtype):
+ return """
+instance of %s {
+ InstanceID="%s";
+ ResourceType=%d;
+ Address="%s";
+ VirtualQuantityUnits="%s";
+ NetworkType="%s";
+ NetworkName="%s";
+ ResourceSubType="%s";
+};""" % (get_typed_class(virt, "NetResourceAllocationSettingData"),
+ inst["InstanceID"],
+ inst["ResourceType"],
+ inst["Address"],
+ inst["VirtualQuantityUnits"],
+ inst["NetworkType"],
+ inst["NetworkName"],
+ resource_subtype)
+# resource_settings()
+
+
+@do_main(supported)
+def main():
+ # init
+ options = main.options
+ server = options.ip
+ virt = options.virt
+
+ server_url = "http://%s" % server
+ cim = pywbem.WBEMConnection(server_url, (CIM_USER, CIM_PASS), CIM_NS)
+
+ _class = get_typed_class(virt, "VirtualSystemManagementService")
+ sys_mgmt_service = cim.EnumerateInstanceNames(_class)[0]
+
+ # Create new domain
+ global domain
+ domain = CIMDomain("cimtest_unset_netrasd", virt, server)
+ if not domain.define():
+ logger.error("Error defining test domain")
+ return FAIL
+
+ # ein KVM_ComputerSystem
+ _class = get_typed_class(virt, "ComputerSystem")
+ computer_system_names = [i for i in cim.EnumerateInstanceNames(_class) if i["Name"] == domain.name]
+
+ logger.info("ComputerSystem Names\n%s", computer_system_names)
+
+ if not computer_system_names:
+ logger.info("Host has no domains defined")
+ return SKIP
+
+ # ain -ac KVM_SystemDevice -arc KVM_NetworkPort <KVM_ComputerSytem Name>
+ a_class = get_typed_class(virt, "SystemDevice")
+ r_class = get_typed_class(virt, "NetworkPort")
+ network_port_names = []
+
+ for inst_name in computer_system_names:
+ assoc_names = cim.AssociatorNames(inst_name, AssocClass=a_class, ResultClass=r_class)
+ network_port_names.extend(assoc_names)
+
+ logger.info("NetworkPort Names\n%s", network_port_names)
+
+ if not network_port_names:
+ logger.info("No NetworkPort instances returned")
+ return XFAIL
+
+ # ai -arc KVM_NetResourceAllocationSettingData <KVM_NetworkPort Name>
+ r_class = get_typed_class(virt, "NetResourceAllocationSettingData")
+ net_rasd_names = []
+
+ for inst_name in network_port_names:
+ assoc_names = cim.AssociatorNames(inst_name, ResultClass=r_class)
+ net_rasd_names.extend(assoc_names)
+
+ logger.info("NetRASD names\n%s", net_rasd_names)
+
+ if not net_rasd_names:
+ logger.info("No NetRASD instances returned")
+ return XFAIL
+
+ for subtype in ["virtio", "",]:
+ logger.info("Setting ResourceSubType to '%s'", subtype)
+
+ modified_net_rasd_names = []
+
+ for inst_name in net_rasd_names:
+ # Get current instance data
+ inst = cim.GetInstance(inst_name)
+ cur_id = inst["InstanceID"]
+ cur_subtype = inst["ResourceSubType"]
+ logger.info("Current ResourceSubType of %s: '%s'", cur_id, cur_subtype)
+
+ # Invoke ModifyResourceSettings
+ val = resource_settings(inst, virt, subtype)
+ ret = cim.InvokeMethod("ModifyResourceSettings", sys_mgmt_service, **{"ResourceSettings": [val,],})
+
+ if ret[0]:
+ logger.error("ERROR Setting ResourceSubtype to '%s': %s", subtype, ret)
+ return FAIL
+
+ modified_net_rasd_names.extend(ret[1]["ResultingResourceSettings"])
+
+ # Get modified instance data
+ inst = cim.GetInstance(ret[1]["ResultingResourceSettings"][0])
+ new_id = inst["InstanceID"]
+ new_subtype = inst["ResourceSubType"]
+
+ logger.info("Modified ResourceSubType of %s: '%s'", new_id, new_subtype)
+
+ if cur_id != new_id:
+ logger.error("Current '%s' and new '%s' InstanceID differ", cur_id, new_id)
+ return FAIL
+
+ if new_subtype != subtype:
+ logger.error("Current '%s' and expected '%s' ResourceSubType differ", new_subtype, subtype)
+ return FAIL
+ # for inst_name...
+
+ net_rasd_names = modified_net_rasd_names
+ #for subtype...
+
+ return PASS
+#main()
+
+if __name__ == "__main__":
+ ret = main()
+
+ if domain:
+ domain.destroy()
+ domain.undefine()
+
+ sys.exit(ret)
12 years, 11 months
[PATCH] Add support for libvirt CPU cgroup for active KVM guests
by Gareth S. Bestor
# HG changeset patch
# User Gareth S. Bestor <bestor(a)us.ibm.com>
# Date 1317635486 25200
# Node ID 2c9a378e141c23eae0b96b2f021adbd14cfb8ef2
# Parent fb09136deb494008eb3aacee420ad74da7d7c294
Add support for libvirt CPU cgroup for active KVM guests
Add support for setting and retreiving the CPU cgroup setting for an active KVM guest
using libivirt scheduling parameter support. Presently this patches only supports earlier
libvirt versions' support of this feature, which only support setting these scheduling
params for *active* guests only, and uses libivrt's earlier scheduling APIs; a subsequent
patch will support both and the newer APIs (version dependent).
A guest's CPU cgroup setting it exposed via the KVM_ProcResourceAllocationSettingData.Weight
property.
Minimum, maximum, Increment and Default weights are exposed appropriately via
the respective Processor pool.
Weight for new guest can be passed in on DefineSystem[]
Weigh for existing (active) guest can be changed via ModifyResourceSettings[]
Signed-off-by: Gareth S. Bestor <bestor(a)us.bm.com>
diff -r fb09136deb49 -r 2c9a378e141c libxkutil/device_parsing.c
--- a/libxkutil/device_parsing.c Tue Aug 30 08:48:36 2011 -0700
+++ b/libxkutil/device_parsing.c Mon Oct 03 02:51:26 2011 -0700
@@ -1297,6 +1297,24 @@
{
int ret;
+ /* Change vcpu cgroup cpu_shares */
+ if (dev->dev.vcpu.weight > 0) {
+ virSchedParameter param;
+
+ strncpy(param.field, "cpu_shares", VIR_DOMAIN_SCHED_FIELD_LENGTH);
+ param.type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
+ param.value.ul = dev->dev.vcpu.weight;
+
+ if (virDomainSetSchedulerParameters(dom, ¶m, 1) != 0) {
+ CU_DEBUG("Failed to set scheduler params for domain");
+ return 0;
+ }
+
+ CU_DEBUG("Changed %s vcpu cgroup cpu_shares to %i",
+ virDomainGetName(dom),
+ dev->dev.vcpu.weight);
+ }
+
if (dev->dev.vcpu.quantity <= 0) {
CU_DEBUG("Unable to set VCPU count to %i",
dev->dev.vcpu.quantity);
diff -r fb09136deb49 -r 2c9a378e141c src/Virt_ComputerSystem.c
--- a/src/Virt_ComputerSystem.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_ComputerSystem.c Mon Oct 03 02:51:26 2011 -0700
@@ -858,6 +858,30 @@
return 0;
}
+static int kvm_scheduler_params(struct infostore_ctx *ctx,
+ virSchedParameter **params)
+{
+ unsigned long long value;
+
+ *params = calloc(1, sizeof(virSchedParameter));
+ if (*params == NULL)
+ return -1;
+
+ value = infostore_get_u64(ctx, "weight");
+
+ if (value != 0) {
+ strncpy((*params)[0].field,
+ "cpu_shares",
+ VIR_DOMAIN_SCHED_FIELD_LENGTH);
+ (*params)[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
+ (*params)[0].value.ul = value;
+
+ return 1;
+ }
+
+ return 0;
+}
+
static void set_scheduler_params(virDomainPtr dom)
{
struct infostore_ctx *ctx;
@@ -881,6 +905,8 @@
count = xen_scheduler_params(ctx, ¶ms);
else if (STREQC(virConnectGetType(conn), "lxc"))
count = lxc_scheduler_params(ctx, ¶ms);
+ else if (STREQC(virConnectGetType(conn), "QEMU"))
+ count = kvm_scheduler_params(ctx, ¶ms);
else {
CU_DEBUG("Not setting sched params for type %s",
virConnectGetType(conn));
diff -r fb09136deb49 -r 2c9a378e141c src/Virt_RASD.c
--- a/src/Virt_RASD.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_RASD.c Mon Oct 03 02:51:26 2011 -0700
@@ -110,7 +110,7 @@
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
struct infostore_ctx *info = NULL;
- uint32_t weight;
+ uint32_t weight = 0;
uint64_t limit;
uint64_t count;
@@ -147,7 +147,45 @@
goto out;
}
- weight = (uint32_t)infostore_get_u64(info, "weight");
+ /* Currently only support CPU cgroups for running KVM guests */
+ if (domain_online(dom) && STREQC(virConnectGetType(conn), "QEMU")) {
+ char *sched;
+ int nparams;
+ unsigned int i;
+ virSchedParameter *params;
+
+ /* First find the number of scheduler params, in order malloc space for them all */
+ sched = virDomainGetSchedulerType(dom, &nparams);
+ if (sched == NULL) {
+ CU_DEBUG("Failed to get scheduler type");
+ goto out;
+ }
+ CU_DEBUG("domain has %d scheduler params", nparams);
+ free(sched);
+
+ /* Now retrieve all the scheduler params for this domain */
+ params = calloc(nparams, sizeof(virSchedParameter));
+ if (virDomainGetSchedulerParameters(dom, params, &nparams) != 0) {
+ CU_DEBUG("Failed to get scheduler params for domain");
+ goto out;
+ }
+
+ /* Look for the CPU cgroup scheduler parameter, called 'cpu_shares' */
+ for (i = 0 ; i < nparams ; i++) {
+ CU_DEBUG("scheduler param #%d name is %s (type %d)",
+ i, params[i].field, params[i].type);
+ if (STREQ(params[i].field, "cpu_shares") &&
+ (params[i].type == VIR_DOMAIN_SCHED_FIELD_ULLONG)) {
+ CU_DEBUG("scheduler param %s = %d",
+ params[i].field, params[i].value.ul);
+ weight = (uint32_t)params[i].value.ul;
+ break; /* Found it! */
+ }
+ }
+ free(params);
+ }
+ else
+ weight = (uint32_t)infostore_get_u64(info, "weight");
limit = infostore_get_u64(info, "limit");
CMSetProperty(inst, "Weight",
diff -r fb09136deb49 -r 2c9a378e141c src/Virt_SettingsDefineCapabilities.c
--- a/src/Virt_SettingsDefineCapabilities.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_SettingsDefineCapabilities.c Mon Oct 03 02:51:26 2011 -0700
@@ -410,7 +410,10 @@
case SDC_RASD_MIN:
num_procs = 0;
limit = 1;
- weight = MIN_XEN_WEIGHT;
+ if (STARTS_WITH(CLASSNAME(ref), "Xen"))
+ weight = MIN_XEN_WEIGHT;
+ else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
+ weight = MIN_KVM_WEIGHT;
id = "Minimum";
break;
case SDC_RASD_MAX:
@@ -418,19 +421,28 @@
if (!ret)
goto out;
limit = 0;
- weight = MAX_XEN_WEIGHT;
+ if (STARTS_WITH(CLASSNAME(ref), "Xen"))
+ weight = MAX_XEN_WEIGHT;
+ else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
+ weight = MAX_KVM_WEIGHT;
id = "Maximum";
break;
case SDC_RASD_INC:
num_procs = 1;
limit = 50;
- weight = INC_XEN_WEIGHT;
+ if (STARTS_WITH(CLASSNAME(ref), "Xen"))
+ weight = INC_XEN_WEIGHT;
+ else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
+ weight = INC_KVM_WEIGHT;
id = "Increment";
break;
case SDC_RASD_DEF:
num_procs = 1;
limit = 0;
- weight = DEFAULT_XEN_WEIGHT;
+ if (STARTS_WITH(CLASSNAME(ref), "Xen"))
+ weight = DEFAULT_XEN_WEIGHT;
+ else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
+ weight = DEFAULT_KVM_WEIGHT;
id = "Default";
break;
default:
@@ -455,6 +467,10 @@
CMSetProperty(inst, "Weight",
(CMPIValue *)&weight, CMPI_uint32);
}
+ else if (STARTS_WITH(CLASSNAME(ref), "KVM")) {
+ CMSetProperty(inst, "Weight",
+ (CMPIValue *)&weight, CMPI_uint32);
+ }
inst_list_add(list, inst);
diff -r fb09136deb49 -r 2c9a378e141c src/Virt_VirtualSystemManagementService.c
--- a/src/Virt_VirtualSystemManagementService.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_VirtualSystemManagementService.c Mon Oct 03 02:51:26 2011 -0700
@@ -1012,6 +1012,8 @@
if (STARTS_WITH(CLASSNAME(op), "Xen"))
def_weight = DEFAULT_XEN_WEIGHT;
+ else if (STARTS_WITH(CLASSNAME(op), "QEMU"))
+ def_weight = DEFAULT_KVM_WEIGHT;
rc = cu_get_u64_prop(inst, "Limit", &dev->dev.vcpu.limit);
if (rc != CMPI_RC_OK)
diff -r fb09136deb49 -r 2c9a378e141c src/Virt_VirtualSystemManagementService.h
--- a/src/Virt_VirtualSystemManagementService.h Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_VirtualSystemManagementService.h Mon Oct 03 02:51:26 2011 -0700
@@ -24,6 +24,11 @@
#define INC_XEN_WEIGHT MAX_XEN_WEIGHT / 2
#define DEFAULT_XEN_WEIGHT 1024
+#define MIN_KVM_WEIGHT 2
+#define MAX_KVM_WEIGHT 262144
+#define INC_KVM_WEIGHT 1
+#define DEFAULT_KVM_WEIGHT 1024
+
CMPIStatus get_vsms(const CMPIObjectPath *reference,
CMPIInstance **_inst,
const CMPIBroker *broker,
12 years, 11 months
[PATCH] [TEST] Adding tests for FilterLists
by Eduardo Lima (Etrunko)
suites/libvirt-cim/cimtest/FilterList/01_enum.py | 71 ++
suites/libvirt-cim/cimtest/FilterList/02_assoc.py | 158 ++++++
suites/libvirt-cim/cimtest/FilterList/03_create.py | 199 ++++++++
suites/libvirt-cim/cimtest/FilterList/helper.py | 515 +++++++++++++++++++++
4 files changed, 943 insertions(+), 0 deletions(-)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1310498051 10800
# Node ID d9741a8b5eb7ccebf21d69f3cde72729bb60ad22
# Parent 779871660a3583dedf1652773196d07093ff26ff
[TEST] Adding tests for FilterLists
helper.py:
- Helper module with classes and functions used by all tests
01_enum.py:
- Enumerate FilterList instances and compare to results from libvirt
02_assoc.py:
- For each FilterList instance, call Associators to get respective
FilterEntries instances and compare to results from libvirt
03_create.py:
- Creates a new FilterList instance and a NestedFilterList associated
to this new instance. Creates a new domain and a new
AppliedFilterList instance associated to the NetworkPort instance of
that new domain.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/suites/libvirt-cim/cimtest/FilterList/01_enum.py b/suites/libvirt-cim/cimtest/FilterList/01_enum.py
new file mode 100644
--- /dev/null
+++ b/suites/libvirt-cim/cimtest/FilterList/01_enum.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 IBM Corp.
+#
+# Authors:
+# Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# CIMTest Filter Lists Enumerate
+#
+
+import sys
+import helper
+
+from CimTest.ReturnCodes import PASS, FAIL
+from CimTest.Globals import logger
+from XenKvmLib.const import do_main
+
+sup_types = ["KVM",]
+
+@do_main(sup_types)
+def main():
+ options = main.options
+
+ _test = helper.FilterListTest(options.ip, options.virt)
+
+ # Fetch current filters with libvirt
+ libvirt_filters = _test.libvirt_filter_lists()
+ if not libvirt_filters:
+ return FAIL
+
+ logger.info("libvirt filters:\n%s", libvirt_filters)
+
+ # Fetch current filters with libvirt-cim
+ cim_filters = _test.cim_filter_lists()
+ if not cim_filters:
+ # TODO: Add some filters of our own
+ return FAIL
+
+ logger.info("libvirt-cim filters:\n%s", cim_filters)
+
+ # Compare results
+ if len(libvirt_filters) != len(cim_filters):
+ logger.error("CIM filters list length is different than libvirt filters list")
+ return FAIL
+
+ for f in libvirt_filters:
+ if f not in cim_filters:
+ logger.error("Filter %s, not found in CIM filters list", f)
+ return FAIL
+
+ return PASS
+# main
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/suites/libvirt-cim/cimtest/FilterList/02_assoc.py b/suites/libvirt-cim/cimtest/FilterList/02_assoc.py
new file mode 100644
--- /dev/null
+++ b/suites/libvirt-cim/cimtest/FilterList/02_assoc.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 IBM Corp.
+#
+# Authors:
+# Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# CIMTest Filter Lists Associators
+#
+
+import sys
+import helper
+
+from CimTest.ReturnCodes import PASS, FAIL, XFAIL
+from CimTest.Globals import logger
+from XenKvmLib.const import do_main
+
+sup_types = ["KVM",]
+
+@do_main(sup_types)
+def main():
+ options = main.options
+
+ _test = helper.FilterListTest(options.ip, options.virt)
+
+ # Fetch current filters with libvirt
+ libvirt_filters = _test.libvirt_entries_in_filter_lists()
+ if not libvirt_filters:
+ return FAIL
+
+ #logger.info("libvirt filters:\n%s", libvirt_filters)
+
+ # Fetch current filters with libvirt-cim
+ cim_filters = _test.cim_entries_in_filter_lists()
+ if not cim_filters:
+ return FAIL
+
+ #logger.info("libvirt-cim filters:\n%s", cim_filters)
+
+ # Compare results
+ if len(libvirt_filters) != len(cim_filters):
+ logger.error("CIM filters list length and libvirt filters list differ")
+ return FAIL
+
+ # Compare each result
+ for inst_name in cim_filters:
+ _cim_f = _test.GetInstance(inst_name)
+ try:
+ _key = (_cim_f["InstanceID"], _cim_f["Name"])
+ _vir_f = libvirt_filters[_key]
+ except KeyError, e:
+ logger.error(e)
+ return FAIL
+
+ logger.info("")
+ logger.info("Processing '%s' filter", _key[1])
+
+ # Check number of rules
+ n_vir_rules = len([e for e in _vir_f.getchildren() if e.tag in ["rule", "filterref"]])
+
+ # process each element
+ instances = cim_filters[inst_name]
+ n_cim_rules = len(instances)
+
+ if n_cim_rules != n_vir_rules:
+ logger.error("Number of rules returned by libvirt (%d) and libvirt-cim (%d) differ",
+ n_vir_rules, n_cim_rules)
+ return FAIL
+
+
+ # TODO: Create a new class to handle the filter parsing
+ def parse_filter(element, spaces=""):
+ logger.info("%s%s(%s)%s",
+ spaces,
+ element.tag,
+ element.attrib and element.attrib or "",
+ element.text and ": %s" % element.text or "")
+
+ # Recurse to last element in tree
+ for e in element:
+ parse_filter(e, "%s " % spaces)
+
+ if element.tag == "filterref":
+ name = element.get("filter")
+ try:
+ i = [inst for inst in instances if inst["Name"] == name][0]
+ logger.info("%s* MATCH: Instance: %s", spaces, i)
+ instances.remove(i)
+ return
+ except:
+ raise Exception("No CIM Instance matching this rule was found")
+ elif element.tag == "rule":
+ if not instances:
+ raise Exception("No CIM Instance matching this rule was found")
+
+ rule = helper.FilterRule(element)
+
+ # Find matching instance
+ logger.info("%s* %s", spaces, rule)
+ for i in instances:
+ props = ""
+ for p in i.properties.keys():
+ props = "%s '%s':'%s'" % (props, p, i[p])
+ logger.info("%s* %s(%s)", spaces, i.classname, props)
+
+ matches, msg = rule.matches(i)
+ if msg:
+ logger.info("%s* %s: %s", spaces, matches and "MATCH" or "DON'T MATCH", msg)
+
+ if matches:
+ instances.remove(i)
+ return
+
+ # No matching instance
+ raise Exception("No CIM instance matching rule found")
+ else:
+ # Unexpected tag, ignore by now
+ pass
+ # parse_filter
+
+ try:
+ parse_filter(_vir_f)
+ except Exception, e:
+ logger.error("Error parsing filter '%s': %s", _vir_f.tag, e)
+ return FAIL
+
+ # Check for leftovers
+ for i in instances:
+ props = ""
+ for p in i.properties.keys():
+ props = "%s '%s':'%s'" % (props, p, i[p])
+
+ logger.error("Could NOT find match for instance %s : {%s}", i.classname, props)
+ return FAIL
+ # end for inst_name in cim_filters
+
+ logger.info("====End of test====")
+ return PASS
+# main
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/suites/libvirt-cim/cimtest/FilterList/03_create.py b/suites/libvirt-cim/cimtest/FilterList/03_create.py
new file mode 100644
--- /dev/null
+++ b/suites/libvirt-cim/cimtest/FilterList/03_create.py
@@ -0,0 +1,199 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 IBM Corp.
+#
+# Authors:
+# Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# CIMTest Filter Lists Create
+#
+
+import sys
+import helper
+
+import pywbem
+
+from CimTest.ReturnCodes import PASS, FAIL, XFAIL
+from CimTest.Globals import logger
+from XenKvmLib.const import do_main
+from XenKvmLib.vxml import get_class
+from VirtLib.utils import run_remote
+
+sup_types = ["KVM",]
+
+domain = None
+
+def get_filter_inst_and_inst_name(name):
+ try:
+ _filters = test.libvirt_filter_lists()
+ _id = test.id_for_filter_name(_filters, name)
+ except Exception, e:
+ # TODO: define a filter of our own
+ logger.error("'%s' filter list not found in libvirt:\n%s", name, e)
+ raise
+
+ # Retrieve instance name for "clean-traffic"
+ try:
+ inst_name = test.FindInstanceName(name)
+ except Exception, e:
+ logger.error("'%s' filter list not found in libvirt-cim\n%s", name, e)
+ raise
+
+ # Retrieve instance for "clean-traffic"
+ inst = test.GetInstance(inst_name)
+
+ if not inst:
+ logger.error("Unable to retrieve instance for '%s' filter list", name)
+ raise Exception()
+ elif inst["InstanceID"] != _id:
+ logger.error("'%s' ids from libvirt and libvirt-cim differ", name)
+ raise Exception()
+
+ return inst, inst_name
+# get_filter_inst_and_inst_name
+
+
+def create_filter_list(name):
+ # Get "clean-traffic" filter instance and instance name
+ clean, clean_name = get_filter_inst_and_inst_name("clean-traffic")
+
+ # Check if filter list already exist then delete it
+ try:
+ inst_name = test.FindInstanceName(name)
+ test.wbem.DeleteInstance(inst_name)
+ logger.info("Instance with name '%s' already exists. Deleting.", name)
+ except:
+ logger.info("No previous Instance with name '%s' found.", name)
+
+ # Create a new FilterList instance based on name parameter
+ global flist_name
+ logger.info("Creating FilterList '%s'", name)
+ flist_name = test.CreateFilterListInstance(name)
+ flist = test.GetInstance(flist_name)
+
+ # A NestedFilterList instance will add the "clean-traffic" filter
+ # as an entry of the newly created FilterList
+ logger.info("Creating NestedFilterList instance")
+ nested_name = test.CreateFilterListInstance(None, "KVM_NestedFilterList",
+ {"Antecedent":flist_name,
+ "Dependent":clean_name})
+
+ logger.info("Got NestedFilterList name '%s'", nested_name)
+ #nested = test.GetInstance(nested_name)
+ #logger.info("Got NestedFilterList '%s'", nested)
+
+ # Check if results match
+ _id, _name = [f for f in test.libvirt_filter_lists() if f[1] == name][0]
+ elements = test.libvirt_filter_dumpxml(_id)
+ filterref = [e for e in elements if e.tag == "filterref"][0]
+ if clean["Name"] != filterref.get("filter"):
+ raise Exception("NestedFilterList name and libvirt filter don't match")
+
+ logger.info("NestedFilterList created successfuly")
+ return flist, flist_name
+# create_filter_list
+
+
+def get_nwport_inst_and_inst_name(domain_name):
+ try:
+ inst_name = test.FindInstanceName(domain_name, "SystemName",
+ "KVM_NetworkPort")
+ inst = test.GetInstance(inst_name)
+ except Exception, e:
+ logger.error("Unable to get NetworkPort instance name for '%s' domain", domain_name)
+ raise
+
+ return inst, inst_name
+#get_nwport_inst_and_inst_name
+
+
+def cleanup():
+ try:
+ # Destroy filter list
+ test.wbem.DeleteInstance(flist_name)
+ except Exception, e:
+ logger.error("Error deleting filter list: %s", e)
+
+ try:
+ # Destroy domain
+ if domain:
+ domain.destroy()
+ domain.undefine()
+ except Exception, e:
+ logger.error("Error destroying domain: %s", e)
+# cleanup
+
+
+@do_main(sup_types)
+def main():
+ result = XFAIL
+ options = main.options
+
+ test_flist = "cimtest-filterlist"
+
+ global test
+ test = helper.FilterListTest(options.ip, options.virt)
+
+ try:
+ # Create a new FilterList instance
+ flist, flist_name = create_filter_list(test_flist)
+
+ # Create a new domain (VM)
+ domain_name = "cimtest-filterlist-domain"
+ global domain
+ domain = helper.CIMDomain(domain_name, test.virt, test.server)
+ domain.define()
+
+ # Get NetworkPort instance and instance name for defined domain
+ nwport, nwport_name = get_nwport_inst_and_inst_name(domain_name)
+
+ # An AppliedFilterList Instance will apply the filter to the network
+ # port of the defined domain
+ test.CreateFilterListInstance(None, "KVM_AppliedFilterList",
+ {"Antecedent":nwport_name,
+ "Dependent":flist_name})
+ except Exception, e:
+ logger.error("Caught exception: %s", e)
+ result = FAIL
+
+ # Check results
+
+ # Cleanup
+ cleanup()
+
+ # Leftovers?
+ try:
+ inst = test.FindInstance(test_flist)
+ logger.error("Leftovers in CIM FilterLists: %s", inst)
+ result = FAIL
+ except IndexError:
+ pass
+
+ try:
+ filt = [f for f in test.libvirt_filter_lists() if f[1] == test_flist][0]
+ logger.error("Leftovers in libvirt filters: %s", filt)
+ result = FAIL
+ except IndexError:
+ pass
+
+ return result
+# main
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/suites/libvirt-cim/cimtest/FilterList/helper.py b/suites/libvirt-cim/cimtest/FilterList/helper.py
new file mode 100644
--- /dev/null
+++ b/suites/libvirt-cim/cimtest/FilterList/helper.py
@@ -0,0 +1,515 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 IBM Corp.
+#
+# Authors:
+# Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+
+import pywbem
+import libvirt
+
+import CimTest
+from CimTest.Globals import logger
+
+import XenKvmLib
+from XenKvmLib.xm_virt_util import virt2uri
+from XenKvmLib.classes import get_typed_class
+from XenKvmLib.vxml import get_class
+
+import VirtLib
+from VirtLib.utils import run_remote
+
+try:
+ from xml.etree import cElementTree as ElementTree
+except:
+ from xml.etree import ElementTree
+
+
+class BaseTestObject(object):
+
+ def __init__(self, server, virt):
+ self.server = server
+ self.virt = virt
+ self.typed_class = get_typed_class(virt, self.cim_basename)
+ self.uri = virt2uri(virt)
+ self.user = CimTest.Globals.CIM_USER
+ self.passwd = CimTest.Globals.CIM_PASS
+ self.namespace = CimTest.Globals.CIM_NS
+ self.wbem = pywbem.WBEMConnection("http://%s" % server,
+ (self.user, self.passwd),
+ self.namespace)
+ self.wbem.debug = True
+ # __init__
+
+ def EnumerateInstances(self, typed_class=None):
+ if not typed_class:
+ typed_class = self.typed_class
+
+ return self.wbem.EnumerateInstances(typed_class)
+ # EnumerateInstances
+
+ def EnumerateInstanceNames(self, typed_class=None):
+ if not typed_class:
+ typed_class = self.typed_class
+
+ return self.wbem.EnumerateInstanceNames(typed_class)
+ # EnumerateInstanceNames
+
+ def __assoc_args(self, assoc_class=None, result_class=None):
+ kargs = {}
+ if assoc_class:
+ kargs["AssocClass"] = assoc_class
+
+ if result_class:
+ kargs["ResultClass"] = result_class
+
+ return kargs
+ # __assoc_args
+
+ def Associators(self, typed_class=None, assoc_class=None, result_class=None):
+ if not typed_class:
+ typed_class = self.typed_class
+
+ kargs = self.__assoc_args(assoc_class, result_class)
+
+ if kargs:
+ return self.wbem.Associators(typed_class, **kargs)
+
+ return self.wbem.Associators(typed_class)
+ # Associators
+
+ def AssociatorNames(self, typed_class=None, assoc_class=None, result_class=None):
+ if not typed_class:
+ typed_class = self.typed_class
+
+ kargs = self.__assoc_args(assoc_class, result_class)
+
+ if kargs:
+ return self.wbem.Associators(typed_class, **kargs)
+
+ return self.wbem.AssociatorNamess(typed_class)
+ # AssociatorNames
+
+ def GetInstance(self, inst_name):
+ return self.wbem.GetInstance(inst_name)
+ # GetInstance
+
+ def FindInstance(self, inst_name, attr="Name", class_name=None):
+ if not class_name:
+ class_name = self.typed_class
+
+ if isinstance(inst_name, str) or isinstance(inst_name, unicode):
+ _insts = self.EnumerateInstances(class_name)
+ return [i for i in _insts if i[attr] == inst_name][0]
+
+ return self.GetInstance(self, inst_name)
+ # FindInstance
+
+ def FindInstanceName(self, _name, attr="Name", class_name=None):
+ if not class_name:
+ class_name = self.typed_class
+
+ _inst_names = self.EnumerateInstanceNames(class_name)
+ return [i for i in _inst_names if i[attr] == _name][0]
+ # FindInstanceName
+
+ def CreateFilterListInstance(self, name, class_name=None, props={}):
+ if not class_name:
+ class_name = self.typed_class
+
+ if name:
+ props["Name"] = name
+
+ logger.info("Creating Instance of %s", class_name)
+ inst = pywbem.CIMInstance(class_name, props)
+ return self.wbem.CreateInstance(inst)
+ # CreateFilterListInstance
+
+ def DumpWBEMDebug(self):
+ logger.info("*** Begin WBEM Debug ***")
+ logger.info(" * Last raw request\n'%s'", self.wbem.last_raw_request)
+ logger.info(" * Last raw reply\n'%s'", self.wbem.last_raw_reply)
+
+ logger.info(" * Last request\n'%s'", self.wbem.last_request)
+ logger.info(" * Last reply\n'%s'", self.wbem.last_reply)
+ logger.info("*** End WBEM Debug ***")
+ # DumpWBEMDebug
+# BaseTestObject
+
+
+class CIMDomain(object):
+
+ def __init__(self, name, virt, server):
+ self.name = name
+ self.server = server
+ self.virt = virt
+ self._domain = get_class(virt)(name)
+ #__init__
+
+ def define(self):
+ return self._domain.cim_define(self.server)
+ # define
+
+ def start(self):
+ return self._domain.cim_start(self.server)
+ # start
+
+ def shutdown(self):
+ return self._domain.cim_shutdown(self.server)
+ # shutdown
+
+ def undefine(self):
+ return self._domain.undefine(self.server)
+ # undefine
+
+ def destroy(self):
+ return self._domain.cim_destroy(self.server)
+ #destroy
+# CIMDomain
+
+
+class FilterListTest(BaseTestObject):
+ cim_basename = "FilterList"
+
+ def __init__(self, server, virt):
+ BaseTestObject.__init__(self, server, virt)
+ # __init__
+
+ def libvirt_filter_lists(self):
+ cmd = "virsh -q -c %s nwfilter-list 2>/dev/null" % self.uri
+ ret, filters = run_remote(self.server, cmd)
+ if ret:
+ logger.error("Error listing existing filters")
+ return None
+
+ filters = filters.split("\n")
+ l = []
+ for f in filters:
+ # Append a tuple of (id, name) to list
+ t = tuple(a for a in f.strip().split() if a)
+ l.append(t)
+
+ return l
+ # libvirt_filter_lists
+
+ def cim_filter_lists(self):
+ _instances = self.EnumerateInstances()
+ l = []
+ for i in _instances:
+ try:
+ # Append a tuple of (id, name) to list
+ l.append((i["InstanceId"], i["Name"]))
+ except KeyError:
+ logger.error("'InstanceID', 'Name' properties not found in Instance %s", i)
+ return None
+
+ return l
+ # cim_filter_lists
+
+ def id_for_filter_name(self, _list, _name):
+ if isinstance(_list[0], tuple):
+ return [t[0] for t in _list if t[1] == _name][0]
+ elif isinstance(_list[0], CIMInstanceName):
+ return self.GetInstance(inst_name)["InstanceID"]
+ raise AttributeError("Expecting list of either tuple or CIMInstanceName")
+ # id_for_filter_name
+
+ def name_for_filter_id(self, _list, _id):
+ if isinstance(_list[0], tuple):
+ return [t[1] for t in _list if t[0] == _id][0]
+ elif isinstance(_list[0], CIMInstance):
+ return [i for i in _list if i["InstanceID"] == _id][0]["Name"]
+ raise AttributeError("Expecting list of either tuple or CIMInstance")
+ # name_for_filter_id
+
+ def libvirt_filter_dumpxml(self, uuid):
+ cmd = "virsh -q -c %s nwfilter-dumpxml %s 2>/dev/null" % (self.uri, uuid)
+ ret, out = run_remote(self.server, cmd)
+ if ret:
+ logger.error("Error executing nwfilter-dumpxml")
+ return None
+
+ # Remove all unecessary spaces and new lines
+ _xml = "".join([a.strip() for a in out.split("\n") if a])
+ return ElementTree.fromstring(_xml)
+ # libvirt_filter_dumpxml
+
+ def libvirt_entries_in_filter_lists(self):
+ filters = self.libvirt_filter_lists()
+
+ d = {}
+ for f in filters:
+ root = self.libvirt_filter_dumpxml(f[0])
+ if not root:
+ return None
+
+ d[f] = root
+
+ return d
+ # libvirt_entries_in_filter_lists
+
+ def cim_entries_in_filter_lists(self):
+ d = {}
+
+ _names = self.EnumerateInstanceNames()
+ for n in _names:
+ l = []
+ l.extend(self.Associators(n, result_class="CIM_FilterEntryBase"))
+ l.extend(self.Associators(n, assoc_class="KVM_NestedFilterList"))
+ d[n] = l
+
+ return d
+ # cim_entries_in_filter_lists
+
+ def libvirt_entries_in_filter_list(self, _name, _id=None):
+ _id_name = (_id, _name)
+
+ if not _id:
+ try:
+ _id_name = (self.id_for_filter_name(d.keys(), _name), _name)
+ except IndexError:
+ return None
+ elif not _name:
+ try:
+ _id_name = (_id, self.name_for_filter_id(d.keys(), _id))
+ except IndexError:
+ return None
+
+ return self.libvirt_filter_dumpxml(_id_name[0])
+ # libvirt_entries_in_filter_list
+
+ def cim_entries_in_filter_list(self, _name, _id=None):
+ _inst_name = None
+
+ if not _id:
+ try:
+ _inst_name = self.GetInstanceName(_name)
+ except IndexError:
+ return None
+ elif not _name:
+ try:
+ _inst = self.GetInstance(_id, "InstanceID")
+ _inst_name = self.GetInstanceName(_inst["Name"])
+ except IndexError:
+ return None
+
+ return self.Associators(_inst_name, result_class="CIM_FilterEntryBase")
+ # cim_entries_in_filter_list
+# FilterListTest
+
+
+class FilterRule(object):
+
+ __directions = {"in" : "1",
+ "out" : "2",
+ "inout": "3",}
+
+ __versions = {"ip" : "4",
+ "ipv6": "6",}
+
+ __actions = {"accept" : "1",
+ "deny" : "2",
+ "drop" : "2",}
+
+ __baserule_map = {"action" : "Action",
+ "direction" : "Direction",
+ "priority" : "Priority",}
+
+ __iprule_map = {"version" : "HdrIPVersion",
+ "" : "HdrFlowLabel",
+ "srcipaddr" : "HdrSrcAddress",
+ "dstipaddr" : "HdrDestAddress",
+ "srcipmask" : "HdrSrcMask",
+ "dstipmask" : "HdrDestMask",
+ "srcipto" : "HdrSrcAddressEndOfRange",
+ "dstipto" : "HdrDestAddressEndOfRange",
+ "srcportstart": "HdrSrcPortStart",
+ "dstportstart": "HdrDestPortStart",
+ "srcportend" : "HdrSrcPortEnd",
+ "dstportend" : "HdrDestPortEnd",
+ "" : "HdrDSCP",
+ "" : "HdrProtocolID",}
+
+ __hdr8021rule_map = {"srcmacaddr": "HdrSrcMACAddr8021",
+ "dstmacaddr": "HdrDestMACAddr8021",
+ "srcmacmask": "HdrSrcMACMask8021",
+ "dstmacmask": "HdrDestMACMask8021",
+ "" : "HdrPriorityValue8021",
+ "" : "HdrVLANID8021",
+ "protocolid": "HdrProtocolID8021",}
+
+ ### FIXME Add to proper rule map
+ """
+ "": "HealthState",
+ "": "StatusDescriptions",
+ "": "Generation",
+ "": "CommunicationStatus",
+ "": "SystemName",
+ "": "DetailedStatus",
+ "": "Caption",
+ "": "OperationalStatus",
+ "": "SystemCreationClassName",
+ "": "Status",
+ "": "Description",
+ "": "InstallDate",
+ "": "CreationClassName",
+ "": "PrimaryStatus",
+ "": "ElementName",
+ "": "Name",
+ "": "IsNegated",
+ "": "InstanceID",
+ "": "OperatingStatus",
+ """
+
+ __basenames = {None : "FilterEntry",
+ "ip" : "IPHeadersFilter",
+ "ipv6": "IPHeadersFilter",
+ "tcp" : "IPHeadersFilter",
+ "udp" : "IPHeadersFilter",
+ "igmp": "IPHeadersFilter",
+ "icmp": "IPHeadersFilter",
+ "mac" : "Hdr8021Filter",
+ "arp" : "Hdr8021Filter",
+ "rarp": "Hdr8021Filter",}
+
+ __rulemaps = {"FilterEntry" : __baserule_map,
+ "IPHeadersFilter": dict(__baserule_map, **__iprule_map),
+ "Hdr8021Filter" : dict(__baserule_map, **__hdr8021rule_map),}
+
+ def __init__(self, element):
+ self.__dict = element.attrib
+ self.__type = None
+
+ for e in element:
+ self.__dict = dict(self.__dict, **e.attrib)
+ if not self.__type:
+ self.__type = e.tag
+
+ try:
+ self.basename = self.__basenames[self.__type]
+ self.rulemap = self.__rulemaps[self.basename]
+ except KeyError:
+ self.basename = None
+ self.rulemap = None
+ # __init__
+
+ def __getattr__(self, key):
+ if key == "direction":
+ return self.__directions[self.__dict[key]]
+ elif key == "version":
+ if self.__type and "ip" in self.__type:
+ return self.__versions[self.__type]
+ elif key == "action":
+ return self.__actions[self.__dict[key]]
+ elif key == "type":
+ return self.__type
+
+ try:
+ return self.__dict[key]
+ except KeyError:
+ return None
+ # __getattr__
+
+ def __repr__(self):
+ return "FilterRule(type=%s, attributes=%s)" % (self.__type, self.__dict)
+ # __repr__
+
+ def __addr_to_list(self, val, base, sep):
+ return [long(v, base) for v in val.split(sep)]
+ # __addr_to_list
+
+ def __cidr_to_list(self, val):
+ int_val = int(val, 10)
+ int_val = (0xffffffff >> (32 - int_val)) << (32 - int_val)
+ o1 = (int_val & 0xff000000) >> 24
+ o2 = (int_val & 0x00ff0000) >> 16
+ o3 = (int_val & 0x0000ff00) >> 8
+ o4 = int_val & 0x000000ff
+ return [o1, o2, o3, o4]
+ # __cidr_to_list
+
+ def matches(self, instance):
+ # Classname
+ if not self.basename or self.basename not in instance.classname:
+ return (False, "Classname '%s' does not match instance '%s'" % (self.basename, instance.classname))
+
+ # IP Version
+ if self.version:
+ prop_name = self.rulemap["version"]
+ try:
+ inst_version = str(instance[prop_name])
+ except KeyError:
+ inst_version = None
+
+ if self.version != inst_version:
+ return (False, "IP version '%s' does not match instance '%s'" % (self.version, inst_version))
+
+ # Other properties
+ for key in self.__dict:
+ try:
+ inst_key = self.rulemap[key]
+ except KeyError:
+ inst_key = None
+
+ if not inst_key:
+ # logger.info("No match for rule attribute '%s'", key)
+ continue
+
+ # convert the property value to string
+ prop = instance.properties[inst_key]
+ val = self.__getattr__(key)
+ if val.startswith("0x"):
+ inst_val = hex(int(prop.value))
+ else:
+ inst_val = str(prop.value)
+
+ # Handle special cases
+ if inst_val != "None":
+ # Netmask?
+ if "mask" in key:
+ if "." in val:
+ val = self.__addr_to_list(val, base, sep)
+ else:
+ # Assume CIDR
+ val = self.__cidr_to_list(val)
+ inst_val = prop.value
+ # Address?
+ elif "addr" in key:
+ if val.startswith("$"):
+ # Can't translate address starting with '$'
+ logger.info("Assuming matching address for '%s:%s' and '%s:%s'", key, val, inst_key,inst_val)
+ continue
+ elif prop.is_array and prop.value:
+ sep = "."
+ base = 10
+ if ":" in val:
+ sep = ":"
+ base = 16
+
+ val = self.__addr_to_list(val, base, sep)
+ inst_val = prop.value
+ # if inst_val != None
+
+ if inst_val != val:
+ return (False, "Values for '%s':'%s' and '%s':'%s' don't match" % (key, val, inst_key, inst_val))
+
+ return (True, "Found matching CIM Instance: %s" % instance)
+ # matches
+# FilterRule
+
12 years, 11 months
[PATCH] FilterEntry: Set HdrProtocolID8021 property
by Eduardo Lima (Etrunko)
src/Virt_FilterEntry.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1317929569 10800
# Node ID 8384b32b9a79999bcf3c414d94bc18789b6d9318
# Parent e6c6f9ccb51303f67fce26e74de9ab746d10a04b
FilterEntry: Set HdrProtocolID8021 property
Also remove a couple of duplicate (CMPIValue *) casts.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/src/Virt_FilterEntry.c b/src/Virt_FilterEntry.c
--- a/src/Virt_FilterEntry.c
+++ b/src/Virt_FilterEntry.c
@@ -27,6 +27,8 @@
#include <arpa/inet.h>
+#include <stdlib.h>
+
#include "acl_parsing.h"
#include "misc_util.h"
#include "xmlgen.h"
@@ -247,7 +249,7 @@
array = octets_to_cmpi(broker, bytes, size);
if (array != NULL)
- CMSetProperty(inst, "HdrDestMACAddr8021", (CMPIValue *)
+ CMSetProperty(inst, "HdrDestMACAddr8021",
(CMPIValue *)&array, CMPI_uint8A);
memset(bytes, 0, sizeof(bytes));
@@ -256,8 +258,16 @@
array = octets_to_cmpi(broker, bytes, size);
if (array != NULL)
- CMSetProperty(inst, "HdrDestMACMask8021", (CMPIValue *)
+ CMSetProperty(inst, "HdrDestMACMask8021",
(CMPIValue *)&array, CMPI_uint8A);
+
+ if (rule->var.mac.protocol_id != NULL) {
+ unsigned long n = strtoul(rule->var.mac.protocol_id,
+ NULL, 16);
+ CMSetProperty(inst, "HdrProtocolID8021",
+ (CMPIValue *)&n, CMPI_uint16);
+ }
+
}
static void fill_rule_data(struct acl_rule *rule,
12 years, 11 months
[PATCH 0 of 4] Various fixes to FilterEntry provider
by Eduardo Lima (Etrunko)
[1/4] acl_parsing: Share code for icmp and icmp rule types
The struct for both ICMP and IGMP rule types have the exact same fields.
With this patch, we avoid duplicating code to handle those rules.
[2/4] FilterEntry: Should be using srcipaddr instead of srcmacaddr
[3/4] FilterEntry: Support for mask in CIDR notation
The values for mask fields may have been written using the CIDR notation[1].
For instance, take the libvirt 'no-ip-multicast' builtin filter:
<filter name='no-ip-multicast' chain='ipv4'>
<uuid>47756f11-6057-1448-2cce-fda40fa23ba4</uuid>
<rule action='drop' direction='out' priority='500'>
<ip dstipaddr='224.0.0.0' dstipmask='4'/>
</rule>
</filter>
As libvirt-cim expects an address like string, for the mask, in this case the
conversion will fail and will output an array with only zero values [0,0,0,0],
when it actually should be [240,0,0,0].
[1] http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
[4/4] FilterEntry: Fix behavior of convert_ip_rule_to_instance
The function was always referencing the 'tcp' fileld of the var union in struct
acl_rule, while it should take into account the rule type to access the correct
fields. This could probably go to acl_parsing, but I thought it would be a less
intrusive change to patch only FilterEntry provider.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
libxkutil/acl_parsing.c | 119 ++++++++++------------------------
libxkutil/acl_parsing.h | 29 +-------
src/Virt_FilterEntry.c | 3 +-
src/Virt_FilterEntry.c | 2 +-
src/Virt_FilterEntry.c | 88 +++++++++++++++++++++----
src/Virt_FilterEntry.c | 162 +++++++++++++++++++++++++++++++++++++----------
6 files changed, 242 insertions(+), 161 deletions(-)
12 years, 11 months