[PATCH 04/15] vlan extension - CIM model - add class EthernetPort

adding the Net_EthernetPort class. Signed-off-by: Wayne Xia <xiawenc@linux.vnet.ibm.com> --- schema/EthernetPort.mof | 4 + schema/EthernetPort.registration | 3 + src/Virt_EthernetPort.c | 565 ++++++++++++++++++++++++++++++++++++++ src/Virt_EthernetPort.h | 58 ++++ 4 files changed, 630 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..4a81c91 --- /dev/null +++ b/schema/EthernetPort.mof @@ -0,0 +1,4 @@ +// Copyright IBM Corp. 2011 +class Net_EthernetPort : CIM_EthernetPort +{ +}; diff --git a/schema/EthernetPort.registration b/schema/EthernetPort.registration new file mode 100644 index 0000000..67320d0 --- /dev/null +++ b/schema/EthernetPort.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# 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..751fb33 --- /dev/null +++ b/src/Virt_EthernetPort.c @@ -0,0 +1,565 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Wenchao Xia <xiawenc@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 "infostore.h" + +#include "Virt_EthernetPort.h" +#include "svpc_types.h" +#include "Virt_Device.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_EASD.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_ep(const CMPIBroker *broker, const char* prefix, + 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); + SAFE_FREE(ep_name); + SAFE_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, EthIface *piface, + CMPIInstance *instance) +{ + int state; + uint16_t cim_type; + CMPIArray *array; + CMPIStatus s; + CMPIString *str; + + if (piface->run_prop.state == ETH_STATE_DOWN) { + state = CIM_STATE_DISABLED; + } else if (piface->run_prop.state == ETH_STATE_UP) { + 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, + EthIface *piface, + const char *prefix, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + 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, + 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, + 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: + SAFE_FREE(br1_name); + SAFE_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; + 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); + SAFE_FREE(eth_name); + SAFE_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: + SAFE_FREE(prefix); + SAFE_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}; + 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@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.6

+1 On 12/07/2011 04:24 AM, Wayne Xia wrote:
adding the Net_EthernetPort class.
Signed-off-by: Wayne Xia<xiawenc@linux.vnet.ibm.com> --- schema/EthernetPort.mof | 4 + schema/EthernetPort.registration | 3 + src/Virt_EthernetPort.c | 565 ++++++++++++++++++++++++++++++++++++++ src/Virt_EthernetPort.h | 58 ++++ 4 files changed, 630 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..4a81c91 --- /dev/null +++ b/schema/EthernetPort.mof @@ -0,0 +1,4 @@ +// Copyright IBM Corp. 2011 +class Net_EthernetPort : CIM_EthernetPort +{ +}; diff --git a/schema/EthernetPort.registration b/schema/EthernetPort.registration new file mode 100644 index 0000000..67320d0 --- /dev/null +++ b/schema/EthernetPort.registration @@ -0,0 +1,3 @@ +# Copyright IBM Corp. 2011 +# 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..751fb33 --- /dev/null +++ b/src/Virt_EthernetPort.c @@ -0,0 +1,565 @@ +/* + * Copyright IBM Corp. 2007 + * + * Authors: + * Wenchao Xia<xiawenc@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 "infostore.h" + +#include "Virt_EthernetPort.h" +#include "svpc_types.h" +#include "Virt_Device.h" +#include "Virt_VirtualEthernetSwitchSystem.h" +#include "Virt_EASD.h" +#include "network_model.h" + +static const CMPIBroker *_BROKER; + +static int set_primary_for_ep(const CMPIBroker *broker, const char* prefix, + 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); + SAFE_FREE(ep_name); + SAFE_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, EthIface *piface, + CMPIInstance *instance) +{ + int state; + uint16_t cim_type; + CMPIArray *array; + CMPIStatus s; + CMPIString *str; + + if (piface->run_prop.state == ETH_STATE_DOWN) { + state = CIM_STATE_DISABLED; + } else if (piface->run_prop.state == ETH_STATE_UP) { + 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, + EthIface *piface, + const char *prefix, + CMPIInstance *instance) +{ + CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL}; + char *errstr; + + 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, + 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, + 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: + SAFE_FREE(br1_name); + SAFE_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; + 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); + SAFE_FREE(eth_name); + SAFE_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: + SAFE_FREE(prefix); + SAFE_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}; + 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@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: + */
-- Chip Vincent Open Virtualization IBM Linux Technology Center cvincent@linux.vnet.ibm.com
participants (2)
-
Chip Vincent
-
Wayne Xia