CIM
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- 3141 discussions
[PATCH 1/2] VirtualSystemManagementService: Remove dead code
- This patch simply removes some code that was already commented for some time
[PATCH 2/2] ComputerSystemIndication: Support libvirt domain events
- This one actually does the job. See its description for more details.
Best regards, Etrunko
--
Eduardo de Barros Lima
Software Engineer, Open Virtualization
Linux Technology Center - IBM/Brazil
eblima(a)br.ibm.com
3
14
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
I am building libvirt-cim with gcc 4.6.3 in fedora 16 and got a bunch of new
warnings. Most of them are about variables that are set but not used anywhere,
but there is one possible access to unitialized variables in Virt_RASD.c which
might result in unexpected behavior.
xmlgen.c: In function 'system_xml':
xmlgen.c:633:28: error: variable 'bl' set but not used [-Werror=unused-but-set-variable]
xmlgen.c:642:28: error: variable 'bl_args' set but not used [-Werror=unused-but-set-variable]
xmlgen.c: In function 'disk_pool_xml':
xmlgen.c:1244:20: error: variable 'path' set but not used [-Werror=unused-but-set-variable]
xmlgen.c: In function 'filter_to_xml':
xmlgen.c:1474:15: error: variable 'msg' set but not used [-Werror=unused-but-set-variable]
Virt_FilterEntry.c: In function 'enum_filter_rules':
Virt_FilterEntry.c:576:30: error: variable 'class_type' set but not used [-Werror=unused-but-set-variable]
Virt_RASD.c: In function 'rasd_from_vdev':
Virt_RASD.c:406:27: error: 'pool' may be used uninitialized in this function [-Werror=uninitialized]
Virt_RASD.c:330:27: note: 'pool' was declared here
Virt_RASD.c:407:26: error: 'vol' may be used uninitialized in this function [-Werror=uninitialized]
Virt_RASD.c:320:26: note: 'vol' was declared here
Virt_VSMigrationService.c: In function 'clear_infstore_migration_flag':
Virt_VSMigrationService.c:1185:15: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_VSMigrationService.c: In function 'migrate_do':
Virt_VSMigrationService.c:1478:15: error: variable 'thread' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'device_instances':
Virt_Device.c:431:15: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'proc_dev_list':
Virt_Device.c:657:13: error: variable 'rc' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'get_device_by_name':
Virt_Device.c:769:21: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c:729:15: error: variable 'rc' set but not used [-Werror=unused-but-set-variable]
Virt_VirtualSystemManagementService.c: In function 'input_rasd_to_vdev':
Virt_VirtualSystemManagementService.c:1384:21: error: variable 'msg' set but not used [-Werror=unused-but-set-variable]
Changes since v1:
- xmlgen.c: Keep 'path' variable and fix value check.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
libxkutil/xmlgen.c | 33 ++++++-----------------
src/Virt_Device.c | 39 +++++++++--------------------
src/Virt_FilterEntry.c | 11 ++------
src/Virt_RASD.c | 17 +++++++-----
src/Virt_VSMigrationService.c | 6 +---
src/Virt_VirtualSystemManagementService.c | 5 +--
6 files changed, 38 insertions(+), 73 deletions(-)
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index afd8c21..d73ffd0 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -630,21 +630,17 @@ static char *system_xml(xmlNodePtr root, struct domain *domain)
tmp = xmlNewChild(root, NULL, BAD_CAST "name", BAD_CAST domain->name);
if (domain->bootloader) {
- xmlNodePtr bl;
-
- bl = xmlNewChild(root,
- NULL,
- BAD_CAST "bootloader",
- BAD_CAST domain->bootloader);
+ tmp = xmlNewChild(root,
+ NULL,
+ BAD_CAST "bootloader",
+ BAD_CAST domain->bootloader);
}
if (domain->bootloader_args) {
- xmlNodePtr bl_args;
-
- bl_args = xmlNewChild(root,
- NULL,
- BAD_CAST "bootloader_args",
- BAD_CAST domain->bootloader_args);
+ tmp = xmlNewChild(root,
+ NULL,
+ BAD_CAST "bootloader_args",
+ BAD_CAST domain->bootloader_args);
}
tmp = xmlNewChild(root,
@@ -1272,7 +1268,7 @@ static const char *disk_pool_xml(xmlNodePtr root,
goto out;
path = xmlNewChild(target, NULL, BAD_CAST "path", BAD_CAST pool->path);
- if (target == NULL)
+ if (path == NULL)
goto out;
return NULL;
@@ -1471,7 +1467,6 @@ char *res_to_xml(struct virt_pool_res *res) {
char *filter_to_xml(struct acl_filter *filter)
{
- char *msg = XML_ERROR;
char *xml = NULL;
xmlNodePtr root = NULL;
xmlNodePtr tmp = NULL;
@@ -1504,17 +1499,7 @@ char *filter_to_xml(struct acl_filter *filter)
goto out;
}
- /* TODO: Not yet supported
- for (i = 0; i < filter->rule_ct; i++) {
- msg = rule_to_xml(root, filter->rules[i]);
- if (msg != NULL)
- goto out;
- }
- */
-
xml = tree_to_xml(root);
- if (xml != NULL)
- msg = NULL; /* no errors */
out:
CU_DEBUG("Filter XML: %s", xml);
diff --git a/src/Virt_Device.c b/src/Virt_Device.c
index faa304d..fd11370 100644
--- a/src/Virt_Device.c
+++ b/src/Virt_Device.c
@@ -428,7 +428,6 @@ static bool device_instances(const CMPIBroker *broker,
struct inst_list *list)
{
int i;
- bool ret;
uint64_t proc_count = 0;
CMPIInstance *instance = NULL;
@@ -475,11 +474,7 @@ static bool device_instances(const CMPIBroker *broker,
}
if (proc_count) {
- ret = vcpu_instances(broker,
- dom,
- ns,
- proc_count,
- list);
+ vcpu_instances(broker, dom, ns, proc_count, list);
}
return true;
@@ -654,16 +649,17 @@ static int proc_dev_list(uint64_t quantity,
struct virt_device **list)
{
int i;
- int rc;
-
*list = (struct virt_device *)calloc(quantity,
sizeof(struct virt_device));
for (i = 0; i < quantity; i++) {
char *dev_num;
+ int ret;
- rc = asprintf(&dev_num, "%d", i);
+ ret = asprintf(&dev_num, "%d", i);
+ if (ret == -1)
+ CU_DEBUG("asprintf error %d" , ret);
(*list)[i].id = strdup(dev_num);
@@ -726,7 +722,6 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
virDomainPtr dom = NULL;
struct virt_device *dev = NULL;
struct inst_list tmp_list;
- bool rc;
inst_list_init(&tmp_list);
@@ -766,24 +761,14 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
}
if (type == CIM_RES_TYPE_PROC) {
- int ret;
int dev_id_num;
-
- ret = sscanf(dev->id, "%d", &dev_id_num);
+ sscanf(dev->id, "%d", &dev_id_num);
- rc = vcpu_inst(broker,
- dom,
- NAMESPACE(reference),
- dev_id_num,
- &tmp_list);
+ vcpu_inst(broker, dom, NAMESPACE(reference),
+ dev_id_num, &tmp_list);
} else {
-
- rc = device_instances(broker,
- dev,
- 1,
- dom,
- NAMESPACE(reference),
- &tmp_list);
+ device_instances(broker, dev, 1, dom,
+ NAMESPACE(reference), &tmp_list);
}
cleanup_virt_devices(&dev, 1);
@@ -799,8 +784,8 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
inst_list_free(&tmp_list);
virConnectClose(conn);
- return s;
-}
+ return s;
+}
CMPIStatus get_device_by_ref(const CMPIBroker *broker,
const CMPIObjectPath *reference,
diff --git a/src/Virt_FilterEntry.c b/src/Virt_FilterEntry.c
index acc3d61..16b211e 100644
--- a/src/Virt_FilterEntry.c
+++ b/src/Virt_FilterEntry.c
@@ -573,17 +573,12 @@ CMPIStatus enum_filter_rules(
struct acl_filter *filters = NULL;
int i, j, count = 0;
CMPIStatus s = {CMPI_RC_OK, NULL};
- enum {NONE, MAC, IP} class_type = NONE;
CU_DEBUG("Reference = %s", REF2STR(reference));
- if (STREQC(CLASSNAME(reference), "KVM_Hdr8021Filter")) {
- class_type = MAC;
- } else if (STREQC(CLASSNAME(reference), "KVM_IPHeadersFilter")) {
- class_type = IP;
- } else if (STREQC(CLASSNAME(reference), "KVM_FilterEntry")) {
- class_type = NONE;
- } else {
+ if (!STREQC(CLASSNAME(reference), "KVM_Hdr8021Filter") &&
+ !STREQC(CLASSNAME(reference), "KVM_IPHeadersFilter") &&
+ !STREQC(CLASSNAME(reference), "KVM_FilterEntry")) {
cu_statusf(broker, &s,
CMPI_RC_ERR_FAILED,
"Unrecognized class type");
diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c
index 4ac2f93..4939f7b 100644
--- a/src/Virt_RASD.c
+++ b/src/Virt_RASD.c
@@ -289,6 +289,11 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
uint16_t type;
CMPIStatus s = {CMPI_RC_OK, NULL};
char *poolid = NULL;
+ virConnectPtr conn = NULL;
+ virStorageVolPtr vol = NULL;
+ virStoragePoolPtr pool = NULL;
+ const char *pool_name = NULL;
+ int ret = -1;
get_vol_size(broker, ref, dev->dev.disk.source, &cap);
@@ -308,7 +313,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
(CMPIValue *)dev->dev.disk.source,
CMPI_chars);
- virConnectPtr conn = connect_by_classname(broker, CLASSNAME(ref), &s);
+ conn = connect_by_classname(broker, CLASSNAME(ref), &s);
if (conn == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -317,8 +322,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- virStorageVolPtr vol = virStorageVolLookupByPath(conn,
- dev->dev.disk.source);
+ vol = virStorageVolLookupByPath(conn, dev->dev.disk.source);
if (vol == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -327,7 +331,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- virStoragePoolPtr pool = virStoragePoolLookupByVolume(vol);
+ pool = virStoragePoolLookupByVolume(vol);
if (pool == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -336,7 +340,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- const char *pool_name = virStoragePoolGetName(pool);
+ pool_name = virStoragePoolGetName(pool);
if (pool_name == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -345,8 +349,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- int ret = asprintf(&poolid, "DiskPool/%s", pool_name);
-
+ ret = asprintf(&poolid, "DiskPool/%s", pool_name);
if (ret == -1) {
CU_DEBUG("Failed to get disk poolid");
goto cont;
diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c
index 4f48a68..d393787 100644
--- a/src/Virt_VSMigrationService.c
+++ b/src/Virt_VSMigrationService.c
@@ -1182,7 +1182,6 @@ static CMPIStatus ensure_dom_offline(virDomainPtr dom)
static void clear_infstore_migration_flag(virDomainPtr dom)
{
struct infostore_ctx *infp;
- bool ret = false;
infp = infostore_open(dom);
if (infp == NULL) {
@@ -1191,7 +1190,7 @@ static void clear_infstore_migration_flag(virDomainPtr dom)
return;
}
- ret = infostore_set_bool(infp, "migrating", false);
+ infostore_set_bool(infp, "migrating", false);
CU_DEBUG("Clearing infostore migrating flag");
infostore_close(infp);
@@ -1475,7 +1474,6 @@ static CMPIStatus migrate_do(const CMPIObjectPath *ref,
CMPIStatus s;
CMPIObjectPath *job_op;
struct migration_job *job;
- CMPI_THREAD_TYPE thread;
uint32_t retcode = 1;
CMPIInstance *ind = NULL;
CMPIInstance *inst = NULL;
@@ -1517,7 +1515,7 @@ static CMPIStatus migrate_do(const CMPIObjectPath *ref,
if (!rc)
CU_DEBUG("Failed to raise indication");
- thread = _BROKER->xft->newThread((void*)migration_thread, job, 0);
+ _BROKER->xft->newThread((void*)migration_thread, job, 0);
retcode = CIM_SVPC_RETURN_JOB_STARTED;
diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
index 5229f56..f8c5f24 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -1381,10 +1381,9 @@ static const char *input_rasd_to_vdev(CMPIInstance *inst,
struct virt_device *dev)
{
const char *val;
- const char *msg;
if (cu_get_str_prop(inst, "ResourceSubType", &val) != CMPI_RC_OK) {
- msg = "InputRASD ResourceSubType field not valid";
+ CU_DEBUG("InputRASD ResourceSubType field not valid");
goto out;
}
dev->dev.input.type = strdup(val);
@@ -1395,7 +1394,7 @@ static const char *input_rasd_to_vdev(CMPIInstance *inst,
else if (STREQC(dev->dev.input.type, "tablet"))
dev->dev.input.bus = strdup("usb");
else {
- msg = "Invalid value for ResourceSubType in InputRASD";
+ CU_DEBUG("Invalid value for ResourceSubType in InputRASD");
goto out;
}
} else
--
1.7.7.5
3
2
From: "Eduardo Lima (Etrunko)" <eblima(a)br.ibm.com>
I am building libvirt-cim with gcc 4.6.3 in fedora 16 and got a bunch of new
warnings. Most of them are about variables that are set but not used anywhere,
but there is one possible access to unitialized variables in Virt_RASD.c which
might result in unexpected behavior.
xmlgen.c: In function 'system_xml':
xmlgen.c:633:28: error: variable 'bl' set but not used [-Werror=unused-but-set-variable]
xmlgen.c:642:28: error: variable 'bl_args' set but not used [-Werror=unused-but-set-variable]
xmlgen.c: In function 'disk_pool_xml':
xmlgen.c:1244:20: error: variable 'path' set but not used [-Werror=unused-but-set-variable]
xmlgen.c: In function 'filter_to_xml':
xmlgen.c:1474:15: error: variable 'msg' set but not used [-Werror=unused-but-set-variable]
Virt_FilterEntry.c: In function 'enum_filter_rules':
Virt_FilterEntry.c:576:30: error: variable 'class_type' set but not used [-Werror=unused-but-set-variable]
Virt_RASD.c: In function 'rasd_from_vdev':
Virt_RASD.c:406:27: error: 'pool' may be used uninitialized in this function [-Werror=uninitialized]
Virt_RASD.c:330:27: note: 'pool' was declared here
Virt_RASD.c:407:26: error: 'vol' may be used uninitialized in this function [-Werror=uninitialized]
Virt_RASD.c:320:26: note: 'vol' was declared here
Virt_VSMigrationService.c: In function 'clear_infstore_migration_flag':
Virt_VSMigrationService.c:1185:15: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_VSMigrationService.c: In function 'migrate_do':
Virt_VSMigrationService.c:1478:15: error: variable 'thread' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'device_instances':
Virt_Device.c:431:15: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'proc_dev_list':
Virt_Device.c:657:13: error: variable 'rc' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c: In function 'get_device_by_name':
Virt_Device.c:769:21: error: variable 'ret' set but not used [-Werror=unused-but-set-variable]
Virt_Device.c:729:15: error: variable 'rc' set but not used [-Werror=unused-but-set-variable]
Virt_VirtualSystemManagementService.c: In function 'input_rasd_to_vdev':
Virt_VirtualSystemManagementService.c:1384:21: error: variable 'msg' set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
libxkutil/xmlgen.c | 34 ++++++------------------
src/Virt_Device.c | 39 +++++++++--------------------
src/Virt_FilterEntry.c | 11 ++------
src/Virt_RASD.c | 17 +++++++-----
src/Virt_VSMigrationService.c | 6 +---
src/Virt_VirtualSystemManagementService.c | 5 +--
6 files changed, 38 insertions(+), 74 deletions(-)
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index afd8c21..46712df 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -630,21 +630,17 @@ static char *system_xml(xmlNodePtr root, struct domain *domain)
tmp = xmlNewChild(root, NULL, BAD_CAST "name", BAD_CAST domain->name);
if (domain->bootloader) {
- xmlNodePtr bl;
-
- bl = xmlNewChild(root,
- NULL,
- BAD_CAST "bootloader",
- BAD_CAST domain->bootloader);
+ tmp = xmlNewChild(root,
+ NULL,
+ BAD_CAST "bootloader",
+ BAD_CAST domain->bootloader);
}
if (domain->bootloader_args) {
- xmlNodePtr bl_args;
-
- bl_args = xmlNewChild(root,
- NULL,
- BAD_CAST "bootloader_args",
- BAD_CAST domain->bootloader_args);
+ tmp = xmlNewChild(root,
+ NULL,
+ BAD_CAST "bootloader_args",
+ BAD_CAST domain->bootloader_args);
}
tmp = xmlNewChild(root,
@@ -1241,7 +1237,6 @@ static const char *disk_pool_xml(xmlNodePtr root,
xmlNodePtr disk = NULL;
xmlNodePtr name = NULL;
xmlNodePtr target = NULL;
- xmlNodePtr path = NULL;
const char *type = NULL;
const char *msg = NULL;
struct disk_pool *pool = &_pool->pool_info.disk;
@@ -1271,7 +1266,7 @@ static const char *disk_pool_xml(xmlNodePtr root,
if (target == NULL)
goto out;
- path = xmlNewChild(target, NULL, BAD_CAST "path", BAD_CAST pool->path);
+ xmlNewChild(target, NULL, BAD_CAST "path", BAD_CAST pool->path);
if (target == NULL)
goto out;
@@ -1471,7 +1466,6 @@ char *res_to_xml(struct virt_pool_res *res) {
char *filter_to_xml(struct acl_filter *filter)
{
- char *msg = XML_ERROR;
char *xml = NULL;
xmlNodePtr root = NULL;
xmlNodePtr tmp = NULL;
@@ -1504,17 +1498,7 @@ char *filter_to_xml(struct acl_filter *filter)
goto out;
}
- /* TODO: Not yet supported
- for (i = 0; i < filter->rule_ct; i++) {
- msg = rule_to_xml(root, filter->rules[i]);
- if (msg != NULL)
- goto out;
- }
- */
-
xml = tree_to_xml(root);
- if (xml != NULL)
- msg = NULL; /* no errors */
out:
CU_DEBUG("Filter XML: %s", xml);
diff --git a/src/Virt_Device.c b/src/Virt_Device.c
index faa304d..fd11370 100644
--- a/src/Virt_Device.c
+++ b/src/Virt_Device.c
@@ -428,7 +428,6 @@ static bool device_instances(const CMPIBroker *broker,
struct inst_list *list)
{
int i;
- bool ret;
uint64_t proc_count = 0;
CMPIInstance *instance = NULL;
@@ -475,11 +474,7 @@ static bool device_instances(const CMPIBroker *broker,
}
if (proc_count) {
- ret = vcpu_instances(broker,
- dom,
- ns,
- proc_count,
- list);
+ vcpu_instances(broker, dom, ns, proc_count, list);
}
return true;
@@ -654,16 +649,17 @@ static int proc_dev_list(uint64_t quantity,
struct virt_device **list)
{
int i;
- int rc;
-
*list = (struct virt_device *)calloc(quantity,
sizeof(struct virt_device));
for (i = 0; i < quantity; i++) {
char *dev_num;
+ int ret;
- rc = asprintf(&dev_num, "%d", i);
+ ret = asprintf(&dev_num, "%d", i);
+ if (ret == -1)
+ CU_DEBUG("asprintf error %d" , ret);
(*list)[i].id = strdup(dev_num);
@@ -726,7 +722,6 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
virDomainPtr dom = NULL;
struct virt_device *dev = NULL;
struct inst_list tmp_list;
- bool rc;
inst_list_init(&tmp_list);
@@ -766,24 +761,14 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
}
if (type == CIM_RES_TYPE_PROC) {
- int ret;
int dev_id_num;
-
- ret = sscanf(dev->id, "%d", &dev_id_num);
+ sscanf(dev->id, "%d", &dev_id_num);
- rc = vcpu_inst(broker,
- dom,
- NAMESPACE(reference),
- dev_id_num,
- &tmp_list);
+ vcpu_inst(broker, dom, NAMESPACE(reference),
+ dev_id_num, &tmp_list);
} else {
-
- rc = device_instances(broker,
- dev,
- 1,
- dom,
- NAMESPACE(reference),
- &tmp_list);
+ device_instances(broker, dev, 1, dom,
+ NAMESPACE(reference), &tmp_list);
}
cleanup_virt_devices(&dev, 1);
@@ -799,8 +784,8 @@ CMPIStatus get_device_by_name(const CMPIBroker *broker,
inst_list_free(&tmp_list);
virConnectClose(conn);
- return s;
-}
+ return s;
+}
CMPIStatus get_device_by_ref(const CMPIBroker *broker,
const CMPIObjectPath *reference,
diff --git a/src/Virt_FilterEntry.c b/src/Virt_FilterEntry.c
index acc3d61..16b211e 100644
--- a/src/Virt_FilterEntry.c
+++ b/src/Virt_FilterEntry.c
@@ -573,17 +573,12 @@ CMPIStatus enum_filter_rules(
struct acl_filter *filters = NULL;
int i, j, count = 0;
CMPIStatus s = {CMPI_RC_OK, NULL};
- enum {NONE, MAC, IP} class_type = NONE;
CU_DEBUG("Reference = %s", REF2STR(reference));
- if (STREQC(CLASSNAME(reference), "KVM_Hdr8021Filter")) {
- class_type = MAC;
- } else if (STREQC(CLASSNAME(reference), "KVM_IPHeadersFilter")) {
- class_type = IP;
- } else if (STREQC(CLASSNAME(reference), "KVM_FilterEntry")) {
- class_type = NONE;
- } else {
+ if (!STREQC(CLASSNAME(reference), "KVM_Hdr8021Filter") &&
+ !STREQC(CLASSNAME(reference), "KVM_IPHeadersFilter") &&
+ !STREQC(CLASSNAME(reference), "KVM_FilterEntry")) {
cu_statusf(broker, &s,
CMPI_RC_ERR_FAILED,
"Unrecognized class type");
diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c
index 4ac2f93..4939f7b 100644
--- a/src/Virt_RASD.c
+++ b/src/Virt_RASD.c
@@ -289,6 +289,11 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
uint16_t type;
CMPIStatus s = {CMPI_RC_OK, NULL};
char *poolid = NULL;
+ virConnectPtr conn = NULL;
+ virStorageVolPtr vol = NULL;
+ virStoragePoolPtr pool = NULL;
+ const char *pool_name = NULL;
+ int ret = -1;
get_vol_size(broker, ref, dev->dev.disk.source, &cap);
@@ -308,7 +313,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
(CMPIValue *)dev->dev.disk.source,
CMPI_chars);
- virConnectPtr conn = connect_by_classname(broker, CLASSNAME(ref), &s);
+ conn = connect_by_classname(broker, CLASSNAME(ref), &s);
if (conn == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -317,8 +322,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- virStorageVolPtr vol = virStorageVolLookupByPath(conn,
- dev->dev.disk.source);
+ vol = virStorageVolLookupByPath(conn, dev->dev.disk.source);
if (vol == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -327,7 +331,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- virStoragePoolPtr pool = virStoragePoolLookupByVolume(vol);
+ pool = virStoragePoolLookupByVolume(vol);
if (pool == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -336,7 +340,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- const char *pool_name = virStoragePoolGetName(pool);
+ pool_name = virStoragePoolGetName(pool);
if (pool_name == NULL) {
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
@@ -345,8 +349,7 @@ static CMPIStatus set_disk_rasd_params(const CMPIBroker *broker,
goto cont;
}
- int ret = asprintf(&poolid, "DiskPool/%s", pool_name);
-
+ ret = asprintf(&poolid, "DiskPool/%s", pool_name);
if (ret == -1) {
CU_DEBUG("Failed to get disk poolid");
goto cont;
diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c
index 4f48a68..d393787 100644
--- a/src/Virt_VSMigrationService.c
+++ b/src/Virt_VSMigrationService.c
@@ -1182,7 +1182,6 @@ static CMPIStatus ensure_dom_offline(virDomainPtr dom)
static void clear_infstore_migration_flag(virDomainPtr dom)
{
struct infostore_ctx *infp;
- bool ret = false;
infp = infostore_open(dom);
if (infp == NULL) {
@@ -1191,7 +1190,7 @@ static void clear_infstore_migration_flag(virDomainPtr dom)
return;
}
- ret = infostore_set_bool(infp, "migrating", false);
+ infostore_set_bool(infp, "migrating", false);
CU_DEBUG("Clearing infostore migrating flag");
infostore_close(infp);
@@ -1475,7 +1474,6 @@ static CMPIStatus migrate_do(const CMPIObjectPath *ref,
CMPIStatus s;
CMPIObjectPath *job_op;
struct migration_job *job;
- CMPI_THREAD_TYPE thread;
uint32_t retcode = 1;
CMPIInstance *ind = NULL;
CMPIInstance *inst = NULL;
@@ -1517,7 +1515,7 @@ static CMPIStatus migrate_do(const CMPIObjectPath *ref,
if (!rc)
CU_DEBUG("Failed to raise indication");
- thread = _BROKER->xft->newThread((void*)migration_thread, job, 0);
+ _BROKER->xft->newThread((void*)migration_thread, job, 0);
retcode = CIM_SVPC_RETURN_JOB_STARTED;
diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
index 5229f56..f8c5f24 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -1381,10 +1381,9 @@ static const char *input_rasd_to_vdev(CMPIInstance *inst,
struct virt_device *dev)
{
const char *val;
- const char *msg;
if (cu_get_str_prop(inst, "ResourceSubType", &val) != CMPI_RC_OK) {
- msg = "InputRASD ResourceSubType field not valid";
+ CU_DEBUG("InputRASD ResourceSubType field not valid");
goto out;
}
dev->dev.input.type = strdup(val);
@@ -1395,7 +1394,7 @@ static const char *input_rasd_to_vdev(CMPIInstance *inst,
else if (STREQC(dev->dev.input.type, "tablet"))
dev->dev.input.bus = strdup("usb");
else {
- msg = "Invalid value for ResourceSubType in InputRASD";
+ CU_DEBUG("Invalid value for ResourceSubType in InputRASD");
goto out;
}
} else
--
1.7.7.5
2
2
[PATCHv2] ComputerSystemIndication: Support libvirt domain events
by Eduardo Lima (Etrunko) 03 Jan '12
by Eduardo Lima (Etrunko) 03 Jan '12
03 Jan '12
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
Port current implementation to use domain events implementation provided by
libvirt. It requires libvirt version 0.9.0 or newer, when the
virEventRegisterDefaultImpl and virEventRunDefaultImpl API's were introduced.
Now that all events are generated by libvirt itself, we don't need to trigger
them manually anymore. Thus, this patch also removes trigger and raise calls
from VirtualSystemManagementService and ComputerSystem providers.
Differences from v1:
- Move call to virRegisterDefaultImpl() to the provider code with protection
to ensure it is called only once.
- Call CBDetachThread() before exiting the lifecycle thread.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
acinclude.m4 | 2 +-
libvirt-cim.spec.in | 4 +-
src/Virt_ComputerSystem.c | 51 +--
src/Virt_ComputerSystemIndication.c | 766 ++++++++++++++---------------
src/Virt_ComputerSystemIndication.h | 5 -
src/Virt_VirtualSystemManagementService.c | 30 +-
6 files changed, 378 insertions(+), 480 deletions(-)
diff --git a/acinclude.m4 b/acinclude.m4
index e313891..e0f76b6 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -243,7 +243,7 @@ AC_DEFUN([CHECK_LIBCU],
AC_DEFUN([CHECK_LIBVIRT],
[
- PKG_CHECK_MODULES([LIBVIRT], [libvirt >= 0.3.2])
+ PKG_CHECK_MODULES([LIBVIRT], [libvirt >= 0.9.0])
AC_SUBST([LIBVIRT_CFLAGS])
AC_SUBST([LIBVIRT_LIBS])
CPPFLAGS="$CPPFLAGS $LIBVIRT_CFLAGS"
diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in
index 5b7267b..f3289db 100644
--- a/libvirt-cim.spec.in
+++ b/libvirt-cim.spec.in
@@ -10,12 +10,12 @@ Source: libvirt-cim-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
URL: http://libvirt.org/CIM/
Requires: libxml2 >= 2.6.0
-Requires: libvirt >= 0.6.3
+Requires: libvirt >= 0.9.0
Requires: unzip
Requires: tog-pegasus
BuildRequires: libcmpiutil >= 0.5.4
BuildRequires: tog-pegasus-devel
-BuildRequires: libvirt-devel >= 0.6.3
+BuildRequires: libvirt-devel >= 0.9.0
# In RHEL5 uuid-devel is provided by e2fsprogs
%if 0%{?el5}
diff --git a/src/Virt_ComputerSystem.c b/src/Virt_ComputerSystem.c
index 098b07a..582253a 100644
--- a/src/Virt_ComputerSystem.c
+++ b/src/Virt_ComputerSystem.c
@@ -492,6 +492,7 @@ static CMPIStatus set_properties(const CMPIBroker *broker,
}
if (!set_name_from_dom(dom, instance)) {
+ CU_DEBUG("Unable to get domain name");
virt_set_status(broker, &s,
CMPI_RC_ERR_FAILED,
virDomainGetConnect(dom),
@@ -500,6 +501,7 @@ static CMPIStatus set_properties(const CMPIBroker *broker,
}
if (!set_uuid_from_dom(dom, instance, &uuid)) {
+ CU_DEBUG("Unable to get domain uuid");
virt_set_status(broker, &s,
CMPI_RC_ERR_FAILED,
virDomainGetConnect(dom),
@@ -514,6 +516,7 @@ static CMPIStatus set_properties(const CMPIBroker *broker,
}
if (!set_state_from_dom(broker, dom, instance)) {
+ CU_DEBUG("Unable to get domain info");
virt_set_status(broker, &s,
CMPI_RC_ERR_FAILED,
virDomainGetConnect(dom),
@@ -660,6 +663,7 @@ CMPIStatus get_domain_by_name(const CMPIBroker *broker,
conn = connect_by_classname(broker, CLASSNAME(reference), &s);
if (conn == NULL) {
+ CU_DEBUG("No such instance");
cu_statusf(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
"No such instance.");
@@ -668,6 +672,7 @@ CMPIStatus get_domain_by_name(const CMPIBroker *broker,
dom = virDomainLookupByName(conn, name);
if (dom == NULL) {
+ CU_DEBUG("Domain '%s' does not exist", name);
virt_set_status(broker, &s,
CMPI_RC_ERR_NOT_FOUND,
conn,
@@ -681,8 +686,10 @@ CMPIStatus get_domain_by_name(const CMPIBroker *broker,
conn,
dom,
&inst);
- if (s.rc != CMPI_RC_OK)
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Unable to retrieve instance from domain");
goto out;
+ }
*_inst = inst;
@@ -766,39 +773,6 @@ DEFAULT_DI();
DEFAULT_EQ();
DEFAULT_INST_CLEANUP();
-static bool trigger_mod_indication(const CMPIContext *context,
- CMPIInstance *prev_inst,
- const CMPIObjectPath *ref)
-{
- CMPIStatus s = {CMPI_RC_OK, NULL};
- const char *ind_name = "ComputerSystemModifiedIndication";
- CMPIInstance *ind = NULL;
- char *type = NULL;
-
- CU_DEBUG("Preparing ComputerSystem indication");
-
- ind = get_typed_instance(_BROKER,
- CLASSNAME(ref),
- ind_name,
- NAMESPACE(ref));
- if (ind == NULL) {
- CU_DEBUG("Failed to create ind '%s'", ind_name);
- goto out;
- }
-
- CU_DEBUG("Setting PreviousInstance");
- CMSetProperty(ind, "PreviousInstance",
- (CMPIValue *)&prev_inst, CMPI_instance);
-
- type = get_typed_class(CLASSNAME(ref), ind_name);
-
- s = stdi_raise_indication(_BROKER, context, type, NAMESPACE(ref), ind);
-
- out:
- free(type);
- return s.rc == CMPI_RC_OK;
-}
-
static int xen_scheduler_params(struct infostore_ctx *ctx,
virSchedParameter **params)
{
@@ -1253,7 +1227,6 @@ static CMPIStatus state_change(CMPIMethodMI *self,
int ret;
const char *name = NULL;
uint32_t rc = 1;
- bool ind_rc;
ret = cu_get_u16_arg(argsin, "RequestedState", &state);
if (ret != CMPI_RC_OK) {
@@ -1282,13 +1255,9 @@ static CMPIStatus state_change(CMPIMethodMI *self,
s = __state_change(name, state, reference);
- if (s.rc == CMPI_RC_OK) {
- ind_rc= trigger_mod_indication(context, prev_inst, reference);
- if (!ind_rc)
- CU_DEBUG("Unable to trigger indication");
-
+ if (s.rc == CMPI_RC_OK)
rc = 0;
- }
+
out:
CMReturnData(results, &rc, CMPI_uint32);
diff --git a/src/Virt_ComputerSystemIndication.c b/src/Virt_ComputerSystemIndication.c
index a00444d..eb1a71c 100644
--- a/src/Virt_ComputerSystemIndication.c
+++ b/src/Virt_ComputerSystemIndication.c
@@ -25,13 +25,13 @@
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
-#include <time.h>
#include <cmpidt.h>
#include <cmpift.h>
#include <cmpimacs.h>
#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
#include <libcmpiutil/libcmpiutil.h>
#include <misc_util.h>
@@ -44,158 +44,187 @@
#include "Virt_ComputerSystemIndication.h"
#include "Virt_HostSystem.h"
-static const CMPIBroker *_BROKER;
#define CSI_NUM_PLATFORMS 3
-enum CSI_PLATFORMS {CSI_XEN,
- CSI_KVM,
- CSI_LXC,
+enum CSI_PLATFORMS {
+ CSI_XEN,
+ CSI_KVM,
+ CSI_LXC,
};
-static CMPI_THREAD_TYPE thread_id[CSI_NUM_PLATFORMS];
-static int active_filters[CSI_NUM_PLATFORMS];
-
-enum CS_EVENTS {CS_CREATED,
- CS_DELETED,
- CS_MODIFIED,
+#define CS_NUM_EVENTS 3
+enum CS_EVENTS {
+ CS_CREATED,
+ CS_DELETED,
+ CS_MODIFIED,
};
-static pthread_cond_t lifecycle_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t lifecycle_mutex = PTHREAD_MUTEX_INITIALIZER;
-static bool lifecycle_enabled = 0;
-
-#define WAIT_TIME 60
-#define FAIL_WAIT_TIME 2
-
-struct dom_xml {
+typedef struct _csi_dom_xml_t csi_dom_xml_t;
+struct _csi_dom_xml_t {
char uuid[VIR_UUID_STRING_BUFLEN];
+ char *name;
char *xml;
- enum {DOM_OFFLINE,
- DOM_ONLINE,
- DOM_PAUSED,
- DOM_CRASHED,
- DOM_GONE,
- } state;
+ csi_dom_xml_t *next;
+ csi_dom_xml_t *prev;
+};
+
+typedef struct _csi_thread_data_t csi_thread_data_t;
+struct _csi_thread_data_t {
+ CMPI_THREAD_TYPE id;
+ int active_filters;
+ int dom_count;
+ csi_dom_xml_t *dom_list;
+ struct ind_args *args;
};
-static void free_dom_xml (struct dom_xml dom)
+static const CMPIBroker *_BROKER;
+static pthread_mutex_t lifecycle_mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool lifecycle_enabled = false;
+static csi_thread_data_t csi_thread_data[CSI_NUM_PLATFORMS] = {{0}, {0}, {0}};
+
+/*
+ * Domain list manipulation
+ */
+static void csi_dom_xml_free(csi_dom_xml_t *dom)
{
- free(dom.xml);
+ free(dom->xml);
+ free(dom->name);
+ free(dom);
}
-static char *sys_name_from_xml(char *xml)
+static int csi_dom_xml_set(csi_dom_xml_t *dom, virDomainPtr dom_ptr, CMPIStatus *s)
{
- char *tmp = NULL;
- char *name = NULL;
- int rc;
+ const char *name;
- tmp = strstr(xml, "<name>");
- if (tmp == NULL)
- goto out;
+ name = virDomainGetName(dom_ptr);
+ if (name == NULL) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to get domain name");
+ return -1;
+ }
- rc = sscanf(tmp, "<name>%a[^<]s</name>", &name);
- if (rc != 1)
- name = NULL;
+ dom->name = strdup(name);
+
+ /* xml */
+ dom->xml = virDomainGetXMLDesc(dom_ptr, VIR_DOMAIN_XML_SECURE);
+ if (dom->xml == NULL) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to get xml desc");
+ return -1;
+ }
- out:
- return name;
+ return 0;
}
-static int dom_state(virDomainPtr dom)
+static csi_dom_xml_t *csi_dom_xml_new(virDomainPtr dom_ptr, CMPIStatus *s)
{
- virDomainInfo info;
- int ret;
+ int rc;
+ csi_dom_xml_t *dom;
- ret = virDomainGetInfo(dom, &info);
- if (ret != 0)
- return DOM_GONE;
+ dom = calloc(1, sizeof(*dom));
+ if (dom == NULL)
+ return NULL;
- switch (info.state) {
- case VIR_DOMAIN_NOSTATE:
- case VIR_DOMAIN_RUNNING:
- case VIR_DOMAIN_BLOCKED:
- return DOM_ONLINE;
+ /* uuid */
+ rc = virDomainGetUUIDString(dom_ptr, dom->uuid);
+ if (rc == -1) {
+ cu_statusf(_BROKER, s,
+ CMPI_RC_ERR_FAILED,
+ "Failed to get domain UUID");
+ goto error;
+ }
- case VIR_DOMAIN_PAUSED:
- return DOM_PAUSED;
+ if (csi_dom_xml_set(dom, dom_ptr, s) == -1)
+ goto error;
- case VIR_DOMAIN_SHUTOFF:
- return DOM_OFFLINE;
+ return dom;
- case VIR_DOMAIN_CRASHED:
- return DOM_CRASHED;
+ error:
+ csi_dom_xml_free(dom);
+ return NULL;
+}
- default:
- return DOM_GONE;
- };
+static void csi_thread_dom_list_append(csi_thread_data_t *thread,
+ csi_dom_xml_t *dom)
+{
+ /* empty list */
+ if (thread->dom_list == NULL) {
+ dom->next = dom->prev = dom;
+ thread->dom_list = dom;
+ goto end;
+ }
+
+ dom->next = thread->dom_list;
+ dom->prev = thread->dom_list->prev;
+
+ thread->dom_list->prev->next = dom;
+ thread->dom_list->prev = dom;
+
+ end:
+ thread->dom_count += 1;
}
-static CMPIStatus doms_to_xml(struct dom_xml **dom_xml_list,
- virDomainPtr *dom_ptr_list,
- int dom_ptr_count)
+static csi_dom_xml_t *csi_thread_dom_list_find(csi_thread_data_t *thread,
+ const char *uuid)
{
- int i;
- int rc;
- CMPIStatus s = {CMPI_RC_OK, NULL};
+ csi_dom_xml_t *dom;
- *dom_xml_list = calloc(dom_ptr_count, sizeof(struct dom_xml));
- for (i = 0; i < dom_ptr_count; i++) {
- rc = virDomainGetUUIDString(dom_ptr_list[i],
- (*dom_xml_list)[i].uuid);
- if (rc == -1) {
- cu_statusf(_BROKER, &s,
- CMPI_RC_ERR_FAILED,
- "Failed to get UUID");
- /* If any domain fails, we fail. */
- break;
- }
+ if (thread->dom_list == NULL)
+ return NULL;
- (*dom_xml_list)[i].xml = virDomainGetXMLDesc(dom_ptr_list[i],
- VIR_DOMAIN_XML_SECURE);
- if ((*dom_xml_list)[i].xml == NULL) {
- cu_statusf(_BROKER, &s,
- CMPI_RC_ERR_FAILED,
- "Failed to get xml desc");
- break;
- }
+ dom = thread->dom_list;
+
+ do {
+ if (STREQ(dom->uuid, uuid))
+ return dom;
- (*dom_xml_list)[i].state = dom_state(dom_ptr_list[i]);
+ dom = dom->next;
+ } while (dom != thread->dom_list);
+
+ return NULL;
+}
+
+static void csi_thread_dom_list_remove(csi_thread_data_t *thread,
+ csi_dom_xml_t *dom)
+{
+ if (dom->next == dom) { /* Only one node */
+ thread->dom_list = NULL;
+ } else {
+ if (thread->dom_list == dom) /* First node */
+ thread->dom_list = dom->next;
+
+ dom->prev->next = dom->next;
+ dom->next->prev = dom->prev;
}
-
- return s;
+
+ thread->dom_count -= 1;
+
+ csi_dom_xml_free(dom);
}
-static bool dom_changed(struct dom_xml prev_dom,
- struct dom_xml *cur_xml,
- int cur_count)
+static void csi_thread_dom_list_free(csi_thread_data_t *thread)
{
- int i;
- bool ret = false;
-
- for (i = 0; i < cur_count; i++) {
- if (strcmp(cur_xml[i].uuid, prev_dom.uuid) != 0)
- continue;
-
- if (strcmp(cur_xml[i].xml, prev_dom.xml) != 0) {
- CU_DEBUG("Domain config changed");
- ret = true;
- }
+ while(thread->dom_list != NULL)
+ csi_thread_dom_list_remove(thread, thread->dom_list);
+}
- if (prev_dom.state != cur_xml[i].state) {
- CU_DEBUG("Domain state changed");
- ret = true;
- }
+static void csi_free_thread_data(void *data)
+{
+ csi_thread_data_t *thread = (csi_thread_data_t *) data;
- break;
- }
-
- return ret;
+ if (data == NULL)
+ return;
+
+ csi_thread_dom_list_free(thread);
+ stdi_free_ind_args(&thread->args);
}
void set_source_inst_props(const CMPIBroker *broker,
- const CMPIContext *context,
- const CMPIObjectPath *ref,
- CMPIInstance *ind)
+ const CMPIContext *context,
+ const CMPIObjectPath *ref,
+ CMPIInstance *ind)
{
const char *host;
const char *hostccn;
@@ -225,7 +254,7 @@ static bool _do_indication(const CMPIBroker *broker,
CMPIInstance *prev_inst,
CMPIInstance *affected_inst,
int ind_type,
- char *prefix,
+ const char *prefix,
struct ind_args *args)
{
const char *ind_type_name = NULL;
@@ -254,10 +283,10 @@ static bool _do_indication(const CMPIBroker *broker,
ind_type_name,
args->ns);
- /* Generally report errors and hope to continue, since we have no one
+ /* Generally report errors and hope to continue, since we have no one
to actually return status to. */
if (ind == NULL) {
- CU_DEBUG("Failed to create ind, type '%s:%s_%s'",
+ CU_DEBUG("Failed to create ind, type '%s:%s_%s'",
args->ns,
prefix,
ind_type_name);
@@ -279,14 +308,15 @@ static bool _do_indication(const CMPIBroker *broker,
CU_DEBUG("problem getting affected_op: '%s'", s.msg);
goto out;
}
+
CMSetNameSpace(affected_op, args->ns);
uuid = CMGetProperty(affected_inst, "UUID", &s);
- CMSetProperty(ind, "IndicationIdentifier",
+ CMSetProperty(ind, "IndicationIdentifier",
(CMPIValue *)&(uuid.value), CMPI_string);
timestamp = CMNewDateTime(broker, &s);
- CMSetProperty(ind, "IndicationTime",
+ CMSetProperty(ind, "IndicationTime",
(CMPIValue *)×tamp, CMPI_dateTime);
if (ind_type == CS_MODIFIED) {
@@ -313,34 +343,6 @@ static bool _do_indication(const CMPIBroker *broker,
return ret;
}
-static bool wait_for_event(int wait_time)
-{
- struct timespec timeout;
- int ret;
-
-
- clock_gettime(CLOCK_REALTIME, &timeout);
- timeout.tv_sec += wait_time;
-
- ret = pthread_cond_timedwait(&lifecycle_cond,
- &lifecycle_mutex,
- &timeout);
-
- return true;
-}
-
-static bool dom_in_list(char *uuid, int count, struct dom_xml *list)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (STREQ(uuid, list[i].uuid))
- return true;
- }
-
- return false;
-}
-
static bool set_instance_state(CMPIInstance *instance)
{
CMPIStatus s = {CMPI_RC_OK, NULL};
@@ -356,7 +358,7 @@ static bool set_instance_state(CMPIInstance *instance)
cim_state_other = CMNewString(_BROKER, "Guest destroyed", &s);
CMSetProperty(instance, "EnabledState",
(CMPIValue *)&cim_state, CMPI_uint16);
- CMSetProperty(instance, "OtherEnabledState",
+ CMSetProperty(instance, "OtherEnabledState",
(CMPIValue *)&cim_state_other, CMPI_string);
health_state = CIM_HEALTH_UNKNOWN;
@@ -382,13 +384,13 @@ static bool set_instance_state(CMPIInstance *instance)
req_state = CIM_STATE_UNKNOWN;
CMSetProperty(instance, "RequestedState",
(CMPIValue *)&req_state, CMPI_uint16);
-
+
return true;
}
-static bool create_deleted_guest_inst(char *xml,
- char *namespace,
- char *prefix,
+static bool create_deleted_guest_inst(const char *xml,
+ const char *namespace,
+ const char *prefix,
CMPIInstance **inst)
{
bool rc = false;
@@ -402,18 +404,18 @@ static bool create_deleted_guest_inst(char *xml,
goto out;
}
- s = instance_from_dominfo(_BROKER,
- namespace,
+ s = instance_from_dominfo(_BROKER,
+ namespace,
prefix,
- dominfo,
- inst);
+ dominfo,
+ inst);
if (s.rc != CMPI_RC_OK) {
CU_DEBUG("instance from domain info error: %s", s.msg);
goto out;
}
rc = set_instance_state(*inst);
- if (!rc)
+ if (!rc)
CU_DEBUG("Error setting instance state");
out:
@@ -422,14 +424,12 @@ static bool create_deleted_guest_inst(char *xml,
return rc;
}
-static bool async_ind(CMPIContext *context,
+static bool async_ind(struct ind_args *args,
int ind_type,
- struct dom_xml prev_dom,
- char *prefix,
- struct ind_args *args)
+ csi_dom_xml_t *dom,
+ const char *prefix)
{
bool rc = false;
- char *name = NULL;
char *cn = NULL;
CMPIObjectPath *op;
CMPIInstance *prev_inst;
@@ -441,13 +441,6 @@ static bool async_ind(CMPIContext *context,
return false;
}
- name = sys_name_from_xml(prev_dom.xml);
- CU_DEBUG("Name for system: '%s'", name);
- if (name == NULL) {
- rc = false;
- goto out;
- }
-
cn = get_typed_class(prefix, "ComputerSystem");
op = CMNewObjectPath(_BROKER, args->ns, cn, &s);
@@ -457,15 +450,32 @@ static bool async_ind(CMPIContext *context,
}
if (ind_type == CS_CREATED || ind_type == CS_MODIFIED) {
- s = get_domain_by_name(_BROKER, op, name, &affected_inst);
- if (s.rc != CMPI_RC_OK) {
+ s = get_domain_by_name(_BROKER, op, dom->name, &affected_inst);
+
+ /* If domain is not found, we create the instance from the data
+ previously stored */
+ if (s.rc == CMPI_RC_ERR_NOT_FOUND) {
+ rc = create_deleted_guest_inst(dom->xml,
+ args->ns,
+ prefix,
+ &affected_inst);
+ if (!rc) {
+ CU_DEBUG("Could not recreate guest instance");
+ goto out;
+ }
+
+ s.rc = CMPI_RC_OK;
+ }
+
+ if (s.rc != CMPI_RC_OK) {
CU_DEBUG("domain by name error");
goto out;
}
+
} else if (ind_type == CS_DELETED) {
- rc = create_deleted_guest_inst(prev_dom.xml,
- args->ns,
- prefix,
+ rc = create_deleted_guest_inst(dom->xml,
+ args->ns,
+ prefix,
&affected_inst);
if (!rc) {
CU_DEBUG("Could not recreate guest instance");
@@ -476,52 +486,134 @@ static bool async_ind(CMPIContext *context,
goto out;
}
- /* FIXME: We are unable to get the previous CS instance after it has
+ /* FIXME: We are unable to get the previous CS instance after it has
been modified. Consider keeping track of the previous
- state in the place we keep track of the requested state */
+ state in the place we keep track of the requested state */
prev_inst = affected_inst;
- CMSetProperty(affected_inst, "Name",
- (CMPIValue *)name, CMPI_chars);
+ CMSetProperty(affected_inst, "Name",
+ (CMPIValue *) dom->name, CMPI_chars);
CMSetProperty(affected_inst, "UUID",
- (CMPIValue *)prev_dom.uuid, CMPI_chars);
+ (CMPIValue *) dom->uuid, CMPI_chars);
- rc = _do_indication(_BROKER, context, prev_inst, affected_inst,
+ rc = _do_indication(_BROKER, args->context, prev_inst, affected_inst,
ind_type, prefix, args);
out:
free(cn);
- free(name);
return rc;
}
-static int platform_from_class(const char *cn)
+static int update_domain_list(virConnectPtr conn, csi_thread_data_t *thread)
{
- if (STARTS_WITH(cn, "Xen"))
- return CSI_XEN;
- else if (STARTS_WITH(cn, "KVM"))
- return CSI_KVM;
- else if (STARTS_WITH(cn, "LXC"))
- return CSI_LXC;
- else
- return -1;
+ virDomainPtr *dom_ptr_list;
+ csi_dom_xml_t *dom;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ int i, count;
+
+ csi_thread_dom_list_free(thread);
+
+ count = get_domain_list(conn, &dom_ptr_list);
+
+ for (i = 0; i < count; i++) {
+ dom = csi_dom_xml_new(dom_ptr_list[i], &s);
+ if (dom == NULL) {
+ CU_DEBUG("Failed to get domain info %s", s.msg);
+ break;
+ }
+
+ csi_thread_dom_list_append(thread, dom);
+ }
+
+ free_domain_list(dom_ptr_list, count);
+ free(dom_ptr_list);
+
+ return s.rc;
+}
+
+static int csi_domain_event_cb(virConnectPtr conn,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *data)
+{
+ int cs_event = CS_MODIFIED;
+ csi_thread_data_t *thread = (csi_thread_data_t *) data;
+ csi_dom_xml_t *dom_xml = NULL;
+ char *prefix = class_prefix_name(thread->args->classname);
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ CU_DEBUG("Event: Domain %s(%d) event: %d detail: %d\n",
+ virDomainGetName(dom), virDomainGetID(dom), event, detail);
+
+ switch (event) {
+ case VIR_DOMAIN_EVENT_DEFINED:
+ if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED) {
+ CU_DEBUG("Domain defined");
+ cs_event = CS_CREATED;
+ dom_xml = csi_dom_xml_new(dom, &s);
+ } else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED) {
+ CU_DEBUG("Domain modified");
+ cs_event = CS_MODIFIED;
+ }
+
+ break;
+
+ case VIR_DOMAIN_EVENT_UNDEFINED:
+ CU_DEBUG("Domain undefined");
+ cs_event = CS_DELETED;
+ break;
+
+ default: /* STARTED, SUSPENDED, RESUMED, STOPPED, SHUTDOWN */
+ CU_DEBUG("Domain modified");
+ cs_event = CS_MODIFIED;
+ break;
+ }
+
+ if (cs_event != CS_CREATED) {
+ char uuid[VIR_UUID_STRING_BUFLEN] = {0};
+ virDomainGetUUIDString(dom, &uuid[0]);
+ dom_xml = csi_thread_dom_list_find(thread, uuid);
+ }
+
+ if (dom_xml == NULL) {
+ CU_DEBUG("Domain not found in current list");
+ goto end;
+ }
+
+ async_ind(thread->args, cs_event, dom_xml, prefix);
+
+ /* Update the domain list accordingly */
+ if (event == VIR_DOMAIN_EVENT_DEFINED) {
+ if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED) {
+ csi_thread_dom_list_append(thread, dom_xml);
+ } else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED) {
+ free(dom_xml->name);
+ free(dom_xml->xml);
+ csi_dom_xml_set(dom_xml, dom, &s);
+ }
+ } else if (event == VIR_DOMAIN_EVENT_DEFINED &&
+ detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) {
+ csi_thread_dom_list_remove(thread, dom_xml);
+ }
+
+ end:
+ free(prefix);
+ return 0;
}
static CMPI_THREAD_RETURN lifecycle_thread(void *params)
{
- struct ind_args *args = (struct ind_args *)params;
- CMPIContext *context = args->context;
- CMPIStatus s;
- int prev_count;
- int cur_count;
- virDomainPtr *tmp_list;
- struct dom_xml *cur_xml = NULL;
- struct dom_xml *prev_xml = NULL;
- virConnectPtr conn;
+ csi_thread_data_t *thread = (csi_thread_data_t *) params;
+ struct ind_args *args = thread->args;
char *prefix = class_prefix_name(args->classname);
- int platform = platform_from_class(args->classname);
- if (prefix == NULL || platform == -1)
+ virConnectPtr conn;
+
+ CMPIStatus s;
+ int cb_id;
+
+ if (prefix == NULL)
goto init_out;
conn = connect_by_classname(_BROKER, args->classname, &s);
@@ -531,86 +623,66 @@ static CMPI_THREAD_RETURN lifecycle_thread(void *params)
goto conn_out;
}
- pthread_mutex_lock(&lifecycle_mutex);
-
- CBAttachThread(_BROKER, context);
+ /* register callback */
+ cb_id = virConnectDomainEventRegisterAny(conn, NULL,
+ VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+ VIR_DOMAIN_EVENT_CALLBACK(csi_domain_event_cb),
+ params, csi_free_thread_data);
- prev_count = get_domain_list(conn, &tmp_list);
- s = doms_to_xml(&prev_xml, tmp_list, prev_count);
- if (s.rc != CMPI_RC_OK)
- CU_DEBUG("doms_to_xml failed. Attempting to continue.");
- free_domain_list(tmp_list, prev_count);
- free(tmp_list);
-
- CU_DEBUG("Entering CSI event loop (%s)", prefix);
- while (active_filters[platform] > 0) {
- int i;
- bool res;
- bool failure = false;
-
- cur_count = get_domain_list(conn, &tmp_list);
- s = doms_to_xml(&cur_xml, tmp_list, cur_count);
- if (s.rc != CMPI_RC_OK) {
- CU_DEBUG("doms_to_xml failed. retry in %d seconds",
- FAIL_WAIT_TIME);
- failure = true;
- goto fail;
- }
-
- free_domain_list(tmp_list, cur_count);
- free(tmp_list);
-
- for (i = 0; i < cur_count; i++) {
- res = dom_in_list(cur_xml[i].uuid, prev_count, prev_xml);
- if (!res)
- async_ind(context, CS_CREATED,
- cur_xml[i], prefix, args);
-
- }
-
- for (i = 0; i < prev_count; i++) {
- res = dom_in_list(prev_xml[i].uuid, cur_count, cur_xml);
- if (!res)
- async_ind(context, CS_DELETED,
- prev_xml[i], prefix, args);
- }
+ if (cb_id == -1) {
+ CU_DEBUG("Failed to register domain event watch for '%s'",
+ args->classname)
+ goto cb_out;
+ }
- for (i = 0; i < prev_count; i++) {
- res = dom_changed(prev_xml[i], cur_xml, cur_count);
- if (res) {
- async_ind(context, CS_MODIFIED,
- prev_xml[i], prefix, args);
+ CBAttachThread(_BROKER, args->context);
- }
- free_dom_xml(prev_xml[i]);
- }
+ /* Get currently defined domains */
+ if (update_domain_list(conn, thread) != CMPI_RC_OK)
+ goto end;
- fail:
- if (failure) {
- wait_for_event(FAIL_WAIT_TIME);
- } else {
- free(prev_xml);
- prev_xml = cur_xml;
- prev_count = cur_count;
- wait_for_event(WAIT_TIME);
+ CU_DEBUG("Entering CSI event loop (%s)", prefix);
+ while (thread->active_filters > 0) {
+ if (virEventRunDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ CU_DEBUG("Failed to run event loop: %s\n",
+ err && err->message ? err->message : "Unknown error");
}
}
CU_DEBUG("Exiting CSI event loop (%s)", prefix);
- thread_id[platform] = 0;
+ CBDetachThread(_BROKER, args->context);
+ end:
+ virConnectDomainEventDeregisterAny(conn, cb_id);
- pthread_mutex_unlock(&lifecycle_mutex);
- stdi_free_ind_args(&args);
+ cb_out:
+
+ thread->id = 0;
+ thread->active_filters = 0;
+
+ if (thread->args != NULL)
+ stdi_free_ind_args(&thread->args);
conn_out:
virConnectClose(conn);
init_out:
free(prefix);
+ return (CMPI_THREAD_RETURN) 0;
+}
- return NULL;
+static int platform_from_class(const char *cn)
+{
+ if (STARTS_WITH(cn, "Xen"))
+ return CSI_XEN;
+ else if (STARTS_WITH(cn, "KVM"))
+ return CSI_KVM;
+ else if (STARTS_WITH(cn, "LXC"))
+ return CSI_LXC;
+ else
+ return -1;
}
static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
@@ -622,17 +694,25 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
{
CMPIStatus s = {CMPI_RC_OK, NULL};
struct std_indication_ctx *_ctx;
- struct ind_args *args;
+ struct ind_args *args = NULL;
int platform;
+ bool error = false;
+ csi_thread_data_t *thread = NULL;
+ static int events_registered = 0;
CU_DEBUG("ActivateFilter for %s", CLASSNAME(op));
pthread_mutex_lock(&lifecycle_mutex);
+ if (events_registered == 0) {
+ events_registered = 1;
+ virEventRegisterDefaultImpl();
+ }
+
_ctx = (struct std_indication_ctx *)mi->hdl;
if (CMIsNullObject(op)) {
- cu_statusf(_BROKER, &s,
+ cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"No ObjectPath given");
goto out;
@@ -647,13 +727,17 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
goto out;
}
- if (thread_id[platform] == 0) {
- args = malloc(sizeof(struct ind_args));
+ thread = &csi_thread_data[platform];
+ thread->active_filters += 1;
+
+ if (thread->id == 0) {
+ args = malloc(sizeof(*args));
if (args == NULL) {
CU_DEBUG("Failed to allocate ind_args");
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"Unable to allocate ind_args");
+ error = true;
goto out;
}
@@ -663,7 +747,7 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
cu_statusf(_BROKER, &s,
CMPI_RC_ERR_FAILED,
"Unable to create thread context");
- free(args);
+ error = true;
goto out;
}
@@ -671,15 +755,17 @@ static CMPIStatus ActivateFilter(CMPIIndicationMI* mi,
args->classname = strdup(CLASSNAME(op));
args->_ctx = _ctx;
- active_filters[platform] += 1;
-
- thread_id[platform] = _BROKER->xft->newThread(lifecycle_thread,
- args,
- 0);
- } else
- active_filters[platform] += 1;
+ thread->args = args;
+ thread->id = _BROKER->xft->newThread(lifecycle_thread,
+ thread, 0);
+ }
out:
+ if (error == true) {
+ thread->active_filters -= 1;
+ free(args);
+ }
+
pthread_mutex_unlock(&lifecycle_mutex);
return s;
@@ -705,11 +791,11 @@ static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi,
goto out;
}
+
pthread_mutex_lock(&lifecycle_mutex);
- active_filters[platform] -= 1;
+ csi_thread_data[platform].active_filters -= 1;
pthread_mutex_unlock(&lifecycle_mutex);
- pthread_cond_signal(&lifecycle_cond);
out:
return s;
}
@@ -736,13 +822,6 @@ static _EI_RTYPE DisableIndications(CMPIIndicationMI* mi,
_EI_RET();
}
-static CMPIStatus trigger_indication(const CMPIContext *context)
-{
- CU_DEBUG("triggered");
- pthread_cond_signal(&lifecycle_cond);
- return(CMPIStatus){CMPI_RC_OK, NULL};
-}
-
DECLARE_FILTER(xen_created, "Xen_ComputerSystemCreatedIndication");
DECLARE_FILTER(xen_deleted, "Xen_ComputerSystemDeletedIndication");
DECLARE_FILTER(xen_modified, "Xen_ComputerSystemModifiedIndication");
@@ -766,126 +845,7 @@ static struct std_ind_filter *filters[] = {
NULL,
};
-static CMPIInstance *get_prev_inst(const CMPIBroker *broker,
- const CMPIInstance *ind,
- CMPIStatus *s)
-{
- CMPIData data;
- CMPIInstance *prev_inst = NULL;
-
- data = CMGetProperty(ind, "PreviousInstance", s);
- if (s->rc != CMPI_RC_OK || CMIsNullValue(data)) {
- cu_statusf(broker, s,
- CMPI_RC_ERR_NO_SUCH_PROPERTY,
- "Unable to get PreviousInstance of the indication");
- goto out;
- }
-
- if (data.type != CMPI_instance) {
- cu_statusf(broker, s,
- CMPI_RC_ERR_TYPE_MISMATCH,
- "Indication SourceInstance is of unexpected type");
- goto out;
- }
-
- prev_inst = data.value.inst;
-
- out:
- return prev_inst;
-}
-
-static CMPIStatus raise_indication(const CMPIBroker *broker,
- const CMPIContext *ctx,
- const CMPIObjectPath *ref,
- const CMPIInstance *ind)
-{
- CMPIStatus s = {CMPI_RC_OK, NULL};
- CMPIInstance *prev_inst;
- CMPIInstance *src_inst;
- CMPIObjectPath *_ref = NULL;
- struct std_indication_ctx *_ctx = NULL;
- struct ind_args *args = NULL;
- char *prefix = NULL;
- bool rc;
-
- if (!lifecycle_enabled) {
- cu_statusf(_BROKER, &s,
- CMPI_RC_ERR_FAILED,
- "CSI not enabled, skipping indication delivery");
- goto out;
- }
-
- prev_inst = get_prev_inst(broker, ind, &s);
- if (s.rc != CMPI_RC_OK || CMIsNullObject(prev_inst))
- goto out;
-
- _ref = CMGetObjectPath(prev_inst, &s);
- if (s.rc != CMPI_RC_OK) {
- cu_statusf(broker, &s,
- CMPI_RC_ERR_FAILED,
- "Unable to get a reference to the guest");
- goto out;
- }
-
- /* FIXME: This is a Pegasus work around. Pegsus loses the namespace
- when an ObjectPath is pulled from an instance */
- if (STREQ(NAMESPACE(_ref), ""))
- CMSetNameSpace(_ref, "root/virt");
-
- s = get_domain_by_ref(broker, _ref, &src_inst);
- if (s.rc != CMPI_RC_OK || CMIsNullObject(src_inst))
- goto out;
-
- _ctx = malloc(sizeof(struct std_indication_ctx));
- if (_ctx == NULL) {
- cu_statusf(broker, &s,
- CMPI_RC_ERR_FAILED,
- "Unable to allocate indication context");
- goto out;
- }
-
- _ctx->brkr = broker;
- _ctx->handler = NULL;
- _ctx->filters = filters;
- _ctx->enabled = lifecycle_enabled;
-
- args = malloc(sizeof(struct ind_args));
- if (args == NULL) {
- cu_statusf(broker, &s,
- CMPI_RC_ERR_FAILED,
- "Unable to allocate ind_args");
- goto out;
- }
-
- args->ns = strdup(NAMESPACE(_ref));
- args->classname = strdup(CLASSNAME(_ref));
- args->_ctx = _ctx;
-
- prefix = class_prefix_name(args->classname);
-
- rc = _do_indication(broker, ctx, prev_inst, src_inst,
- CS_MODIFIED, prefix, args);
-
- if (!rc) {
- cu_statusf(_BROKER, &s,
- CMPI_RC_ERR_FAILED,
- "Unable to generate indication");
- }
-
- out:
- if (args != NULL)
- stdi_free_ind_args(&args);
-
- if (_ctx != NULL)
- free(_ctx);
-
- free(prefix);
- return s;
-}
-
static struct std_indication_handler csi = {
- .raise_fn = raise_indication,
- .trigger_fn = trigger_indication,
.activate_fn = ActivateFilter,
.deactivate_fn = DeActivateFilter,
.enable_fn = EnableIndications,
@@ -896,10 +856,10 @@ DEFAULT_IND_CLEANUP();
DEFAULT_AF();
DEFAULT_MP();
-STDI_IndicationMIStub(,
+STDI_IndicationMIStub(,
Virt_ComputerSystemIndicationProvider,
_BROKER,
- libvirt_cim_init(),
+ libvirt_cim_init(),
&csi,
filters);
diff --git a/src/Virt_ComputerSystemIndication.h b/src/Virt_ComputerSystemIndication.h
index 0f8f1b7..594c3ed 100644
--- a/src/Virt_ComputerSystemIndication.h
+++ b/src/Virt_ComputerSystemIndication.h
@@ -24,11 +24,6 @@
#include <cmpidt.h>
#include <stdbool.h>
-bool cs_lifecycle_indication(const CMPIBroker *broker,
- const CMPIContext *ctx,
- const CMPIObjectPath *newsystem,
- char *type);
-
void set_source_inst_props(const CMPIBroker *broker,
const CMPIContext *context,
const CMPIObjectPath *ref,
diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
index 4d26429..46bc9b5 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -1894,7 +1894,7 @@ static CMPIStatus raise_rasd_indication(const CMPIContext *context,
CMPIObjectPath *op = NULL;
int i;
- CU_DEBUG("raise_rasd_indication");
+ CU_DEBUG("raise_rasd_indication %s", base_type);
type = get_typed_class(CLASSNAME(ref), base_type);
@@ -2105,22 +2105,6 @@ static CMPIInstance *create_system(const CMPIContext *context,
return inst;
}
-static bool trigger_indication(const CMPIContext *context,
- const char *base_type,
- const CMPIObjectPath *ref)
-{
- char *type;
- CMPIStatus s;
-
- type = get_typed_class(CLASSNAME(ref), base_type);
-
- s = stdi_trigger_indication(_BROKER, context, type, NAMESPACE(ref));
-
- free(type);
-
- return s.rc == CMPI_RC_OK;
-}
-
static CMPIStatus define_system(CMPIMethodMI *self,
const CMPIContext *context,
const CMPIResult *results,
@@ -2156,9 +2140,6 @@ static CMPIStatus define_system(CMPIMethodMI *self,
CMAddArg(argsout, "ResultingSystem", &result, CMPI_ref);
}
- trigger_indication(context,
- "ComputerSystemCreatedIndication",
- reference);
out:
if (s.rc == CMPI_RC_OK)
rc = CIM_SVPC_RETURN_COMPLETED;
@@ -2261,9 +2242,6 @@ error:
NULL,
reference,
&list);
- trigger_indication(context,
- "ComputerSystemDeletedIndication",
- reference);
}
virDomainFree(dom);
@@ -2345,12 +2323,8 @@ static CMPIStatus update_system_settings(const CMPIContext *context,
connect_and_create(xml, ref, &s);
}
- if (s.rc == CMPI_RC_OK) {
+ if (s.rc == CMPI_RC_OK)
set_autostart(vssd, ref, dom);
- trigger_indication(context,
- "ComputerSystemModifiedIndication",
- ref);
- }
out:
free(xml);
--
1.7.4.4
2
2
I'm happy announce the release of libvirt-cim-0.6.
The new release is available at:
ftp://libvirt.org/libvirt-cim/libvirt-cim-0.6.0.tar.gz
libvirt-cim-0.6:
* ComputerSystemIndication: Support libvirt domain events (Eduardo Lima
(Etrunko))
* Network QoS Patch2 (Gareth S. Bestor)
* cpu cgroup patch 2 (Gareth S. Bestor)
* Build: Make 'make distcheck' happy (Eduardo Lima (Etrunko))
* Build: Remove tests subdirs from source (Eduardo Lima (Etrunko)
--
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent(a)linux.vnet.ibm.com
_______________________________________________
Libvirt-cim mailing list
Libvirt-cim(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvirt-cim
1
0
From: Gareth S. Bestor <bestor(a)us.ibm.com>
This patch updates the earlier patch to libvirt-cim for network bandwidth QOS
support. Previous patch had to perform all external host 'tc' (traffic control)
commands from within libvirt-cim providers, because earlier versions of
libvirt lacked native QoS support. libvirt 0.9.4 added native QoS support;
this new patch for libvirt-cim removes earlier QoS hacks in favor of directly
exploiting libvirt equivalent QoS function and configuration. Note, libvirt
supports three tunables for network bandwidth QoS: average, peak and burst,
for both inbound and outbound traffic independently.
This revised libvirt-cim patch only exposes - as previously - inbound traffic
QoS, but adds peak to previous average tunable support.
Selection of earlier (libvirt-cim QoS hack) vs latter (native libvirt QoS)
is done at compile-time based on libvirt version being built against.
As previously, QoS capabilites are exposed on the virtual network pool, and
the QoS setting for a specific guest's NIC are exposed on the associated
network device RASD. QoS settings may be specified during guest creation
(DefineSystem) or guest modification (ModifyResourceSettings).
Signed-off-by: Gareth S. Bestor <bestor(a)us.ibm.com>
---
libxkutil/device_parsing.c | 34 +++++++++++++++++++++
libxkutil/device_parsing.h | 2 +
libxkutil/xmlgen.c | 39 ++++++++++++++++++++++++
src/Virt_RASD.c | 33 ++++++++++++++++++--
src/Virt_SettingsDefineCapabilities.c | 47 +++++++++++++++++++++++++----
src/Virt_VirtualSystemManagementService.c | 22 +++++++++++++-
6 files changed, 166 insertions(+), 11 deletions(-)
diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index 371838f..7eaa63e 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -444,7 +444,39 @@ static int parse_net_device(xmlNode *inode, struct virt_device **vdevs)
ndev->filter_ref = get_attr_value(child, "filter");
} else if (XSTREQ(child->name, "virtualport")) {
parse_vsi_device(child, ndev);
+#if LIBVIR_VERSION_NUMBER >= 9000
+ } else if (XSTREQ(child->name, "bandwidth")) {
+ /* Network QoS bandwidth support */
+ xmlNode *grandchild = NULL;
+ for (grandchild = child->children;
+ grandchild != NULL;
+ grandchild = grandchild->next) {
+ if (XSTREQ(grandchild->name, "inbound")) {
+ /* Only expose inbound bandwidth */
+ char *val;
+
+ val = get_attr_value(grandchild,
+ "average");
+ if (val != NULL) {
+ sscanf(val, "%" PRIu64,
+ &ndev->reservation);
+ free(val);
+ } else
+ ndev->reservation = 0;
+
+ val = get_attr_value(grandchild,
+ "peak");
+ if (val != NULL) {
+ sscanf(val, "%" PRIu64,
+ &ndev->limit);
+ free(val);
+ } else
+ ndev->limit = 0;
+ break;
+ }
+ }
}
+#endif
}
@@ -861,6 +893,8 @@ struct virt_device *virt_device_dup(struct virt_device *_dev)
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.reservation = _dev->dev.net.reservation;
+ dev->dev.net.limit = _dev->dev.net.limit;
} else if (dev->type == CIM_RES_TYPE_DISK) {
DUP_FIELD(dev, _dev, dev.disk.type);
DUP_FIELD(dev, _dev, dev.disk.device);
diff --git a/libxkutil/device_parsing.h b/libxkutil/device_parsing.h
index ab104d9..f24268b 100644
--- a/libxkutil/device_parsing.h
+++ b/libxkutil/device_parsing.h
@@ -66,6 +66,8 @@ struct net_device {
char *device;
char *net_mode;
char *filter_ref;
+ uint64_t reservation;
+ uint64_t limit;
struct vsi_device vsi;
};
diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
index aae1e51..638cffe 100644
--- a/libxkutil/xmlgen.c
+++ b/libxkutil/xmlgen.c
@@ -320,6 +320,45 @@ static const char *net_xml(xmlNodePtr root, struct domain *dominfo)
BAD_CAST net->filter_ref);
}
+#if LIBVIR_VERSION_NUMBER >= 9000
+ /* Network QoS settings saved under <bandwidth> XML section */
+ if (net->reservation || net->limit) {
+ int ret;
+ char *string = NULL;
+
+ tmp = xmlNewChild(nic, NULL,
+ BAD_CAST "bandwidth", NULL);
+ if (tmp == NULL)
+ return XML_ERROR;
+
+ /* Set inbound bandwidth from Reservation & Limit */
+ tmp = xmlNewChild(tmp, NULL,
+ BAD_CAST "inbound", NULL);
+ if (tmp == NULL)
+ return XML_ERROR;
+
+ if (net->reservation) {
+ ret = asprintf(&string, "%" PRIu64,
+ net->reservation);
+ if (ret == -1)
+ return XML_ERROR;
+ xmlNewProp(tmp, BAD_CAST "average",
+ BAD_CAST string);
+ free(string);
+ }
+
+ if (net->limit) {
+ ret = asprintf(&string, "%" PRIu64,
+ net->limit);
+ if (ret == -1)
+ return XML_ERROR;
+ xmlNewProp(tmp, BAD_CAST "peak",
+ BAD_CAST string);
+ free(string);
+ }
+ }
+#endif
+
if (STREQ(dev->dev.net.type, "network"))
msg = set_net_source(nic, net, "network");
else if (STREQ(dev->dev.net.type, "bridge"))
diff --git a/src/Virt_RASD.c b/src/Virt_RASD.c
index e148674..a868c21 100644
--- a/src/Virt_RASD.c
+++ b/src/Virt_RASD.c
@@ -39,6 +39,7 @@
#include "svpc_types.h"
#include "Virt_Device.h"
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
#define QOSCMD_MAC2BANDWIDTH "_ROOT=$(tc class show dev %s | awk '($4==\"root\")\
{print $3}')\n _ID=$(tc filter show dev %s | awk 'BEGIN {RS=\"\\nfilter\"} (NR>2)\
@@ -48,6 +49,7 @@ m1,m2,m3,m4,m5,m6,$18)}' | awk -v mm=%s '($1==mm){print $2}')\n \
if [[ -n \"$_ID\" ]]; then\n tc class show dev %s | awk -v rr=$_ROOT -v id=$_ID \
'($4==\"parent\" && $5==rr && $3==id){print \
substr($13,1,(index($13,\"Kbit\")-1))}'\n fi\n"
+#endif
const static CMPIBroker *_BROKER;
@@ -463,11 +465,7 @@ static CMPIStatus set_net_rasd_params(const CMPIBroker *broker,
const struct virt_device *dev,
CMPIInstance *inst)
{
- FILE *pipe = NULL;
- char *cmd = NULL;
- uint64_t val = 0;
CMPIStatus s = {CMPI_RC_OK, NULL};
- int i;
CMSetProperty(inst,
"NetworkType",
@@ -485,8 +483,14 @@ static CMPIStatus set_net_rasd_params(const CMPIBroker *broker,
(CMPIValue *)dev->dev.net.source,
CMPI_chars);
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
if ((dev->dev.net.mac != NULL) && (dev->dev.net.source != NULL)) {
+ FILE *pipe = NULL;
+ char *cmd = NULL;
+ uint64_t val = 0;
+ int i;
+
/* Get tc performance class bandwidth for this MAC addr */
i = asprintf(&cmd, QOSCMD_MAC2BANDWIDTH, dev->dev.net.source,
dev->dev.net.source,
@@ -511,6 +515,25 @@ static CMPIStatus set_net_rasd_params(const CMPIBroker *broker,
}
free(cmd);
}
+#else
+ if (dev->dev.net.reservation) {
+ CMSetProperty(inst,
+ "Reservation",
+ (CMPIValue *)&(dev->dev.net.reservation),
+ CMPI_uint64);
+
+ if (dev->dev.net.limit)
+ CMSetProperty(inst,
+ "Limit",
+ (CMPIValue *)&(dev->dev.net.limit),
+ CMPI_uint64);
+
+ CMSetProperty(inst,
+ "AllocationUnits",
+ (CMPIValue *)"KiloBytes per Second",
+ CMPI_chars);
+ }
+#endif
if ((dev->dev.net.source != NULL) &&
(STREQ(dev->dev.net.type, "direct")))
@@ -543,7 +566,9 @@ static CMPIStatus set_net_rasd_params(const CMPIBroker *broker,
(CMPIValue *)dev->dev.net.poolid,
CMPI_chars);
+#if LIBVIR_VERSION_NUMBER < 9000
out:
+#endif
return s;
}
diff --git a/src/Virt_SettingsDefineCapabilities.c b/src/Virt_SettingsDefineCapabilities.c
index 129749e..660103a 100644
--- a/src/Virt_SettingsDefineCapabilities.c
+++ b/src/Virt_SettingsDefineCapabilities.c
@@ -74,9 +74,11 @@ const static CMPIBroker *_BROKER;
#define NEW_VOL_RASD 2
/* QoS Network support */
+#if LIBVIR_VERSION_NUMBER < 9000
#define QOSCMD_LISTCLASSES "_ROOT=$(tc class show dev %s | awk '($4==\"root\")\
{print $3}')\n tc class show dev %s | awk -v rr=$_ROOT \
'($4==\"parent\" && $5==rr){print $3\" \"$13}'\n"
+#endif
static bool system_has_vt(virConnectPtr conn)
{
@@ -567,6 +569,8 @@ static CMPIStatus set_net_props(int type,
const char *net_type,
const char *net_name,
uint64_t num_nics,
+ uint64_t reservation,
+ uint64_t limit,
const char *device,
const char *src_dev,
const char *net_mode,
@@ -594,6 +598,21 @@ static CMPIStatus set_net_props(int type,
CMSetProperty(inst, "VirtualQuantity",
(CMPIValue *)&num_nics, CMPI_uint64);
+#if LIBVIR_VERSION_NUMBER >= 9000
+ /* Network QoS support for later libvirt versions */
+ if (reservation)
+ CMSetProperty(inst, "Reservation",
+ (CMPIValue *)&reservation, CMPI_uint64);
+
+ if (limit)
+ CMSetProperty(inst, "Limit",
+ (CMPIValue *)&reservation, CMPI_uint64);
+
+ if (reservation || limit)
+ CMSetProperty(inst, "AllocationUnits",
+ (CMPIValue *)"KiloBytes per Second", CMPI_chars);
+#endif
+
if (device != NULL)
CMSetProperty(inst, "VirtualDevice",
(CMPIValue *)device, CMPI_chars);
@@ -647,6 +666,8 @@ static CMPIStatus net_template(const CMPIObjectPath *ref,
{
bool ret;
uint64_t num_nics;
+ uint64_t reservation = 0;
+ uint64_t limit = 0;
const char *id;
CMPIStatus s = {CMPI_RC_OK, NULL};
int i,j;
@@ -658,16 +679,21 @@ static CMPIStatus net_template(const CMPIObjectPath *ref,
switch (template_type) {
case SDC_RASD_MIN:
num_nics = 0;
+ reservation = 1;
+ limit = 1;
id = "Minimum";
break;
case SDC_RASD_MAX:
ret = get_max_nics(ref, &num_nics, &s);
if (!ret)
goto out;
+ /* No apparant maximum reservation or limit QoS setting in libvirt! */
id = "Maximum";
break;
case SDC_RASD_INC:
num_nics = 1;
+ reservation = 1;
+ limit = 1;
id = "Increment";
break;
case SDC_RASD_DEF:
@@ -689,7 +715,9 @@ static CMPIStatus net_template(const CMPIObjectPath *ref,
id,
type[i],
name[i],
- num_nics,
+ num_nics,
+ reservation,
+ limit,
device[j],
NULL,
NULL,
@@ -707,22 +735,26 @@ static CMPIStatus net_template(const CMPIObjectPath *ref,
}
s = set_net_props(template_type, ref, id, "direct", NULL,
- num_nics, NULL, "eth1", "vepa", NULL,
+ num_nics, reservation, limit,
+ NULL, "eth1", "vepa", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, list);
/* profile id*/
s = set_net_props(template_type, ref, id, "direct", NULL,
- num_nics, NULL, "eth1", "vepa", NULL,
+ num_nics, reservation, limit,
+ NULL, "eth1", "vepa", NULL,
"802.1Qbh", NULL, NULL, NULL,
NULL, "my_profile", list);
/* no profile id but with instance id*/
s = set_net_props(template_type, ref, id, "direct", NULL,
- num_nics, NULL, "eth1", "vepa", NULL,
+ num_nics, reservation, limit,
+ NULL, "eth1", "vepa", NULL,
"802.1Qbg", "managerid", "typeid",
"typeidversion", "instanceid", NULL,
list);
/* no profile id and no instance id*/
s = set_net_props(template_type, ref, id, "direct", NULL,
- num_nics, NULL, "eth1", "vepa", NULL,
+ num_nics, reservation, limit,
+ NULL, "eth1", "vepa", NULL,
"802.1Qbg", "managerid", "typeid",
"typeidversion", "NULL", "NULL", list);
@@ -814,6 +846,7 @@ static CMPIStatus set_net_pool_props(const CMPIObjectPath *ref,
return s;
}
+#if LIBVIR_VERSION_NUMBER < 9000
static char * get_bridge_name(virConnectPtr conn, const char *name)
{
char *bridge = NULL;
@@ -913,7 +946,7 @@ static CMPIStatus qos_hack(
return s;
}
-
+#endif
static CMPIStatus net_pool_template(const CMPIObjectPath *ref,
int template_type,
@@ -2086,8 +2119,10 @@ static CMPIStatus sdc_rasds_for_type(const CMPIObjectPath *ref,
}
}
+#if LIBVIR_VERSION_NUMBER < 9000
if (type == CIM_RES_TYPE_NET)
s = qos_hack(ref, list);
+#endif
out:
return s;
diff --git a/src/Virt_VirtualSystemManagementService.c b/src/Virt_VirtualSystemManagementService.c
index 0141515..4e16b81 100644
--- a/src/Virt_VirtualSystemManagementService.c
+++ b/src/Virt_VirtualSystemManagementService.c
@@ -68,6 +68,7 @@
#define RASD_IND_DELETED "ResourceAllocationSettingDataDeletedIndication"
#define RASD_IND_MODIFIED "ResourceAllocationSettingDataModifiedIndication"
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
#define QOSCMD_BANDWIDTH2ID "_ROOT=$(tc class show dev %s | awk '($4==\"root\")\
{print $3}')\n tc class show dev %s | awk -v rr=$_ROOT -v bw=%uKbit \
@@ -96,6 +97,7 @@ $U32 match u16 0x0800 0xFFFF at -2 match u16 0x$ME2 0xFFFF at -4 match u32 \
ffff: prio 50 u32\"; $U32 match u16 0x0800 0xFFFF at -2 match u32 0x$MI2 \
0xFFFFFFFF at -12 match u16 0x$MI1 0xFFFF at -14 police rate %uKbit burst 15k \
drop\n"
+#endif
const static CMPIBroker *_BROKER;
@@ -105,6 +107,7 @@ enum ResourceAction {
RESOURCE_MOD,
};
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
static CMPIStatus add_qos_for_mac(const uint64_t qos,
const char *mac,
@@ -202,6 +205,7 @@ static CMPIStatus remove_qos_for_mac(const uint64_t qos,
free(cmd);
return s;
}
+#endif
static CMPIStatus check_uuid_in_use(const CMPIObjectPath *ref,
struct domain *domain)
@@ -973,6 +977,15 @@ static const char *net_rasd_to_vdev(CMPIInstance *inst,
dev->dev.net.model = NULL;
else
dev->dev.net.model = strdup(val);
+
+ if (cu_get_u64_prop(inst, "Reservation",
+ &dev->dev.net.reservation) != CMPI_RC_OK)
+ dev->dev.net.reservation = 0;
+
+ if (cu_get_u64_prop(inst, "Limit",
+ &dev->dev.net.limit) != CMPI_RC_OK)
+ dev->dev.net.limit = 0;
+
out:
free(network);
return msg;
@@ -1645,8 +1658,10 @@ static const char *classify_resources(CMPIArray *resources,
} else if (type == CIM_RES_TYPE_NET) {
struct virt_device dev;
int ncount = count + domain->dev_net_ct;
+#if LIBVIR_VERSION_NUMBER < 9000
uint64_t qos_val = 0;
const char *qos_unitstr;
+#endif
memset(&dev, 0, sizeof(dev));
msg = rasd_to_vdev(inst,
@@ -1659,6 +1674,7 @@ static const char *classify_resources(CMPIArray *resources,
ncount,
&domain->dev_net_ct);
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
if (((&dev)->dev.net.mac != NULL) &&
((&dev)->dev.net.source != NULL) &&
@@ -1672,6 +1688,7 @@ static const char *classify_resources(CMPIArray *resources,
(&dev)->dev.net.mac,
(&dev)->dev.net.source);
}
+#endif
} else if (type == CIM_RES_TYPE_GRAPHICS) {
struct virt_device dev;
int gcount = count + domain->dev_graphics_ct;
@@ -2763,14 +2780,16 @@ static CMPIStatus resource_mod(struct domain *dominfo,
(type == CIM_RES_TYPE_INPUT))
cu_statusf(_BROKER, &s, CMPI_RC_OK, "");
else {
+#if LIBVIR_VERSION_NUMBER < 9000
uint64_t qos_val = 0;
const char *qos_unitstr;
-
+#endif
s = _resource_dynamic(dominfo,
dev,
RESOURCE_MOD,
CLASSNAME(op));
+#if LIBVIR_VERSION_NUMBER < 9000
/* Network QoS support */
if ((type == CIM_RES_TYPE_NET) &&
(dev->dev.net.mac != NULL) &&
@@ -2785,6 +2804,7 @@ static CMPIStatus resource_mod(struct domain *dominfo,
dev->dev.net.mac,
dev->dev.net.source);
}
+#endif
}
break;
}
--
1.7.1
2
2
add the class Net_EthernetPortAllocationSettingData. According To DSP1050,
there are two kinds of EASD, EASD_EA and EASD_EC, which describe Ethernetprot
settings and connection settings.
Signed-off-by: Wayne Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/EthernetPortAllocationSettingData.mof | 21 +
.../EthernetPortAllocationSettingData.registration | 3 +
src/Virt_EASD.c | 733 ++++++++++++++++++++
src/Virt_EASD.h | 61 ++
4 files changed, 818 insertions(+), 0 deletions(-)
create mode 100644 schema/EthernetPortAllocationSettingData.mof
create mode 100644 schema/EthernetPortAllocationSettingData.registration
create mode 100644 src/Virt_EASD.c
create mode 100644 src/Virt_EASD.h
diff --git a/schema/EthernetPortAllocationSettingData.mof b/schema/EthernetPortAllocationSettingData.mof
new file mode 100644
index 0000000..8a1b38b
--- /dev/null
+++ b/schema/EthernetPortAllocationSettingData.mof
@@ -0,0 +1,21 @@
+// Copyright IBM Corp. 2011
+
+[Description ("Virtutal EthernetPort Setting Data"),
+ Provider("cmpi::Virt_EASD")
+]
+
+class Net_EthernetPortAllocationSettingData : CIM_EthernetPortAllocationSettingData
+{
+ uint16 PortVID;
+ uint16 DesiredEndPointMode;
+
+ [Description("VLAN type of the port, "
+ "Now only support IEEE 802.1.q."),
+ ValueMap { "0", "1", "2", "3" },
+ Values { "Not VLAN", "IEEE 802.1.q", "IEEE 802.1.qbg", "IEEE 802.1.qbh" }]
+ uint16 VLANType;
+
+ uint16 ReorderHdr;
+ string VLANQosIngress;
+ string VLANQosEgress;
+};
diff --git a/schema/EthernetPortAllocationSettingData.registration b/schema/EthernetPortAllocationSettingData.registration
new file mode 100644
index 0000000..bedd029
--- /dev/null
+++ b/schema/EthernetPortAllocationSettingData.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2011
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_EthernetPortAllocationSettingData root/virt Virt_EASD Virt_EASD instance
diff --git a/src/Virt_EASD.c b/src/Virt_EASD.c
new file mode 100644
index 0000000..cb786a5
--- /dev/null
+++ b/src/Virt_EASD.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)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_EASD.h"
+#include "svpc_types.h"
+#include "Virt_Device.h"
+#include "Virt_VirtualEthernetSwitchSystem.h"
+#include "network_model.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_easd(const CMPIBroker *broker, const char* prefix,
+ EthIface *piface, int type, CMPIInstance *instance)
+{
+ char *eth_name, *easd_name;
+ int asret;
+ uint16_t res_type = CIM_NUM_SWITCHPORT;
+ uint16_t vlan_mode;
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ eth_name = get_ethportsd_name_from_iface(piface->name, type);
+ asret = asprintf(&easd_name, "%s/%s", prefix, eth_name);
+
+ CMSetProperty(instance, "InstanceID",
+ (CMPIValue *)easd_name, CMPI_chars);
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)eth_name, CMPI_chars);
+ SAFE_FREE(easd_name);
+ SAFE_FREE(eth_name);
+
+ CMSetProperty(instance, "ResourceType",
+ (CMPIValue *)&res_type, CMPI_uint16);
+
+ if (piface->eth_type == ETH_TYPE_PHYSICAL) {
+ vlan_mode = CIM_NUM_VLAN_MODE_TRUNK;
+ CMSetProperty(instance, "DesiredEndPointMode",
+ (CMPIValue *)&vlan_mode, CMPI_uint16);
+ }
+
+
+ if (piface->mac != NULL) {
+ CMSetProperty(instance, "Address",
+ (CMPIValue *)piface->mac, CMPI_chars);
+ }
+
+ return 1;
+}
+
+static int set_secondary_for_easd(const CMPIBroker *broker, EthIface *piface,
+ CMPIInstance *instance)
+{
+ VLAN_Prop *pvlan;
+ VLAN_Prop_8021q *pvlan8021q;
+ uint16_t vid, hdr;
+ CMPIArray *conn_array;
+ CMPIString *cm_str;
+ char *str = NULL, *egress = NULL, *ingress = NULL;
+ CMPIStatus s;
+ int ret;
+ uint16_t vlantype = 0;
+ uint16_t visibility = CIM_NUM_CONSUMERVISIBILITY_VIRTUALIZED;
+
+ if (piface->eth_type == ETH_TYPE_PHYSICAL) {
+ visibility = CIM_NUM_CONSUMERVISIBILITY_PASSEDTHROUGH;
+ }
+ CMSetProperty(instance, "ConsumerVisibility",
+ (CMPIValue *)&visibility, CMPI_uint16);
+
+ if ((piface->eth_type != ETH_TYPE_VLAN) ||
+ (piface->pvlan_prop == NULL)) {
+ goto out;
+ }
+ pvlan = piface->pvlan_prop;
+
+ if (pvlan->vlan_type == VLAN_TYPE_802_1_Q) {
+ pvlan8021q = &(pvlan->props.prop_8021q);
+ vid = pvlan8021q->vlan_id;
+ CMSetProperty(instance, "PortVID",
+ (CMPIValue *)&vid, CMPI_uint16);
+
+ str = vlanid_to_connection_name(vid);
+ conn_array = CMNewArray(broker, 1, CMPI_string, &s);
+ if ((s.rc != CMPI_RC_OK) || (str == NULL)) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Error creating Connection "
+ "list and its string");
+ CU_DEBUG("CMNewArray or string creation failed");
+ goto out;
+ }
+ cm_str = CMNewString(broker, str, &s);
+ if (s.rc != CMPI_RC_OK) {
+ CU_DEBUG("Error creating CMPIString");
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Error creating CMPIString for "
+ "BootDevices item");
+
+ goto out;
+ }
+ CMSetArrayElementAt(conn_array, 0, (CMPIValue *)&cm_str,
+ CMPI_string);
+ CMSetProperty(instance, "Connection",
+ (CMPIValue *)&conn_array, CMPI_stringA);
+ hdr = pvlan8021q->reorder_hdr;
+ CMSetProperty(instance, "ReorderHdr",
+ (CMPIValue *)&hdr, CMPI_uint16);
+
+ if ((pvlan8021q->ingress.count > 0) &&
+ (pvlan8021q->ingress.count <= 8)) {
+ ret = vlan_8021q_qos_num_to_str(&ingress,
+ &(pvlan8021q->ingress));
+ if (ret == 1) {
+ CMSetProperty(instance, "VLANQosIngress",
+ (CMPIValue *)ingress, CMPI_chars);
+ } else {
+ CU_DEBUG("failed to generate vlan qos "
+ "string.");
+ }
+ }
+ if ((pvlan8021q->egress.count > 0) &&
+ (pvlan8021q->egress.count <= 8)) {
+ ret = vlan_8021q_qos_num_to_str(&egress,
+ &(pvlan8021q->egress));
+ if (ret == 1) {
+ CMSetProperty(instance, "VLANQosEgress",
+ (CMPIValue *)egress, CMPI_chars);
+ } else {
+ CU_DEBUG("failed to generate vlan qos "
+ "string.");
+ }
+ }
+ vlantype = 1;
+ }
+ CMSetProperty(instance, "VLANType",
+ (CMPIValue *)&vlantype, CMPI_uint16);
+
+out:
+ SAFE_FREE(str);
+ SAFE_FREE(egress);
+ SAFE_FREE(ingress);
+ return 1;
+}
+
+static CMPIStatus add_conn_properties(const CMPIBroker *broker,
+ EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *eth_name, *easd_name;
+ int asret;
+ CMPIArray *array;
+ CMPIString *tmp;
+
+ if (piface->name == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "device name not set");
+ goto out;
+ }
+ if (dest == NULL) {
+ CU_DEBUG("warn: connection dest is NULL.");
+ }
+
+ eth_name = get_ethportsd_name_from_iface(piface->name, EASD_TYPE_EA);
+ asret = asprintf(&easd_name, "%s:%s", prefix, eth_name);
+ CMSetProperty(instance, "Parent",
+ (CMPIValue *)easd_name, CMPI_chars);
+ SAFE_FREE(easd_name);
+ SAFE_FREE(eth_name);
+
+ array = CMNewArray(broker, 1, CMPI_string, &s);
+ tmp = CMNewString(broker, dest, NULL);
+ CMSetArrayElementAt(array, 0, &(tmp), CMPI_string);
+ CMSetProperty(instance, "HostResource",
+ (CMPIValue *)&array, CMPI_stringA);
+
+
+ out:
+ return s;
+}
+
+static CMPIStatus set_properties(const CMPIBroker *broker,
+ EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ int type,
+ CMPIInstance *instance)
+{
+ CMPIStatus s = {CMPI_RC_ERR_FAILED, NULL};
+ char *errstr;
+
+ if (!set_primary_for_easd(broker, prefix, piface, type, 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 (type == EASD_TYPE_EA) {
+ if (!set_secondary_for_easd(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;
+ }
+ } else {
+ s = add_conn_properties(broker,
+ piface,
+ prefix,
+ dest,
+ instance);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ }
+
+ cu_statusf(broker, &s,
+ CMPI_RC_OK,
+ "");
+
+ out:
+ return s;
+}
+
+static CMPIStatus instance_from_easd_build(const CMPIBroker *broker,
+ EthIface *piface,
+ const char *prefix,
+ const char *dest,
+ int type,
+ 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,
+ "EthernetPortAllocationSettingData",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init SwitchSystem 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,
+ dest,
+ type,
+ inst);
+
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+/* vsname and req_type are filter conditions */
+static CMPIStatus instance_from_easd(const CMPIBroker *broker,
+ EthIface *piface,
+ const char *vsname,
+ int req_type,
+ 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;
+
+ CU_DEBUG("enter instance_for_easd with vsname %s, type %d.",
+ vsname, req_type);
+ 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 the EA instance */
+ if (!(req_type&EASD_TYPE_EA)) {
+ goto ea_build_end;
+ }
+ if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br1_name,
+ NULL,
+ EASD_TYPE_EA,
+ 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_easd_build(broker,
+ piface,
+ br2_name,
+ NULL,
+ EASD_TYPE_EA,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ ea_build_end:
+
+ /* building the EC instance */
+ if (!(req_type&EASD_TYPE_EC)) {
+ goto ec_build_end;
+ }
+ if ((br1_name == NULL) || (br2_name == NULL)) {
+ goto ec_build_end;
+ }
+ /* connection exist, so a EC_easd should be added for each bridge */
+ if ((vsname == NULL) || (0 == strcmp(vsname, br1_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br1_name,
+ br2_name,
+ EASD_TYPE_EC,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ if ((vsname == NULL) || (0 == strcmp(vsname, br2_name))) {
+ inst = NULL;
+ s = instance_from_easd_build(broker,
+ piface,
+ br2_name,
+ br1_name,
+ EASD_TYPE_EC,
+ reference,
+ properties,
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(plist, inst);
+ }
+ ec_build_end:
+
+ out:
+ SAFE_FREE(br1_name);
+ SAFE_FREE(br2_name);
+ return s;
+}
+
+CMPIStatus get_easd_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;
+ int type;
+ EthIfacesList ifaces_list;
+ struct inst_list list;
+
+ CU_DEBUG("####prefix %s", prefix);
+ eth_ifaceslist_init(&ifaces_list);
+ inst_list_init(&list);
+
+ eth_name = get_iface_name_from_ethportsd(name, &type);
+ 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("%d ethportd found.", ifaces_list.count);
+ eth_ifaceslist_print(&ifaces_list);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+
+ inst = NULL;
+ s = instance_from_easd(broker,
+ ifaces_list.pifaces[0],
+ prefix,
+ type,
+ 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_easd_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_easd_by_name(broker, prefix, suffix, reference,
+ properties, _inst);
+
+ out:
+ SAFE_FREE(prefix);
+ SAFE_FREE(suffix);
+ return s;
+}
+
+CMPIStatus get_easd_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, "InstanceID", &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_easd_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_easds(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 easd, found following devices.")
+ eth_ifaceslist_print(&ifaces_list);
+
+ i = 0;
+ while (i < ifaces_list.count) {
+ s = instance_from_easd(broker,
+ ifaces_list.pifaces[i],
+ ref_vsname,
+ EASD_TYPE_EA|EASD_TYPE_EC,
+ 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_easds(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_easds(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_easds(_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_easds(_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_easd_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_EASD,
+ _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_EASD.h b/src/Virt_EASD.h
new file mode 100644
index 0000000..215553b
--- /dev/null
+++ b/src/Virt_EASD.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)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_EASD_H
+#define __VIRT_EASD_H
+
+#include "device_parsing.h"
+
+CMPIStatus enum_easds(const CMPIBroker *broker,
+ const char *ref_vsname,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ struct inst_list *plist);
+
+CMPIStatus get_easd_by_name(const CMPIBroker *broker,
+ const char *prefix,
+ const char *name,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_easd_by_id(const CMPIBroker *broker,
+ const char *id,
+ const CMPIObjectPath *reference,
+ const char **properties,
+ CMPIInstance **_inst);
+
+CMPIStatus get_easd_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
2
17
this patch modifies the makefiles to add new files to be compiled
Signed-off-by: Wayne Xia <xiawenc(a)linux.vnet.ibm.com>
---
Makefile.am | 16 ++++++++++++++--
libxkutil/Makefile.am | 11 +++++++++--
src/Makefile.am | 49 +++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 64 insertions(+), 12 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5f004ec..32b84df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -63,7 +63,13 @@ MOFS = \
schema/EntriesInFilterList.mof \
schema/NestedFilterList.mof \
schema/AppliedFilterList.mof \
- schema/HostedFilterList.mof
+ schema/HostedFilterList.mof \
+ schema/VirtualEthernetSwitchSystem.mof \
+ schema/VirtualEthernetSwitchSystemManagementService.mof \
+ schema/VirtualEthernetSwitchSystemSettingData.mof \
+ schema/EthernetPort.mof \
+ schema/EthernetPortAllocationSettingData.mof \
+ schema/VESSSDComponent.mof
INTEROP_MOFS = \
schema/ComputerSystem.mof \
@@ -150,7 +156,13 @@ REGS = \
schema/EntriesInFilterList.registration \
schema/NestedFilterList.registration \
schema/AppliedFilterList.registration \
- schema/HostedFilterList.registration
+ schema/HostedFilterList.registration \
+ schema/VirtualEthernetSwitchSystem.registration \
+ schema/VirtualEthernetSwitchSystemManagementService.registration \
+ schema/VirtualEthernetSwitchSystemSettingData.registration \
+ schema/EthernetPort.registration \
+ schema/EthernetPortAllocationSettingData.registration \
+ schema/VESSSDComponent.registration
INTEROP_REGS = \
schema/RegisteredProfile.registration \
diff --git a/libxkutil/Makefile.am b/libxkutil/Makefile.am
index f6abce5..c5ac53c 100644
--- a/libxkutil/Makefile.am
+++ b/libxkutil/Makefile.am
@@ -5,12 +5,19 @@ AM_CFLAGS = $(CFLAGS_STRICT) \
-DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE@.conf\"
noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h infostore.h \
- pool_parsing.h acl_parsing.h
+ pool_parsing.h acl_parsing.h \
+ network_model.h \
+ host_network_API.h host_network_basic.h host_network_helper.h \
+ host_network_implement_cmdline.h host_network_error.h
lib_LTLIBRARIES = libxkutil.la
libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \
- xmlgen.c infostore.c pool_parsing.c acl_parsing.c
+ xmlgen.c infostore.c pool_parsing.c acl_parsing.c \
+ network_model.c \
+ host_network_API.c host_network_basic.c host_network_helper.c \
+ host_network_implement_cmdline.c
+
libxkutil_la_LDFLAGS = -version-info @VERSION_INFO@
libxkutil_la_LIBADD = @LIBVIRT_LIBS@ \
@LIBUUID_LIBS@
diff --git a/src/Makefile.am b/src/Makefile.am
index e4e8aa1..b067666 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,7 +25,12 @@ noinst_HEADERS = profiles.h svpc_types.h \
Virt_ConsoleRedirectionServiceCapabilities.h \
Virt_KVMRedirectionSAP.h \
Virt_FilterList.h \
- Virt_FilterEntry.h
+ Virt_FilterEntry.h \
+ Virt_VirtualEthernetSwitchSystem.h \
+ Virt_VirtualEthernetSwitchSystemManagementService.h \
+ Virt_VESSSD.h \
+ Virt_EthernetPort.h \
+ Virt_EASD.h
XKUADD = $(top_builddir)/libxkutil/libxkutil.la
@@ -86,7 +91,13 @@ provider_LTLIBRARIES = libVirt_ComputerSystem.la \
libVirt_EntriesInFilterList.la \
libVirt_NestedFilterList.la \
libVirt_HostedFilterList.la \
- libVirt_AppliedFilterList.la
+ libVirt_AppliedFilterList.la \
+ libVirt_VirtualEthernetSwitchSystem.la \
+ libVirt_VirtualEthernetSwitchSystemManagementService.la \
+ libVirt_VESSSD.la \
+ libVirt_EthernetPort.la \
+ libVirt_EASD.la \
+ libVirt_VESSSDComponent.la
libVirt_ComputerSystem_la_SOURCES = Virt_ComputerSystem.c
libVirt_ComputerSystem_la_DEPENDENCIES = libVirt_VirtualSystemSnapshotService.la
@@ -117,9 +128,9 @@ libVirt_VirtualSystemManagementCapabilities_la_DEPENDENCIES = libVirt_HostSystem
libVirt_VirtualSystemManagementCapabilities_la_SOURCES = Virt_VirtualSystemManagementCapabilities.c
libVirt_VirtualSystemManagementCapabilities_la_LIBADD = -lVirt_HostSystem
-libVirt_SystemDevice_la_DEPENDENCIES = libVirt_ComputerSystem.la libVirt_Device.la
+libVirt_SystemDevice_la_DEPENDENCIES = libVirt_ComputerSystem.la libVirt_Device.la libVirt_VirtualEthernetSwitchSystem.la libVirt_EthernetPort.la
libVirt_SystemDevice_la_SOURCES = Virt_SystemDevice.c
-libVirt_SystemDevice_la_LIBADD = -lVirt_ComputerSystem -lVirt_Device
+libVirt_SystemDevice_la_LIBADD = -lVirt_ComputerSystem -lVirt_Device -lVirt_VirtualEthernetSwitchSystem -lVirt_EthernetPort
libVirt_VSSD_la_SOURCES = Virt_VSSD.c
libVirt_HostSystem_la_SOURCES = Virt_HostSystem.c
@@ -188,9 +199,9 @@ libVirt_VSSDComponent_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la
libVirt_VSSDComponent_la_SOURCES = Virt_VSSDComponent.c
libVirt_VSSDComponent_la_LIBADD = -lVirt_VSSD -lVirt_RASD
-libVirt_SettingsDefineState_la_DEPENDENCIES = libVirt_Device.la libVirt_RASD.la libVirt_VSSD.la libVirt_ComputerSystem.la
+libVirt_SettingsDefineState_la_DEPENDENCIES = libVirt_Device.la libVirt_RASD.la libVirt_VSSD.la libVirt_ComputerSystem.la libVirt_VirtualEthernetSwitchSystem.la libVirt_VESSSD.la libVirt_EASD.la libVirt_EthernetPort.la
libVirt_SettingsDefineState_la_SOURCES = Virt_SettingsDefineState.c
-libVirt_SettingsDefineState_la_LIBADD = -lVirt_Device -lVirt_RASD -lVirt_VSSD -lVirt_ComputerSystem
+libVirt_SettingsDefineState_la_LIBADD = -lVirt_Device -lVirt_RASD -lVirt_VSSD -lVirt_ComputerSystem -lVirt_VirtualEthernetSwitchSystem -lVirt_VESSSD -lVirt_EASD -lVirt_EthernetPort
libVirt_ResourceAllocationFromPool_la_DEPENDENCIES = libVirt_DevicePool.la libVirt_RASD.la
libVirt_ResourceAllocationFromPool_la_SOURCES = Virt_ResourceAllocationFromPool.c
@@ -204,9 +215,9 @@ libVirt_HostedService_la_DEPENDENCIES = libVirt_VirtualSystemManagementService.l
libVirt_HostedService_la_SOURCES = Virt_HostedService.c
libVirt_HostedService_la_LIBADD = -lVirt_VirtualSystemManagementService -lVirt_ResourcePoolConfigurationService -lVirt_VSMigrationService -lVirt_HostSystem -lVirt_ConsoleRedirectionService
-libVirt_ElementSettingData_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la
+libVirt_ElementSettingData_la_DEPENDENCIES = libVirt_VSSD.la libVirt_RASD.la libVirt_EASD.la libVirt_VESSSD.la libVirt_EthernetPort.la
libVirt_ElementSettingData_la_SOURCES = Virt_ElementSettingData.c
-libVirt_ElementSettingData_la_LIBADD = -lVirt_VSSD -lVirt_RASD
+libVirt_ElementSettingData_la_LIBADD = -lVirt_VSSD -lVirt_RASD -lVirt_EASD -lVirt_VESSSD -lVirt_EthernetPort
libVirt_VSMigrationCapabilities_la_SOURCES = Virt_VSMigrationCapabilities.c
@@ -275,3 +286,25 @@ libVirt_HostedFilterList_la_LIBADD = -lVirt_HostSystem -lVirt_FilterList
libVirt_AppliedFilterList_la_DEPENDENCIES = libVirt_Device.la libVirt_FilterList.la
libVirt_AppliedFilterList_la_SOURCES = Virt_AppliedFilterList.c
libVirt_AppliedFilterList_la_LIBADD = -lVirt_Device -lVirt_FilterList
+
+libVirt_VirtualEthernetSwitchSystem_la_SOURCES = Virt_VirtualEthernetSwitchSystem.c
+
+libVirt_VESSSD_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la
+libVirt_VESSSD_la_SOURCES = Virt_VESSSD.c
+libVirt_VESSSD_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem
+
+libVirt_EthernetPort_la_DEPENDENCIES = libVirt_EASD.la
+libVirt_EthernetPort_la_SOURCES = Virt_EthernetPort.c
+libVirt_EthernetPort_la_LIBADD = -lVirt_EASD
+
+libVirt_EASD_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la
+libVirt_EASD_la_SOURCES = Virt_EASD.c
+libVirt_EASD_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem
+
+libVirt_VirtualEthernetSwitchSystemManagementService_la_DEPENDENCIES = libVirt_VirtualEthernetSwitchSystem.la libVirt_VESSSD.la libVirt_EASD.la libVirt_HostSystem.la libVirt_VirtualSystemManagementService.la
+libVirt_VirtualEthernetSwitchSystemManagementService_la_SOURCES = Virt_VirtualEthernetSwitchSystemManagementService.c
+libVirt_VirtualEthernetSwitchSystemManagementService_la_LIBADD = -lVirt_VirtualEthernetSwitchSystem -lVirt_VESSSD -lVirt_EASD -lVirt_HostSystem -lVirt_VirtualSystemManagementService
+
+libVirt_VESSSDComponent_la_DEPENDENCIES = libVirt_VESSSD.la libVirt_EASD.la
+libVirt_VESSSDComponent_la_SOURCES = Virt_VESSSDComponent.c
+libVirt_VESSSDComponent_la_LIBADD = -lVirt_VESSSD -lVirt_EASD
--
1.7.6
2
3
These patches would do following things: building up the network system CIM
model, building up basic framework and functions below to implement the
configuration, add the bridge and vlan802.1.q configuration capabilities in
CIM model and library below.
Now this patch implement the functionalities with commandline style, which
means it depends on command ip, ifconfig, brctl and /proc/net/vlan/. In this
way it is very sensitive to these command's output format. Maybe another
implemetion could avoid that in the future.
Since libvirt-cim is not a daemon program that would always be brought up
when the emulator was up, so there lacks a mechnism to save the configuration
and set them when system reboot, so these patch uses system directory
/etc/sysconfig/network-script/
to store the settings.
The things above means that a linux kernel later than 2.6 and RedHat
distribution is needed. Other distriution may work but not tested. If
the implemention goes to libvirt the restrict would be removed.
Related profiles: the most important are DSP1050, DSP1097, DSP 2025(draft),
Other are: DSP1041, DSP1014.
Typical usage: assuming you have pNIC eth0. Use following xml files passed
to wbemexec could create bridge testbr with eth0.10 attached, which means all
VMs connecting to testbr would have access to IEEE802.1.q vlan 10.
XML 1
<?xml version="1.0" encoding="utf-8" ?>
<CIM CIMVERSION="2.0" DTDVERSION="2.0">
<MESSAGE ID="4711" PROTOCOLVERSION="1.0">
<SIMPLEREQ>
<METHODCALL NAME="DefineSystem">
<LOCALINSTANCEPATH>
<LOCALNAMESPACEPATH>
<NAMESPACE NAME="root"></NAMESPACE><NAMESPACE NAME="virt"></NAMESPACE>
</LOCALNAMESPACEPATH>
<INSTANCENAME CLASSNAME="Net_VirtualEthernetSwitchSystemManagementService">
<KEYBINDING NAME="CreationClassName"><KEYVALUE VALUETYPE="string">Net_VirtualEthernetSwitchSystemManagementService</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="Name"><KEYVALUE VALUETYPE="string">Management Service</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="SystemCreationClassName"><KEYVALUE VALUETYPE="string">KVM_HostSystem</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="SystemName"><KEYVALUE VALUETYPE="string">unknown</KEYVALUE></KEYBINDING>
</INSTANCENAME>
</LOCALINSTANCEPATH>
<PARAMVALUE NAME="SystemSettings" PARAMTYPE="string">
<VALUE>
instance of Net_VirtualEthernetSwitchSystemSettingData {
VirtualSystemIdentifier ="VS_testbr1";
STP = 1;
};
</VALUE>
</PARAMVALUE>
</METHODCALL>
</SIMPLEREQ>
</MESSAGE>
</CIM>
XML 2
<?xml version="1.0" encoding="utf-8" ?>
<CIM CIMVERSION="2.0" DTDVERSION="2.0">
<MESSAGE ID="4711" PROTOCOLVERSION="1.0">
<SIMPLEREQ>
<METHODCALL NAME="AddResourceSettings">
<LOCALINSTANCEPATH>
<LOCALNAMESPACEPATH>
<NAMESPACE NAME="root"></NAMESPACE><NAMESPACE NAME="virt"></NAMESPACE>
</LOCALNAMESPACEPATH>
<INSTANCENAME CLASSNAME="Net_VirtualEthernetSwitchSystemManagementService">
<KEYBINDING NAME="CreationClassName"><KEYVALUE VALUETYPE="string">Net_VirtualEthernetSwitchSystemManagementService</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="Name"><KEYVALUE VALUETYPE="string">Management Service</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="SystemCreationClassName"><KEYVALUE VALUETYPE="string">KVM_HostSystem</KEYVALUE></KEYBINDING>
<KEYBINDING NAME="SystemName"><KEYVALUE VALUETYPE="string">unknown</KEYVALUE></KEYBINDING>
</INSTANCENAME>
</LOCALINSTANCEPATH>
<PARAMVALUE NAME="AffectedConfiguration">
<VALUE.REFERENCE>
<INSTANCENAME CLASSNAME="Net_VirtualEthernetSwitchSettingData">
<KEYBINDING NAME="InstanceID"><KEYVALUE VALUETYPE="string">Virt:VS_eth0</KEYVALUE></KEYBINDING>
</INSTANCENAME>
</VALUE.REFERENCE>
</PARAMVALUE>
<PARAMVALUE NAME="ResourceSettings" PARAMTYPE="string">
<VALUE.ARRAY>
<VALUE>
instance of Net_EthernetPortAllocationSettingData {
InstanceID = "VS_eth0/EA_eth0.10";
ElementName = "EA_eth0.10";
VLANType = 1;
Connection = {"VLAN10"};
ReorderHdr = 0;
};
</VALUE>
<VALUE>
instance of Net_EthernetPortAllocationSettingData {
InstanceID = "VS_eth0/EC_eth0.10";
HostResource = {"VS_testbr1"};
Parent = "EA_eth0.10";
};
</VALUE>
</VALUE.ARRAY>
</PARAMVALUE>
</METHODCALL>
</SIMPLEREQ>
</MESSAGE>
</CIM>
Wayne Xia (15):
vlan extension - makefile change
vlan extension - CIM model - add class VESS
vlan extension - CIM model - add class VESSSD
vlan extension - CIM model - add class EthernetPort
vlan extension - CIM model - add class
EthernetPortAllocationSettingData
vlan extension - CIM model - add association Net_SettingsDeineState
vlan extension - CIM model - add association Net_SystemDevice
vlan extension - CIM model - add association Net_VESSSDComponent
vlan extension - CIM model - add association Net_ElementSettingData
vlan extension - CIM model - add core class VESSMS
vlan extension - CIM model - add help functions
vlan extension - function lib - add the API
vlan extension - function lib - add the core structure
vlan extension - function lib - add the helper functions
vlan extension - function lib - add the implemention of commandline
Makefile.am | 16 +-
libxkutil/Makefile.am | 11 +-
libxkutil/host_network_API.c | 150 ++
libxkutil/host_network_API.h | 32 +
libxkutil/host_network_basic.c | 639 +++++++
libxkutil/host_network_basic.h | 166 ++
libxkutil/host_network_error.h | 28 +
libxkutil/host_network_helper.c | 659 +++++++
libxkutil/host_network_helper.h | 192 ++
libxkutil/host_network_implement_cmdline.c | 2002 ++++++++++++++++++++
libxkutil/host_network_implement_cmdline.h | 55 +
libxkutil/network_model.c | 466 +++++
libxkutil/network_model.h | 105 +
schema/ElementSettingData.mof | 16 +-
schema/ElementSettingData.registration | 4 +-
schema/EthernetPort.mof | 4 +
schema/EthernetPort.registration | 3 +
schema/EthernetPortAllocationSettingData.mof | 21 +
.../EthernetPortAllocationSettingData.registration | 3 +
schema/SettingsDefineState.mof | 9 +-
schema/SettingsDefineState.registration | 3 +-
schema/SystemDevice.mof | 18 +-
schema/SystemDevice.registration | 3 +-
schema/VESSSDComponent.mof | 8 +
schema/VESSSDComponent.registration | 3 +
schema/VirtualEthernetSwitchSystem.mof | 10 +
schema/VirtualEthernetSwitchSystem.registration | 3 +
...irtualEthernetSwitchSystemManagementService.mof | 14 +
...ernetSwitchSystemManagementService.registration | 3 +
schema/VirtualEthernetSwitchSystemSettingData.mof | 27 +
...ualEthernetSwitchSystemSettingData.registration | 3 +
src/Makefile.am | 49 +-
src/Virt_EASD.c | 733 +++++++
src/Virt_EASD.h | 61 +
src/Virt_ElementSettingData.c | 229 +++-
src/Virt_EthernetPort.c | 565 ++++++
src/Virt_EthernetPort.h | 58 +
src/Virt_HostSystem.c | 2 +-
src/Virt_HostSystem.h | 2 +
src/Virt_SettingsDefineState.c | 256 +++
src/Virt_SystemDevice.c | 126 ++
src/Virt_VESSSD.c | 372 ++++
src/Virt_VESSSD.h | 39 +
src/Virt_VESSSDComponent.c | 181 ++
src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++
src/Virt_VirtualEthernetSwitchSystem.h | 52 +
..._VirtualEthernetSwitchSystemManagementService.c | 1342 +++++++++++++
..._VirtualEthernetSwitchSystemManagementService.h | 31 +
src/Virt_VirtualSystemManagementService.c | 17 +-
src/Virt_VirtualSystemManagementService.h | 10 +
50 files changed, 9255 insertions(+), 29 deletions(-)
create mode 100644 libxkutil/host_network_API.c
create mode 100644 libxkutil/host_network_API.h
create mode 100644 libxkutil/host_network_basic.c
create mode 100644 libxkutil/host_network_basic.h
create mode 100644 libxkutil/host_network_error.h
create mode 100644 libxkutil/host_network_helper.c
create mode 100644 libxkutil/host_network_helper.h
create mode 100644 libxkutil/host_network_implement_cmdline.c
create mode 100644 libxkutil/host_network_implement_cmdline.h
create mode 100644 libxkutil/network_model.c
create mode 100644 libxkutil/network_model.h
create mode 100644 schema/EthernetPort.mof
create mode 100644 schema/EthernetPort.registration
create mode 100644 schema/EthernetPortAllocationSettingData.mof
create mode 100644 schema/EthernetPortAllocationSettingData.registration
create mode 100644 schema/VESSSDComponent.mof
create mode 100644 schema/VESSSDComponent.registration
create mode 100644 schema/VirtualEthernetSwitchSystem.mof
create mode 100644 schema/VirtualEthernetSwitchSystem.registration
create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.mof
create mode 100644 schema/VirtualEthernetSwitchSystemManagementService.registration
create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.mof
create mode 100644 schema/VirtualEthernetSwitchSystemSettingData.registration
create mode 100644 src/Virt_EASD.c
create mode 100644 src/Virt_EASD.h
create mode 100644 src/Virt_EthernetPort.c
create mode 100644 src/Virt_EthernetPort.h
create mode 100644 src/Virt_VESSSD.c
create mode 100644 src/Virt_VESSSD.h
create mode 100644 src/Virt_VESSSDComponent.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h
create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystemManagementService.h
--
1.7.6
4
6
this patch added the Net_VirtualEthernetSwitchSystem class.
Signed-off-by: Wayne Xia <xiawenc(a)linux.vnet.ibm.com>
---
schema/VirtualEthernetSwitchSystem.mof | 10 +
schema/VirtualEthernetSwitchSystem.registration | 3 +
src/Virt_VirtualEthernetSwitchSystem.c | 483 +++++++++++++++++++++++
src/Virt_VirtualEthernetSwitchSystem.h | 52 +++
4 files changed, 548 insertions(+), 0 deletions(-)
create mode 100644 schema/VirtualEthernetSwitchSystem.mof
create mode 100644 schema/VirtualEthernetSwitchSystem.registration
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.c
create mode 100644 src/Virt_VirtualEthernetSwitchSystem.h
diff --git a/schema/VirtualEthernetSwitchSystem.mof b/schema/VirtualEthernetSwitchSystem.mof
new file mode 100644
index 0000000..5c016fd
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystem.mof
@@ -0,0 +1,10 @@
+// Copyright IBM Corp. 2011
+[Description (
+ "A class derived from CIM_ComputerSystem to represent "
+ "the Virtual Bridge on the host."),
+ Provider("cmpi::Virt_VirtualEthernetSwitchSystem")
+]
+class Net_VirtualEthernetSwitchSystem : CIM_ComputerSystem
+{
+
+};
diff --git a/schema/VirtualEthernetSwitchSystem.registration b/schema/VirtualEthernetSwitchSystem.registration
new file mode 100644
index 0000000..4cd6bf4
--- /dev/null
+++ b/schema/VirtualEthernetSwitchSystem.registration
@@ -0,0 +1,3 @@
+# Copyright IBM Corp. 2007
+# Classname Namespace ProviderName ProviderModule ProviderTypes
+Net_VirtualEthernetSwitchSystem root/virt Virt_VirtualEthernetSwitchSystem Virt_VirtualEthernetSwitchSystem instance method
diff --git a/src/Virt_VirtualEthernetSwitchSystem.c b/src/Virt_VirtualEthernetSwitchSystem.c
new file mode 100644
index 0000000..1998205
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystem.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)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 <unistd.h>
+#include <limits.h>
+
+#include <cmpidt.h>
+#include <cmpift.h>
+#include <cmpimacs.h>
+
+#include <libvirt/libvirt.h>
+
+#include "cs_util.h"
+#include <libcmpiutil/libcmpiutil.h>
+#include "misc_util.h"
+#include "infostore.h"
+#include "device_parsing.h"
+
+#include <libcmpiutil/std_invokemethod.h>
+#include <libcmpiutil/std_instance.h>
+#include <libcmpiutil/std_indication.h>
+
+#include "Virt_VirtualEthernetSwitchSystem.h"
+#include "Virt_HostSystem.h"
+#include "Virt_VirtualSystemSnapshotService.h"
+#include "network_model.h"
+
+static const CMPIBroker *_BROKER;
+
+static int set_primary_for_switch(const CMPIBroker *broker, EthIface *piface,
+ CMPIInstance *instance)
+{
+ char *name;
+ uint16_t dedicated;
+ CMPIArray *array;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+
+ if (piface->name == NULL) {
+ return 0;
+ }
+
+ name = get_switch_name_from_iface(piface->name);
+ CMSetProperty(instance, "Name",
+ (CMPIValue *)name, CMPI_chars);
+ CMSetProperty(instance, "ElementName",
+ (CMPIValue *)name, CMPI_chars);
+ SAFE_FREE(name);
+
+ array = CMNewArray(broker, 1, CMPI_uint16, &s);
+ if ((s.rc != CMPI_RC_OK) || (CMIsNullObject(array))) {
+ return 0;
+ }
+ dedicated = CIM_NUM_SWITCH_DEDICATED;
+ CMSetArrayElementAt(array, 0, &dedicated, CMPI_uint16);
+ CMSetProperty(instance, "Dedicated",
+ (CMPIValue *)&array, CMPI_uint16A);
+
+ return 1;
+}
+
+static int set_secondary_for_switch(const CMPIBroker *broker, EthIface *piface,
+ CMPIInstance *instance)
+{
+ int state;
+ 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);
+
+ return 1;
+}
+
+/* Populate an instance with information from a switch */
+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_switch(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_switch(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_switch(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ EthIface *piface,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ inst = get_typed_instance(broker,
+ NETWORK_CLASS_PREFIX,
+ "VirtualEthernetSwitchSystem",
+ NAMESPACE(reference));
+ if (inst == NULL) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "Unable to init VirtualEthernetSwitchSystem instance");
+ goto out;
+ }
+
+ s = set_properties(broker,
+ piface,
+ NETWORK_CLASS_PREFIX,
+ inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ *_inst = inst;
+
+ out:
+ return s;
+}
+
+CMPIStatus enum_switches(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool names_only)
+{
+ struct inst_list list;
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ EthIfacesList ifaces_list;
+ int ret, i;
+ char *errstr;
+
+ inst_list_init(&list);
+ 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_switch(broker,
+ reference,
+ ifaces_list.pifaces[i],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+ inst_list_add(&list, inst);
+ i++;
+ }
+
+ if (names_only) {
+ cu_return_instance_names(results, &list);
+ } else {
+ cu_return_instances(results, &list);
+ }
+
+ out:
+ inst_list_free(&list);
+ eth_ifaceslist_uninit(&ifaces_list);
+
+ return s;
+}
+
+CMPIStatus get_switch_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;
+ 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_switch(broker,
+ reference,
+ ifaces_list.pifaces[0],
+ &inst);
+ if (s.rc != CMPI_RC_OK) {
+ goto out;
+ }
+
+ *_inst = inst;
+
+ out:
+ eth_ifaceslist_uninit(&ifaces_list);
+ SAFE_FREE(eth_name);
+ return s;
+}
+
+CMPIStatus get_switch_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+ const char *name = NULL;
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ "No domain name specified");
+ goto out;
+ }
+
+ s = get_switch_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:
+
+ return s;
+}
+
+static CMPIStatus __state_change(const CMPIBroker *broker,
+ const char *name,
+ uint16_t state,
+ const CMPIObjectPath *ref)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ EthIface iface;
+ int iface_state;
+ int ret;
+ char *errstr;
+
+ eth_iface_init(&iface);
+ iface.name = get_iface_name_from_switch(name);
+ if (iface.name == NULL) {
+ errstr = "failed to get iface name.";
+ CU_DEBUG("for %s, %s.", name, errstr);
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_FAILED,
+ errstr);
+ goto out;
+ }
+ if (state == CIM_STATE_ENABLED) {
+ iface_state = ETH_STATE_UP;
+ } else if (state == CIM_STATE_DISABLED) {
+ iface_state = ETH_STATE_DOWN;
+ } else {
+ cu_statusf(broker, &s,
+ CMPI_RC_ERR_NOT_SUPPORTED,
+ "State not supported");
+ goto out;
+ }
+
+ ret = change_state_host_iface(&iface, iface_state);
+ 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;
+ }
+
+
+ out:
+ eth_iface_uninit(&iface);
+ return s;
+}
+
+static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference)
+{
+ return enum_switches(_BROKER, reference, results, true);
+}
+
+static CMPIStatus EnumInstances(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ return enum_switches(_BROKER, reference, results, false);
+}
+
+static CMPIStatus GetInstance(CMPIInstanceMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const char **properties)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ CMPIInstance *inst = NULL;
+
+ s = get_switch_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();
+
+static CMPIStatus state_change(CMPIMethodMI *self,
+ const CMPIContext *context,
+ const CMPIResult *results,
+ const CMPIObjectPath *reference,
+ const CMPIArgs *argsin,
+ CMPIArgs *argsout)
+{
+ CMPIStatus s;
+ CMPIInstance *prev_inst = NULL;
+ uint16_t state;
+ int ret;
+ const char *name = NULL;
+ uint32_t rc = 1;
+
+ ret = cu_get_u16_arg(argsin, "RequestedState", &state);
+ if (ret != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Invalid RequestedState");
+ goto out;
+ }
+
+ if (cu_get_str_path(reference, "Name", &name) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Name key not specified");
+ goto out;
+ }
+
+ s = get_switch_by_name(_BROKER, name, reference, &prev_inst);
+ if (s.rc != CMPI_RC_OK || prev_inst == NULL) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_INVALID_PARAMETER,
+ "Unable to get instance for guest '%s'",
+ name);
+ goto out;
+ }
+
+ s = __state_change(_BROKER, name, state, reference);
+
+ if (s.rc == CMPI_RC_OK) {
+ rc = 0;
+ }
+ out:
+ CMReturnData(results, &rc, CMPI_uint32);
+
+ return s;
+}
+
+STD_InstanceMIStub(,
+ Virt_VirtualEthernetSwitchSystem,
+ _BROKER,
+ libvirt_cim_init());
+
+static struct method_handler RequestStateChange = {
+ .name = "RequestStateChange",
+ .handler = state_change,
+ .args = {{"RequestedState", CMPI_uint16, false},
+ {"TimeoutPeriod", CMPI_dateTime, true},
+ ARG_END
+ }
+};
+
+static struct method_handler *my_handlers[] = {
+ &RequestStateChange,
+ NULL
+};
+
+STDIM_MethodMIStub(,
+ Virt_VirtualEthernetSwitchSystem,
+ _BROKER,
+ libvirt_cim_init(),
+ my_handlers);
+
+/*
+ * 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_VirtualEthernetSwitchSystem.h b/src/Virt_VirtualEthernetSwitchSystem.h
new file mode 100644
index 0000000..de8587b
--- /dev/null
+++ b/src/Virt_VirtualEthernetSwitchSystem.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)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_VIRTUALETHERNETSWITCHSYSTEM_H
+#define __VIRT_VIRTUALETHERNETSWITCHSYSTEM_H
+
+#include "misc_util.h"
+
+CMPIStatus enum_switches(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ const CMPIResult *results,
+ bool names_only);
+
+CMPIStatus get_switch_by_ref(const CMPIBroker *broker,
+ const CMPIObjectPath *reference,
+ CMPIInstance **_inst);
+
+
+CMPIStatus get_switch_by_name(const CMPIBroker *broker,
+ const char *name,
+ const CMPIObjectPath *reference,
+ 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
2
2