CIM
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- 3141 discussions
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
According to recent changes in FilterList and FilterEntry providers.
03_create.py:
- Creation and deletion of AppliedFilterList instance
- Deletion of NestedFilterList instance
- Deletion of FilterList instance
helper.py:
- Removed warning about Deprecated use of lxml functionality
- New filter rule actions
- Match protocol id
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
suites/libvirt-cim/cimtest/FilterList/03_create.py | 35 +++++++++++++---
suites/libvirt-cim/cimtest/FilterList/helper.py | 42 +++++++++++++++++---
2 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/suites/libvirt-cim/cimtest/FilterList/03_create.py b/suites/libvirt-cim/cimtest/FilterList/03_create.py
index e828e92..551a01f 100644
--- a/suites/libvirt-cim/cimtest/FilterList/03_create.py
+++ b/suites/libvirt-cim/cimtest/FilterList/03_create.py
@@ -38,6 +38,9 @@ from VirtLib.utils import run_remote
sup_types = ["KVM",]
domain = None
+flist_name = None
+nested_name = None
+applied_name = None
def get_filter_inst_and_inst_name(name):
try:
@@ -89,6 +92,7 @@ def create_filter_list(name):
# A NestedFilterList instance will add the "clean-traffic" filter
# as an entry of the newly created FilterList
+ global nested_name
logger.info("Creating NestedFilterList instance")
nested_name = test.CreateFilterListInstance(None, "KVM_NestedFilterList",
{"Antecedent":flist_name,
@@ -125,8 +129,11 @@ def get_nwport_inst_and_inst_name(domain_name):
def cleanup():
try:
- # Destroy filter list
- test.wbem.DeleteInstance(flist_name)
+ # Destroy filter list instances
+ for n in [applied_name, nested_name, flist_name]:
+ if n is not None:
+ logger.info("Deleting instance %s", n)
+ test.wbem.DeleteInstance(n)
except Exception, e:
logger.error("Error deleting filter list: %s", e)
@@ -165,15 +172,29 @@ def main():
# 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})
+ global applied_name
+ logger.info ("Creating AppliedFilterList instance")
+ applied_name = test.CreateFilterListInstance(None, "KVM_AppliedFilterList",
+ {"Antecedent":nwport_name,
+ "Dependent":flist_name})
+ logger.info("Got AppliedFilterList name '%s'", applied_name)
+ #applied = test.GetInstance(applied_name)
+ #logger.info("Got AppliedFilterList '%s'", applied)
+
+ # Check results
+ filterref = test.libvirt_applied_filter_lists(domain_name)[0]
+ rule = helper.FilterRule(filterref)
+ if rule.filter != test_flist:
+ raise Exception("AppliedFilterList name '%s' does not match expected '%s'",
+ rule.filter, test_flist)
+
+ test.cim_applied_filter_lists(domain_name)
+ logger.info("AppliedFilterList created succesfully")
+ result = PASS
except Exception, e:
logger.error("Caught exception: %s", e)
result = FAIL
- # Check results
-
# Cleanup
cleanup()
diff --git a/suites/libvirt-cim/cimtest/FilterList/helper.py b/suites/libvirt-cim/cimtest/FilterList/helper.py
index 9ae2f62..5202fa6 100644
--- a/suites/libvirt-cim/cimtest/FilterList/helper.py
+++ b/suites/libvirt-cim/cimtest/FilterList/helper.py
@@ -252,7 +252,7 @@ class FilterListTest(BaseTestObject):
d = {}
for f in filters:
root = self.libvirt_filter_dumpxml(f[0])
- if not root:
+ if root is None:
return None
d[f] = root
@@ -307,6 +307,22 @@ class FilterListTest(BaseTestObject):
return self.Associators(_inst_name, result_class="CIM_FilterEntryBase")
# cim_entries_in_filter_list
+
+ def libvirt_applied_filter_lists(self, dom_name):
+ cmd = "virsh -q -c %s dumpxml %s 2>/dev/null" % (self.uri, dom_name)
+ ret, dom_xml = run_remote(self.server, cmd)
+ if ret:
+ logger.error("Error retrieving domain xml for %s", dom_name)
+ return None
+
+ xdoc = etree.fromstring(dom_xml)
+ filter_list = xdoc.xpath("/domain/devices/interface/filterref")
+ return filter_list
+ # libvirt_applied_filter_lists
+
+ def cim_applied_filter_lists(self, dom_name):
+ pass
+ # cim_applied_filter_lists
# FilterListTest
@@ -319,9 +335,17 @@ class FilterRule(object):
__versions = {"ip" : "4",
"ipv6": "6",}
- __actions = {"accept" : "1",
- "deny" : "2",
- "drop" : "2",}
+ __actions = {"accept" : "1",
+ "deny" : "2",
+ "drop" : "2",
+ "reject" : "3",
+ "return" : "4",
+ "continue" : "5",}
+
+ __protocolids = {"ipv4": "2048",
+ "arp" : "2054",
+ "rarp": "32821",
+ "ipv6": "34525",}
__baserule_map = {"action" : "Action",
"direction" : "Direction",
@@ -394,7 +418,7 @@ class FilterRule(object):
for e in element:
self.__dict = dict(self.__dict, **e.attrib)
- if not self.__type:
+ if self.__type is None:
self.__type = e.tag
try:
@@ -415,6 +439,12 @@ class FilterRule(object):
return self.__actions[self.__dict[key]]
elif key == "type":
return self.__type
+ elif key == "protocolid":
+ value = self.__dict[key]
+ try:
+ return self.__protocolids[value]
+ except KeyError:
+ return value
try:
return self.__dict[key]
@@ -470,7 +500,7 @@ class FilterRule(object):
# convert the property value to string
prop = instance.properties[inst_key]
val = self.__getattr__(key)
- if val.startswith("0x"):
+ if isinstance(val, str) and val.startswith("0x"):
inst_val = hex(int(prop.value))
else:
inst_val = str(prop.value)
--
1.7.7.6
2
1
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
These changes are necessary due to recent changes in the libvirt network
filters specification. Cimtests were also updated to match these changes.
http://libvirt.org/formatnwfilter.html
Eduardo Lima (Etrunko) (4):
FilterEntry: Change 'Priority' property type
FilterList: Add 'Priority' property
FilterEntry: Update action property
FilterEntry: Accept protocol id string values
libxkutil/acl_parsing.c | 2 +
libxkutil/acl_parsing.h | 1 +
schema/FilterEntry.mof | 26 ++++++++++++------------
schema/FilterList.mof | 9 ++++++++
src/Makefile.am | 4 +-
src/Virt_FilterEntry.c | 49 +++++++++++++++++++++++++++++++++++-----------
src/Virt_FilterEntry.h | 6 +++++
src/Virt_FilterList.c | 5 +++-
8 files changed, 74 insertions(+), 28 deletions(-)
--
1.7.7.6
3
14
01 Feb '12
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
This series provides a generic linked list implementation for libxkutil that is
based on the one originally developed for the libvirt domain events support
recently integrated upstream.
As test case I ported the ComputerSystemIndication provider code to use this
list implementation. In the near future it will be also used by the event loop
that I am currently working on to allow systems with libvirt older than 0.9.0
to make use of the same feature.
Other possible use cases would be to port the code of libxkutil/*_parsing* to
also use the list implementation instead of static arrays.
Changes from v4:
- Fix possible NULL dereference in list_last_node()
- Fix possible leak in acl_parsing.c
Changes from v3:
- Fix crashes in list_free(), list_first_node() and list_count()
- Include patch that ports the acl filter ref code to use the linked list
implementation
Changes from v2:
- Make list struct private
Changes from v1:
- Fix version iformation in Makefile.am
Eduardo Lima (Etrunko) (3):
libxkutil: Linked list helper
CSI: Use list helper implementation
ACL: Use linked list helper for filter refs
libxkutil/Makefile.am | 51 +++++--
libxkutil/acl_parsing.c | 58 +++------
libxkutil/acl_parsing.h | 5 +-
libxkutil/list_util.c | 254 +++++++++++++++++++++++++++++++++++
libxkutil/list_util.h | 73 ++++++++++
libxkutil/xmlgen.c | 30 +++-
src/Virt_ComputerSystemIndication.c | 95 ++++----------
src/Virt_NestedFilterList.c | 73 ++++++-----
8 files changed, 472 insertions(+), 167 deletions(-)
create mode 100644 libxkutil/list_util.c
create mode 100644 libxkutil/list_util.h
--
1.7.7.6
1
4
01 Feb '12
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
This series provides a generic linked list implementation for libxkutil that is
based on the one originally developed for the libvirt domain events support
recently integrated upstream.
As test case I ported the ComputerSystemIndication provider code to use this
list implementation. In the near future it will be also used by the event loop
that I am currently working on to allow systems with libvirt older than 0.9.0
to make use of the same feature.
Other possible use cases would be to port the code of libxkutil/*_parsing* to
also use the list implementation instead of static arrays.
Changes from v3:
- Fix crashes in list_free(), list_first_node() and list_count()
- Include patch that ports the acl filter ref code to use the linked list
implementation
Changes from v2:
- Make list struct private
Changes from v1:
- Fix version iformation in Makefile.am
Eduardo Lima (Etrunko) (3):
libxkutil: Linked list helper
CSI: Use list helper implementation
ACL: Use linked list helper for filter refs
libxkutil/Makefile.am | 51 +++++--
libxkutil/acl_parsing.c | 58 ++------
libxkutil/acl_parsing.h | 5 +-
libxkutil/list_util.c | 254 +++++++++++++++++++++++++++++++++++
libxkutil/list_util.h | 73 ++++++++++
libxkutil/xmlgen.c | 30 +++-
src/Virt_ComputerSystemIndication.c | 95 ++++----------
src/Virt_NestedFilterList.c | 73 ++++++-----
8 files changed, 471 insertions(+), 168 deletions(-)
create mode 100644 libxkutil/list_util.c
create mode 100644 libxkutil/list_util.h
--
1.7.7.6
1
5
From: Chip Vincent <cvincent(a)us.ibm.com>
Fixes many small issues with the current AppliedFilterList provider.
1) Fix Create to properly return a complete object path and fix Delete to
properly parse that path.
2) Persist applied filer rules. Since it's not possible to dyanmically update
a single device, I've changed the code to modify and re-define the VM to
essentially add/remove ACL filter associations.
I also updated the code to minimize domain/device parsing overhead. For
some strange reason, our internal APIs sometimes take a virDomainPtr and
other times a struct domain * forcing providers who work with domains
*and* devices to parse everything twice. Until the internal APIs are
cleaned up, I simply parse everything once and then fetch the device
manually from the struct domain *.
3) Add VIR_DOMAIN_XML_INACTIVE to virDomainGetXML(). By default, libvirt only
returns the XML of the running domain. We need to fetch the *stored* XML
that will be used for the next boot so that all changes made while the VM
is running are preserved.
Changes from v3:
- Fix NestedFilterList DeleteInstance
- Fix remove_filter_ref() in acl_parsing.c (intend to refactor in
future patch)
Changes from v2:
- Return the correct reference in NestedFilterList
Changes from v1:
- Fix leak and other comments
- Fix all cases virDomainGetXML()
- Fix NestedFilterList Create/Delete instance
Signed-off-by: Chip Vincent <cvincent(a)us.ibm.com>
---
libxkutil/acl_parsing.c | 1 +
libxkutil/device_parsing.c | 6 ++-
src/Virt_AppliedFilterList.c | 97 +++++++++++++++++++----------------
src/Virt_ComputerSystem.c | 3 +-
src/Virt_ComputerSystemIndication.c | 3 +-
src/Virt_FilterList.c | 5 ++-
src/Virt_NestedFilterList.c | 19 +++++--
src/Virt_VSMigrationService.c | 3 +-
8 files changed, 82 insertions(+), 55 deletions(-)
diff --git a/libxkutil/acl_parsing.c b/libxkutil/acl_parsing.c
index 5b6d7bb..9c4b4b2 100644
--- a/libxkutil/acl_parsing.c
+++ b/libxkutil/acl_parsing.c
@@ -652,6 +652,7 @@ int remove_filter_ref(struct acl_filter *filter, const char *name)
/* TODO: called infrequently, but needs optimization */
old_refs = filter->refs;
+ filter->ref_ct = 0;
for (i = 0; i < filter->ref_ct; i++) {
if (STREQC(old_refs[i], name)) {
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index a1e8d6c..ff86f2a 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -996,7 +996,8 @@ int get_devices(virDomainPtr dom, struct virt_device **list, int type)
char *xml;
int ret;
- xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
+ xml = virDomainGetXMLDesc(dom,
+ VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE);
if (xml == NULL)
return 0;
@@ -1241,7 +1242,8 @@ int get_dominfo(virDomainPtr dom, struct domain **dominfo)
char *xml;
int ret;
int start;
- xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
+ xml = virDomainGetXMLDesc(dom,
+ VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE);
if (xml == NULL)
return 0;
diff --git a/src/Virt_AppliedFilterList.c b/src/Virt_AppliedFilterList.c
index bc31c14..538adf4 100644
--- a/src/Virt_AppliedFilterList.c
+++ b/src/Virt_AppliedFilterList.c
@@ -97,67 +97,60 @@ static CMPIrc cu_get_ref_path(const CMPIObjectPath *reference,
if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
return CMPI_RC_ERR_NO_SUCH_PROPERTY;
- /* how to parse and object path? */
+ 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 libxkutil/device_parsing.c */
-static int update_device(virDomainPtr dom,
- struct virt_device *dev)
+static int update_domain(virConnectPtr conn,
+ struct domain *dominfo)
{
-#if LIBVIR_VERSION_NUMBER > 8000
char *xml = NULL;
- int flags = VIR_DOMAIN_DEVICE_MODIFY_CURRENT |
- VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
- int ret = 0;
+ virDomainPtr dom = NULL;
- xml = device_to_xml(dev);
+ xml = system_to_xml(dominfo);
if (xml == NULL) {
- CU_DEBUG("Failed to get XML for device '%s'", dev->id);
+ CU_DEBUG("Failed to get XML from domain %s", dominfo->name);
goto out;
}
- if (virDomainUpdateDeviceFlags(dom, xml, flags) != 0) {
- CU_DEBUG("Failed to dynamically update device");
+ dom = virDomainDefineXML(conn, xml);
+ if (dom == NULL) {
+ CU_DEBUG("Failed to update domain %s", dominfo->name);
goto out;
}
- ret = 1;
out:
free(xml);
+ virDomainFree(dom);
- return ret;
-#else
return 0;
-#endif
}
-/* TODO: Port to libxkutil/device_parsing.c */
-static int get_device_by_devid(virDomainPtr dom,
+static int get_device_by_devid(struct domain *dominfo,
const char *devid,
- int type,
struct virt_device **dev)
{
- int i, ret = 0;
- struct virt_device *devices = NULL;
- int count = get_devices(dom, &devices, type);
+ int i;
+ struct virt_device *devices = dominfo->dev_net;
+ int count = dominfo->dev_net_ct;
+
+ if (dev == NULL)
+ return 0;
for (i = 0; i < count; i++) {
if (STREQC(devid, devices[i].id)) {
CU_DEBUG("Found '%s'", devices[i].id);
- *dev = virt_device_dup(&devices[i]);
- if (*dev != NULL)
- ret = 1;
-
- break;
+ *dev = &devices[i];
+ return 0;
}
}
- cleanup_virt_devices(&devices, count);
-
- return ret;
+ return 1;
}
/**
@@ -425,6 +418,8 @@ static CMPIStatus CreateInstance(
struct virt_device *device = NULL;
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ struct domain *dominfo = NULL;
+ CMPIObjectPath *_reference = NULL;
conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
if (conn == NULL)
@@ -487,8 +482,12 @@ static CMPIStatus CreateInstance(
goto out;
}
- get_device_by_devid(dom, net_name, CIM_RES_TYPE_NET, &device);
- if (device == NULL) {
+ if (get_dominfo(dom, &dominfo) == 0) {
+ CU_DEBUG("Failed to get dominfo");
+ goto out;
+ }
+
+ if (get_device_by_devid(dominfo, net_name, &device) != 0) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"Dependent.Name object does not exist");
@@ -502,14 +501,19 @@ static CMPIStatus CreateInstance(
device->dev.net.filter_ref = strdup(filter_name);
- if (update_device(dom, device) == 0) {
+ if (update_domain(conn, dominfo) != 0) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
- "Failed to update device");
+ "Failed to update domain");
goto out;
}
- CMReturnObjectPath(results, reference);
+ /* create new object path */
+ _reference = CMClone(reference, NULL);
+ CMAddKey(_reference, "Antecedent", (CMPIValue *)&antecedent, CMPI_ref);
+ CMAddKey(_reference, "Dependent", (CMPIValue *)&dependent, CMPI_ref);
+
+ CMReturnObjectPath(results, _reference);
CU_DEBUG("CreateInstance complete");
out:
@@ -542,6 +546,7 @@ static CMPIStatus DeleteInstance(
struct virt_device *device = NULL;
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
+ struct domain *dominfo = NULL;
conn = connect_by_classname(_BROKER, CLASSNAME(reference), &s);
if (conn == NULL)
@@ -557,7 +562,7 @@ static CMPIStatus DeleteInstance(
goto out;
}
- if (cu_get_str_path(reference, "DeviceID",
+ if (cu_get_str_path(antecedent, "DeviceID",
&device_name) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
@@ -573,7 +578,7 @@ static CMPIStatus DeleteInstance(
goto out;
}
- if (cu_get_str_path(reference, "Name",
+ if (cu_get_str_path(dependent, "Name",
&filter_name) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
@@ -585,7 +590,7 @@ static CMPIStatus DeleteInstance(
if (filter == NULL) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
- "Antecedent.Name object does not exist");
+ "Dependent.Name object does not exist");
goto out;
}
@@ -600,11 +605,15 @@ static CMPIStatus DeleteInstance(
goto out;
}
- get_device_by_devid(dom, net_name, CIM_RES_TYPE_NET, &device);
- if (device == NULL) {
+ if (get_dominfo(dom, &dominfo) == 0) {
+ CU_DEBUG("Failed to get dominfo");
+ goto out;
+ }
+
+ if (get_device_by_devid(dominfo, net_name, &device) != 0) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
- "Dependent.Name object does not exist");
+ "Antecedent.Name object does not exist");
goto out;
}
@@ -613,14 +622,14 @@ static CMPIStatus DeleteInstance(
device->dev.net.filter_ref = NULL;
}
- if (update_device(dom, device) == 0) {
+ if (update_domain(conn, dominfo) != 0) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
- "Failed to update device");
+ "Failed to update domain");
goto out;
}
- CU_DEBUG("CreateInstance complete");
+ CU_DEBUG("DeleteInstance complete");
out:
free(domain_name);
diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c
index 582253a..e6c7e55 100644
--- a/src/Virt_ComputerSystem.c
+++ b/src/Virt_ComputerSystem.c
@@ -926,7 +926,8 @@ static CMPIStatus domain_reset(virDomainPtr dom)
return s;
}
- xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
+ xml = virDomainGetXMLDesc(dom,
+ VIR_DOMAIN_XML_INACTIVE |VIR_DOMAIN_XML_SECURE);
if (xml == NULL) {
CU_DEBUG("Unable to retrieve domain XML");
virt_set_status(_BROKER, &s,
diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c
index eb1a71c..6ef2ddc 100644
--- a/src/Virt_ComputerSystemIndication.c
+++ b/src/Virt_ComputerSystemIndication.c
@@ -107,7 +107,8 @@ static int csi_dom_xml_set(csi_dom_xml_t *dom, virDomainPtr dom_ptr, CMPIStatus
dom->name = strdup(name);
/* xml */
- dom->xml = virDomainGetXMLDesc(dom_ptr, VIR_DOMAIN_XML_SECURE);
+ dom->xml = virDomainGetXMLDesc(dom_ptr,
+ VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE);
if (dom->xml == NULL) {
cu_statusf(_BROKER, s,
CMPI_RC_ERR_FAILED,
diff --git a/src/Virt_FilterList.c b/src/Virt_FilterList.c
index 35d18a9..5b1b6e8 100644
--- a/src/Virt_FilterList.c
+++ b/src/Virt_FilterList.c
@@ -358,7 +358,10 @@ static CMPIStatus DeleteInstance(
goto out;
}
- delete_filter(conn, filter);
+ if (delete_filter(conn, filter) != 0) {
+ CU_DEBUG("Failed to delete filter %s", filter->name);
+ goto out;
+ }
out:
cleanup_filters(&filter, 1);
diff --git a/src/Virt_NestedFilterList.c b/src/Virt_NestedFilterList.c
index 894cd7c..81c4408 100644
--- a/src/Virt_NestedFilterList.c
+++ b/src/Virt_NestedFilterList.c
@@ -98,7 +98,10 @@ static CMPIrc cu_get_ref_path(const CMPIObjectPath *reference,
if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
return CMPI_RC_ERR_NO_SUCH_PROPERTY;
- /* how to parse and object path? */
+ if ((value.type != CMPI_ref) || CMIsNullObject(value.value.ref))
+ return CMPI_RC_ERR_TYPE_MISMATCH;
+
+ *_reference = value.value.ref;
return CMPI_RC_OK;
}
@@ -305,6 +308,7 @@ static CMPIStatus CreateInstance(
const char *child_name = NULL;
struct acl_filter *child_filter = NULL;
virConnectPtr conn = NULL;
+ CMPIObjectPath *_reference = NULL;
CU_DEBUG("Reference = %s", REF2STR(reference));
@@ -383,7 +387,12 @@ static CMPIStatus CreateInstance(
goto out;
}
- CMReturnObjectPath(results, reference);
+ /* create new object path */
+ _reference = CMClone(reference, NULL);
+ CMAddKey(_reference, "Antecedent", (CMPIValue *)&antecedent, CMPI_ref);
+ CMAddKey(_reference, "Dependent", (CMPIValue *)&dependent, CMPI_ref);
+
+ CMReturnObjectPath(results, _reference);
CU_DEBUG("CreateInstance completed");
out:
@@ -423,7 +432,7 @@ static CMPIStatus DeleteInstance(
goto out;
}
- if (cu_get_str_path(reference, "Name", &parent_name) != CMPI_RC_OK) {
+ if (cu_get_str_path(antecedent, "Name", &parent_name) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"Unable to get Antecedent.Name property");
@@ -446,7 +455,7 @@ static CMPIStatus DeleteInstance(
goto out;
}
- if (cu_get_str_path(reference, "Name", &child_name) != CMPI_RC_OK) {
+ if (cu_get_str_path(dependent, "Name", &child_name) != CMPI_RC_OK) {
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"Unable to get Dependent.Name property");
@@ -475,7 +484,7 @@ static CMPIStatus DeleteInstance(
goto out;
}
- CU_DEBUG("CreateInstance completed");
+ CU_DEBUG("DeleteInstance completed");
out:
cleanup_filters(&parent_filter, 1);
diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c
index d393787..76e3d25 100644
--- a/src/Virt_VSMigrationService.c
+++ b/src/Virt_VSMigrationService.c
@@ -1070,7 +1070,8 @@ static CMPIStatus prepare_migrate(virDomainPtr dom,
{
CMPIStatus s = {CMPI_RC_OK, NULL};
- *xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
+ *xml = virDomainGetXMLDesc(dom,
+ VIR_DOMAIN_XML_INACTIVE | VIR_DOMAIN_XML_SECURE);
if (*xml == NULL) {
virt_set_status(_BROKER, &s,
--
1.7.1
2
3
01 Feb '12
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
This series provides a generic linked list implementation for libxkutil that is
based on the one originally developed for the libvirt domain events support
recently integrated upstream.
As test case I ported the ComputerSystemIndication provider code to use this
list implementation. In the near future it will be also used by the event loop
that I am currently working on to allow systems with libvirt older than 0.9.0
to make use of the same feature.
Other possible use cases would be to port the code of libxkutil/*_parsing* to
also use the list implementation instead of static arrays.
Changes from v2:
- Make list struct private
Changes from v1:
- Fix version iformation in Makefile.am
Eduardo Lima (Etrunko) (2):
libxkutil: Linked list helper
CSI: Use list helper implementation
libxkutil/Makefile.am | 51 ++++++--
libxkutil/list_util.c | 243 +++++++++++++++++++++++++++++++++++
libxkutil/list_util.h | 71 ++++++++++
src/Virt_ComputerSystemIndication.c | 95 ++++----------
4 files changed, 377 insertions(+), 83 deletions(-)
create mode 100644 libxkutil/list_util.c
create mode 100644 libxkutil/list_util.h
--
1.7.7.6
1
3
From: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
Add EASD for EthernetPort. According DSP1097, There are two kinds of EASD:
EA stands for Settings of EthernetPort, EC stands for Settings for Connection
between EthernetPort.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/EthernetPortAllocationSettingData.mof | 22 +
.../EthernetPortAllocationSettingData.registration | 3 +
src/Virt_EASD.c | 709 ++++++++++++++++++++
src/Virt_EASD.h | 59 ++
4 files changed, 793 insertions(+), 0 deletions(-)
create mode 100644 schema/EthernetPortAllocationSettingData.mof
create mode 100644 schema/EthernetPortAllocationSettingData.registration
create mode 100644 src/Virt_EASD.c
create mode 100644 src/Virt_EASD.h
diff --git a/schema/EthernetPortAllocationSettingData.mof b/schema/EthernetPortAllocationSettingData.mof
new file mode 100644
index 0000000..726bb1f
--- /dev/null
+++ b/schema/EthernetPortAllocationSettingData.mof
@@ -0,0 +1,22 @@
+// Copyright IBM Corp. 2012
+
+[Description ("Virtutal EthernetPort Setting Data"),
+ Provider("cmpi::Virt_EASD")
+]
+
+class Net_EthernetPortAllocationSettingData : CIM_EthernetPortAllocationSettingData
+{
+ uint16 PortVID;
+ uint16 DesiredEndPointMode;
+
+ [Description("VLAN type of the port, "
+ "Now only support IEEE 802.1.q."),
+ ValueMap { "0", "1", "2", "3" },
+ Values { "Not VLAN", "IEEE 802.1.q", "IEEE 802.1.qbg", "IEEE 802.1.qbh" }]
+ uint16 VLANType;
+
+ uint16 AutoStart;
+
+ uint16 DHCP;
+
+};
diff --git a/schema/EthernetPortAllocationSettingData.registration b/schema/EthernetPortAllocationSettingData.registration
new file mode 100644
index 0000000..8925739
--- /dev/null
+++ b/schema/EthernetPortAllocationSettingData.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2012
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_EthernetPortAllocationSettingData root/virt Virt_EASD Virt_EASD instance
diff --git a/src/Virt_EASD.c b/src/Virt_EASD.c
new file mode 100644
index 0000000..bdcf125
--- /dev/null
+++ b/src/Virt_EASD.c
@@ -0,0 +1,709 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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 <inttypes.h>
+#include <sys/stat.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <libcmpiutil/std_instance.h>
+
+#include "misc_util.h"
+#include "cs_util.h"
+#include "device_parsing.h"
+#include "network_model_helper.h"
+
+#include "Virt_EASD.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_easd(const CMPIBroker *broker, const char* prefix,
+ struct EthIface *piface, int type, CMPIInstance *instance)
+{
+ char *eth_name, *easd_name;
+ int asret;
+ uint16_t res_type = CIM_NUM_SWITCHPORT;
+ uint16_t vlan_mode;
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ eth_name = get_ethportsd_name_from_iface(piface->name, type);
+ asret = asprintf(&easd_name, "%s/%s", prefix, eth_name);
+
+ CMSetProperty(instance, "InstanceID",
+ (CMPIValue *)easd_name, CMPI_chars);
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)eth_name, CMPI_chars);
+ CU_FREE(easd_name);
+ CU_FREE(eth_name);
+
+ CMSetProperty(instance, "ResourceType",
+ (CMPIValue *)&res_type, CMPI_uint16);
+
+ if (piface->eth_type == ETH_TYPE_ETHER_PHYSICAL) {
+ vlan_mode = CIM_NUM_VLAN_MODE_TRUNK;
+ CMSetProperty(instance, "DesiredEndPointMode",
+ (CMPIValue *)&vlan_mode, CMPI_uint16);
+ }
+
+
+ if (piface->mac != NULL) {
+ CMSetProperty(instance, "Address",
+ (CMPIValue *)piface->mac, CMPI_chars);
+ }
+
+ return 1;
+}
+
+static int set_secondary_for_easd(const CMPIBroker *broker,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ struct VLAN_Prop *pvlan;
+ struct VLAN_Prop_8021q *pvlan8021q;
+ uint16_t vid;
+ CMPIArray *conn_array;
+ CMPIString *cm_str;
+ char *str = NULL;
+ CMPIStatus s;
+ uint16_t vlantype = 0;
+ uint16_t visibility = CIM_NUM_CONSUMERVISIBILITY_VIRTUALIZED;
+
+ if (piface->eth_type == ETH_TYPE_ETHER_PHYSICAL) {
+ visibility = CIM_NUM_CONSUMERVISIBILITY_PASSEDTHROUGH;
+ }
+ CMSetProperty(instance, "ConsumerVisibility",
+ (CMPIValue *)&visibility, CMPI_uint16);
+
+ if (piface->protocol_prop.ipv4_prop.DHCP >= 0) {
+ CMSetProperty(instance, "DHCP",
+ (CMPIValue *)&piface->protocol_prop.ipv4_prop.DHCP,
+ CMPI_uint16);
+ }
+
+ if (piface->run_prop.boot_mode >= 0) {
+ CMSetProperty(instance, "AutoStart",
+ (CMPIValue *)&piface->run_prop.boot_mode,
+ CMPI_uint16);
+ }
+
+ if ((piface->eth_type != ETH_TYPE_ETHER_VLAN) ||
+ (piface->pvlan_prop == NULL)) {
+ goto out;
+ }
+ pvlan = piface->pvlan_prop;
+
+ if (pvlan->vlan_type == VLAN_TYPE_802_1_Q) {
+ pvlan8021q = &(pvlan->props.prop_8021q);
+ vid = pvlan8021q->vlan_id;
+ CMSetProperty(instance, "PortVID",
+ (CMPIValue *)&vid, CMPI_uint16);
+
+ str = vlanid_to_connection_name(vid);
+ conn_array = CMNewArray(broker, 1, CMPI_string, &s);
+ if ((s.rc != CMPI_RC_OK) || (str == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Error creating Connection "
+ "list and its string");
+ CU_DEBUG("CMNewArray or string creation failed");
+ goto out;
+ }
+ cm_str = CMNewString(broker, str, &s);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Error creating CMPIString");
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Error creating CMPIString for "
+ "BootDevices item");
+
+ goto out;
+ }
+ CMSetArrayElementAt(conn_array, 0, (CMPIValue *)&cm_str,
+ CMPI_string);
+ CMSetProperty(instance, "Connection",
+ (CMPIValue *)&conn_array, CMPI_stringA);
+
+ vlantype = 1;
+ }
+ CMSetProperty(instance, "VLANType",
+ (CMPIValue *)&vlantype, CMPI_uint16);
+
+out:
+ CU_FREE(str);
+ return 1;
+}
+
+static CMPIStatus add_conn_properties(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *eth_name, *easd_name;
+ int asret;
+ CMPIArray *array;
+ CMPIString *tmp;
+
+ if (piface->name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "device name not set");
+ goto out;
+ }
+ if (dest == NULL) {
+ CU_DEBUG("warn: connection dest is NULL.");
+ }
+
+ eth_name = get_ethportsd_name_from_iface(piface->name, EASD_TYPE_EA);
+ asret = asprintf(&easd_name, "%s:%s", prefix, eth_name);
+ CMSetProperty(instance, "Parent",
+ (CMPIValue *)easd_name, CMPI_chars);
+ CU_FREE(easd_name);
+ CU_FREE(eth_name);
+
+ array = CMNewArray(broker, 1, CMPI_string, &s);
+ tmp = CMNewString(broker, dest, NULL);
+ CMSetArrayElementAt(array, 0, &(tmp), CMPI_string);
+ CMSetProperty(instance, "HostResource",
+ (CMPIValue *)&array, CMPI_stringA);
+
+
+ out:
+ return s;
+}
+
+static CMPIStatus set_properties(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ int type,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *errstr;
+
+ if (!set_primary_for_easd(broker, prefix, piface, type, instance)) {
+ errstr = "failed to set primary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ if (type == EASD_TYPE_EA) {
+ if (!set_secondary_for_easd(broker, piface, instance)) {
+ errstr = "failed to set secondary properties"
+ " for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ } else {
+ s = add_conn_properties(broker,
+ piface,
+ prefix,
+ dest,
+ instance);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+
+ out:
+ return s;
+}
+
+static CMPIStatus instance_from_easd_build(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ int type,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIInstance *inst = NULL;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *keys[] = {"InstanceID", NULL};
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+ "EthernetPortAllocationSettingData",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init SwitchSystem instance");
+ goto out;
+ }
+
+
+ s = CMSetPropertyFilter(inst, properties, keys);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Unable to set property filter: %d", s.rc);
+ }
+
+ s = set_properties(broker,
+ piface,
+ prefix,
+ dest,
+ type,
+ inst);
+
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+/* vsname and req_type are filter conditions */
+static CMPIStatus instance_from_easd(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *vsname,
+ int req_type,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist)
+{
+
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *br1_name = NULL, *br2_name = NULL;
+
+ CU_DEBUG("enter instance_for_easd with vsname %s, type %d.",
+ vsname, req_type);
+ get_possible_bridge_name_for_cim_model(piface, &br1_name, &br2_name);
+ if (br1_name == NULL) {
+ CU_DEBUG("failed to find any bridge for the port %s.",
+ piface->name);
+ }
+
+ /* building the EA instance */
+ if (!(req_type&EASD_TYPE_EA)) {
+ goto ea_build_end;
+ }
+ if ((vsname == NULL) || (br1_name == NULL) ||
+ (0 == strcmp(vsname, br1_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br1_name,
+ NULL,
+ EASD_TYPE_EA,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+
+ /* following is to make it comform to CIM profile which require two
+ ethports connectted to pNIC and vswitch, but we have only one piface
+ on linux indicating it is connected to pNIC and bridge at sametime */
+ if (br2_name == NULL) {
+ goto out;
+ }
+
+ if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br2_name,
+ NULL,
+ EASD_TYPE_EA,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ ea_build_end:
+
+ /* building the EC instance */
+ if (!(req_type&EASD_TYPE_EC)) {
+ goto ec_build_end;
+ }
+ if ((br1_name == NULL) || (br2_name == NULL)) {
+ goto ec_build_end;
+ }
+ /* connection exist, so a EC_easd should be added for each bridge */
+ if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br1_name,
+ br2_name,
+ EASD_TYPE_EC,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br2_name,
+ br1_name,
+ EASD_TYPE_EC,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ ec_build_end:
+
+ out:
+ CU_FREE(br1_name);
+ CU_FREE(br2_name);
+ return s;
+}
+
+CMPIStatus get_easd_by_name(const CMPIBroker *broker,
+ const char *prefix,
+ const char *name,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *eth_name = NULL;
+ char *dest = NULL;
+ char *errstr;
+ int ret;
+ int type;
+ struct EthIfacesList ifaces_list;
+ struct inst_list list;
+
+ CU_DEBUG("####prefix %s", prefix);
+ eth_ifaceslist_init(&ifaces_list);
+ inst_list_init(&list);
+
+ eth_name = get_iface_name_from_ethportsd(name, &type);
+ if (eth_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert instance name");
+ CU_DEBUG("ethport name %s failed to convert.", name);
+ goto out;
+ }
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_ethport_for_name, eth_name);
+
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (ifaces_list.count != 1) {
+ errstr = "expected ethport not found.";
+ CU_DEBUG("%d ethportd found.", ifaces_list.count);
+ eth_ifaceslist_print(&ifaces_list);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ inst = NULL;
+ s = instance_from_easd(broker,
+ ifaces_list.pifaces[0],
+ prefix,
+ type,
+ reference,
+ properties,
+ &list);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (list.cur == 0) {
+ CU_DEBUG("%d instance found, expect is 1.", list.cur);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "no such instance.");
+ goto out;
+ }
+
+ if (list.cur > 1) {
+ CU_DEBUG("%d instance found, expect is 1.", list.cur);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "instance found do not match expectation");
+ goto out;
+ }
+
+ *_inst = list.list[0];
+ list.list[0] = NULL;
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+ inst_list_free(&list);
+ CU_FREE(eth_name);
+ CU_FREE(dest);
+ return s;
+}
+
+CMPIStatus get_easd_by_id(const CMPIBroker *broker,
+ const char *id,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ char *prefix = NULL;
+ char *suffix = NULL;
+ if (id == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "ID is NULL'", id);
+ }
+ if (!parse_fq_devid(id, &prefix, &suffix) || (prefix == NULL) ||
+ (suffix == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Invalid InstanceID `%s'", id);
+ goto out;
+ }
+ s = get_easd_by_name(broker, prefix, suffix, reference,
+ properties, _inst);
+
+ out:
+ CU_FREE(prefix);
+ CU_FREE(suffix);
+ return s;
+}
+
+CMPIStatus get_easd_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *name = NULL;
+ char *prefix = NULL;
+ const char *id;
+
+ if (cu_get_str_path(reference, "InstanceID", &id) != CMPI_RC_OK) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "No such instance (InstanceID)");
+ goto out;
+ }
+ if ((!parse_fq_devid(id, &prefix, &name)) ||
+ (name == NULL) || (prefix == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Failed to translate (InstanceID)");
+ goto out;
+ }
+
+ s = get_easd_by_name(broker, prefix, name, reference,
+ properties, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ s = cu_validate_ref(broker, reference, inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ free(name);
+ free(prefix);
+
+ return s;
+}
+
+
+CMPIStatus enum_easds(const CMPIBroker *broker,
+ const char *ref_vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct EthIfacesList ifaces_list;
+ int ret, i;
+ char *errstr;
+
+ eth_ifaceslist_init(&ifaces_list);
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_ethport, NULL);
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ CU_DEBUG("enum easd, found following devices.")
+ eth_ifaceslist_print(&ifaces_list);
+
+ i = 0;
+ while (i < ifaces_list.count) {
+ s = instance_from_easd(broker,
+ ifaces_list.pifaces[i],
+ ref_vsname,
+ EASD_TYPE_EA|EASD_TYPE_EC,
+ reference,
+ properties,
+ plist);
+ i++;
+ /* this should never fail */
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("unexpected fail.");
+ break;
+ }
+ }
+
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+
+ return s;
+}
+
+static CMPIStatus return_enum_easds(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ const char **properties,
+ const bool names_only)
+{
+ struct inst_list list;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ inst_list_init(&list);
+ s = enum_easds(broker, NULL, reference, properties, &list);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (names_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 *reference)
+{
+ return return_enum_easds(_BROKER, reference, results,
+ NULL, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+
+ return return_enum_easds(_BROKER, reference, results,
+ properties, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const char **properties)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ s = get_easd_by_ref(_BROKER, ref, properties, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ CMReturnInstance(results, inst);
+
+ out:
+ return s;
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_INST_CLEANUP();
+DEFAULT_EQ();
+
+STD_InstanceMIStub(,
+ Virt_EASD,
+ _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:
+ */
diff --git a/src/Virt_EASD.h b/src/Virt_EASD.h
new file mode 100644
index 0000000..f9d13ec
--- /dev/null
+++ b/src/Virt_EASD.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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
+ */
+#ifndef __VIRT_EASD_H
+#define __VIRT_EASD_H
+
+CMPIStatus enum_easds(const CMPIBroker *broker,
+ const char *ref_vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist);
+
+CMPIStatus get_easd_by_name(const CMPIBroker *broker,
+ const char *prefix,
+ const char *name,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_easd_by_id(const CMPIBroker *broker,
+ const char *id,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_easd_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.7.1
1
0
31 Jan '12
From: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
This patch add EthernetPort. EthernetPort is always a port on a switch,
So eth0.10 is modeled as VS_eth0/EP_eth0.10,
eth0 is modeled as VS_eth0/EP_Eth0.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/EthernetPort.mof | 4 +
schema/EthernetPort.registration | 3 +
src/Virt_EthernetPort.c | 561 ++++++++++++++++++++++++++++++++++++++
src/Virt_EthernetPort.h | 58 ++++
4 files changed, 626 insertions(+), 0 deletions(-)
create mode 100644 schema/EthernetPort.mof
create mode 100644 schema/EthernetPort.registration
create mode 100644 src/Virt_EthernetPort.c
create mode 100644 src/Virt_EthernetPort.h
diff --git a/schema/EthernetPort.mof b/schema/EthernetPort.mof
new file mode 100644
index 0000000..9d5e23e
--- /dev/null
+++ b/schema/EthernetPort.mof
@@ -0,0 +1,4 @@
+// Copyright IBM Corp. 2012
+class Net_EthernetPort : CIM_EthernetPort
+{
+};
diff --git a/schema/EthernetPort.registration b/schema/EthernetPort.registration
new file mode 100644
index 0000000..e0e0f0c
--- /dev/null
+++ b/schema/EthernetPort.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2012
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_EthernetPort root/virt Virt_EthernetPort Virt_EthernetPort instance
diff --git a/src/Virt_EthernetPort.c b/src/Virt_EthernetPort.c
new file mode 100644
index 0000000..cdef910
--- /dev/null
+++ b/src/Virt_EthernetPort.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright IBM Corp. 2007
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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 <inttypes.h>
+#include <sys/stat.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <libcmpiutil/std_instance.h>
+
+#include "misc_util.h"
+#include "cs_util.h"
+#include "device_parsing.h"
+#include "network_model_helper.h"
+
+#include "Virt_EthernetPort.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_ep(const CMPIBroker *broker, const char* prefix,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ char *eth_name, *ep_name;
+ const char *syscls_name = "Virt_VirtualEthernetSwitchSystem";
+ int asret;
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ eth_name = get_ethport_name_from_iface(piface->name);
+ asret = asprintf(&ep_name, "%s/%s", prefix, eth_name);
+
+ CMSetProperty(instance, "DeviceID",
+ (CMPIValue *)ep_name, CMPI_chars);
+
+ CMSetProperty(instance, "InstanceID",
+ (CMPIValue *)ep_name, CMPI_chars);
+
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)eth_name, CMPI_chars);
+ CU_FREE(ep_name);
+ CU_FREE(eth_name);
+
+ CMSetProperty(instance, "SystemCreationClassName",
+ (CMPIValue *)syscls_name, CMPI_chars);
+
+ CMSetProperty(instance, "SystemName",
+ (CMPIValue *)prefix, CMPI_chars);
+
+ return 1;
+}
+
+static int set_secondary_for_ep(const CMPIBroker *broker,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ int state;
+ uint16_t cim_type;
+ CMPIArray *array;
+ CMPIStatus s;
+ CMPIString *str;
+
+ if (piface->run_prop.status == ETH_STATE_INACTIVE) {
+ state = CIM_STATE_DISABLED;
+ } else if (piface->run_prop.status == ETH_STATE_ACTIVE) {
+ state = CIM_STATE_ENABLED;
+ } else {
+ state = CIM_STATE_UNKNOWN;
+ }
+ CMSetProperty(instance, "EnabledState",
+ (CMPIValue *)&state, CMPI_uint16);
+ CMSetProperty(instance, "RequestedState",
+ (CMPIValue *)&state, CMPI_uint16);
+
+ cim_type = CIM_NUM_NET_ETHERNET;
+ CMSetProperty(instance, "LinkTechnology",
+ (CMPIValue *)&cim_type, CMPI_uint16);
+
+ if (piface->mac != NULL) {
+ array = CMNewArray(broker, 1, CMPI_string, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) {
+ CU_DEBUG("failed to create array.");
+ return 0;
+ }
+ str = CMNewString(broker, piface->mac, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(str))) {
+ CU_DEBUG("failed to create array.");
+ return 0;
+ }
+
+ CMSetArrayElementAt(array, 0, &str, CMPI_string);
+
+ CMSetProperty(instance, "NetworkAddresses",
+ (CMPIValue *)&array, CMPI_stringA);
+ }
+
+ return 1;
+}
+
+static CMPIStatus set_properties(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *errstr = NULL;
+
+ if (!set_primary_for_ep(broker, prefix, piface, instance)) {
+ errstr = "failed to set primary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ if (!set_secondary_for_ep(broker, piface, instance)) {
+ errstr = "failed to set secondary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+
+ out:
+ return s;
+}
+
+
+static CMPIStatus instance_from_ep_build(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIInstance *inst = NULL;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *keys[] = {"InstanceID", NULL};
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+ "EthernetPort",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init ep instance");
+ goto out;
+ }
+
+ s = CMSetPropertyFilter(inst, properties, keys);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Unable to set property filter: %d", s.rc);
+ }
+
+ s = set_properties(broker,
+ piface,
+ prefix,
+ inst);
+
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+
+static CMPIStatus instance_from_ep(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist)
+{
+
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *br1_name = NULL, *br2_name = NULL;
+
+ get_possible_bridge_name_for_cim_model(piface, &br1_name, &br2_name);
+ if (br1_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to find any bridge for the port.");
+ CU_DEBUG("failed to find any bridge for the port %s.",
+ piface->name);
+ goto out;
+ }
+
+ /* building up the instance */
+ if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) {
+ inst = NULL;
+ s = instance_from_ep_build(broker,
+ piface,
+ br1_name,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+
+ /* following is to make it comform to CIM profile which require two
+ ethports connectted to pNIC and vswitch, but we have only one piface
+ on linux indicating it is connected to pNIC and bridge at sametime */
+ if (br2_name == NULL) {
+ goto out;
+ }
+
+ if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) {
+ inst = NULL;
+ s = instance_from_ep_build(broker,
+ piface,
+ br2_name,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+
+
+ out:
+ CU_FREE(br1_name);
+ CU_FREE(br2_name);
+ return s;
+}
+
+CMPIStatus get_ep_by_name(const CMPIBroker *broker,
+ const char *prefix,
+ const char *name,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *eth_name = NULL;
+ char *dest = NULL;
+ char *errstr;
+ int ret;
+ struct EthIfacesList ifaces_list;
+ struct inst_list list;
+
+ eth_ifaceslist_init(&ifaces_list);
+ inst_list_init(&list);
+
+ eth_name = get_iface_name_from_ethport(name);
+ if (eth_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert instance name");
+ CU_DEBUG("ethport name %s failed to convert.", name);
+ goto out;
+ }
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_ethport_for_name, eth_name);
+
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (ifaces_list.count != 1) {
+ errstr = "expected ethport not found.";
+ CU_DEBUG("%s\n", errstr);
+ eth_ifaceslist_print(&ifaces_list);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ inst = NULL;
+ s = instance_from_ep(broker,
+ ifaces_list.pifaces[0],
+ prefix,
+ reference,
+ properties,
+ &list);
+
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (list.cur == 0) {
+ CU_DEBUG("%d instance found, expect is 1.", list.cur);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "no such instance.");
+ goto out;
+ }
+
+ if (list.cur > 1) {
+ CU_DEBUG("%d instance found, expect is 1.", list.cur);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "instance found do not match expectation");
+ goto out;
+ }
+
+ *_inst = list.list[0];
+ list.list[0] = NULL;
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+ inst_list_free(&list);
+ CU_FREE(eth_name);
+ CU_FREE(dest);
+ return s;
+}
+
+CMPIStatus get_ep_by_id(const CMPIBroker *broker,
+ const char *id,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ char *prefix = NULL;
+ char *suffix = NULL;
+ if (id == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "ID is NULL'", id);
+ }
+ if (!parse_fq_devid(id, &prefix, &suffix) || (prefix == NULL) ||
+ (suffix == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Invalid InstanceID `%s'", id);
+ goto out;
+ }
+ s = get_ep_by_name(broker, prefix, suffix, reference,
+ properties, _inst);
+
+ out:
+ CU_FREE(prefix);
+ CU_FREE(suffix);
+ return s;
+}
+
+CMPIStatus get_ep_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *name = NULL;
+ char *prefix = NULL;
+ const char *id;
+
+ if (cu_get_str_path(reference, "DeviceID", &id) != CMPI_RC_OK) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "No such instance (InstanceID)");
+ goto out;
+ }
+ if ((!parse_fq_devid(id, &prefix, &name)) ||
+ (name == NULL) || (prefix == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Failed to translate (InstanceID)");
+ goto out;
+ }
+
+ s = get_ep_by_name(broker, prefix, name, reference,
+ properties, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ s = cu_validate_ref(broker, reference, inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ free(name);
+ free(prefix);
+
+ return s;
+}
+
+
+CMPIStatus enum_eps(const CMPIBroker *broker,
+ const char *ref_vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct EthIfacesList ifaces_list;
+ int ret, i;
+ char *errstr;
+
+ eth_ifaceslist_init(&ifaces_list);
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_ethport, NULL);
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ CU_DEBUG("enum ep, found following devices.")
+ eth_ifaceslist_print(&ifaces_list);
+
+ i = 0;
+ while (i < ifaces_list.count) {
+ s = instance_from_ep(broker,
+ ifaces_list.pifaces[i],
+ ref_vsname,
+ reference,
+ properties,
+ plist);
+ i++;
+ /* this should never fail */
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("unexpected fail.");
+ break;
+ }
+ }
+
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+
+ return s;
+}
+
+static CMPIStatus return_enum_eps(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ const char **properties,
+ const bool names_only)
+{
+ struct inst_list list;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ inst_list_init(&list);
+ s = enum_eps(broker, NULL, reference, properties, &list);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (names_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 *reference)
+{
+ return return_enum_eps(_BROKER, reference, results, NULL, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+
+ return return_enum_eps(_BROKER, reference, results, properties, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const char **properties)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ s = get_ep_by_ref(_BROKER, ref, properties, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ CMReturnInstance(results, inst);
+
+ out:
+ return s;
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_INST_CLEANUP();
+DEFAULT_EQ();
+
+STD_InstanceMIStub(,
+ Virt_EthernetPort,
+ _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:
+ */
diff --git a/src/Virt_EthernetPort.h b/src/Virt_EthernetPort.h
new file mode 100644
index 0000000..f474af2
--- /dev/null
+++ b/src/Virt_EthernetPort.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wencao Xia <xiawenc(a)cn.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
+ */
+#ifndef __VIRT_ETHERNETPORT_H
+#define __VIRT_ETHERNETPORT_H
+
+CMPIStatus enum_eps(const CMPIBroker *broker,
+ const char *ref_vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist);
+
+CMPIStatus get_ep_by_name(const CMPIBroker *broker,
+ const char *prefix,
+ const char *name,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_ep_by_id(const CMPIBroker *broker,
+ const char *id,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_ep_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.7.1
1
0
From: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
This patch add VESSSD, VirtualSwitch are bridge and pNIC on host.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/VirtualEthernetSwitchSystemSettingData.mof | 31 ++
...ualEthernetSwitchSystemSettingData.registration | 3 +
src/Virt_VESSSD.c | 382 ++++++++++++++++++++
src/Virt_VESSSD.h | 39 ++
4 files changed, 455 insertions(+), 0 deletions(-)
create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof
create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration
create mode 100644 src/Virt_VESSSD.c
create mode 100644 src/Virt_VESSSD.h
diff --git a/schema/VirtualEthernetSwitchSystemSettingData.mof b/schema/VirtualEthernetSwitchSystemSettingData.mof
new file mode 100644
index 0000000..b6ecc65
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystemSettingData.mof
@@ -0,0 +1,31 @@
+// Copyright IBM Corp. 2012
+
+
+/* fix me: the libvirt-cim lacks parent class
+ "VirtualEthernetSwitchSettingData" defined in DSP1050 */
+[Description (
+ "A class derived from Virt_VirtualEthernetSystemSettingData to represent "
+ "the config of ."),
+ Provider("cmpi::Virt_VESSSD")
+]
+class Net_VirtualEthernetSwitchSystemSettingData : CIM_VirtualSystemSettingData
+{
+
+ [Description ("Virtual Switch System type number")]
+ string VirtualSystemType;
+
+ string AssociatedResourcePool;
+
+ uint16 VLAN_Connection[];
+
+ uint16 MaxNumAddress;
+
+ uint16 EVBMode;
+
+ uint16 STP;
+
+ uint16 AutoStart;
+
+ uint16 DHCP;
+
+};
diff --git a/schema/VirtualEthernetSwitchSystemSettingData.registration b/schema/VirtualEthernetSwitchSystemSettingData.registration
new file mode 100644
index 0000000..1ba7e0c
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystemSettingData.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2012
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_VirtualEthernetSwitchSystemSettingData root/virt Virt_VESSSD Virt_VESSSD instance
diff --git a/src/Virt_VESSSD.c b/src/Virt_VESSSD.c
new file mode 100644
index 0000000..587741e
--- /dev/null
+++ b/src/Virt_VESSSD.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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 <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <libcmpiutil/std_instance.h>
+
+#include "cs_util.h"
+#include "misc_util.h"
+#include "device_parsing.h"
+
+#include "Virt_VESSSD.h"
+#include "network_model_helper.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_vesssd(const char *prefix, const CMPIBroker *broker,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ char *name, *vesssd_name;
+ int asret;
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ CMSetProperty(instance, "VirtualSystemType",
+ (CMPIValue *)"DMTF:VirtualEthernetSwitch", CMPI_chars);
+
+ name = get_switch_name_from_iface(piface->name);
+ asret = asprintf(&vesssd_name, "%s:%s", prefix, name);
+
+ CMSetProperty(instance, "InstanceID",
+ (CMPIValue *)vesssd_name, CMPI_chars);
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)name, CMPI_chars);
+ CMSetProperty(instance, "VirtualSystemIdentifier",
+ (CMPIValue *)name, CMPI_chars);
+ CMSetProperty(instance, "VirtualSystemType",
+ (CMPIValue *)prefix, CMPI_chars);
+
+
+
+ free(vesssd_name);
+ CU_FREE(name);
+
+ return 1;
+}
+
+static int set_secondary_for_vesssd(const CMPIBroker *broker,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ if (piface->eth_type == ETH_TYPE_ETHER_BRIDGE) {
+ CMSetProperty(instance, "STP",
+ (CMPIValue *)&piface->pbr_prop->STP, CMPI_uint16);
+ }
+
+ if (piface->protocol_prop.ipv4_prop.DHCP >= 0) {
+ CMSetProperty(instance, "DHCP",
+ (CMPIValue *)&piface->protocol_prop.ipv4_prop.DHCP,
+ CMPI_uint16);
+ }
+
+ if (piface->run_prop.boot_mode >= 0) {
+ CMSetProperty(instance, "AutoStart",
+ (CMPIValue *)&piface->run_prop.boot_mode,
+ CMPI_uint16);
+ }
+
+ return 1;
+}
+
+/* Populate an instance with information from a switch */
+static CMPIStatus set_properties(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *errstr;
+
+ if (!set_primary_for_vesssd(prefix, broker, piface, instance)) {
+ errstr = "failed to set primary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (!set_secondary_for_vesssd(broker, piface, instance)) {
+ errstr = "failed to set secondary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+
+ out:
+ return s;
+}
+
+static CMPIStatus instance_from_vesssd(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ struct EthIface *piface,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+ "VirtualEthernetSwitchSystemSettingData",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init SwitchSystem instance");
+ goto out;
+ }
+
+ s = set_properties(broker,
+ piface,
+ VESSD_SYSTEM_PREFIX,
+ inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+CMPIStatus enum_vesssd(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ struct inst_list *plist)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct EthIfacesList ifaces_list;
+ int ret, i;
+ char *errstr;
+
+ eth_ifaceslist_init(&ifaces_list);
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_switch, NULL);
+
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ i = 0;
+ while (i < ifaces_list.count) {
+ CMPIInstance *inst = NULL;
+
+ s = instance_from_vesssd(broker,
+ reference,
+ ifaces_list.pifaces[i],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ inst_list_add(plist, inst);
+ i++;
+ }
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+
+ return s;
+}
+
+static CMPIStatus return_enum_vesssd(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool names_only)
+{
+ struct inst_list list;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ inst_list_init(&list);
+
+ s = enum_vesssd(broker, reference, &list);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (names_only) {
+ cu_return_instance_names(results, &list);
+ } else {
+ cu_return_instances(results, &list);
+ }
+ out:
+ inst_list_free(&list);
+ return s;
+}
+
+CMPIStatus get_vesssd_by_name(const CMPIBroker *broker,
+ const char *name,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *eth_name = NULL;
+ char *errstr;
+ int ret;
+ struct EthIfacesList ifaces_list;
+
+ eth_ifaceslist_init(&ifaces_list);
+
+ eth_name = get_iface_name_from_switch(name);
+ if (eth_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert switch_name");
+ CU_DEBUG("switch name %s failed to convert.", name);
+ goto out;
+ }
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_switch_for_name, eth_name);
+
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (ifaces_list.count != 1) {
+ errstr = "expected switch not found.";
+ CU_DEBUG("%s\n", errstr);
+ eth_ifaceslist_print(&ifaces_list);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ s = instance_from_vesssd(broker,
+ reference,
+ ifaces_list.pifaces[0],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+ CU_FREE(eth_name);
+ return s;
+}
+
+CMPIStatus get_vesssd_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *name = NULL;
+
+ if ((!parse_instanceid(reference, NULL, &name)) || (name == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "No such instance (InstanceID)");
+ goto out;
+ }
+
+ s = get_vesssd_by_name(broker, name, reference, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ s = cu_validate_ref(broker, reference, inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ free(name);
+
+ return s;
+}
+
+static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ return return_enum_vesssd(_BROKER, reference, results, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ return return_enum_vesssd(_BROKER, reference, results, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ CMPIStatus s;
+ CMPIInstance *inst = NULL;
+
+ s = get_vesssd_by_ref(_BROKER, reference, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ CMReturnInstance(results, inst);
+
+ out:
+ return s;
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+STD_InstanceMIStub(,
+ Virt_VESSSD,
+ _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:
+ */
diff --git a/src/Virt_VESSSD.h b/src/Virt_VESSSD.h
new file mode 100644
index 0000000..5105057
--- /dev/null
+++ b/src/Virt_VESSSD.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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
+ */
+#ifndef __VIRT_VESSSD_H
+#define __VIRT_VESSSD_H
+
+
+CMPIStatus enum_vesssd(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ struct inst_list *plist);
+
+CMPIStatus get_vesssd_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst);
+
+CMPIStatus get_vesssd_by_name(const CMPIBroker *broker,
+ const char *name,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst);
+
+
+#endif
--
1.7.1
1
0
From: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
This patch add VESS according DSP1097.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/VirtualEthernetSwitchSystem.mof | 10 +
schema/VirtualEthernetSwitchSystem.registration | 3 +
src/Virt_VirtualEthernetSwitchSystem.c | 478 +++++++++++++++++++++++
src/Virt_VirtualEthernetSwitchSystem.h | 52 +++
4 files changed, 543 insertions(+), 0 deletions(-)
create mode 100644 schema/VirtualEthernetSwitchSystem.mof
create mode 100644 schema/VirtualEthernetSwitchSystem.registration
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h
diff --git a/schema/VirtualEthernetSwitchSystem.mof b/schema/VirtualEthernetSwitchSystem.mof
new file mode 100644
index 0000000..6c43719
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystem.mof
@@ -0,0 +1,10 @@
+// Copyright IBM Corp. 2012
+[Description (
+ "A class derived from CIM_ComputerSystem to represent "
+ "the Virtual Bridge on the host."),
+ Provider("cmpi::Virt_VirtualEthernetSwitchSystem")
+]
+class Net_VirtualEthernetSwitchSystem : CIM_ComputerSystem
+{
+
+};
diff --git a/schema/VirtualEthernetSwitchSystem.registration b/schema/VirtualEthernetSwitchSystem.registration
new file mode 100644
index 0000000..ac94e7c
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystem.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2012
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_VirtualEthernetSwitchSystem root/virt Virt_VirtualEthernetSwitchSystem Virt_VirtualEthernetSwitchSystem instance method
diff --git a/src/Virt_VirtualEthernetSwitchSystem.c b/src/Virt_VirtualEthernetSwitchSystem.c
new file mode 100644
index 0000000..14fb340
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystem.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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 <unistd.h>
+#include <limits.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <libcmpiutil/std_invokemethod.h>
+#include <libcmpiutil/std_instance.h>
+#include <libcmpiutil/std_indication.h>
+
+#include "Virt_VirtualEthernetSwitchSystem.h"
+#include "device_parsing.h"
+#include "network_model_helper.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_switch(const CMPIBroker *broker,
+ const struct EthIface *piface, CMPIInstance *instance)
+{
+ char *name;
+ uint16_t dedicated;
+ CMPIArray *array;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ name = get_switch_name_from_iface(piface->name);
+ CMSetProperty(instance, "Name",
+ (CMPIValue *)name, CMPI_chars);
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)name, CMPI_chars);
+ CU_FREE(name);
+
+ array = CMNewArray(broker, 1, CMPI_uint16, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) {
+ return 0;
+ }
+ dedicated = CIM_NUM_SWITCH_DEDICATED;
+ CMSetArrayElementAt(array, 0, &dedicated, CMPI_uint16);
+ CMSetProperty(instance, "Dedicated",
+ (CMPIValue *)&array, CMPI_uint16A);
+
+ return 1;
+}
+
+static int set_secondary_for_switch(const CMPIBroker *broker,
+ struct EthIface *piface, CMPIInstance *instance)
+{
+ int state;
+ if (piface->run_prop.status == ETH_STATE_INACTIVE) {
+ state = CIM_STATE_DISABLED;
+ } else if (piface->run_prop.status == ETH_STATE_ACTIVE) {
+ state = CIM_STATE_ENABLED;
+ } else {
+ state = CIM_STATE_UNKNOWN;
+ }
+ CMSetProperty(instance, "EnabledState",
+ (CMPIValue *)&state, CMPI_uint16);
+ CMSetProperty(instance, "RequestedState",
+ (CMPIValue *)&state, CMPI_uint16);
+
+ return 1;
+}
+
+/* Populate an instance with information from a switch */
+static CMPIStatus set_properties(const CMPIBroker *broker,
+ struct EthIface *piface,
+ const char *prefix,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *errstr;
+
+ if (!set_primary_for_switch(broker, piface, instance)) {
+ errstr = "failed to set primary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (!set_secondary_for_switch(broker, piface, instance)) {
+ errstr = "failed to set secondary properties for instance.";
+ CU_DEBUG("%s, iface name %s.", errstr, piface->name);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+
+ out:
+ return s;
+}
+
+static CMPIStatus instance_from_switch(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ struct EthIface *piface,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+ "VirtualEthernetSwitchSystem",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init VirtualEthernetSwitchSystem instance");
+ goto out;
+ }
+
+ s = set_properties(broker,
+ piface,
+ NETWORK_CLASS_PREFIX,
+ inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+CMPIStatus enum_switches(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool names_only)
+{
+ struct inst_list list;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct EthIfacesList ifaces_list;
+ int ret, i;
+ char *errstr;
+
+ inst_list_init(&list);
+ eth_ifaceslist_init(&ifaces_list);
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_switch, NULL);
+
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ eth_ifaceslist_print(&ifaces_list);
+
+ i = 0;
+ while (i < ifaces_list.count) {
+ CMPIInstance *inst = NULL;
+
+ s = instance_from_switch(broker,
+ reference,
+ ifaces_list.pifaces[i],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(&list, inst);
+ i++;
+ }
+
+ if (names_only) {
+ cu_return_instance_names(results, &list);
+ } else {
+ cu_return_instances(results, &list);
+ }
+
+ out:
+ inst_list_free(&list);
+ eth_ifaceslist_uninit(&ifaces_list);
+
+ return s;
+}
+
+CMPIStatus get_switch_by_name(const CMPIBroker *broker,
+ const char *name,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char *eth_name = NULL;
+ char *errstr;
+ int ret;
+ struct EthIfacesList ifaces_list;
+
+ eth_ifaceslist_init(&ifaces_list);
+
+ eth_name = get_iface_name_from_switch(name);
+ if (eth_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert switch_name");
+ CU_DEBUG("switch name %s failed to convert.", name);
+ goto out;
+ }
+
+ ret = get_host_ifaces(&ifaces_list,
+ eth_iface_filter_cim_switch_for_name, eth_name);
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (ifaces_list.count != 1) {
+ errstr = "expected switch not found.";
+ CU_DEBUG("%s\n", errstr);
+ eth_ifaceslist_print(&ifaces_list);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ s = instance_from_switch(broker,
+ reference,
+ ifaces_list.pifaces[0],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+ CU_FREE(eth_name);
+ return s;
+}
+
+CMPIStatus get_switch_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ const char *name = NULL;
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "No domain name specified");
+ goto out;
+ }
+
+ s = get_switch_by_name(broker, name, reference, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ s = cu_validate_ref(broker, reference, inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+
+ return s;
+}
+
+static CMPIStatus __state_change(const CMPIBroker *broker,
+ const char *name,
+ uint16_t state,
+ const CMPIObjectPath *ref)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct EthIface iface;
+ int iface_state;
+ int ret;
+ char *errstr;
+
+ eth_iface_init(&iface);
+ iface.name = get_iface_name_from_switch(name);
+ if (iface.name == NULL) {
+ errstr = "failed to get iface name.";
+ CU_DEBUG("for %s, %s.", name, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (state == CIM_STATE_ENABLED) {
+ iface_state = ETH_STATE_ACTIVE;
+ } else if (state == CIM_STATE_DISABLED) {
+ iface_state = ETH_STATE_INACTIVE;
+ } else {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_SUPPORTED,
+ "State not supported");
+ goto out;
+ }
+
+ /* TBD in next patch
+ ret = change_state_host_iface(&iface, iface_state); */
+ if (ret != 1) {
+ errstr = get_host_iface_error_reason(ret);
+ CU_DEBUG("error num %d returned, reason %s.", ret, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+
+ out:
+ eth_iface_uninit(&iface);
+ return s;
+}
+
+static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ return enum_switches(_BROKER, reference, results, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ return enum_switches(_BROKER, reference, results, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ s = get_switch_by_ref(_BROKER, reference, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ CMReturnInstance(results, inst);
+
+ out:
+ return s;
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+static CMPIStatus state_change(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s;
+ CMPIInstance *prev_inst = NULL;
+ uint16_t state;
+ int ret;
+ const char *name = NULL;
+ uint32_t rc = 1;
+
+ ret = cu_get_u16_arg(argsin, "RequestedState", &state);
+ if (ret != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Invalid RequestedState");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Name key not specified");
+ goto out;
+ }
+
+ s = get_switch_by_name(_BROKER, name, reference, &prev_inst);
+ if (s.rc != CMPI_RC_OK || prev_inst == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Unable to get instance for guest '%s'",
+ name);
+ goto out;
+ }
+
+ s = __state_change(_BROKER, name, state, reference);
+
+ if (s.rc == CMPI_RC_OK) {
+ rc = 0;
+ }
+ out:
+ CMReturnData(results, &rc, CMPI_uint32);
+
+ return s;
+}
+
+STD_InstanceMIStub(,
+ Virt_VirtualEthernetSwitchSystem,
+ _BROKER,
+ libvirt_cim_init());
+
+static struct method_handler RequestStateChange = {
+ .name = "RequestStateChange",
+ .handler = state_change,
+ .args = {{"RequestedState", CMPI_uint16, false},
+ {"TimeoutPeriod", CMPI_dateTime, true},
+ ARG_END
+ }
+};
+
+static struct method_handler *my_handlers[] = {
+ &RequestStateChange,
+ NULL
+};
+
+STDIM_MethodMIStub(,
+ Virt_VirtualEthernetSwitchSystem,
+ _BROKER,
+ libvirt_cim_init(),
+ my_handlers);
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/src/Virt_VirtualEthernetSwitchSystem.h b/src/Virt_VirtualEthernetSwitchSystem.h
new file mode 100644
index 0000000..de8587b
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystem.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.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
+ */
+#ifndef __VIRT_VIRTUALETHERNETSWITCHSYSTEM_H
+#define __VIRT_VIRTUALETHERNETSWITCHSYSTEM_H
+
+#include "misc_util.h"
+
+CMPIStatus enum_switches(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool names_only);
+
+CMPIStatus get_switch_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst);
+
+
+CMPIStatus get_switch_by_name(const CMPIBroker *broker,
+ const char *name,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst);
+
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-set-style: "K&R"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.7.1
1
0