# HG changeset patch
# User Wayne Xia <xiawenc(a)linux.vnet.ibm.com>
# Date 1313744037 -28800
# Node ID 5554a150cc764fb1799d86bfd4e201cee9edfedd
# Parent c54aafd0b2c6414f91b96bc30e2f148bb78d5c59
[Draft] add ethernetport device type, do you think this style is acceptable?
This patch is a draft for virtual LAN management. According to the DSP file
ethernetport class is needed, but currently we only have networkport class.
In this patch, additional information is added to net device representing the
cim class, because ethernetport is the subclass of networkport, and they should
share the same xml parsing procedure but show as different instances. To achieve
this, some functions are changed to add one more parameter stands for the cim
class it wants.
Also some association mapping is changed to add ethernetport.
Signed-off-by: Wayne Xia <xiawenc(a)linux.vnet.ibm.com>
diff -r c54aafd0b2c6 -r 5554a150cc76 Makefile.am
--- a/Makefile.am Tue Aug 30 08:48:36 2011 -0700
+++ b/Makefile.am Fri Aug 19 16:53:57 2011 +0800
@@ -63,7 +63,8 @@
schema/EntriesInFilterList.mof \
schema/NestedFilterList.mof \
schema/AppliedFilterList.mof \
- schema/HostedFilterList.mof
+ schema/HostedFilterList.mof \
+ schema/EthernetPort.mof
INTEROP_MOFS = \
schema/ComputerSystem.mof \
@@ -150,7 +151,8 @@
schema/EntriesInFilterList.registration \
schema/NestedFilterList.registration \
schema/AppliedFilterList.registration \
- schema/HostedFilterList.registration
+ schema/HostedFilterList.registration \
+ schema/EthernetPort.registration
INTEROP_REGS = \
schema/RegisteredProfile.registration \
diff -r c54aafd0b2c6 -r 5554a150cc76 libvirt-cim.spec.in
--- a/libvirt-cim.spec.in Tue Aug 30 08:48:36 2011 -0700
+++ b/libvirt-cim.spec.in Fri Aug 19 16:53:57 2011 +0800
@@ -10,12 +10,12 @@
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
URL:
http://libvirt.org/CIM/
Requires: libxml2 >= 2.6.0
-Requires: libvirt >= 0.6.3
+#Requires: libvirt >= 0.6.3
Requires: unzip
Requires: tog-pegasus
BuildRequires: libcmpiutil >= 0.5.4
BuildRequires: tog-pegasus-devel
-BuildRequires: libvirt-devel >= 0.6.3
+#BuildRequires: libvirt-devel >= 0.6.3
# In RHEL5 uuid-devel is provided by e2fsprogs
%if 0%{?el5}
diff -r c54aafd0b2c6 -r 5554a150cc76 libxkutil/device_parsing.c
--- a/libxkutil/device_parsing.c Tue Aug 30 08:48:36 2011 -0700
+++ b/libxkutil/device_parsing.c Fri Aug 19 16:53:57 2011 +0800
@@ -81,6 +81,7 @@
free(dev->device);
free(dev->net_mode);
free(dev->filter_ref);
+ cleanup_vsi_device(&dev->vsi);
}
static void cleanup_emu_device(struct emu_device *dev)
@@ -427,7 +428,6 @@
vdev->id = strdup(ndev->mac);
*vdevs = vdev;
-
return 1;
err:
cleanup_net_device(ndev);
@@ -653,8 +653,9 @@
return true;
}
-static int do_parse(xmlNodeSet *nsv, int type, struct virt_device **l)
+static int do_parse_subclass(xmlNodeSet *nsv, int type, int subclass, struct virt_device
**l)
{
+ CU_DEBUG("cim subclass is %d", subclass);
int devidx;
int lstidx = 0;
int count = 0;
@@ -698,6 +699,11 @@
if (devices <= 0)
continue;
+ /* attach additional info about the requested CIM model */
+ if (type == CIM_RES_TYPE_NET) {
+ tmp_list->dev.net.ciminfo.cim_subclass = subclass;
+ }
+
if (!resize_devlist(&list, lstidx + devices)) {
/* Skip these devices and try again for the
* next cycle, which will probably fail, but
@@ -723,7 +729,7 @@
/* do nothing, just swallow the message. */
}
-static int parse_devices(const char *xml, struct virt_device **_list, int type)
+static int parse_devices_subclass(const char *xml, struct virt_device **_list, int type,
int subclass)
{
int len = 0;
int count = 0;
@@ -764,7 +770,7 @@
== NULL)
goto err3;
- count = do_parse(xpathObj->nodesetval, type, _list);
+ count = do_parse_subclass(xpathObj->nodesetval, type, subclass, _list);
xmlSetGenericErrorFunc(NULL, NULL);
xmlXPathFreeObject(xpathObj);
@@ -776,6 +782,11 @@
return count;
}
+static int parse_devices(const char *xml, struct virt_device **_list, int type)
+{
+ return parse_devices_subclass(xml, _list, type, CIM_RES_SUBTYPE_BASE);
+}
+
#define DUP_FIELD(d, s, f) do { \
if ((s)->f != NULL) \
(d)->f = strdup((s)->f); \
@@ -808,6 +819,7 @@
DUP_FIELD(dev, _dev, dev.net.vsi.instance_id);
DUP_FIELD(dev, _dev, dev.net.vsi.filter_ref);
DUP_FIELD(dev, _dev, dev.net.vsi.profile_id);
+ dev->dev.net.ciminfo = _dev->dev.net.ciminfo;
} else if (dev->type == CIM_RES_TYPE_DISK) {
DUP_FIELD(dev, _dev, dev.disk.type);
DUP_FIELD(dev, _dev, dev.disk.device);
@@ -906,6 +918,11 @@
int get_devices(virDomainPtr dom, struct virt_device **list, int type)
{
+ return get_devices_subclass(dom, list, type, CIM_RES_SUBTYPE_BASE);
+}
+
+int get_devices_subclass(virDomainPtr dom, struct virt_device **list, int type, int
subclass)
+{
char *xml;
int ret;
@@ -918,13 +935,14 @@
else if (type == CIM_RES_TYPE_PROC)
ret = _get_proc_device(xml, list);
else
- ret = parse_devices(xml, list, type);
+ ret = parse_devices_subclass(xml, list, type, subclass);
free(xml);
return ret;
}
+
char *get_fq_devid(char *host, char *_devid)
{
char *devid;
diff -r c54aafd0b2c6 -r 5554a150cc76 libxkutil/device_parsing.h
--- a/libxkutil/device_parsing.h Tue Aug 30 08:48:36 2011 -0700
+++ b/libxkutil/device_parsing.h Fri Aug 19 16:53:57 2011 +0800
@@ -33,6 +33,10 @@
#include "../src/svpc_types.h"
+struct cim_info {
+ int cim_subclass; /* pls make sure it is initialized as 0 */
+};
+
struct vsi_device {
char *vsi_type;
char *manager_id;
@@ -67,6 +71,7 @@
char *net_mode;
char *filter_ref;
struct vsi_device vsi;
+ struct cim_info ciminfo;
};
struct mem_device {
@@ -201,6 +206,7 @@
void cleanup_dominfo(struct domain **dominfo);
int get_devices(virDomainPtr dom, struct virt_device **list, int type);
+int get_devices_subclass(virDomainPtr dom, struct virt_device **list, int type, int
subclasstype);
void cleanup_virt_device(struct virt_device *dev);
void cleanup_virt_devices(struct virt_device **devs, int count);
diff -r c54aafd0b2c6 -r 5554a150cc76 schema/EthernetPort.mof
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/EthernetPort.mof Fri Aug 19 16:53:57 2011 +0800
@@ -0,0 +1,4 @@
+// Copyright IBM Corp. 2011
+class KVM_EthernetPort : CIM_EthernetPort
+{
+};
diff -r c54aafd0b2c6 -r 5554a150cc76 schema/EthernetPort.registration
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/EthernetPort.registration Fri Aug 19 16:53:57 2011 +0800
@@ -0,0 +1,4 @@
+# Copyright IBM Corp. 2011
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+# KVM_EthernetPort root/virt Virt_EthernetPort Virt_EthernetPort instance
+KVM_EthernetPort root/virt Virt_Device Virt_Device instance
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Makefile.am
--- a/src/Makefile.am Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Makefile.am Fri Aug 19 16:53:57 2011 +0800
@@ -25,7 +25,8 @@
Virt_ConsoleRedirectionServiceCapabilities.h \
Virt_KVMRedirectionSAP.h \
Virt_FilterList.h \
- Virt_FilterEntry.h
+ Virt_FilterEntry.h \
+ Virt_VLANDefines.h
XKUADD = $(top_builddir)/libxkutil/libxkutil.la
@@ -36,7 +37,7 @@
providerdir = $(PROVIDERDIR)
-# When adding new provider libraries, be sure place it in the list
+# When adding new provider libraries, be sure place it in the list
# after any dependant libraries.
provider_LTLIBRARIES = libVirt_ComputerSystem.la \
libVirt_Device.la \
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Virt_Device.c
--- a/src/Virt_Device.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_Device.c Fri Aug 19 16:53:57 2011 +0800
@@ -36,6 +36,7 @@
#include "device_parsing.h"
#include "Virt_Device.h"
+#include "Virt_VLANDefines.h"
#define CIM_NET_UNKNOWN 0
#define CIM_NET_ETHERNET 2
@@ -96,10 +97,17 @@
CMPIInstance *inst;
virConnectPtr conn;
+ char* classname = NULL;
+ if (dev->ciminfo.cim_subclass == CIM_RES_SUBTYPE_NET_ETHERNETPORT) {
+ classname = "EthernetPort";
+ } else {
+ classname = "NetworkPort";
+ }
+
conn = virDomainGetConnect(dom);
inst = get_typed_instance(broker,
pfx_from_conn(conn),
- "NetworkPort",
+ classname,
ns);
if (!net_set_type(inst, dev))
@@ -111,6 +119,129 @@
return inst;
}
+/* this function returns the virtual switch name, just like a domain */
+static char* VLAN_get_vs_name(char* switchname)
+{
+ char* retname = NULL;
+ if (switchname == NULL) {
+ return NULL;
+ }
+ char* prefix = VS_PREFIX_CHAR;
+ if (asprintf(&retname, "%s%s", prefix, switchname) == -1) {
+ return NULL;
+ } else {
+ return retname;
+ }
+}
+
+/* following function are used for ethernetport attached to vitual switch */
+static int ethernetport_set_hwaddr_vs(CMPIInstance *instance,
+ struct net_device *dev,
+ const CMPIBroker *broker)
+{
+ CMPIArray *array;
+ CMPIStatus s;
+ CMPIString *str;
+
+ array = CMNewArray(broker, 1, CMPI_string, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array)))
+ return 0;
+
+ str = CMNewString(broker, "Unknown", &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(str)))
+ return 0;
+
+ CMSetArrayElementAt(array, 0, &str, CMPI_string);
+
+ CMSetProperty(instance, "NetworkAddresses",
+ (CMPIValue *)&array, CMPI_stringA);
+
+ return 1;
+}
+
+static int ethernetport_set_devid_vs(CMPIInstance *instance,
+ struct virt_device *dev,
+ const virDomainPtr dom)
+{
+ char *id;
+ char *vsname = VLAN_get_vs_name(dev->dev.net.source);
+ if (vsname == NULL) {
+ CU_DEBUG("Failed to get vsname");
+ return 0;
+ }
+
+ id = get_fq_devid(vsname, dev->dev.net.device);
+ free(vsname);
+
+ if (id == NULL)
+ return 0;
+
+ CMSetProperty(instance, "DeviceID",
+ (CMPIValue *)id, CMPI_chars);
+
+ free(id);
+
+ return 1;
+}
+
+static int ethernetport_set_systemname_vs(CMPIInstance *instance,
+ struct virt_device *dev,
+ const virDomainPtr dom)
+{
+ virConnectPtr conn = NULL;
+
+ char *vsname = VLAN_get_vs_name(dev->dev.net.source);
+ if (vsname == NULL) {
+ CU_DEBUG("Failed to get vsname");
+ return 0;
+ }
+ CMSetProperty(instance, "SystemName",
+ vsname, CMPI_chars);
+ free(vsname);
+
+ conn = virDomainGetConnect(dom);
+ if (conn) {
+ char *sccn = NULL;
+ sccn = get_typed_class(pfx_from_conn(conn), "ComputerSystem");
+ if (sccn != NULL)
+ CMSetProperty(instance, "SystemCreationClassName",
+ (CMPIValue *)sccn, CMPI_chars);
+ free(sccn);
+ }
+
+ return 1;
+}
+
+static CMPIInstance *ethernetport_instance_vs(const CMPIBroker *broker,
+ struct net_device *dev,
+ const virDomainPtr dom,
+ const char *ns)
+{
+ CMPIInstance *inst;
+ virConnectPtr conn;
+
+ if ((dev->source == NULL)||(dev->device == NULL)) {
+ CU_DEBUG("no source or device in netdev found, vm's dev mac
%s,"
+ " maybe this vm is not started", dev->mac);
+ return NULL;
+ }
+
+
+ conn = virDomainGetConnect(dom);
+ inst = get_typed_instance(broker,
+ pfx_from_conn(conn),
+ "EthernetPort",
+ ns);
+
+ if (!net_set_type(inst, dev))
+ return NULL;
+
+ if (!ethernetport_set_hwaddr_vs(inst, dev, broker))
+ return NULL;
+
+ return inst;
+}
+
static int disk_set_name(CMPIInstance *instance,
struct disk_device *dev)
{
@@ -468,10 +599,27 @@
if (!instance)
return false;
-
+
device_set_devid(instance, dev, dom);
device_set_systemname(instance, dom);
inst_list_add(list, instance);
+
+ /* add ethernetports */
+ if ((dev->type == CIM_RES_TYPE_NET) &&
+ (dev->dev.net.ciminfo.cim_subclass ==
CIM_RES_SUBTYPE_NET_ETHERNETPORT)) {
+ /* add instance as ethernetport on virtual switch */
+ instance = ethernetport_instance_vs(broker,
+ &dev->dev.net,
+ dom,
+ ns);
+ if (!instance) {
+ continue;
+ }
+
+ ethernetport_set_devid_vs(instance, dev, dom);
+ ethernetport_set_systemname_vs(instance, dev, dom);
+ inst_list_add(list, instance);
+ }
}
if (proc_count) {
@@ -489,6 +637,8 @@
{
if (strstr(classname, "NetworkPort"))
return CIM_RES_TYPE_NET;
+ else if (strstr(classname, "EthernetPort"))
+ return CIM_RES_TYPE_NET;
else if (strstr(classname, "LogicalDisk"))
return CIM_RES_TYPE_DISK;
else if (strstr(classname, "Memory"))
@@ -503,10 +653,19 @@
return CIM_RES_TYPE_UNKNOWN;
}
+uint16_t cim_subclass_from_device_classname(const char *classname)
+{
+ if (strstr(classname, "EthernetPort"))
+ return CIM_RES_SUBTYPE_NET_ETHERNETPORT;
+ else
+ return CIM_RES_SUBTYPE_BASE;
+}
+
static CMPIStatus _get_devices(const CMPIBroker *broker,
const CMPIObjectPath *reference,
const virDomainPtr dom,
const uint16_t type,
+ const uint16_t subclass,
struct inst_list *list)
{
CMPIStatus s = {CMPI_RC_OK, NULL};
@@ -514,7 +673,7 @@
bool rc;
struct virt_device *devs = NULL;
- count = get_devices(dom, &devs, type);
+ count = get_devices_subclass(dom, &devs, type, subclass);
if (count <= 0)
goto out;
@@ -542,6 +701,7 @@
const CMPIObjectPath *reference,
const virDomainPtr dom,
const uint16_t type,
+ const uint16_t subclass,
struct inst_list *list)
{
CMPIStatus s;
@@ -553,6 +713,7 @@
reference,
dom,
cim_res_types[i],
+ CIM_RES_SUBTYPE_BASE,
list);
}
else
@@ -560,6 +721,7 @@
reference,
dom,
type,
+ subclass,
list);
return s;
@@ -571,6 +733,16 @@
const uint16_t type,
struct inst_list *list)
{
+ return enum_devices_subclass(broker, reference, domain, type,
CIM_RES_SUBTYPE_BASE, list);
+}
+
+CMPIStatus enum_devices_subclass(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char *domain,
+ const uint16_t type,
+ const uint16_t subclass,
+ struct inst_list *list)
+{
CMPIStatus s = {CMPI_RC_OK, NULL};
virConnectPtr conn = NULL;
virDomainPtr *doms = NULL;
@@ -593,6 +765,7 @@
reference,
doms[i],
type,
+ subclass,
list);
virDomainFree(doms[i]);
@@ -617,10 +790,11 @@
inst_list_init(&list);
- s = enum_devices(_BROKER,
+ s = enum_devices_subclass(_BROKER,
reference,
- NULL,
+ NULL,
res_type_from_device_classname(CLASSNAME(reference)),
+ cim_subclass_from_device_classname(CLASSNAME(reference)),
&list);
if (s.rc != CMPI_RC_OK)
goto out;
@@ -673,16 +847,17 @@
return quantity;
}
-static struct virt_device *find_dom_dev(virDomainPtr dom,
+static struct virt_device *find_dom_dev(virDomainPtr dom,
char *device,
- int type)
+ int type,
+ int subclass)
{
struct virt_device *list = NULL;
struct virt_device *dev = NULL;
int count;
int i;
- count = get_devices(dom, &list, type);
+ count = get_devices_subclass(dom, &list, type, subclass);
if (!count) {
CU_DEBUG("No devices for %i", type);
goto out;
@@ -719,6 +894,16 @@
const uint16_t type,
CMPIInstance **_inst)
{
+ return get_device_by_name_subclass(broker, reference, name, type,
CIM_RES_SUBTYPE_BASE, _inst);
+}
+
+CMPIStatus get_device_by_name_subclass(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char *name,
+ const uint16_t type,
+ const uint16_t subclass,
+ CMPIInstance **_inst)
+{
CMPIStatus s = {CMPI_RC_OK, NULL};
char *domain = NULL;
char *device = NULL;
@@ -741,7 +926,7 @@
if (parse_devid(name, &domain, &device) != 1) {
cu_statusf(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
- "No such instance (bad id %s)",
+ "No such instance (bad id %s)",
name);
goto out;
}
@@ -756,7 +941,7 @@
goto err;
}
- dev = find_dom_dev(dom, device, type);
+ dev = find_dom_dev(dom, device, type, subclass);
if (!dev) {
cu_statusf(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -768,7 +953,7 @@
if (type == CIM_RES_TYPE_PROC) {
int ret;
int dev_id_num;
-
+
ret = sscanf(dev->id, "%d", &dev_id_num);
rc = vcpu_inst(broker,
@@ -777,11 +962,11 @@
dev_id_num,
&tmp_list);
} else {
-
- rc = device_instances(broker,
- dev,
+
+ rc = device_instances(broker,
+ dev,
1,
- dom,
+ dom,
NAMESPACE(reference),
&tmp_list);
}
@@ -799,8 +984,8 @@
inst_list_free(&tmp_list);
virConnectClose(conn);
- return s;
-}
+ return s;
+}
CMPIStatus get_device_by_ref(const CMPIBroker *broker,
const CMPIObjectPath *reference,
@@ -817,10 +1002,11 @@
goto out;
}
- s = get_device_by_name(broker,
- reference,
- name,
- res_type_from_device_classname(CLASSNAME(reference)),
+ s = get_device_by_name_subclass(broker,
+ reference,
+ name,
+ res_type_from_device_classname(CLASSNAME(reference)),
+ cim_subclass_from_device_classname(CLASSNAME(reference)),
&inst);
if (s.rc != CMPI_RC_OK)
goto out;
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Virt_Device.h
--- a/src/Virt_Device.h Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_Device.h Fri Aug 19 16:53:57 2011 +0800
@@ -40,6 +40,14 @@
const uint16_t type,
struct inst_list *list);
+/* the same as above, but added cim sublcass info */
+CMPIStatus enum_devices_subclass(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char *domain,
+ const uint16_t type,
+ const uint16_t subclass,
+ struct inst_list *list);
+
/**
* Returns the device instance defined by the reference
*
@@ -69,8 +77,18 @@
const uint16_t type,
CMPIInstance **_inst);
+/* the same as above, but added CIM sublcass info */
+CMPIStatus get_device_by_name_subclass(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const char *name,
+ const uint16_t type,
+ const uint16_t subclass,
+ CMPIInstance **_inst);
+
uint16_t res_type_from_device_classname(const char *classname);
+uint16_t cim_subclass_from_device_classname(const char *classname);
+
int get_input_dev_caption(const char *type,
const char *bus,
char **cap);
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Virt_SettingsDefineState.c
--- a/src/Virt_SettingsDefineState.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_SettingsDefineState.c Fri Aug 19 16:53:57 2011 +0800
@@ -331,6 +331,7 @@
"KVM_Processor",
"KVM_Memory",
"KVM_NetworkPort",
+ "KVM_EthernetPort",
"KVM_LogicalDisk",
"KVM_DisplayController",
"KVM_PointingDevice",
@@ -353,6 +354,7 @@
"KVM_DiskResourceAllocationSettingData",
"KVM_MemResourceAllocationSettingData",
"KVM_NetResourceAllocationSettingData",
+ "KVM_NetResourceAllocationSettingData",
"KVM_ProcResourceAllocationSettingData",
"KVM_GraphicsResourceAllocationSettingData",
"KVM_InputResourceAllocationSettingData",
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Virt_SystemDevice.c
--- a/src/Virt_SystemDevice.c Tue Aug 30 08:48:36 2011 -0700
+++ b/src/Virt_SystemDevice.c Fri Aug 19 16:53:57 2011 +0800
@@ -139,6 +139,7 @@
"KVM_Processor",
"KVM_Memory",
"KVM_NetworkPort",
+ "KVM_EthernetPort",
"KVM_LogicalDisk",
"KVM_DisplayController",
"KVM_PointingDevice",
diff -r c54aafd0b2c6 -r 5554a150cc76 src/Virt_VLANDefines.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Virt_VLANDefines.h Fri Aug 19 16:53:57 2011 +0800
@@ -0,0 +1,6 @@
+#ifndef VLANDEFINES_H
+#define VLANDEFINES_H
+
+#define VS_PREFIX_CHAR ("VS_")
+
+#endif
diff -r c54aafd0b2c6 -r 5554a150cc76 src/svpc_types.h
--- a/src/svpc_types.h Tue Aug 30 08:48:36 2011 -0700
+++ b/src/svpc_types.h Fri Aug 19 16:53:57 2011 +0800
@@ -36,6 +36,13 @@
#define CIM_RES_TYPE_IMAGE 32768
#define CIM_RES_TYPE_COUNT 6
+
+/* Subtype representing the class in CIM model */
+#define CIM_RES_SUBTYPE_BASE 0
+/* NetworkPort subtypes */
+#define CIM_RES_SUBTYPE_NET_NETWORKPORT CIM_RES_SUBTYPE_BASE
+#define CIM_RES_SUBTYPE_NET_ETHERNETPORT 1
+
const static int cim_res_types[CIM_RES_TYPE_COUNT] =
{CIM_RES_TYPE_NET,
CIM_RES_TYPE_DISK,