This patch added a new service class VESSMS which can modify host network
about adding, modifying, deleting 802.1.q vlan and bridge.
The model of bridge modification is according to VSMS model, and on DSP1097
it says virtual switch should be managed similar to ComputerSystem.
The model of allocation of vlan port, is on chapter 9.1.2 of DSP1050_1.0.
Difference is that, this patch did not use Parent propety to identify which
switch it should belongs to, but use property InstanceID to say it, such as
VS_eth0/EA_eth0.10, because using Parent for port allocation needs to implement
EC_POOL making things more complicate.
The model of connecting of vlan port with bridge, is on chapter 9.1.4 of
DSP1050_1.0. The patch matches it despite of that EA_POOL and EC_POOL are not
implemented.
V7: Some host network checking such as checking of existence for an EthIface
before modify it, are moved to function library. Code style changed to fit
libvirt-cim. Added properties AutoStart, DHCP, Delay. Other things are same
with V2.
Signed-off-by: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
---
...irtualEthernetSwitchSystemManagementService.mof | 14 +
...ernetSwitchSystemManagementService.registration | 3 +
src/Virt_HostSystem.c | 2 +-
src/Virt_HostSystem.h | 2 +
..._VirtualEthernetSwitchSystemManagementService.c | 1289 ++++++++++++++++++++
..._VirtualEthernetSwitchSystemManagementService.h | 31 +
src/Virt_VirtualSystemManagementService.c | 2 +-
src/Virt_VirtualSystemManagementService.h | 4 +
8 files changed, 1345 insertions(+), 2 deletions(-)
create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof
create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.registration
create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h
diff --git a/schema/VirtualEthernetSwitchSystemManagementService.mof
b/schema/VirtualEthernetSwitchSystemManagementService.mof
new file mode 100644
index 0000000..5317305
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystemManagementService.mof
@@ -0,0 +1,14 @@
+// Copyright IBM Corp. 2011
+
+[Provider("cmpi::Virt_VirtualEthernetSwitchSystemManagementService")]
+class Net_VirtualEthernetSwitchSystemManagementService :
CIM_VirtualSystemManagementService
+{
+ [Description("HG changeset id of the providers")]
+ string Changeset;
+
+ [Description("HG revision number of the providers")]
+ string Revision;
+
+ [Description("Package Version")]
+ string Release;
+};
diff --git a/schema/VirtualEthernetSwitchSystemManagementService.registration
b/schema/VirtualEthernetSwitchSystemManagementService.registration
new file mode 100644
index 0000000..ef2b4b1
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystemManagementService.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2011
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_VirtualEthernetSwitchSystemManagementService root/virt
Virt_VirtualEthernetSwitchSystemManagementService
Virt_VirtualEthernetSwitchSystemManagementService method instance
diff --git a/src/Virt_HostSystem.c b/src/Virt_HostSystem.c
index 724a5ea..de8ec13 100644
--- a/src/Virt_HostSystem.c
+++ b/src/Virt_HostSystem.c
@@ -76,7 +76,7 @@ static int resolve_host(char *host, char *buf, int size)
return 0;
}
-static int get_fqdn(char *buf, int size)
+int get_fqdn(char *buf, int size)
{
char host[256];
int ret = 0;
diff --git a/src/Virt_HostSystem.h b/src/Virt_HostSystem.h
index 53ebf1c..3b988c1 100644
--- a/src/Virt_HostSystem.h
+++ b/src/Virt_HostSystem.h
@@ -21,6 +21,8 @@
#ifndef __VIRT_HOSTSYSTEM_H
#define __VIRT_HOSTSYSTEM_H
+int get_fqdn(char *buf, int size);
+
CMPIStatus get_host(const CMPIBroker *broker,
const CMPIContext *context,
const CMPIObjectPath *reference,
diff --git a/src/Virt_VirtualEthernetSwitchSystemManagementService.c
b/src/Virt_VirtualEthernetSwitchSystemManagementService.c
new file mode 100644
index 0000000..1048676
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystemManagementService.c
@@ -0,0 +1,1289 @@
+/*
+ * Copyright IBM Corp. 2012
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <time.h>
+#include <sys/time.h>
+#include <libvirt/libvirt.h>
+
+#include "cmpidt.h"
+#include "cmpift.h"
+#include "cmpimacs.h"
+
+#include "cs_util.h"
+#include "misc_util.h"
+#include "device_parsing.h"
+#include "xmlgen.h"
+
+#include <libcmpiutil/libcmpiutil.h>
+#include <libcmpiutil/std_invokemethod.h>
+#include <libcmpiutil/std_indication.h>
+#include <libcmpiutil/std_instance.h>
+
+#include "misc_util.h"
+#include "infostore.h"
+
+#include "Virt_VirtualSystemManagementService.h"
+#include "Virt_VirtualEthernetSwitchSystemManagementService.h"
+#include "Virt_VirtualEthernetSwitchSystem.h"
+#include "Virt_HostSystem.h"
+#include "Virt_EASD.h"
+#include "network_model_helper.h"
+#include "svpc_types.h"
+
+#include "config.h"
+
+
+static const CMPIBroker *_BROKER;
+
+typedef enum ResourceAction {
+ RESOURCE_ADD,
+ RESOURCE_DEL,
+ RESOURCE_MOD,
+} ResourceAction;
+
+static CMPIArray *set_result_res_vessms(struct inst_list *list,
+ const char *ns)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *op = NULL;
+ CMPIArray *res = NULL;
+ int i = 0;
+
+ if (list->cur == 0) {
+ CU_DEBUG("No resources were added or modified");
+ return res;
+ }
+
+ res = CMNewArray(_BROKER, list->cur, CMPI_ref, &s);
+ if ((s.rc != CMPI_RC_OK) || (res == NULL)) {
+ CU_DEBUG("Unable to create results array");
+ goto out;
+ }
+
+ for (i = 0; list->list[i] != NULL; i++) {
+ op = CMGetObjectPath(list->list[i], NULL);
+ if (op == NULL) {
+ CU_DEBUG("Unable to EASD reference");
+ goto out;
+ }
+ CMSetNameSpace(op, ns);
+
+ s = CMSetArrayElementAt(res, i, (CMPIValue *)&op, CMPI_ref);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Error setting results array element");
+ goto out;
+ }
+ }
+
+ out:
+ if (s.rc != CMPI_RC_OK) {
+ res = NULL;
+ }
+
+ return res;
+}
+
+static CMPIStatus check_piface_for_easd_ea(const CMPIBroker *broker,
+ struct EthIface *piface)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ struct VLAN_Prop_8021q *pvlan_8021q;
+ if ((piface->eth_type != ETH_TYPE_ETHER_VLAN) ||
+ (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "now only support opertaion for IEEE 802.1.q.");
+ CU_DEBUG("only support IEEE 802.1.q, request is:");
+ eth_iface_print(piface);
+ goto out;
+ }
+
+ pvlan_8021q = &(piface->pvlan_prop->props.prop_8021q);
+ if ((pvlan_8021q->vlan_id < 0) || (pvlan_8021q->vlan_id > 4095)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "invalid vlan id set.");
+ CU_DEBUG("invalid vlan id %d set.", pvlan_8021q->vlan_id);
+ goto out;
+ }
+
+ out:
+ return s;
+}
+
+static CMPIStatus check_piface_for_easd_ec(const CMPIBroker *broker,
+ struct EthIface *piface_src,
+ struct EthIface *piface_dest)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ if ((piface_dest->eth_type != ETH_TYPE_ETHER_BRIDGE) ||
+ (piface_dest->name == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "now only support connection between bridge and "
+ "port, but the dest is not a bridge or "
+ "dest name not got.");
+ CU_DEBUG("requested connectting device %s is not a bridge.",
+ piface_dest->name);
+ goto out;
+ }
+
+ if (piface_src->name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "connection src port was not got.");
+ CU_DEBUG("connection src port was not got.");
+ goto out;
+ }
+
+ out:
+ return s;
+}
+
+/* piface need to be created before calling the funtion */
+static CMPIStatus instance_to_vesssd(const CMPIBroker *broker,
+ struct EthIface *piface,
+ CMPIInstance *inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIObjectPath *opathp = NULL;
+ const char *brname = NULL;
+ const char *cn = NULL;
+ char *pfx = NULL;
+ uint16_t stp, delay, dhcp, boot_mode;
+ int ret;
+
+ opathp = CMGetObjectPath(inst, NULL);
+ if (opathp == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "failed to get object path.");
+ goto out;
+ }
+
+ cn = CLASSNAME(opathp);
+ pfx = class_prefix_name(cn);
+ if (pfx == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "Unknown prefix for the class.");
+ goto out;
+ }
+
+ ret = cu_get_str_prop(inst, "VirtualSystemIdentifier", &brname);
+ if (ret != CMPI_RC_OK) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "property VirtualSystemIdentifier not set.");
+ CU_DEBUG("failed to get property VirtualSystemIdentifier.");
+ goto out;
+ }
+ piface->name = get_iface_name_from_switch(brname);
+ if (piface->name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert switch_name");
+ CU_DEBUG("switch name %s failed to convert.", brname);
+ goto out;
+ }
+
+ ret = cu_get_u16_prop(inst, "STP", &stp);
+ if (ret == CMPI_RC_OK) {
+ piface->pbr_prop->STP = stp;
+ }
+
+ ret = cu_get_u16_prop(inst, "Delay", &delay);
+ if (ret == CMPI_RC_OK) {
+ piface->pbr_prop->delay = delay;
+ }
+
+ ret = cu_get_u16_prop(inst, "DHCP", &dhcp);
+ if (ret == CMPI_RC_OK) {
+ piface->protocol_prop.ipv4_prop.DHCP = dhcp;
+ }
+
+ ret = cu_get_u16_prop(inst, "AutoStart", &boot_mode);
+ if (ret == CMPI_RC_OK) {
+ piface->run_prop.boot_mode = boot_mode;
+ }
+
+ out:
+ free(pfx);
+ return s;
+}
+
+static CMPIStatus instance_to_easd_ea(const CMPIBroker *broker,
+ struct EthIface *piface,
+ CMPIInstance *inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIStatus s_tmp;
+ int ret, temp;
+ uint16_t vlan_type = 0;
+ uint16_t dhcp, boot_mode;
+ char *charpvalues[8];
+ int charpcount = 0;
+ struct VLAN_Prop_8021q *pvlan_8021q = NULL;
+
+ ret = cu_get_u16_prop(inst, "VLANType", &vlan_type);
+ if (ret == CMPI_RC_OK) {
+ if (vlan_type == 1) {
+ piface->eth_type = ETH_TYPE_ETHER_VLAN;
+ piface->pvlan_prop->vlan_type = VLAN_TYPE_802_1_Q;
+ pvlan_8021q = &(piface->pvlan_prop->props.prop_8021q);
+ } else {
+ CU_DEBUG("unsupported VLANType "
+ "%d requested", vlan_type);
+ }
+ } else {
+ CU_DEBUG("VLANType is missing");
+ }
+
+ if ((pvlan_8021q == NULL) ||
+ (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q)) {
+ goto end_of_8021q;
+ }
+
+ pvlan_8021q->parent = CU_STRDUP(piface->dep_ifname);
+
+ s_tmp = get_array_string_from_instance(broker, inst, "Connection",
+ charpvalues, &charpcount, 8);
+ if ((s_tmp.rc == CMPI_RC_OK) && (charpcount == 1)) {
+ temp = vlanid_from_connection_name(charpvalues[0]);
+ if ((temp >= 0) && (temp < 4096)) {
+ pvlan_8021q->vlan_id = temp;
+ }
+ } else {
+ CU_DEBUG("Connnection property have %d settings.",
charpcount);
+ }
+
+ end_of_8021q:
+
+ ret = cu_get_u16_prop(inst, "DHCP", &dhcp);
+ if (ret == CMPI_RC_OK) {
+ piface->protocol_prop.ipv4_prop.DHCP = dhcp;
+ }
+
+ ret = cu_get_u16_prop(inst, "AutoStart", &boot_mode);
+ if (ret == CMPI_RC_OK) {
+ piface->run_prop.boot_mode = boot_mode;
+ }
+
+ return s;
+}
+
+static CMPIStatus instance_to_easd_ec(const CMPIBroker *broker,
+ struct EthIface *piface_src,
+ struct EthIface *piface_dest,
+ CMPIInstance *inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL}, s_tmp;
+ int ret, i;
+ char *charpvalues[8];
+ int charpcount = 0;
+ char *prefix = NULL, *portname = NULL;
+ const char *tmp;
+
+ s_tmp = get_array_string_from_instance(broker, inst, "HostResource",
+ charpvalues, &charpcount, 8);
+ if ((s_tmp.rc == CMPI_RC_OK) && (charpcount == 1)) {
+ piface_dest->name = get_iface_name_from_switch(charpvalues[0]);
+ if (piface_dest->name != NULL) {
+ piface_dest->eth_type = ETH_TYPE_ETHER_BRIDGE;
+ }
+ } else {
+ CU_DEBUG("HostResource have %d settings.", charpcount);
+ }
+ i = 0;
+ while (i < charpcount) {
+ CU_FREE(charpvalues[i]);
+ i++;
+ }
+
+ ret = cu_get_str_prop(inst, "Parent", &tmp);
+ if (ret == CMPI_RC_OK) {
+ if (1 == parse_fq_devid(tmp, &prefix, &portname)) {
+ CU_FREE(piface_src->name);
+ piface_src->name = get_iface_name_from_ethportsd(portname,
+ NULL);
+ }
+ }
+ piface_src->eth_type = ETH_TYPE_ETHER_ANY;
+
+ CU_FREE(prefix);
+ CU_FREE(portname);
+ return s;
+}
+
+/* pifaces need to be created before calling the funtion */
+static CMPIStatus instance_to_easd(const CMPIBroker *broker,
+ const char *preset_parent,
+ struct EthIface *piface_src,
+ struct EthIface *piface_dest,
+ CMPIInstance *inst,
+ int *type)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ char *prefix = NULL;
+ char *name = NULL;
+ char *port_name = NULL;
+ char *switch_name = NULL;
+ const char *tmp;
+ int request_type = 0;
+ int ret;
+
+ CU_DEBUG("enter inst to easd, preset_parent is %s.", preset_parent);
+ /* If a preset_parent is set by the user, then the code use it as
+ parent device. This parameter was used when user call the method
+ with parameter AffectedSystem. */
+ if (preset_parent == NULL) {
+ s = get_instanceid(inst, &prefix, &name);
+ if ((s.rc != CMPI_RC_OK) ||
+ (prefix == NULL) || (name == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "failed to translate InstanceId");
+ CU_DEBUG("failed to translate InstanceId, "
+ "prefix %s, name %s.", prefix, name);
+ goto out;
+ }
+ } else {
+ /*fix me, use value from Parent if ElementName was not set */
+ ret = cu_get_str_prop(inst, "ElementName", &tmp);
+ if (ret == CMPI_RC_OK) {
+ name = CU_STRDUP(tmp);
+ prefix = CU_STRDUP(preset_parent);
+ } else {
+ s = get_instanceid(inst, &prefix, &name);
+ if ((s.rc != CMPI_RC_OK) || (name == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "failed to get port name, "
+ "InstanceID or ElementName "
+ "need to be set correctly.");
+ CU_DEBUG("failed to geto port name, "
+ "prefix %s, name %s.", prefix, name);
+ goto out;
+ }
+ }
+ }
+
+ if (name == NULL) {
+ s = get_instanceid(inst, &prefix, &name);
+ if ((s.rc != CMPI_RC_OK) ||
+ (prefix == NULL) || (name == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_FOUND,
+ "failed to translate InstanceId");
+ CU_DEBUG("failed to translate InstanceId, "
+ "prefix %s, name %s.", prefix, name);
+ goto out;
+ }
+ }
+
+ switch_name = get_iface_name_from_switch(prefix);
+ if (switch_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert instance prefix name");
+ CU_DEBUG("switch name %s failed to convert.", prefix);
+ goto out;
+ }
+ port_name = get_iface_name_from_ethportsd(name, &request_type);
+ if (port_name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to convert instance suffix name");
+ CU_DEBUG("ethport name %s failed to convert.", name);
+ goto out;
+ }
+
+ if (request_type == EASD_TYPE_EA) {
+ piface_src->name = port_name;
+ piface_src->dep_ifname = switch_name;
+ port_name = NULL;
+ switch_name = NULL;
+ s = instance_to_easd_ea(broker, piface_src, inst);
+ } else {
+ piface_src->name = port_name;
+ port_name = NULL;
+ s = instance_to_easd_ec(broker, piface_src, piface_dest, inst);
+ }
+
+ out:
+ *type = request_type;
+ CU_FREE(prefix);
+ CU_FREE(name);
+ CU_FREE(port_name);
+ CU_FREE(switch_name);
+ return s;
+}
+
+static CMPIStatus _update_easd_for(const CMPIBroker *broker,
+ const CMPIContext *context,
+ const CMPIObjectPath *ref,
+ const char *preset_parent,
+ CMPIInstance *rasd,
+ ResourceAction action)
+{
+ CMPIStatus s;
+ int type;
+ struct EthIface iface_src, iface_dest;
+ int ret;
+ char *errstr;
+
+ eth_iface_init(&iface_src);
+ eth_iface_init(&iface_dest);
+ eth_iface_add_br_prop(&iface_src);
+ eth_iface_add_vlan_prop(&iface_src, VLAN_TYPE_802_1_Q);
+ eth_iface_add_br_prop(&iface_dest);
+ eth_iface_add_vlan_prop(&iface_dest, VLAN_TYPE_802_1_Q);
+
+
+ CU_DEBUG("Enter _update_easd_for");
+ s = instance_to_easd(broker, preset_parent,
+ &iface_src, &iface_dest, rasd, &type);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ if (type == EASD_TYPE_EA) {
+ s = check_piface_for_easd_ea(broker, &iface_src);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ CU_DEBUG("easd-EA operation with request type %d,"
+ "iface settings is :", action);
+ eth_iface_print(&iface_src);
+ if (action == RESOURCE_ADD) {
+ ret = add_host_iface(&iface_src);
+ } else if (action == RESOURCE_MOD) {
+ ret = mod_host_iface(&iface_src);
+ } else if (action == RESOURCE_DEL) {
+ ret = del_host_iface(&iface_src);
+ } else {
+ errstr = "requested an unsupported operation.";
+ CU_DEBUG("%s", errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ } else {
+ s = check_piface_for_easd_ec(broker, &iface_src, &iface_dest);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ CU_DEBUG("easd-EC operation with request type %d,"
+ "iface settings are :", action);
+ eth_iface_print(&iface_src);
+ eth_iface_print(&iface_dest);
+ if (action == RESOURCE_ADD) {
+ ret = connect_two_ifaces(&iface_src, &iface_dest);
+ } else if (action == RESOURCE_DEL) {
+ ret = disconnect_two_ifaces(&iface_src, &iface_dest);
+ } else {
+ errstr = "requested an unsupported operation.";
+ CU_DEBUG("%s", errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ }
+
+ 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_src);
+ eth_iface_uninit(&iface_dest);
+ return s;
+}
+
+static CMPIStatus _update_easd_settings(const CMPIContext *context,
+ const CMPIObjectPath *ref,
+ const char *bridge,
+ CMPIArray *resources,
+ const CMPIResult *results,
+ ResourceAction action,
+ struct inst_list *list)
+{
+ int i;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ int count = 0;
+ uint32_t rc = CIM_SVPC_RETURN_FAILED;
+
+ CU_DEBUG("Enter _update_easd_settings");
+ if (resources == NULL) {
+ CU_DEBUG("No easd settings.");
+ goto out;
+ }
+
+ count = CMGetArrayCount(resources, &s);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("failed to get array size.");
+ goto out;
+ }
+
+ i = 0;
+ CU_DEBUG("Trying update %d easds.", count);
+ while (i < count) {
+ CMPIData item;
+ CMPIInstance *inst;
+ item = CMGetArrayElementAt(resources, i, NULL);
+ inst = item.value.inst;
+
+ s = _update_easd_for(_BROKER,
+ context,
+ ref,
+ bridge,
+ inst,
+ action);
+ if (s.rc != CMPI_RC_OK) {
+ break;
+ }
+ inst_list_add(list, inst);
+ i++;
+ }
+
+ out:
+ if (s.rc == CMPI_RC_OK) {
+ rc = CIM_SVPC_RETURN_COMPLETED;
+ }
+ if ((results != NULL) && (resources != NULL)) {
+ CMReturnData(results, &rc, CMPI_uint32);
+ }
+
+ return s;
+}
+
+static CMPIStatus easd_refs_to_insts(const CMPIBroker *broker,
+ const CMPIContext *ctx,
+ const CMPIObjectPath *reference,
+ CMPIArray *arr,
+ CMPIArray **ret_arr)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIArray *tmp_arr;
+ int i;
+ int c;
+
+ c = CMGetArrayCount(arr, &s);
+ if (s.rc != CMPI_RC_OK) {
+ return s;
+ }
+
+ tmp_arr = CMNewArray(broker,
+ c,
+ CMPI_instance,
+ &s);
+
+ for (i = 0; i < c; i++) {
+ CMPIData d;
+ CMPIObjectPath *ref;
+ CMPIInstance *inst = NULL;
+ const char *id;
+
+ d = CMGetArrayElementAt(arr, i, &s);
+ ref = d.value.ref;
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Unable to get ResourceSettings[%i]", i);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get ResourceSettings");
+ goto out;
+ }
+
+ if (cu_get_str_path(ref, "InstanceID", &id) != CMPI_RC_OK)
{
+ CU_DEBUG("Unable to get InstanceID of `%s'",
+ REF2STR(ref));
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to get InstanceID");
+ goto out;
+ }
+
+ s = get_easd_by_id(broker, id, reference, NULL, &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ CMSetArrayElementAt(tmp_arr, i,
+ &inst,
+ CMPI_instance);
+
+ }
+
+ *ret_arr = tmp_arr;
+
+ out:
+ return s;
+}
+
+static CMPIInstance *create_switch_system(const CMPIContext *context,
+ CMPIInstance *vsssd,
+ CMPIArray *resources,
+ const CMPIObjectPath *ref,
+ const CMPIObjectPath *refconf,
+ CMPIStatus *s)
+{
+ CMPIInstance *inst = NULL;
+ struct EthIface iface_br;
+ int ret;
+ char *errstr;
+ char *br_name = NULL;
+ struct inst_list list;
+
+ inst_list_init(&list);
+ eth_iface_init(&iface_br);
+ eth_iface_add_br_prop(&iface_br);
+
+ CU_DEBUG("Enter create_switch_system");
+ if (refconf != NULL) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "creating switch system with"
+ " reference is not supported now.");
+ goto out;
+ }
+
+ *s = instance_to_vesssd(_BROKER, &iface_br, vsssd);
+ if (s->rc != CMPI_RC_OK) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "failed to translate settings.");
+ goto out;
+ }
+ iface_br.eth_type = ETH_TYPE_ETHER_BRIDGE;
+ CU_DEBUG("Creating Switch System as follow:");
+ eth_iface_print(&iface_br);
+
+ ret = add_host_iface(&iface_br);
+ 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;
+ }
+
+ br_name = get_switch_name_from_iface(iface_br.name);
+ *s = _update_easd_settings(context,
+ ref,
+ br_name,
+ resources,
+ NULL,
+ RESOURCE_ADD,
+ &list);
+
+
+ *s = get_switch_by_name(_BROKER,
+ br_name,
+ ref,
+ &inst);
+
+ out:
+ inst_list_free(&list);
+ eth_iface_uninit(&iface_br);
+ free(br_name);
+
+ return inst;
+}
+
+static CMPIStatus update_switchsystem_settings(const CMPIContext *context,
+ const CMPIObjectPath *ref,
+ CMPIInstance *vsssd)
+{
+ CMPIStatus s;
+ struct EthIface iface_br;
+ struct EthIfacesList ifaces_list;
+ int ret;
+ char *errstr;
+
+ eth_ifaceslist_init(&ifaces_list);
+ eth_iface_init(&iface_br);
+
+ eth_iface_add_br_prop(&iface_br);
+
+ s = instance_to_vesssd(_BROKER, &iface_br, vsssd);
+ if (s.rc != CMPI_RC_OK || (iface_br.name == NULL)) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "failed to translate settings.");
+ goto out;
+
+ }
+
+ CU_DEBUG("update switch settings as following settings:");
+ eth_iface_print(&iface_br);
+ ret = mod_host_iface(&iface_br);
+ 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_ifaceslist_uninit(&ifaces_list);
+ eth_iface_uninit(&iface_br);
+ return s;
+}
+
+static CMPIStatus define_switch_system_parse_args(const CMPIArgs *argsin,
+ CMPIInstance **sys,
+ const char *ns,
+ CMPIArray **res,
+ CMPIObjectPath **refconf)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ if (cu_get_inst_arg(argsin, "SystemSettings", sys) != CMPI_RC_OK) {
+ CU_DEBUG("No SystemSettings string argument");
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Missing argument `SystemSettings'");
+ goto out;
+ }
+
+ if (cu_get_array_arg(argsin, "ResourceSettings", res) !=
+ CMPI_RC_OK) {
+ CU_DEBUG("Did not get ResourceSettings arg");
+ *res = NULL;
+ }
+
+ if (cu_get_ref_arg(argsin, "ReferenceConfiguration", refconf) !=
+ CMPI_RC_OK) {
+ CU_DEBUG("Did not get ReferenceConfiguration arg");
+ *refconf = NULL;
+ }
+ out:
+ return s;
+}
+
+static CMPIStatus define_system(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *vsssd;
+ CMPIArray *res;
+ CMPIObjectPath *refconf;
+ CMPIInstance *sys = NULL;
+ CMPIObjectPath *result;
+ uint32_t rc = CIM_SVPC_RETURN_FAILED;
+
+ CU_DEBUG("DefineSystem");
+
+ s = define_switch_system_parse_args(argsin,
+ &vsssd,
+ NAMESPACE(reference),
+ &res,
+ &refconf);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ sys = create_switch_system(context, vsssd, res, reference, refconf, &s);
+ if (sys == NULL) {
+ goto out;
+ }
+
+ result = CMGetObjectPath(sys, &s);
+ if ((result != NULL) && (s.rc == CMPI_RC_OK)) {
+ CMSetNameSpace(result, NAMESPACE(reference));
+ CMAddArg(argsout, "ResultingSystem", &result, CMPI_ref);
+ }
+
+
+ out:
+ if (s.rc == CMPI_RC_OK) {
+ rc = CIM_SVPC_RETURN_COMPLETED;
+ }
+ CMReturnData(results, &rc, CMPI_uint32);
+
+ return s;
+}
+
+static CMPIStatus destroy_system(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ const char *br_name = NULL;
+ struct EthIface iface_br;
+ uint32_t rc = IM_RC_FAILED;
+ CMPIObjectPath *sys;
+ int ret;
+ char *errstr;
+
+ eth_iface_init(&iface_br);
+ CU_DEBUG("entering destroy switch system.");
+
+ if (cu_get_ref_arg(argsin, "AffectedSystem", &sys) != CMPI_RC_OK)
{
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "AffectedSystem not set");
+ goto out;
+ }
+
+ br_name = get_key_from_ref_arg(argsin, "AffectedSystem",
"Name");
+ if (br_name == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed get Name of AffectedSystem");
+ goto out;
+ }
+
+ iface_br.name = get_iface_name_from_switch(br_name);
+ if (iface_br.name == NULL) {
+ CU_DEBUG("failed to get iface name from %s.", br_name);
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to translate Name of AffectedSystem");
+ goto out;
+ }
+
+ iface_br.eth_type = ETH_TYPE_ETHER_BRIDGE;
+ CU_DEBUG("Deleting Switch System as follow:");
+ eth_iface_print(&iface_br);
+
+ ret = del_host_iface(&iface_br);
+ 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;
+ }
+
+ rc = IM_RC_OK;
+
+ out:
+ eth_iface_uninit(&iface_br);
+ CMReturnData(results, &rc, CMPI_uint32);
+ return s;
+}
+
+
+static CMPIStatus mod_system_settings(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIInstance *inst;
+ CMPIStatus s;
+ uint32_t rc;
+
+ if (cu_get_inst_arg(argsin, "SystemSettings", &inst) != CMPI_RC_OK)
{
+
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing SystemSettings");
+ goto out;
+ }
+
+ s = update_switchsystem_settings(context, reference, inst);
+ out:
+ if (s.rc == CMPI_RC_OK) {
+ rc = CIM_SVPC_RETURN_COMPLETED;
+ } else {
+ rc = CIM_SVPC_RETURN_FAILED;
+ }
+
+ CMReturnData(results, &rc, CMPI_uint32);
+
+ return s;
+}
+
+static CMPIStatus add_resource_settings(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIArray *arr;
+ CMPIStatus s;
+ CMPIObjectPath *sys;
+ char *bridge = NULL;
+ CMPIArray *res = NULL;
+ struct inst_list list;
+
+ inst_list_init(&list);
+
+ if (cu_get_array_arg(argsin, "ResourceSettings", &arr) !=
CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing ResourceSettings");
+ return s;
+ }
+
+ if (cu_get_ref_arg(argsin,
+ "AffectedConfiguration",
+ &sys) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Missing AffectedConfiguration parameter");
+ return s;
+ }
+
+ if (!parse_instanceid(sys, NULL, &bridge)) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "AffectedConfiguration has invalid InstanceID");
+ return s;
+ }
+
+ s = _update_easd_settings(context,
+ reference,
+ bridge,
+ arr,
+ results,
+ RESOURCE_ADD,
+ &list);
+
+ free(bridge);
+
+ res = set_result_res_vessms(&list, NAMESPACE(reference));
+ inst_list_free(&list);
+ CMAddArg(argsout, "ResultingResourceSettings", &res, CMPI_refA);
+
+
+ return s;
+}
+
+static CMPIStatus mod_resource_settings(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIArray *arr;
+ CMPIStatus s;
+ CMPIArray *res = NULL;
+ struct inst_list list;
+
+ CU_DEBUG("Enter mod_resource_settings");
+ inst_list_init(&list);
+
+ if (cu_get_array_arg(argsin, "ResourceSettings", &arr) !=
CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing ResourceSettings");
+ return s;
+ }
+
+ s = _update_easd_settings(context,
+ reference,
+ NULL,
+ arr,
+ results,
+ RESOURCE_MOD,
+ &list);
+
+ res = set_result_res_vessms(&list, NAMESPACE(reference));
+ CMAddArg(argsout, "ResultingResourceSettings", &res, CMPI_refA);
+ inst_list_free(&list);
+
+ return s;
+}
+
+static CMPIStatus rm_resource_settings(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ /* The RemoveResources case is different from either Add or
+ * Modify, because it takes references instead of instances
+ */
+
+ CMPIArray *arr;
+ CMPIArray *resource_arr = NULL;
+ CMPIStatus s;
+ struct inst_list list;
+
+ inst_list_init(&list);
+
+ if (cu_get_array_arg(argsin, "ResourceSettings", &arr) !=
CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Missing ResourceSettings");
+ goto out;
+ }
+
+ /* delete is simple, just specify the names */
+ s = easd_refs_to_insts(_BROKER, context, reference, arr,
+ &resource_arr);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ s = _update_easd_settings(context,
+ reference,
+ NULL,
+ resource_arr,
+ results,
+ RESOURCE_DEL,
+ &list);
+ out:
+ inst_list_free(&list);
+
+ return s;
+}
+
+static struct method_handler DefineSystem = {
+ .name = "DefineSystem",
+ .handler = define_system,
+ .args = {{"SystemSettings", CMPI_instance, false},
+ {"ResourceSettings", CMPI_instanceA, true},
+ {"ReferenceConfiguration", CMPI_ref, true},
+ ARG_END
+ }
+};
+
+static struct method_handler DestroySystem = {
+ .name = "DestroySystem",
+ .handler = destroy_system,
+ .args = {{"AffectedSystem", CMPI_ref, false},
+ ARG_END
+ }
+};
+
+static struct method_handler AddResourceSettings = {
+ .name = "AddResourceSettings",
+ .handler = add_resource_settings,
+ .args = {{"AffectedConfiguration", CMPI_ref, false},
+ {"ResourceSettings", CMPI_instanceA, false},
+ ARG_END
+ }
+};
+
+static struct method_handler ModifyResourceSettings = {
+ .name = "ModifyResourceSettings",
+ .handler = mod_resource_settings,
+ .args = {{"ResourceSettings", CMPI_instanceA, false},
+ ARG_END
+ }
+};
+
+static struct method_handler ModifySystemSettings = {
+ .name = "ModifySystemSettings",
+ .handler = mod_system_settings,
+ .args = {{"SystemSettings", CMPI_instance, false},
+ ARG_END
+ }
+};
+
+static struct method_handler RemoveResourceSettings = {
+ .name = "RemoveResourceSettings",
+ .handler = rm_resource_settings,
+ .args = {{"ResourceSettings", CMPI_refA, false},
+ ARG_END
+ }
+};
+
+static struct method_handler *my_handlers[] = {
+ &DefineSystem,
+ &DestroySystem,
+ &AddResourceSettings,
+ &ModifyResourceSettings,
+ &ModifySystemSettings,
+ &RemoveResourceSettings,
+ NULL,
+};
+
+STDIM_MethodMIStub(, Virt_VirtualEthernetSwitchSystemManagementService,
+ _BROKER, libvirt_cim_init(), my_handlers);
+
+
+CMPIStatus get_vessms(const CMPIObjectPath *reference,
+ CMPIInstance **_inst,
+ const CMPIBroker *broker,
+ const CMPIContext *context,
+ bool is_get_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ char host_name[256];
+ CMPIArray *array;
+ uint16_t op_status;
+
+ *_inst = NULL;
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+
"VirtualEthernetSwitchSystemManagementService",
+ NAMESPACE(reference));
+
+ if (inst == NULL) {
+ CU_DEBUG("Failed to get typed instance");
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to create instance");
+ goto out;
+ }
+
+ CMSetProperty(inst, "Caption",
+ (CMPIValue *)"VLAN and VBridge services", CMPI_chars);
+
+ CMSetProperty(inst, "Name",
+ (CMPIValue *)"Management Service", CMPI_chars);
+
+ if (0 == get_fqdn(host_name, sizeof(host_name))) {
+ CMSetProperty(inst, "SystemName",
+ (CMPIValue *)host_name, CMPI_chars);
+ }
+
+ CMSetProperty(inst, "SystemCreationClassName",
+ (CMPIValue *)"KVM_HostSystem", CMPI_chars);
+
+
+ CMSetProperty(inst, "Revision",
+ (CMPIValue *)LIBVIRT_CIM_RV, CMPI_chars);
+
+ CMSetProperty(inst, "Release",
+ (CMPIValue *)PACKAGE_VERSION, CMPI_chars);
+
+ array = CMNewArray(broker, 1, CMPI_uint16, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) {
+ goto out;
+ }
+
+ op_status = CIM_OPERATIONAL_STATUS;
+ CMSetArrayElementAt(array, 0, &op_status, CMPI_uint16);
+
+ CMSetProperty(inst, "OperationalStatus",
+ (CMPIValue *)&array, CMPI_uint16A);
+
+ if (is_get_inst) {
+ s = cu_validate_ref(broker, reference, inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+ out:
+ *_inst = inst;
+
+ return s;
+}
+
+static CMPIStatus return_vessms(const CMPIContext *context,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool name_only,
+ bool is_get_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst;
+
+ s = get_vessms(reference, &inst, _BROKER, context, is_get_inst);
+ if ((s.rc != CMPI_RC_OK) || (inst == NULL)) {
+ goto out;
+ }
+
+ if (name_only) {
+ cu_return_instance_name(results, inst);
+ } else {
+ CMReturnInstance(results, inst);
+ }
+ out:
+ return s;
+}
+
+static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ return return_vessms(context, reference, results, true, false);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+
+ return return_vessms(context, reference, results, false, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *ref,
+ const char **properties)
+{
+ return return_vessms(context, ref, results, false, true);
+}
+
+DEFAULT_CI();
+DEFAULT_MI();
+DEFAULT_DI();
+DEFAULT_EQ();
+DEFAULT_INST_CLEANUP();
+
+STD_InstanceMIStub(,
+ Virt_VirtualEthernetSwitchSystemManagementService,
+ _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_VirtualEthernetSwitchSystemManagementService.h
b/src/Virt_VirtualEthernetSwitchSystemManagementService.h
new file mode 100644
index 0000000..07c0f4e
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystemManagementService.h
@@ -0,0 +1,31 @@
+/*
+ * 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 VESSMS_H
+#define VESSMS_H
+
+CMPIStatus get_vessms(const CMPIObjectPath *reference,
+ CMPIInstance **_inst,
+ const CMPIBroker *broker,
+ const CMPIContext *context,
+ bool is_get_inst);
+
+#endif
diff --git a/src/Virt_VirtualSystemManagementService.c
b/src/Virt_VirtualSystemManagementService.c
index 6f42c42..761263b 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -2836,7 +2836,7 @@ static CMPIStatus _update_resources_for(const CMPIContext *context,
return s;
}
-static CMPIStatus get_instanceid(CMPIInstance *rasd,
+CMPIStatus get_instanceid(CMPIInstance *rasd,
char **domain,
char **devid)
{
diff --git a/src/Virt_VirtualSystemManagementService.h
b/src/Virt_VirtualSystemManagementService.h
index dbf17cb..d5ee4e4 100644
--- a/src/Virt_VirtualSystemManagementService.h
+++ b/src/Virt_VirtualSystemManagementService.h
@@ -34,3 +34,7 @@ CMPIStatus get_vsms(const CMPIObjectPath *reference,
const CMPIBroker *broker,
const CMPIContext *context,
bool is_get_inst);
+
+CMPIStatus get_instanceid(CMPIInstance *rasd,
+ char **domain,
+ char **devid);
--
1.7.1