
This patch add VESSSD, VirtualSwitch are bridge and pNIC on host. V7: added Delay, AutoStart, DHCP properties which exist in libvirtAPI. V6: same with V2. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- schema/VirtualEthernetSwitchSystemSettingData.mof | 33 ++ ...ualEthernetSwitchSystemSettingData.registration | 3 + src/Virt_VESSSD.c | 392 ++++++++++++++++++++ src/Virt_VESSSD.h | 39 ++ 4 files changed, 467 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..9dea980 --- /dev/null +++ b/schema/VirtualEthernetSwitchSystemSettingData.mof @@ -0,0 +1,33 @@ +// 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 Delay; + + 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..724d3b8 --- /dev/null +++ b/src/Virt_VESSSD.c @@ -0,0 +1,392 @@ +/* + * Copyright IBM Corp. 2012 + * + * 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 <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) +{ + uint16_t dhcp; + if (piface->eth_type == ETH_TYPE_ETHER_BRIDGE) { + if (piface->pbr_prop->STP >= 0) { + CMSetProperty(instance, "STP", + (CMPIValue *)&piface->pbr_prop->STP, CMPI_uint16); + } + if (piface->pbr_prop->delay >= 0) { + CMSetProperty(instance, "Delay", + (CMPIValue *)&piface->pbr_prop->delay, CMPI_uint16); + } + } + + if (piface->protocol_prop.ipv4_prop.DHCP == 1) { + dhcp = 1; + } else { + /* dhcp would be -1 because in xml of + in netcf it would never be 0. */ + dhcp = 0; + } + CMSetProperty(instance, "DHCP", (CMPIValue *)&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@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