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

Chip Vincent cvincent at linux.vnet.ibm.com
Fri Dec 23 19:53:28 UTC 2011


+1
On 12/07/2011 04:24 AM, Wayne Xia wrote:
> adding the Net_EthernetPort class.
>
> Signed-off-by: Wayne Xia<xiawenc at 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 at 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 at 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 at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list