[PATCH 0 of 1] [TEST] Don't send commands via ssh for localhost
by Eduardo Lima (Etrunko)
Alright, this patch has been around for a while and I think the results
are very similar to the version which sends all commands via ssh, except
for the performance boost.
I am now sending the patch for appreciation and requesting some feedback,
especially if there is any specific test that was working but is now broke
because of this patch.
If possible, run the full cimtest suite first in a pristine checkout and
save the run_report.txt file with a different name. After that, apply the
patch to the tree and run the suite again. Reply to this email attaching
both files so we can analyse the results.
Best regards, Etrunko
--
Eduardo de Barros Lima
Software Engineer, Open Virtualization
Linux Technology Center - IBM/Brazil
eblima(a)br.ibm.com
13 years, 6 months
[PATCH] [TEST] Fix exception in tests
by Eduardo Lima (Etrunko)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1309289907 10800
# Node ID 6397c0670c35acc78ac13d737b408bb90e30632e
# Parent 3c218fe48bb7b9d89549dcca213dd7e0b60035af
[TEST] Fix exception in tests
--------------------------------------------------------------------
Memory - 01_memory.py: FAIL
ERROR - Got CIM error CIM_ERR_FAILED: Failed to define domain: operation virDomainDefineXML forbidden for read only access with return code 1
Traceback (most recent call last):
File "/home/etrunko/projects/virt/cimtest/suites/libvirt-cim/lib/XenKvmLib/const.py", line 140, in do_try
rc = f()
File "01_memory.py", line 66, in main
capacity = dev.ConsumableBlocks * dev.BlockSize / 1024
AttributeError: 'NoneType' object has no attribute 'ConsumableBlocks'
--------------------------------------------------------------------
SettingsDefineCapabilities - 01_forward.py: FAIL
ERROR - [dpool, mpool, ppool, npool] None
ERROR - TypeError : 'int' object is not iterable
Traceback (most recent call last):
File "/home/etrunko/projects/virt/cimtest/suites/libvirt-cim/lib/XenKvmLib/const.py", line 140, in do_try
rc = f()
File "01_forward.py", line 204, in main
status, pool = get_pool_details(virt, server)
TypeError: 'int' object is not iterable
--------------------------------------------------------------------
VirtualSystemManagementService - 28_definesystem_with_vsi_profile.py: FAIL
ERROR - Exception: 'NoneType' object has no attribute 'InstanceID'
ERROR - Unable to get template RASDs for vsi_guest
ERROR - UnboundLocalError : local variable 'cxml' referenced before assignment
Traceback (most recent call last):
File "/home/etrunko/projects/virt/cimtest/suites/libvirt-cim/lib/XenKvmLib/const.py", line 140, in do_try
rc = f()
File "28_definesystem_with_vsi_profile.py", line 211, in main
cxml.cim_destroy(server)
UnboundLocalError: local variable 'cxml' referenced before assignment
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/suites/libvirt-cim/cimtest/Memory/01_memory.py b/suites/libvirt-cim/cimtest/Memory/01_memory.py
--- a/suites/libvirt-cim/cimtest/Memory/01_memory.py
+++ b/suites/libvirt-cim/cimtest/Memory/01_memory.py
@@ -59,15 +59,16 @@
if dev is None:
logger.error("GetInstance() returned None")
status = 1
- elif dev.ConsumableBlocks > dev.NumberOfBlocks:
- logger.error("ConsumableBlocks should not be larger than NumberOfBlocks")
- status = 1
+ else:
+ if dev.ConsumableBlocks > dev.NumberOfBlocks:
+ logger.error("ConsumableBlocks should not be larger than NumberOfBlocks")
+ status = 1
- capacity = dev.ConsumableBlocks * dev.BlockSize / 1024
+ capacity = dev.ConsumableBlocks * dev.BlockSize / 1024
- if capacity != alloc_mem:
- logger.error("Capacity should be %i MB instead of %i MB", alloc_mem, capacity)
- status = 1
+ if capacity != alloc_mem:
+ logger.error("Capacity should be %i MB instead of %i MB", alloc_mem, capacity)
+ status = 1
if status == 0:
logger.info("Checked memory capacity: %s MB", capacity)
diff --git a/suites/libvirt-cim/cimtest/SettingsDefineCapabilities/01_forward.py b/suites/libvirt-cim/cimtest/SettingsDefineCapabilities/01_forward.py
--- a/suites/libvirt-cim/cimtest/SettingsDefineCapabilities/01_forward.py
+++ b/suites/libvirt-cim/cimtest/SettingsDefineCapabilities/01_forward.py
@@ -142,7 +142,7 @@
if dpool.InstanceID == None or mpool.InstanceID == None \
or npool.InstanceID == None or ppool.InstanceID == None:
logger.error("Get pool None")
- return FAIL
+ return FAIL, None
else:
pool_set = [dpool, mpool, ppool, npool]
except Exception, detail:
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/28_definesystem_with_vsi_profile.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/28_definesystem_with_vsi_profile.py
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/28_definesystem_with_vsi_profile.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/28_definesystem_with_vsi_profile.py
@@ -175,6 +175,7 @@
nrasd_cn = get_typed_class(virt, 'NetResourceAllocationSettingData')
status = FAIL
+ cxml = None
try:
rasd_list = get_rasd_list(server, virt, vsi_defaults, nrasd_cn)
@@ -208,8 +209,9 @@
except Exception, details:
logger.error(details)
- cxml.cim_destroy(server)
- cxml.undefine(server)
+ if cxml is not None:
+ cxml.cim_destroy(server)
+ cxml.undefine(server)
return status
13 years, 6 months
Release of libvirt-cim-0.5.13
by Chip Vincent
The new release is available at:
ftp://libvirt.org/libvirt-cim/libvirt-cim-0.5.13.tar.gz
libvirt-cim-0.5.13
* Add write support for FilterList (Chip Vincent)
* Add read-only support (Eduardo Lima)
* Fix MemoryPool.Reserved (Chip Vincent)
* Check libvirt version before compiling ACL (Chip Vincent)
* Fix AppliedFilterList Associators (Chip Vincent)
* Libvirt dependency should be 0.6.3 (Chip Vincent)
* Conditional build requirement for RPM package (Eduardo Lima)
* Fill up NetworkName attribute (Eduardo Lima)
* Add DCN ACL classes & providers (Chip Vincent)
* Configure tweaks (Eduardo Lima)
* Update RPM spec file to match Fedora (Eduardo Lima)
* Migration was failing due to lost connection (Sharad Mishra)
* Fix file permissions (Eduardo Lima)
* Update .hgignore (Eduardo Lima)
* Configure: Check for libuuid (Eduardo Lima)
* Fix for VirtualSystemManagementService test (Chip Vincent)
* Fix connection leaks (Sharad Mishra)
* Ensure graphics devices have unique IDs (Chip Vincent)
* Add support for StoragePool autostart (Sharad Mishra)
* Add support for console/serial grahpics devices (Chip Vincent)
* Add check to verify that sysname is not null (Sharad Mishra)
* Added support for disk driver (Sharad Mishra)
* Add VNC autoport support (Chip Vincent)
* Add support for Pegasus OOP grouping (Chip Vincent)
* Add SCCN and CCN for SwitchService (Sharad Mishra)
* Fixing NullPointerException (Sharad Mishra)
* Auto refresh StoragePools (Sharad Mishra)
* Query switch to find its vsi capabilities (Sharad Mishra)
* Set CreationClassName property in VSMS (Sharad Mishra)
* Set/Reset VM autostart (Sharad Mishra)
* Remove test for duplicate mac address (Sharad Mishra)
* Add support for deactivation of disk caching (Sharad Mishra)
* Add readonly property to disk (Sharad Mishra)
--
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent(a)linux.vnet.ibm.com
13 years, 6 months
[PATCH] (#2) Add write support for FilterList and NestedFilterList
by Chip Vincent
# HG changeset patch
# User Chip Vincent <cvincent(a)us.ibm.com>
# Date 1309213800 14400
# Node ID 2a1c7e5112590eb7157b566facd61ea9fc815b85
# Parent 75411f53df02159c3fa6ce5810c9446579e3d66d
(#2) Add write support for FilterList and NestedFilterList
Changes since #1:
- fixed compilation issue
This allows clients to create new filter lists and then associate them
with other filter lists to create complex filters. This patch also has some
minor bug fixes to AppliedFilterList so the new filters can be applied
to existing NetworkPort instances. The new cimtests for the create/delete
associations are still under construction, but you can easily test
FilterList create/delete (foundation) with the following commands:
# wbemcli ci 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="",Name="",SystemCreationClassName="",SystemName=""' 'Name="test"'
# wbemcli di 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="KVM_FilterList",Name="test",SystemCreationClassName="KVM_HostSystem",SystemName="oc0840652111.ibm.com"'
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
diff --git a/libxkutil/acl_parsing.c b/libxkutil/acl_parsing.c
--- a/libxkutil/acl_parsing.c
+++ b/libxkutil/acl_parsing.c
@@ -551,6 +551,57 @@
#endif
}
+int create_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ virNWFilterPtr vfilter = NULL;
+ char *xml = NULL;
+
+ if (filter == NULL)
+ return 0;
+
+ xml = filter_to_xml(filter);
+ if (xml == NULL)
+ return 0;
+
+ vfilter = virNWFilterDefineXML(conn, xml);
+
+ free(xml);
+
+ if (vfilter == NULL)
+ return 0;
+
+ virNWFilterFree(vfilter);
+
+ return 1;
+}
+
+int update_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ if (delete_filter(conn, filter) == 0 ||
+ create_filter(conn, filter) == 0)
+ return 0;
+
+ return 1;
+}
+
+int delete_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ virNWFilterPtr vfilter = NULL;
+
+ if (filter == NULL)
+ return 0;
+
+ vfilter = virNWFilterLookupByUUIDString(conn, filter->uuid);
+ if (vfilter == NULL)
+ return 0;
+
+ if (virNWFilterUndefine(vfilter) != 0) {
+ virNWFilterFree(vfilter);
+ return 0;
+ }
+
+ return 1;
+}
int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule)
{
@@ -605,6 +656,28 @@
return 1;
}
+int remove_filter_ref(struct acl_filter *filter, const char *name)
+{
+ int i;
+ char **old_refs = NULL;
+
+ if ((filter == NULL) || (name == NULL))
+ return 0;
+
+ /* TODO: called infrequently, but needs optimization */
+ old_refs = filter->refs;
+
+ for (i = 0; i < filter->ref_ct; i++) {
+ if (STREQC(old_refs[i], name)) {
+ free(old_refs[i]);
+ }
+ else
+ append_filter_ref(filter, old_refs[i]);
+ }
+
+ return 1;
+}
+
char *make_rule_id(const char *filter, int index)
{
int ret;
diff --git a/libxkutil/acl_parsing.h b/libxkutil/acl_parsing.h
--- a/libxkutil/acl_parsing.h
+++ b/libxkutil/acl_parsing.h
@@ -194,11 +194,17 @@
char *make_rule_id(const char *filter, int index);
int parse_rule_id(const char *rule_id, char **filter, int *index);
+int create_filter(virConnectPtr conn, struct acl_filter *filter);
+int update_filter(virConnectPtr conn, struct acl_filter *filter);
+int delete_filter(virConnectPtr conn, struct acl_filter *filter);
+
/** NOTE: Both append functions take parameters allocated by caller and
* freed by cleanup_filter(s)
*/
int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule);
int append_filter_ref(struct acl_filter *filter, char *name);
+int remove_filter_ref(struct acl_filter *filter, const char *name);
+
#endif
/*
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -1360,6 +1360,59 @@
return xml;
}
+char *filter_to_xml(struct acl_filter *filter)
+{
+ char *msg = XML_ERROR;
+ char *xml = NULL;
+ xmlNodePtr root = NULL;
+ xmlNodePtr tmp = NULL;
+ int i;
+
+ root = xmlNewNode(NULL, BAD_CAST "filter");
+ if (root == NULL)
+ goto out;
+
+ if (xmlNewProp(root, BAD_CAST "name", BAD_CAST filter->name) == NULL)
+ goto out;
+
+ if (filter->chain != NULL)
+ if (xmlNewProp(root, BAD_CAST "chain",
+ BAD_CAST filter->chain) == NULL)
+ goto out;
+
+ if (filter->uuid != NULL) {
+ tmp = xmlNewChild(root, NULL, BAD_CAST "uuid", NULL);
+ if (xmlNewProp(tmp, NULL, BAD_CAST filter->uuid) == NULL)
+ goto out;
+ }
+
+ for (i = 0; i < filter->ref_ct; i++) {
+ tmp = xmlNewChild(root, NULL, BAD_CAST "filterref", NULL);
+ if (xmlNewProp(tmp, BAD_CAST "filter",
+ BAD_CAST filter->refs[i]) == NULL)
+ goto out;
+ }
+
+ /* TODO: Not yet supported
+ for (i = 0; i < filter->rule_ct; i++) {
+ msg = rule_to_xml(root, filter->rules[i]);
+ if (msg != NULL)
+ goto out;
+ }
+ */
+
+ xml = tree_to_xml(root);
+ if (xml != NULL)
+ msg = NULL; /* no errors */
+
+ out:
+ CU_DEBUG("Filter XML: %s", msg);
+
+ xmlFreeNode(root);
+
+ return xml;
+}
+
/*
* Local Variables:
* mode: C
diff --git a/schema/NestedFilterList.registration b/schema/NestedFilterList.registration
--- a/schema/NestedFilterList.registration
+++ b/schema/NestedFilterList.registration
@@ -1,3 +1,3 @@
# Copyright IBM Corp. 2011
# Classname Namespace ProviderName ProviderModule ProviderTypes
-KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList association
+KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList instance association
diff --git a/src/Virt_AppliedFilterList.c b/src/Virt_AppliedFilterList.c
--- a/src/Virt_AppliedFilterList.c
+++ b/src/Virt_AppliedFilterList.c
@@ -411,10 +411,6 @@
libvirt_cim_init(),
handlers);
-DEFAULT_GI();
-DEFAULT_EIN();
-DEFAULT_EI();
-
static CMPIStatus CreateInstance(
CMPIInstanceMI *self,
const CMPIContext *context,
@@ -434,6 +430,8 @@
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
if (cu_get_ref_prop(instance, "Antecedent",
&antecedent) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
@@ -473,6 +471,8 @@
goto out;
}
+ CU_DEBUG("DeviceID = %s", device_name);
+
if (parse_fq_devid(device_name, &domain_name, &net_name) == 0) {
CU_DEBUG("Failed to parse devid");
goto out;
@@ -492,7 +492,11 @@
goto out;
}
- free(device->dev.net.filter_ref);
+ if (device->dev.net.filter_ref != NULL) {
+ free(device->dev.net.filter_ref);
+ device->dev.net.filter_ref = NULL;
+ }
+
device->dev.net.filter_ref = strdup(filter_name);
if (update_device(dom, device) == 0) {
@@ -502,10 +506,10 @@
goto out;
}
+ CU_DEBUG("CreateInstance complete");
+
out:
- free((char *)filter_name);
free(domain_name);
- free((char *)device_name);
free(net_name);
cleanup_filter(filter);
@@ -535,6 +539,8 @@
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
if (cu_get_ref_path(reference, "Antecedent",
&antecedent) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
@@ -574,6 +580,8 @@
goto out;
}
+ CU_DEBUG("DeviceID = %s", device_name);
+
if (parse_fq_devid(device_name, &domain_name, &net_name) == 0) {
CU_DEBUG("Failed to parse devid");
goto out;
@@ -593,8 +601,10 @@
goto out;
}
- free(device->dev.net.filter_ref);
- device->dev.net.filter_ref = NULL;
+ if (device->dev.net.filter_ref != NULL) {
+ free(device->dev.net.filter_ref);
+ device->dev.net.filter_ref = NULL;
+ }
if (update_device(dom, device) == 0) {
cu_statusf(_BROKER, &s,
@@ -603,10 +613,10 @@
goto out;
}
+ CU_DEBUG("CreateInstance complete");
+
out:
- free((char *)filter_name);
free(domain_name);
- free((char *)device_name);
free(net_name);
cleanup_filter(filter);
@@ -618,12 +628,15 @@
return s;
}
+DEFAULT_GI();
+DEFAULT_EIN();
+DEFAULT_EI();
DEFAULT_MI();
DEFAULT_EQ();
DEFAULT_INST_CLEANUP();
STD_InstanceMIStub(,
- Virt_AppliedFilterEntry,
+ Virt_AppliedFilterList,
_BROKER,
libvirt_cim_init());
diff --git a/src/Virt_FilterList.c b/src/Virt_FilterList.c
--- a/src/Virt_FilterList.c
+++ b/src/Virt_FilterList.c
@@ -81,6 +81,32 @@
return inst;
}
+static struct acl_filter *convert_instance_to_filter(
+ const CMPIInstance *instance,
+ const CMPIContext *context,
+ CMPIStatus *s)
+{
+ struct acl_filter *filter = NULL;
+ const char *name = NULL;
+
+ if (cu_get_str_prop(instance, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Name property");
+ goto out;
+ }
+
+ filter = malloc(sizeof(*filter));
+ if (filter == NULL)
+ goto out;
+
+ memset(filter, 0, sizeof(*filter));
+ filter->name = strdup(name);
+
+ out:
+ return filter;
+}
+
CMPIStatus enum_filter_lists(const CMPIBroker *broker,
const CMPIContext *context,
const CMPIObjectPath *reference,
@@ -230,9 +256,114 @@
return s;
}
-DEFAULT_CI();
+static CMPIStatus CreateInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *name = NULL;
+ struct acl_filter *filter = NULL;
+ CMPIInstance *_instance = NULL;
+ virConnectPtr conn = NULL;
+
+ /**Get Name from instance rather than reference since keys
+ * are set by this provider, not the client.
+ */
+ if (cu_get_str_prop(instance, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Name property");
+ goto out;
+ }
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ get_filter_by_name(conn, name, &filter);
+ if (filter != NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_ALREADY_EXISTS,
+ "Instance already exists");
+ goto out;
+ }
+
+ filter = convert_instance_to_filter(instance, context, &s);
+ if (filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to convert instance to filter");
+ goto out;
+ }
+
+ if (create_filter(conn, filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to create filter");
+ goto out;
+ }
+
+ _instance = convert_filter_to_instance(filter,
+ _BROKER,
+ context,
+ reference,
+ &s);
+
+ if(_instance != NULL)
+ cu_return_instance_name(results, _instance);
+
+ CU_DEBUG("CreateInstance complete");
+
+ out:
+ cleanup_filter(filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+static CMPIStatus DeleteInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *name = NULL;
+ struct acl_filter *filter = NULL;
+ virConnectPtr conn = NULL;
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Unable to get Name from reference");
+ goto out;
+ }
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ get_filter_by_name(conn, name, &filter);
+ if (filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Instance does not exist");
+ goto out;
+ }
+
+ delete_filter(conn, filter);
+
+ out:
+ cleanup_filter(filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
DEFAULT_MI();
-DEFAULT_DI();
DEFAULT_EQ();
DEFAULT_INST_CLEANUP();
diff --git a/src/Virt_NestedFilterList.c b/src/Virt_NestedFilterList.c
--- a/src/Virt_NestedFilterList.c
+++ b/src/Virt_NestedFilterList.c
@@ -38,6 +38,71 @@
static const CMPIBroker *_BROKER;
+/* TODO: Port to libcmpiutil/args_util.c */
+/**
+ * Get a reference property of an instance
+ *
+ * @param inst The instance
+ * @param prop The property name
+ * @param reference A pointer to a CMPIObjectPath* that will be set
+ * if successful
+ * @returns
+ * - CMPI_RC_OK on success
+ * - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
+ * - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
+ * - CMPI_RC_OK otherwise
+ */
+static CMPIrc cu_get_ref_prop(const CMPIInstance *instance,
+ const char *prop,
+ CMPIObjectPath **reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIData value;
+
+ /* REQUIRE_PROPERY_DEFINED(instance, prop, value, &s); */
+ value = CMGetProperty(instance, prop, &s);
+ if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
+ return CMPI_RC_ERR_NO_SUCH_PROPERTY;
+
+ if ((value.type != CMPI_ref) || CMIsNullObject(value.value.ref))
+ return CMPI_RC_ERR_TYPE_MISMATCH;
+
+ *reference = value.value.ref;
+
+ return CMPI_RC_OK;
+}
+
+/* TODO: Port to libcmpiutil/args_util.c */
+/**
+ * Get a reference component of an object path
+ *
+ * @param _reference The reference
+ * @param key The key name
+ * @param reference A pointer to a CMPIObjectPath* that will be set
+ * if successful
+ * @returns
+ * - CMPI_RC_OK on success
+ * - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
+ * - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
+ * - CMPI_RC_OK otherwise
+ */
+static CMPIrc cu_get_ref_path(const CMPIObjectPath *reference,
+ const char *key,
+ CMPIObjectPath **_reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIData value;
+
+ /* REQUIRE_PROPERY_DEFINED(instance, prop, value, &s); */
+ value = CMGetKey(reference, key, &s);
+ if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
+ return CMPI_RC_ERR_NO_SUCH_PROPERTY;
+
+ /* how to parse and object path? */
+
+ return CMPI_RC_OK;
+}
+
/**
* given a filter, find all *direct* filter_refs
*/
@@ -224,6 +289,202 @@
libvirt_cim_init(),
handlers);
+DEFAULT_GI();
+DEFAULT_EIN();
+DEFAULT_EI();
+
+static CMPIStatus CreateInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *antecedent = NULL;
+ const char *parent_name = NULL;
+ struct acl_filter *parent_filter = NULL;
+ CMPIObjectPath *dependent = NULL;
+ const char *child_name = NULL;
+ struct acl_filter *child_filter = NULL;
+ virConnectPtr conn = NULL;
+
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ if (cu_get_ref_prop(instance, "Antecedent",
+ &antecedent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &parent_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, parent_name, &parent_filter);
+ if (parent_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Antecedent.Name object does not exist");
+ goto out;
+ }
+
+ if (cu_get_ref_prop(instance, "Dependent",
+ &dependent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &child_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, child_name, &child_filter);
+ if (child_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Dependent.Name object does not exist");
+ goto out;
+ }
+
+ if (append_filter_ref(parent_filter, strdup(child_name)) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to append filter reference");
+ goto out;
+ }
+
+ if (update_filter(conn, parent_filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to update filter");
+ goto out;
+ }
+
+ CU_DEBUG("CreateInstance completed");
+
+ out:
+ cleanup_filter(parent_filter);
+ cleanup_filter(child_filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+static CMPIStatus DeleteInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *antecedent = NULL;
+ const char *parent_name = NULL;
+ struct acl_filter *parent_filter = NULL;
+ CMPIObjectPath *dependent = NULL;
+ const char *child_name = NULL;
+ struct acl_filter *child_filter = NULL;
+ virConnectPtr conn = NULL;
+
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ if (cu_get_ref_path(reference, "Antecedent",
+ &antecedent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &parent_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, parent_name, &parent_filter);
+ if (parent_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Antecedent.Name object does not exist");
+ goto out;
+ }
+
+ if (cu_get_ref_path(reference, "Dependent",
+ &dependent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &child_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, child_name, &child_filter);
+ if (child_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Dependent.Name object does not exist");
+ goto out;
+ }
+
+ if (remove_filter_ref(parent_filter, child_name) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to remove filter reference");
+ goto out;
+ }
+
+ if (update_filter(conn, parent_filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to update filter");
+ goto out;
+ }
+
+ CU_DEBUG("CreateInstance completed");
+
+ out:
+ cleanup_filter(parent_filter);
+ cleanup_filter(child_filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+DEFAULT_MI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+STD_InstanceMIStub(,
+ Virt_NestedFilterList,
+ _BROKER,
+ libvirt_cim_init());
+
/*
* Local Variables:
* mode: C
13 years, 6 months
[PATCH] (#4) Add read-only support
by Eduardo Lima (Etrunko)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1308270993 14400
# Node ID 83f0e989145d86bc84dac05ef371c536a9734673
# Parent a2f523cd39c29977ed07247a38316d44f5123874
Add read-only support.
This patch enables a consumer of libvirt-cim to put it in read-only
mode by adding the key-value pair 'readonly=true' to libvirt-cim.conf.
Also clean-up some extra whitespace in touched files.
Changes from #1:
- Fix build error on RHEL 6
Changes from #2:
- Small typo in libvirt-cim.conf
Changes from #3:
- Removed unecessary debug messages
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/Makefile.am b/Makefile.am
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,9 @@
pkgdata_SCRIPTS = provider-register.sh
+libvirtcim_confdir = @sysconfdir@
+dist_libvirtcim_conf_DATA = @PACKAGE@.conf
+
EXTRA_DIST = schema $(MOFS) $(REGS) $(INTEROP_MOFS) $(INTEROP_REGS) \
$(pkgdata_SCRIPTS) libvirt-cim.spec.in libvirt-cim.spec \
doc/CodingStyle doc/SubmittingPatches \
diff --git a/acinclude.m4 b/acinclude.m4
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -270,6 +270,15 @@
LDFLAGS="$LDFLAGS $LIBUUID_LIBS"
])
+AC_DEFUN([CHECK_LIBCONFIG],
+ [
+ PKG_CHECK_MODULES([LIBCONFIG], [libconfig])
+ AC_SUBST([LIBCONFIG_CFLAGS])
+ AC_SUBST([LIBCONFIG_LIBS])
+ CPPFLAGS="$CPPFLAGS $LIBCONFIG_CFLAGS"
+ LDFLAGS="$LDFLAGS $LIBCONFIG_LIBS"
+ ])
+
# A convenience macro that spits out a fail message for a particular test
#
# AC_CHECK_FAIL($LIBNAME,$PACKAGE_SUGGEST,$URL,$EXTRA)
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@
CHECK_LIBXML2
CHECK_LIBCU
CHECK_LIBUUID
+CHECK_LIBCONFIG
CFLAGS_STRICT="-Werror"
diff --git a/libvirt-cim.conf b/libvirt-cim.conf
new file mode 100644
--- /dev/null
+++ b/libvirt-cim.conf
@@ -0,0 +1,13 @@
+#
+# libvirt-cim config file
+#
+# This config file is based on the libconfig format. For more information,
+# please check http://www.hyperrealm.com/libconfig/
+#
+
+# readonly (boolean)
+# Defines if connection to libvirt is read-only or not
+# Possible values: {true,false}
+# Default value: false
+#
+# readonly = false;
diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in
--- a/libvirt-cim.spec.in
+++ b/libvirt-cim.spec.in
@@ -26,6 +26,7 @@
BuildRequires: libxml2-devel
BuildRequires: libcmpiutil-devel
+BuildRequires: libconfig-devel
BuildConflicts: sblim-cmpi-devel
%description
@@ -135,6 +136,7 @@
%{_datadir}/libvirt-cim/*.registration
%{_datadir}/libvirt-cim/cim_schema_*-MOFs.zip
%{_sysconfdir}/ld.so.conf.d/libvirt-cim.conf
+%{_sysconfdir}/libvirt-cim.conf
%changelog
* Wed Oct 28 2009 Richard Maciel <rmaciel(a)linux.vnet.ibm.com> - 0.1-1
diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
--- a/libxkutil/Makefile.am
+++ b/libxkutil/Makefile.am
@@ -1,7 +1,8 @@
# Copyright IBM Corp. 2007
SUBDIRS = tests
-CFLAGS += $(CFLAGS_STRICT)
+AM_CFLAGS = $(CFLAGS_STRICT) \
+ -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
diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
--- a/libxkutil/misc_util.c
+++ b/libxkutil/misc_util.c
@@ -35,11 +35,12 @@
#include <libcmpiutil/libcmpiutil.h>
#include <libcmpiutil/std_association.h>
+#include <libconfig.h>
#include "misc_util.h"
#include "cs_util.h"
-#include <config.h>
+#include "config.h"
#define URI_ENV "HYPURI"
@@ -55,6 +56,37 @@
return NULL;
}
+static int is_read_only(void)
+{
+ config_t conf;
+ int ret, readonly = 0;
+ const char *readonly_str = "readonly";
+
+ config_init(&conf);
+
+ ret = config_read_file(&conf, LIBVIRTCIM_CONF);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error reading config file at line %d: '%s'\n",
+ conf.error_line, conf.error_text);
+ goto out;
+ }
+
+ ret = config_lookup_bool(&conf, readonly_str, &readonly);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error: '%s' not found in config file\n",
+ readonly_str);
+ goto out;
+ }
+
+ CU_DEBUG("'%s' value in '%s' config file: %d\n", readonly_str,
+ LIBVIRTCIM_CONF, readonly);
+out:
+ config_destroy(&conf);
+
+ /* Default value is 0 (false) */
+ return readonly;
+}
+
virConnectPtr connect_by_classname(const CMPIBroker *broker,
const char *classname,
CMPIStatus *s)
@@ -66,7 +98,7 @@
uri = cn_to_uri(classname);
if (!uri) {
- cu_statusf(broker, s,
+ cu_statusf(broker, s,
CMPI_RC_ERR_FAILED,
"Unable to generate URI from classname");
return NULL;
@@ -74,7 +106,11 @@
CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
- conn = virConnectOpen(uri);
+ if (is_read_only())
+ conn = virConnectOpenReadOnly(uri);
+ else
+ conn = virConnectOpen(uri);
+
if (!conn) {
CU_DEBUG("Unable to connect to `%s'", uri);
return NULL;
@@ -258,7 +294,7 @@
inst = CMNewInstance(broker, op, &s);
if ((s.rc != CMPI_RC_OK) || CMIsNullObject(inst))
goto out;
-
+
CMSetProperty(inst, "CreationClassName",
(CMPIValue *)new_cn, CMPI_chars);
@@ -310,7 +346,7 @@
if (STREQC(pfx, "CIM")) {
cu_statusf(broker, status,
CMPI_RC_ERR_FAILED,
- "Please exactly specify the class (check CIMOM behavior!): %s",
+ "Please exactly specify the class (check CIMOM behavior!): %s",
CLASSNAME(reference));
rc = false;
}
@@ -347,7 +383,7 @@
free(pfx);
}
-
+
free(ref_pfx);
return rc;
}
@@ -367,13 +403,13 @@
CLASSNAME(source_ref),
assoc_classname,
NAMESPACE(source_ref));
-
+
if (ref_inst != NULL) {
CMPIObjectPath *target_ref;
-
+
target_ref = CMGetObjectPath(target_inst, NULL);
- set_reference(assoc, ref_inst,
+ set_reference(assoc, ref_inst,
source_ref, target_ref);
}
13 years, 6 months
[PATCH] (#3) Add read-only support
by Eduardo Lima (Etrunko)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1308270993 14400
# Node ID 3a299dba1101ed6fc4c13fb90bdad7f24ed0d2ea
# Parent a2f523cd39c29977ed07247a38316d44f5123874
Add read-only support.
This patch enables a consumer of libvirt-cim to put it in read-only
mode by adding the key-value pair 'readonly=true' to libvirt-cim.conf.
Also clean-up some extra whitespace in touched files.
Changes from #1:
- Fix build error on RHEL 6
Changes from #2:
- Small typo in libvirt-cim.conf
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/Makefile.am b/Makefile.am
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,9 @@
pkgdata_SCRIPTS = provider-register.sh
+libvirtcim_confdir = @sysconfdir@
+dist_libvirtcim_conf_DATA = @PACKAGE@.conf
+
EXTRA_DIST = schema $(MOFS) $(REGS) $(INTEROP_MOFS) $(INTEROP_REGS) \
$(pkgdata_SCRIPTS) libvirt-cim.spec.in libvirt-cim.spec \
doc/CodingStyle doc/SubmittingPatches \
diff --git a/acinclude.m4 b/acinclude.m4
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -270,6 +270,15 @@
LDFLAGS="$LDFLAGS $LIBUUID_LIBS"
])
+AC_DEFUN([CHECK_LIBCONFIG],
+ [
+ PKG_CHECK_MODULES([LIBCONFIG], [libconfig])
+ AC_SUBST([LIBCONFIG_CFLAGS])
+ AC_SUBST([LIBCONFIG_LIBS])
+ CPPFLAGS="$CPPFLAGS $LIBCONFIG_CFLAGS"
+ LDFLAGS="$LDFLAGS $LIBCONFIG_LIBS"
+ ])
+
# A convenience macro that spits out a fail message for a particular test
#
# AC_CHECK_FAIL($LIBNAME,$PACKAGE_SUGGEST,$URL,$EXTRA)
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@
CHECK_LIBXML2
CHECK_LIBCU
CHECK_LIBUUID
+CHECK_LIBCONFIG
CFLAGS_STRICT="-Werror"
diff --git a/libvirt-cim.conf b/libvirt-cim.conf
new file mode 100644
--- /dev/null
+++ b/libvirt-cim.conf
@@ -0,0 +1,13 @@
+#
+# libvirt-cim config file
+#
+# This config file is based on the libconfig format. For more information,
+# please check http://www.hyperrealm.com/libconfig/
+#
+
+# readonly (boolean)
+# Defines if connection to libvirt is read-only or not
+# Possible values: {true,false}
+# Default value: false
+#
+# readonly = false;
diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in
--- a/libvirt-cim.spec.in
+++ b/libvirt-cim.spec.in
@@ -26,6 +26,7 @@
BuildRequires: libxml2-devel
BuildRequires: libcmpiutil-devel
+BuildRequires: libconfig-devel
BuildConflicts: sblim-cmpi-devel
%description
@@ -135,6 +136,7 @@
%{_datadir}/libvirt-cim/*.registration
%{_datadir}/libvirt-cim/cim_schema_*-MOFs.zip
%{_sysconfdir}/ld.so.conf.d/libvirt-cim.conf
+%{_sysconfdir}/libvirt-cim.conf
%changelog
* Wed Oct 28 2009 Richard Maciel <rmaciel(a)linux.vnet.ibm.com> - 0.1-1
diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
--- a/libxkutil/Makefile.am
+++ b/libxkutil/Makefile.am
@@ -1,7 +1,8 @@
# Copyright IBM Corp. 2007
SUBDIRS = tests
-CFLAGS += $(CFLAGS_STRICT)
+AM_CFLAGS = $(CFLAGS_STRICT) \
+ -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
diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
--- a/libxkutil/misc_util.c
+++ b/libxkutil/misc_util.c
@@ -35,11 +35,12 @@
#include <libcmpiutil/libcmpiutil.h>
#include <libcmpiutil/std_association.h>
+#include <libconfig.h>
#include "misc_util.h"
#include "cs_util.h"
-#include <config.h>
+#include "config.h"
#define URI_ENV "HYPURI"
@@ -55,6 +56,37 @@
return NULL;
}
+static int is_read_only(void)
+{
+ config_t conf;
+ int ret, readonly = 0;
+ const char *readonly_str = "readonly";
+
+ config_init(&conf);
+
+ ret = config_read_file(&conf, LIBVIRTCIM_CONF);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error reading config file at line %d: '%s'\n",
+ conf.error_line, conf.error_text);
+ goto out;
+ }
+
+ ret = config_lookup_bool(&conf, readonly_str, &readonly);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error: '%s' not found in config file\n",
+ readonly_str);
+ goto out;
+ }
+
+ CU_DEBUG("'%s' value in '%s' config file: %d\n", readonly_str,
+ LIBVIRTCIM_CONF, readonly);
+out:
+ config_destroy(&conf);
+
+ /* Default value is 0 (false) */
+ return readonly;
+}
+
virConnectPtr connect_by_classname(const CMPIBroker *broker,
const char *classname,
CMPIStatus *s)
@@ -66,7 +98,7 @@
uri = cn_to_uri(classname);
if (!uri) {
- cu_statusf(broker, s,
+ cu_statusf(broker, s,
CMPI_RC_ERR_FAILED,
"Unable to generate URI from classname");
return NULL;
@@ -74,7 +106,11 @@
CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
- conn = virConnectOpen(uri);
+ if (is_read_only())
+ conn = virConnectOpenReadOnly(uri);
+ else
+ conn = virConnectOpen(uri);
+
if (!conn) {
CU_DEBUG("Unable to connect to `%s'", uri);
return NULL;
@@ -258,7 +294,7 @@
inst = CMNewInstance(broker, op, &s);
if ((s.rc != CMPI_RC_OK) || CMIsNullObject(inst))
goto out;
-
+
CMSetProperty(inst, "CreationClassName",
(CMPIValue *)new_cn, CMPI_chars);
@@ -310,7 +346,7 @@
if (STREQC(pfx, "CIM")) {
cu_statusf(broker, status,
CMPI_RC_ERR_FAILED,
- "Please exactly specify the class (check CIMOM behavior!): %s",
+ "Please exactly specify the class (check CIMOM behavior!): %s",
CLASSNAME(reference));
rc = false;
}
@@ -347,7 +383,7 @@
free(pfx);
}
-
+
free(ref_pfx);
return rc;
}
@@ -367,13 +403,13 @@
CLASSNAME(source_ref),
assoc_classname,
NAMESPACE(source_ref));
-
+
if (ref_inst != NULL) {
CMPIObjectPath *target_ref;
-
+
target_ref = CMGetObjectPath(target_inst, NULL);
- set_reference(assoc, ref_inst,
+ set_reference(assoc, ref_inst,
source_ref, target_ref);
}
diff --git a/src/Virt_AllocationCapabilities.c b/src/Virt_AllocationCapabilities.c
--- a/src/Virt_AllocationCapabilities.c
+++ b/src/Virt_AllocationCapabilities.c
@@ -47,6 +47,7 @@
CLASSNAME(ref),
"AllocationCapabilities",
NAMESPACE(ref));
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
if (*alloc_cap == NULL) {
cu_statusf(broker, &s,
CMPI_RC_ERR_FAILED,
@@ -70,6 +71,7 @@
goto out;
}
out:
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -85,6 +87,7 @@
const char *inst_id;
int i;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
inst_list_init(&device_pool_list);
if (!provider_is_responsible(broker, ref, &s))
@@ -132,6 +135,7 @@
out:
inst_list_free(&device_pool_list);
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -144,14 +148,20 @@
CMPIInstance *pool;
CMPIStatus s;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
s = get_pool_by_name(broker, ref, poolid, &pool);
- if ((pool == NULL) || (s.rc != CMPI_RC_OK))
+ if ((pool == NULL) || (s.rc != CMPI_RC_OK)) {
+ CU_DEBUG("%s(%d): return 1 ", __FUNCTION__, __LINE__);
return s;
+ }
s = ac_from_pool(broker, ref, pool, inst);
- if (s.rc != CMPI_RC_OK)
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("%s(%d): return 2 ", __FUNCTION__, __LINE__);
return s;
+ }
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return cu_validate_ref(broker, ref, *inst);
}
@@ -165,6 +175,7 @@
CMPIStatus s = {CMPI_RC_OK, NULL};
struct inst_list list;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
inst_list_init(&list);
s = enum_alloc_cap_instances(broker,
@@ -183,6 +194,7 @@
out:
inst_list_free(&list);
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -195,13 +207,16 @@
CMPIStatus s = {CMPI_RC_OK, NULL};
const char* id;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
if (cu_get_str_path(reference, "InstanceID", &id) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"No InstanceID specified");
+ CU_DEBUG("%s(%d): return 1 ", __FUNCTION__, __LINE__);
return s;
}
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return return_alloc_cap_instances(_BROKER,
reference,
results,
13 years, 6 months
[PATCH] (#2) Add read-only support
by Eduardo Lima (Etrunko)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1308270993 14400
# Node ID 5f1a03d548ef810f67be9e326d565222e01a0451
# Parent a2f523cd39c29977ed07247a38316d44f5123874
Add read-only support.
This patch enables a consumer of libvirt-cim to put it in read-only
mode by adding the key-value pair 'readonly=true' to libvirt-cim.conf.
Also clean-up some extra whitespace in touched files.
Changes from #1:
- Fix build error on RHEL 6
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/Makefile.am b/Makefile.am
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,9 @@
pkgdata_SCRIPTS = provider-register.sh
+libvirtcim_confdir = @sysconfdir@
+dist_libvirtcim_conf_DATA = @PACKAGE@.conf
+
EXTRA_DIST = schema $(MOFS) $(REGS) $(INTEROP_MOFS) $(INTEROP_REGS) \
$(pkgdata_SCRIPTS) libvirt-cim.spec.in libvirt-cim.spec \
doc/CodingStyle doc/SubmittingPatches \
diff --git a/acinclude.m4 b/acinclude.m4
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -270,6 +270,15 @@
LDFLAGS="$LDFLAGS $LIBUUID_LIBS"
])
+AC_DEFUN([CHECK_LIBCONFIG],
+ [
+ PKG_CHECK_MODULES([LIBCONFIG], [libconfig])
+ AC_SUBST([LIBCONFIG_CFLAGS])
+ AC_SUBST([LIBCONFIG_LIBS])
+ CPPFLAGS="$CPPFLAGS $LIBCONFIG_CFLAGS"
+ LDFLAGS="$LDFLAGS $LIBCONFIG_LIBS"
+ ])
+
# A convenience macro that spits out a fail message for a particular test
#
# AC_CHECK_FAIL($LIBNAME,$PACKAGE_SUGGEST,$URL,$EXTRA)
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@
CHECK_LIBXML2
CHECK_LIBCU
CHECK_LIBUUID
+CHECK_LIBCONFIG
CFLAGS_STRICT="-Werror"
diff --git a/libvirt-cim.conf b/libvirt-cim.conf
new file mode 100644
--- /dev/null
+++ b/libvirt-cim.conf
@@ -0,0 +1,13 @@
+#
+# libvirt-cim config file
+#
+# This config file is based on the libconfig format. For more information,
+# please check http://www.hyperrealm.com/libconfig/
+#
+
+# readonly (boolean)
+# Defines wether connection to libvirt is read-only or not
+# Possible values: {true,false}
+# Default value: false
+#
+# readonly = false;
diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in
--- a/libvirt-cim.spec.in
+++ b/libvirt-cim.spec.in
@@ -26,6 +26,7 @@
BuildRequires: libxml2-devel
BuildRequires: libcmpiutil-devel
+BuildRequires: libconfig-devel
BuildConflicts: sblim-cmpi-devel
%description
@@ -135,6 +136,7 @@
%{_datadir}/libvirt-cim/*.registration
%{_datadir}/libvirt-cim/cim_schema_*-MOFs.zip
%{_sysconfdir}/ld.so.conf.d/libvirt-cim.conf
+%{_sysconfdir}/libvirt-cim.conf
%changelog
* Wed Oct 28 2009 Richard Maciel <rmaciel(a)linux.vnet.ibm.com> - 0.1-1
diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
--- a/libxkutil/Makefile.am
+++ b/libxkutil/Makefile.am
@@ -1,7 +1,8 @@
# Copyright IBM Corp. 2007
SUBDIRS = tests
-CFLAGS += $(CFLAGS_STRICT)
+AM_CFLAGS = $(CFLAGS_STRICT) \
+ -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
diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
--- a/libxkutil/misc_util.c
+++ b/libxkutil/misc_util.c
@@ -35,11 +35,12 @@
#include <libcmpiutil/libcmpiutil.h>
#include <libcmpiutil/std_association.h>
+#include <libconfig.h>
#include "misc_util.h"
#include "cs_util.h"
-#include <config.h>
+#include "config.h"
#define URI_ENV "HYPURI"
@@ -55,6 +56,37 @@
return NULL;
}
+static int is_read_only(void)
+{
+ config_t conf;
+ int ret, readonly = 0;
+ const char *readonly_str = "readonly";
+
+ config_init(&conf);
+
+ ret = config_read_file(&conf, LIBVIRTCIM_CONF);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error reading config file at line %d: '%s'\n",
+ conf.error_line, conf.error_text);
+ goto out;
+ }
+
+ ret = config_lookup_bool(&conf, readonly_str, &readonly);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error: '%s' not found in config file\n",
+ readonly_str);
+ goto out;
+ }
+
+ CU_DEBUG("'%s' value in '%s' config file: %d\n", readonly_str,
+ LIBVIRTCIM_CONF, readonly);
+out:
+ config_destroy(&conf);
+
+ /* Default value is 0 (false) */
+ return readonly;
+}
+
virConnectPtr connect_by_classname(const CMPIBroker *broker,
const char *classname,
CMPIStatus *s)
@@ -66,7 +98,7 @@
uri = cn_to_uri(classname);
if (!uri) {
- cu_statusf(broker, s,
+ cu_statusf(broker, s,
CMPI_RC_ERR_FAILED,
"Unable to generate URI from classname");
return NULL;
@@ -74,7 +106,11 @@
CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
- conn = virConnectOpen(uri);
+ if (is_read_only())
+ conn = virConnectOpenReadOnly(uri);
+ else
+ conn = virConnectOpen(uri);
+
if (!conn) {
CU_DEBUG("Unable to connect to `%s'", uri);
return NULL;
@@ -258,7 +294,7 @@
inst = CMNewInstance(broker, op, &s);
if ((s.rc != CMPI_RC_OK) || CMIsNullObject(inst))
goto out;
-
+
CMSetProperty(inst, "CreationClassName",
(CMPIValue *)new_cn, CMPI_chars);
@@ -310,7 +346,7 @@
if (STREQC(pfx, "CIM")) {
cu_statusf(broker, status,
CMPI_RC_ERR_FAILED,
- "Please exactly specify the class (check CIMOM behavior!): %s",
+ "Please exactly specify the class (check CIMOM behavior!): %s",
CLASSNAME(reference));
rc = false;
}
@@ -347,7 +383,7 @@
free(pfx);
}
-
+
free(ref_pfx);
return rc;
}
@@ -367,13 +403,13 @@
CLASSNAME(source_ref),
assoc_classname,
NAMESPACE(source_ref));
-
+
if (ref_inst != NULL) {
CMPIObjectPath *target_ref;
-
+
target_ref = CMGetObjectPath(target_inst, NULL);
- set_reference(assoc, ref_inst,
+ set_reference(assoc, ref_inst,
source_ref, target_ref);
}
diff --git a/src/Virt_AllocationCapabilities.c b/src/Virt_AllocationCapabilities.c
--- a/src/Virt_AllocationCapabilities.c
+++ b/src/Virt_AllocationCapabilities.c
@@ -47,6 +47,7 @@
CLASSNAME(ref),
"AllocationCapabilities",
NAMESPACE(ref));
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
if (*alloc_cap == NULL) {
cu_statusf(broker, &s,
CMPI_RC_ERR_FAILED,
@@ -70,6 +71,7 @@
goto out;
}
out:
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -85,6 +87,7 @@
const char *inst_id;
int i;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
inst_list_init(&device_pool_list);
if (!provider_is_responsible(broker, ref, &s))
@@ -132,6 +135,7 @@
out:
inst_list_free(&device_pool_list);
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -144,14 +148,20 @@
CMPIInstance *pool;
CMPIStatus s;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
s = get_pool_by_name(broker, ref, poolid, &pool);
- if ((pool == NULL) || (s.rc != CMPI_RC_OK))
+ if ((pool == NULL) || (s.rc != CMPI_RC_OK)) {
+ CU_DEBUG("%s(%d): return 1 ", __FUNCTION__, __LINE__);
return s;
+ }
s = ac_from_pool(broker, ref, pool, inst);
- if (s.rc != CMPI_RC_OK)
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("%s(%d): return 2 ", __FUNCTION__, __LINE__);
return s;
+ }
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return cu_validate_ref(broker, ref, *inst);
}
@@ -165,6 +175,7 @@
CMPIStatus s = {CMPI_RC_OK, NULL};
struct inst_list list;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
inst_list_init(&list);
s = enum_alloc_cap_instances(broker,
@@ -183,6 +194,7 @@
out:
inst_list_free(&list);
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return s;
}
@@ -195,13 +207,16 @@
CMPIStatus s = {CMPI_RC_OK, NULL};
const char* id;
+ CU_DEBUG("%s(%d): Begin", __FUNCTION__, __LINE__);
if (cu_get_str_path(reference, "InstanceID", &id) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"No InstanceID specified");
+ CU_DEBUG("%s(%d): return 1 ", __FUNCTION__, __LINE__);
return s;
}
+ CU_DEBUG("%s(%d): End", __FUNCTION__, __LINE__);
return return_alloc_cap_instances(_BROKER,
reference,
results,
13 years, 6 months
[PATCH] Add read-only support
by Eduardo Lima (Etrunko)
# HG changeset patch
# User Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
# Date 1308270993 14400
# Node ID 9be9d0b2eed352a96bd07dcff435b8de5f7a43c6
# Parent a2f523cd39c29977ed07247a38316d44f5123874
Add read-only support.
This patch enables a consumer of libvirt-cim to put it in read-only
mode by adding the key-value pair 'readonly=true' to libvirt-cim.conf.
Also clean-up some extra whitespace in touched files.
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
diff --git a/Makefile.am b/Makefile.am
--- a/Makefile.am
+++ b/Makefile.am
@@ -172,6 +172,9 @@
pkgdata_SCRIPTS = provider-register.sh
+libvirtcim_confdir = @sysconfdir@
+dist_libvirtcim_conf_DATA = @PACKAGE@.conf
+
EXTRA_DIST = schema $(MOFS) $(REGS) $(INTEROP_MOFS) $(INTEROP_REGS) \
$(pkgdata_SCRIPTS) libvirt-cim.spec.in libvirt-cim.spec \
doc/CodingStyle doc/SubmittingPatches \
diff --git a/acinclude.m4 b/acinclude.m4
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -270,6 +270,15 @@
LDFLAGS="$LDFLAGS $LIBUUID_LIBS"
])
+AC_DEFUN([CHECK_LIBCONFIG],
+ [
+ PKG_CHECK_MODULES([LIBCONFIG], [libconfig])
+ AC_SUBST([LIBCONFIG_CFLAGS])
+ AC_SUBST([LIBCONFIG_LIBS])
+ CPPFLAGS="$CPPFLAGS $LIBCONFIG_CFLAGS"
+ LDFLAGS="$LDFLAGS $LIBCONFIG_LIBS"
+ ])
+
# A convenience macro that spits out a fail message for a particular test
#
# AC_CHECK_FAIL($LIBNAME,$PACKAGE_SUGGEST,$URL,$EXTRA)
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@
CHECK_LIBXML2
CHECK_LIBCU
CHECK_LIBUUID
+CHECK_LIBCONFIG
CFLAGS_STRICT="-Werror"
diff --git a/libvirt-cim.conf b/libvirt-cim.conf
new file mode 100644
--- /dev/null
+++ b/libvirt-cim.conf
@@ -0,0 +1,13 @@
+#
+# libvirt-cim config file
+#
+# This config file is based on the libconfig format. For more information,
+# please check http://www.hyperrealm.com/libconfig/
+#
+
+# readonly (boolean)
+# Defines wether connection to libvirt is read-only or not
+# Possible values: {true,false}
+# Default value: false
+#
+# readonly = false;
diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in
--- a/libvirt-cim.spec.in
+++ b/libvirt-cim.spec.in
@@ -26,6 +26,7 @@
BuildRequires: libxml2-devel
BuildRequires: libcmpiutil-devel
+BuildRequires: libconfig-devel
BuildConflicts: sblim-cmpi-devel
%description
@@ -135,6 +136,7 @@
%{_datadir}/libvirt-cim/*.registration
%{_datadir}/libvirt-cim/cim_schema_*-MOFs.zip
%{_sysconfdir}/ld.so.conf.d/libvirt-cim.conf
+%{_sysconfdir}/libvirt-cim.conf
%changelog
* Wed Oct 28 2009 Richard Maciel <rmaciel(a)linux.vnet.ibm.com> - 0.1-1
diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
--- a/libxkutil/Makefile.am
+++ b/libxkutil/Makefile.am
@@ -1,7 +1,8 @@
# Copyright IBM Corp. 2007
SUBDIRS = tests
-CFLAGS += $(CFLAGS_STRICT)
+AM_CFLAGS = $(CFLAGS_STRICT) \
+ -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
diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
--- a/libxkutil/misc_util.c
+++ b/libxkutil/misc_util.c
@@ -35,11 +35,12 @@
#include <libcmpiutil/libcmpiutil.h>
#include <libcmpiutil/std_association.h>
+#include <libconfig.h>
#include "misc_util.h"
#include "cs_util.h"
-#include <config.h>
+#include "config.h"
#define URI_ENV "HYPURI"
@@ -55,6 +56,37 @@
return NULL;
}
+static int is_read_only(void)
+{
+ config_t conf;
+ int ret, readonly = 0;
+ const char *readonly_str = "readonly";
+
+ config_init(&conf);
+
+ ret = config_read_file(&conf, LIBVIRTCIM_CONF);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error reading config file(%d): '%s'\n",
+ conf.error_type, conf.error_text);
+ goto out;
+ }
+
+ ret = config_lookup_bool(&conf, readonly_str, &readonly);
+ if (ret == CONFIG_FALSE) {
+ CU_DEBUG("Error: '%s' not found in config file\n",
+ readonly_str);
+ goto out;
+ }
+
+ CU_DEBUG("'%s' value in '%s' config file: %d\n", readonly_str,
+ LIBVIRTCIM_CONF, readonly);
+out:
+ config_destroy(&conf);
+
+ /* Default value is 0 (false) */
+ return readonly;
+}
+
virConnectPtr connect_by_classname(const CMPIBroker *broker,
const char *classname,
CMPIStatus *s)
@@ -66,7 +98,7 @@
uri = cn_to_uri(classname);
if (!uri) {
- cu_statusf(broker, s,
+ cu_statusf(broker, s,
CMPI_RC_ERR_FAILED,
"Unable to generate URI from classname");
return NULL;
@@ -74,7 +106,11 @@
CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
- conn = virConnectOpen(uri);
+ if (is_read_only())
+ conn = virConnectOpenReadOnly(uri);
+ else
+ conn = virConnectOpen(uri);
+
if (!conn) {
CU_DEBUG("Unable to connect to `%s'", uri);
return NULL;
@@ -258,7 +294,7 @@
inst = CMNewInstance(broker, op, &s);
if ((s.rc != CMPI_RC_OK) || CMIsNullObject(inst))
goto out;
-
+
CMSetProperty(inst, "CreationClassName",
(CMPIValue *)new_cn, CMPI_chars);
@@ -310,7 +346,7 @@
if (STREQC(pfx, "CIM")) {
cu_statusf(broker, status,
CMPI_RC_ERR_FAILED,
- "Please exactly specify the class (check CIMOM behavior!): %s",
+ "Please exactly specify the class (check CIMOM behavior!): %s",
CLASSNAME(reference));
rc = false;
}
@@ -347,7 +383,7 @@
free(pfx);
}
-
+
free(ref_pfx);
return rc;
}
@@ -367,13 +403,13 @@
CLASSNAME(source_ref),
assoc_classname,
NAMESPACE(source_ref));
-
+
if (ref_inst != NULL) {
CMPIObjectPath *target_ref;
-
+
target_ref = CMGetObjectPath(target_inst, NULL);
- set_reference(assoc, ref_inst,
+ set_reference(assoc, ref_inst,
source_ref, target_ref);
}
13 years, 6 months
[PATCH] Add write support for FilterList and NestedFilterList
by Chip Vincent
# HG changeset patch
# User Chip Vincent <cvincent(a)us.ibm.com>
# Date 1309213800 14400
# Node ID 03e3f95547078be19d8d22cac83ce38daf7510b9
# Parent 75411f53df02159c3fa6ce5810c9446579e3d66d
Add write support for FilterList and NestedFilterList
This allows clients to create new filter lists and then associate them
with other filter lists to create complex filters. This patch also has some
minor bug fixes to AppliedFilterList so the new filters can be applied
to existing NetworkPort instances. The new cimtests for the create/delete
associations are still under construction, but you can easily test
FilterList create/delete (foundation) with the following commands:
# wbemcli ci 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="",Name="",SystemCreationClassName="",SystemName=""' 'Name="test"'
# wbemcli di 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="KVM_FilterList",Name="test",SystemCreationClassName="KVM_HostSystem",SystemName="oc0840652111.ibm.com"'
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
diff --git a/libxkutil/acl_parsing.c b/libxkutil/acl_parsing.c
--- a/libxkutil/acl_parsing.c
+++ b/libxkutil/acl_parsing.c
@@ -551,6 +551,57 @@
#endif
}
+int create_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ virNWFilterPtr vfilter = NULL;
+ char *xml = NULL;
+
+ if (filter == NULL)
+ return 0;
+
+ xml = filter_to_xml(filter);
+ if (xml == NULL)
+ return 0;
+
+ vfilter = virNWFilterDefineXML(conn, xml);
+
+ free(xml);
+
+ if (vfilter == NULL)
+ return 0;
+
+ virNWFilterFree(vfilter);
+
+ return 1;
+}
+
+int update_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ if (delete_filter(conn, filter) == 0 ||
+ create_filter(conn, filter) == 0)
+ return 0;
+
+ return 1;
+}
+
+int delete_filter(virConnectPtr conn, struct acl_filter *filter)
+{
+ virNWFilterPtr vfilter = NULL;
+
+ if (filter == NULL)
+ return 0;
+
+ vfilter = virNWFilterLookupByUUIDString(conn, filter->uuid);
+ if (vfilter == NULL)
+ return 0;
+
+ if (virNWFilterUndefine(vfilter) != 0) {
+ virNWFilterFree(vfilter);
+ return 0;
+ }
+
+ return 1;
+}
int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule)
{
@@ -605,6 +656,28 @@
return 1;
}
+int remove_filter_ref(struct acl_filter *filter, const char *name)
+{
+ int i;
+ char **old_refs = NULL;
+
+ if ((filter == NULL) || (name == NULL))
+ return 0;
+
+ /* TODO: called infrequently, but needs optimization */
+ old_refs = filter->refs;
+
+ for (i = 0; i < filter->ref_ct; i++) {
+ if (STREQC(old_refs[i], name)) {
+ free(old_refs[i]);
+ }
+ else
+ append_filter_ref(filter, old_refs[i]);
+ }
+
+ return 1;
+}
+
char *make_rule_id(const char *filter, int index)
{
int ret;
diff --git a/libxkutil/acl_parsing.h b/libxkutil/acl_parsing.h
--- a/libxkutil/acl_parsing.h
+++ b/libxkutil/acl_parsing.h
@@ -194,11 +194,17 @@
char *make_rule_id(const char *filter, int index);
int parse_rule_id(const char *rule_id, char **filter, int *index);
+int create_filter(virConnectPtr conn, struct acl_filter *filter);
+int update_filter(virConnectPtr conn, struct acl_filter *filter);
+int delete_filter(virConnectPtr conn, struct acl_filter *filter);
+
/** NOTE: Both append functions take parameters allocated by caller and
* freed by cleanup_filter(s)
*/
int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule);
int append_filter_ref(struct acl_filter *filter, char *name);
+int remove_filter_ref(struct acl_filter *filter, const char *name);
+
#endif
/*
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -1360,6 +1360,59 @@
return xml;
}
+char *filter_to_xml(struct acl_filter *filter)
+{
+ char *msg = XML_ERROR;
+ char *xml = NULL;
+ xmlNodePtr root = NULL;
+ xmlNodePtr tmp = NULL;
+ int i;
+
+ root = xmlNewNode(NULL, BAD_CAST "filter");
+ if (root == NULL)
+ goto out;
+
+ if (xmlNewProp(root, BAD_CAST "name", BAD_CAST filter->name) == NULL)
+ goto out;
+
+ if (filter->chain != NULL)
+ if (xmlNewProp(root, BAD_CAST "chain",
+ BAD_CAST filter->chain) == NULL)
+ goto out;
+
+ if (filter->uuid != NULL) {
+ tmp = xmlNewChild(root, NULL, BAD_CAST "uuid", NULL);
+ if (xmlNewProp(tmp, NULL, BAD_CAST filter->uuid) == NULL)
+ goto out;
+ }
+
+ for (i = 0; i < filter->ref_ct; i++) {
+ tmp = xmlNewChild(root, NULL, BAD_CAST "filterref", NULL);
+ if (xmlNewProp(tmp, BAD_CAST "filter",
+ BAD_CAST filter->refs[i]) == NULL)
+ goto out;
+ }
+
+ /* TODO: Not yet supported
+ for (i = 0; i < filter->rule_ct; i++) {
+ msg = rule_to_xml(root, filter->rules[i]);
+ if (msg != NULL)
+ goto out;
+ }
+ */
+
+ xml = tree_to_xml(root);
+ if (xml != NULL)
+ msg = NULL; /* no errors */
+
+ out:
+ CU_DEBUG("Filter XML: %s", msg);
+
+ xmlFreeNode(root);
+
+ return xml;
+}
+
/*
* Local Variables:
* mode: C
diff --git a/schema/NestedFilterList.registration b/schema/NestedFilterList.registration
--- a/schema/NestedFilterList.registration
+++ b/schema/NestedFilterList.registration
@@ -1,3 +1,3 @@
# Copyright IBM Corp. 2011
# Classname Namespace ProviderName ProviderModule ProviderTypes
-KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList association
+KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList instance association
diff --git a/src/Virt_AppliedFilterList.c b/src/Virt_AppliedFilterList.c
--- a/src/Virt_AppliedFilterList.c
+++ b/src/Virt_AppliedFilterList.c
@@ -411,10 +411,6 @@
libvirt_cim_init(),
handlers);
-DEFAULT_GI();
-DEFAULT_EIN();
-DEFAULT_EI();
-
static CMPIStatus CreateInstance(
CMPIInstanceMI *self,
const CMPIContext *context,
@@ -434,6 +430,8 @@
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
if (cu_get_ref_prop(instance, "Antecedent",
&antecedent) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
@@ -473,6 +471,8 @@
goto out;
}
+ CU_DEBUG("DeviceID = %s", device_name);
+
if (parse_fq_devid(device_name, &domain_name, &net_name) == 0) {
CU_DEBUG("Failed to parse devid");
goto out;
@@ -492,7 +492,11 @@
goto out;
}
- free(device->dev.net.filter_ref);
+ if (device->dev.net.filter_ref != NULL) {
+ free(device->dev.net.filter_ref);
+ device->dev.net.filter_ref = NULL;
+ }
+
device->dev.net.filter_ref = strdup(filter_name);
if (update_device(dom, device) == 0) {
@@ -502,10 +506,10 @@
goto out;
}
+ CU_DEBUG("CreateInstance complete");
+
out:
- free((char *)filter_name);
free(domain_name);
- free((char *)device_name);
free(net_name);
cleanup_filter(filter);
@@ -535,6 +539,8 @@
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
if (cu_get_ref_path(reference, "Antecedent",
&antecedent) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
@@ -574,6 +580,8 @@
goto out;
}
+ CU_DEBUG("DeviceID = %s", device_name);
+
if (parse_fq_devid(device_name, &domain_name, &net_name) == 0) {
CU_DEBUG("Failed to parse devid");
goto out;
@@ -593,8 +601,10 @@
goto out;
}
- free(device->dev.net.filter_ref);
- device->dev.net.filter_ref = NULL;
+ if (device->dev.net.filter_ref != NULL) {
+ free(device->dev.net.filter_ref);
+ device->dev.net.filter_ref = NULL;
+ }
if (update_device(dom, device) == 0) {
cu_statusf(_BROKER, &s,
@@ -603,10 +613,10 @@
goto out;
}
+ CU_DEBUG("CreateInstance complete");
+
out:
- free((char *)filter_name);
free(domain_name);
- free((char *)device_name);
free(net_name);
cleanup_filter(filter);
@@ -618,12 +628,15 @@
return s;
}
+DEFAULT_GI();
+DEFAULT_EIN();
+DEFAULT_EI();
DEFAULT_MI();
DEFAULT_EQ();
DEFAULT_INST_CLEANUP();
STD_InstanceMIStub(,
- Virt_AppliedFilterEntry,
+ Virt_AppliedFilterList,
_BROKER,
libvirt_cim_init());
diff --git a/src/Virt_FilterList.c b/src/Virt_FilterList.c
--- a/src/Virt_FilterList.c
+++ b/src/Virt_FilterList.c
@@ -81,6 +81,32 @@
return inst;
}
+static struct acl_filter *convert_instance_to_filter(
+ const CMPIInstance *instance,
+ const CMPIContext *context,
+ CMPIStatus *s)
+{
+ struct acl_filter *filter = NULL;
+ const char *name = NULL;
+
+ if (cu_get_str_prop(instance, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Name property");
+ goto out;
+ }
+
+ filter = malloc(sizeof(*filter));
+ if (filter == NULL)
+ goto out;
+
+ memset(filter, 0, sizeof(*filter));
+ filter->name = strdup(name);
+
+ out:
+ return filter;
+}
+
CMPIStatus enum_filter_lists(const CMPIBroker *broker,
const CMPIContext *context,
const CMPIObjectPath *reference,
@@ -230,9 +256,114 @@
return s;
}
-DEFAULT_CI();
+static CMPIStatus CreateInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *name = NULL;
+ struct acl_filter *filter = NULL;
+ CMPIInstance *_instance = NULL;
+ virConnectPtr conn = NULL;
+
+ /**Get Name from instance rather than reference since keys
+ * are set by this provider, not the client.
+ */
+ if (cu_get_str_prop(instance, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Name property");
+ goto out;
+ }
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ get_filter_by_name(conn, name, &filter);
+ if (filter != NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_ALREADY_EXISTS,
+ "Instance already exists");
+ goto out;
+ }
+
+ filter = convert_instance_to_filter(instance, context, &s);
+ if (filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to convert instance to filter");
+ goto out;
+ }
+
+ if (create_filter(conn, filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to create filter");
+ goto out;
+ }
+
+ _instance = convert_filter_to_instance(filter,
+ _BROKER,
+ context,
+ reference,
+ &s);
+
+ if(_instance != NULL)
+ cu_return_instance_name(results, _instance);
+
+ CU_DEBUG("CreateInstance complete");
+
+ out:
+ cleanup_filter(filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+static CMPIStatus DeleteInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *name = NULL;
+ struct acl_filter *filter = NULL;
+ virConnectPtr conn = NULL;
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Unable to get Name from reference");
+ goto out;
+ }
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ get_filter_by_name(conn, name, &filter);
+ if (filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Instance does not exist");
+ goto out;
+ }
+
+ delete_filter(conn, filter);
+
+ out:
+ cleanup_filter(filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
DEFAULT_MI();
-DEFAULT_DI();
DEFAULT_EQ();
DEFAULT_INST_CLEANUP();
diff --git a/src/Virt_NestedFilterList.c b/src/Virt_NestedFilterList.c
--- a/src/Virt_NestedFilterList.c
+++ b/src/Virt_NestedFilterList.c
@@ -38,6 +38,71 @@
static const CMPIBroker *_BROKER;
+/* TODO: Port to libcmpiutil/args_util.c */
+/**
+ * Get a reference property of an instance
+ *
+ * @param inst The instance
+ * @param prop The property name
+ * @param reference A pointer to a CMPIObjectPath* that will be set
+ * if successful
+ * @returns
+ * - CMPI_RC_OK on success
+ * - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
+ * - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
+ * - CMPI_RC_OK otherwise
+ */
+static CMPIrc cu_get_ref_prop(const CMPIInstance *instance,
+ const char *prop,
+ CMPIObjectPath **reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIData value;
+
+ /* REQUIRE_PROPERY_DEFINED(instance, prop, value, &s); */
+ value = CMGetProperty(instance, prop, &s);
+ if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
+ return CMPI_RC_ERR_NO_SUCH_PROPERTY;
+
+ if ((value.type != CMPI_ref) || CMIsNullObject(value.value.ref))
+ return CMPI_RC_ERR_TYPE_MISMATCH;
+
+ *reference = value.value.ref;
+
+ return CMPI_RC_OK;
+}
+
+/* TODO: Port to libcmpiutil/args_util.c */
+/**
+ * Get a reference component of an object path
+ *
+ * @param _reference The reference
+ * @param key The key name
+ * @param reference A pointer to a CMPIObjectPath* that will be set
+ * if successful
+ * @returns
+ * - CMPI_RC_OK on success
+ * - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
+ * - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
+ * - CMPI_RC_OK otherwise
+ */
+static CMPIrc cu_get_ref_path(const CMPIObjectPath *reference,
+ const char *key,
+ CMPIObjectPath **_reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIData value;
+
+ /* REQUIRE_PROPERY_DEFINED(instance, prop, value, &s); */
+ value = CMGetKey(reference, key, &s);
+ if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
+ return CMPI_RC_ERR_NO_SUCH_PROPERTY;
+
+ /* how to parse and object path? */
+
+ return CMPI_RC_OK;
+}
+
/**
* given a filter, find all *direct* filter_refs
*/
@@ -224,6 +289,203 @@
libvirt_cim_init(),
handlers);
+DEFAULT_GI();
+DEFAULT_EIN();
+DEFAULT_EI();
+
+static CMPIStatus CreateInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *antecedent = NULL;
+ const char *parent_name = NULL;
+ struct acl_filter *parent_filter = NULL;
+ CMPIObjectPath *dependent = NULL;
+ const char *child_name = NULL;
+ struct acl_filter *child_filter = NULL;
+ virConnectPtr conn = NULL;
+
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ if (cu_get_ref_prop(instance, "Antecedent",
+ &antecedent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &parent_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, parent_name, &parent_filter);
+ if (parent_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Antecedent.Name object does not exist");
+ goto out;
+ }
+
+ if (cu_get_ref_prop(instance, "Dependent",
+ &dependent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &child_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, child_name, &child_filter);
+ if (child_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Dependent.Name object does not exist");
+ goto out;
+ }
+
+ if (append_filter_ref(parent_filter, strdup(child_name)) == 0) {
+ free(dup);
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to append filter reference");
+ goto out;
+ }
+
+ if (update_filter(conn, parent_filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to update filter");
+ goto out;
+ }
+
+ CU_DEBUG("CreateInstance completed");
+
+ out:
+ cleanup_filter(parent_filter);
+ cleanup_filter(child_filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+static CMPIStatus DeleteInstance(
+ CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *antecedent = NULL;
+ const char *parent_name = NULL;
+ struct acl_filter *parent_filter = NULL;
+ CMPIObjectPath *dependent = NULL;
+ const char *child_name = NULL;
+ struct acl_filter *child_filter = NULL;
+ virConnectPtr conn = NULL;
+
+ CU_DEBUG("Reference = %s", REF2STR(reference));
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
+ if (conn == NULL)
+ goto out;
+
+ if (cu_get_ref_path(reference, "Antecedent",
+ &antecedent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &parent_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Antecedent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, parent_name, &parent_filter);
+ if (parent_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Antecedent.Name object does not exist");
+ goto out;
+ }
+
+ if (cu_get_ref_path(reference, "Dependent",
+ &dependent) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent property");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &child_name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get Dependent.Name property");
+ goto out;
+ }
+
+ get_filter_by_name(conn, child_name, &child_filter);
+ if (child_filter == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Dependent.Name object does not exist");
+ goto out;
+ }
+
+ if (remove_filter_ref(parent_filter, child_name) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to remove filter reference");
+ goto out;
+ }
+
+ if (update_filter(conn, parent_filter) == 0) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to update filter");
+ goto out;
+ }
+
+ CU_DEBUG("CreateInstance completed");
+
+ out:
+ cleanup_filter(parent_filter);
+ cleanup_filter(child_filter);
+ virConnectClose(conn);
+
+ return s;
+}
+
+DEFAULT_MI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+STD_InstanceMIStub(,
+ Virt_NestedFilterList,
+ _BROKER,
+ libvirt_cim_init());
+
/*
* Local Variables:
* mode: C
13 years, 6 months
[PATCH] (#2) Fix MemoryPool.Reserved to show only actively allocated memory
by Chip Vincent
# HG changeset patch
# User Chip Vincent <cvincent(a)us.ibm.com>
# Date 1308756569 14400
# Node ID c5a9510b6bd1569c6ab0966624306e29ecd81727
# Parent 6c29c5b284443e226e7d97e7e5f11848b0c4e761
(#2) Fix MemoryPool.Reserved to show only actively allocated memory.
It appears Reserved is meant to show memory that is taken (actively in use by
VMs) as opposed to memory that is potentially taken (assigned to defined, but
not running VMs).
Also added CurrentlyConsumedResource (a much clearer name for the same thing)
and ConsumedResourceUnits, fixed units to conform with DSP1045, and cleaned
up some extraneous whitespace.
Changes from #1:
- Fix return code checking
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
diff --git a/src/Virt_DevicePool.c b/src/Virt_DevicePool.c
--- a/src/Virt_DevicePool.c
+++ b/src/Virt_DevicePool.c
@@ -676,17 +676,47 @@
return memory != 0;
}
-static bool mempool_set_reserved(CMPIInstance *inst, virConnectPtr conn)
+static bool mempool_set_consumed(CMPIInstance *inst, virConnectPtr conn)
{
- uint64_t memory;
+ uint64_t memory = 0;
+ int *domain_ids = NULL;
+ int count, i = 0;
- /* NB: This doesn't account for memory to be claimed
- * by ballooning dom0
- */
- memory = allocated_memory(conn);
+ count = virConnectNumOfDomains(conn);
+ if (count <= 0)
+ goto out;
+
+ domain_ids = calloc(count, sizeof(domain_ids[0]));
+ if (domain_ids == NULL)
+ goto out;
+
+ if (virConnectListDomains(conn, domain_ids, count) == -1)
+ goto out;
+
+ for (i = 0; i < count; i++) {
+ virDomainPtr dom = NULL;
+ virDomainInfo dom_info;
+
+ dom = virDomainLookupByID(conn, domain_ids[i]);
+ if (dom == NULL) {
+ CU_DEBUG("Cannot connect to domain %n: excluding",
+ domain_ids[i]);
+ continue;
+ }
+
+ if (virDomainGetInfo(dom, &dom_info) == 0)
+ memory += dom_info.memory;
+
+ virDomainFree(dom);
+ }
+
+ out:
+ free(domain_ids);
CMSetProperty(inst, "Reserved",
(CMPIValue *)&memory, CMPI_uint64);
+ CMSetProperty(inst, "CurrentlyConsumedResource",
+ (CMPIValue *)&memory, CMPI_uint64);
return memory != 0;
}
@@ -726,10 +756,14 @@
CMSetProperty(inst, "ResourceType",
(CMPIValue *)&type, CMPI_uint16);
- if (units != NULL)
+ if (units != NULL) {
CMSetProperty(inst, "AllocationUnits",
(CMPIValue *)units, CMPI_chars);
+ CMSetProperty(inst, "ConsumedResourceUnits",
+ (CMPIValue *)units, CMPI_chars);
+ }
+
if (caption != NULL)
CMSetProperty(inst, "Caption",
(CMPIValue *)caption, CMPI_chars);
@@ -761,9 +795,9 @@
ns);
mempool_set_total(inst, conn);
- mempool_set_reserved(inst, conn);
+ mempool_set_consumed(inst, conn);
- set_params(inst, CIM_RES_TYPE_MEM, id, "KiloBytes", NULL, true);
+ set_params(inst, CIM_RES_TYPE_MEM, id, "byte*2^10", NULL, true);
inst_list_add(list, inst);
13 years, 6 months