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

Wayne Xia xiawenc at linux.vnet.ibm.com
Wed Dec 7 09:24:40 UTC 2011


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:
+ */
-- 
1.7.6





More information about the Libvirt-cim mailing list