[PATCH] [TEST] Fix VSMS 09_procrasd_persist and 11_define_memrasdunits
by Eduardo Lima (Etrunko)
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
Both tests were failing due to reusing an instance of the class for defining
domains in a loop. The error message was the following:
ERROR - Got CIM error CIM_ERR_FAILED: ResourceSettings Error: VirtualDevice
property must be unique for each DiskResourceAllocationSettingData in a
single guest with return code 1
A recent change in XenKvmLib/vxml.py necessary for the new test
32_modify_cdrom_media.py triggered this bug. To avoid this error we simply
create a new instance of that class in each iteration of the loop.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
.../09_procrasd_persist.py | 3 ++-
.../11_define_memrasdunits.py | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
index 91415dd..a53c5ac 100644
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
@@ -119,11 +119,12 @@ def main():
virt = options.virt
server = options.ip
- cxml = get_class(virt)(test_dom)
+ cxml = None
prasd_cn = get_typed_class(virt, "ProcResourceAllocationSettingData")
dom_define = dom_start = False
try:
for count in range(3):
+ cxml = get_class(virt)(test_dom)
status = setup_guest(server, virt, cxml, prasd_cn)
if status != PASS:
return status
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/11_define_memrasdunits.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/11_define_memrasdunits.py
index 8c032c2..3f54ff4 100644
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/11_define_memrasdunits.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/11_define_memrasdunits.py
@@ -113,8 +113,7 @@ def check_value(options):
def main():
options = main.options
- cxml = get_class(options.virt)(default_dom)
-
+ cxml = None
status = FAIL
guest_is_undefined = None
@@ -123,6 +122,7 @@ def main():
value = mem_bytes >> shift
+ cxml = get_class(options.virt)(default_dom)
status = try_define(options, units, value, cxml)
if status != PASS:
break
--
1.7.4.4
12 years, 11 months
Error doing make install for libvirt-cim
by Deepak Shetty
Hi,
I am getting the following error while doing ' make install' for
libvirt-cim. Can someone pls help provide some pointers on what could be
wrong here ?
....
....
test -z "/home/dpkshetty/usr/lib/cmpi" || /bin/mkdir -p
"/home/dpkshetty/usr/lib/cmpi"
/bin/bash ../libtool --mode=install /usr/bin/install -c
libVirt_ComputerSystem.la libVirt_Device.la libVirt_RASD.la
libVirt_HostSystem.la libVirt_VSSD.la
libVirt_EnabledLogicalElementCapabilities.la libVirt_DevicePool.la
libVirt_RegisteredProfile.la libVirt_VSMigrationCapabilities.la
libVirt_VSMigrationSettingData.la
libVirt_VirtualSystemSnapshotServiceCapabilities.la libVirt_SystemDevice.la
libVirt_ComputerSystemIndication.la
libVirt_ResourceAllocationSettingDataIndication.la libVirt_SwitchService.la
libVirt_ComputerSystemMigrationIndication.la
libVirt_VirtualSystemManagementCapabilities.la
libVirt_AllocationCapabilities.la libVirt_ReferencedProfile.la
libVirt_VirtualSystemSnapshotService.la
libVirt_VirtualSystemManagementService.la
libVirt_ResourcePoolConfigurationService.la
libVirt_ResourcePoolConfigurationCapabilities.la
libVirt_VSMigrationService.la libVirt_ConsoleRedirectionService.la
libVirt_ConsoleRedirectionServiceCapabilities.la
libVirt_KVMRedirectionSAP.la libVirt_SettingsDefineCapabilities.la
libVirt_HostedDependency.la libVirt_ElementConformsToProfile.la
libVirt_HostedResourcePool.la libVirt_ElementCapabilities.la
libVirt_VSSDComponent.la libVirt_SettingsDefineState.la
libVirt_ResourceAllocationFromPool.la libVirt_ElementAllocatedFromPool.la
libVirt_HostedService.la libVirt_ElementSettingData.la
libVirt_ConcreteComponent.la libVirt_ServiceAffectsElement.la
libVirt_HostedAccessPoint.la libVirt_ServiceAccessBySAP.la
libVirt_SAPAvailableForElement.la libVirt_FilterList.la
libVirt_FilterEntry.la libVirt_EntriesInFilterList.la
libVirt_NestedFilterList.la libVirt_HostedFilterList.la
libVirt_AppliedFilterList.la '/home/dpkshetty/usr/lib/cmpi'
*libtool: install: warning: relinking `libVirt_ComputerSystem.la'*
libtool: install: (cd /home/dpkshetty/work/libvirt-cim/libvirt-cim/src;
/bin/bash /home/dpkshetty/work/libvirt-cim/libvirt-cim/libtool --silent
--tag CC --mode=relink gcc -g -O2 -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE
-D_LARGEFILE64_SOURCE -Wall -Wmissing-prototypes -Wmissing-declarations
-Wstrict-prototypes -Wpointer-arith -Wformat=2 -Wformat-security
-Wformat-nonliteral -Wno-format-y2k -Wcast-align -Wno-unused-value
-DLIBVIRT_CIM_CS=\"2714b9a5e842\" -DLIBVIRT_CIM_RV=\"1151\" -I../libxkutil
../libxkutil/libxkutil.la -version-info 5:14:5 -L/home/dpkshetty/usr/lib
-lvirt -ldl -L/home/dpkshetty/usr/lib -lcmpiutil -L/usr/lib/i386-linux-gnu
-luuid -o libVirt_ComputerSystem.la -rpath /home/dpkshetty/usr/lib/cmpi
Virt_ComputerSystem.lo -lVirt_VirtualSystemSnapshotService )
*/usr/bin/ld: cannot find -lVirt_VirtualSystemSnapshotService*
collect2: ld returned 1 exit status
libtool: install: error: relink `libVirt_ComputerSystem.la' with the above
command before installing it
make[2]: *** [install-providerLTLIBRARIES] Error 1
make[2]: Leaving directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/src'
make[1]: *** [install-am] Error 2
make[1]: Leaving directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/src'
make: *** [install-recursive] Error 1
13 years
[PATCH] Avoid connection to libvirt if previous attempt fails
by Eduardo Lima (Etrunko)
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
This is a workaround to avoid libvirt flooding error messages in syslog. This
happens often if a client submits queries for CIM_ superclasses, which then will
translate to a query for each registered class. In our case KVM_, LXC_ and XEN_.
Ideally, there should be a way to ask libvirt if a given URI or hypervisor is
enabled/supported. A patch for that feature is on the works, and as soon as it
is integrated to libvirt tree this feature will be updated.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
libxkutil/misc_util.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c
index c2cc204..61893c3 100644
--- a/libxkutil/misc_util.c
+++ b/libxkutil/misc_util.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
@@ -53,6 +54,46 @@ static int libvirt_initialized = 0;
#define URI_ENV "HYPURI"
+struct _hypervisor_status_t {
+ const char *name;
+ bool enabled;
+};
+
+typedef struct _hypervisor_status_t hypervisor_status_t;
+
+static hypervisor_status_t hypervisor_list[] = {
+ { "xen", true },
+ { "kvm", true },
+ { "lxc", true },
+ { NULL },
+};
+
+static bool get_hypervisor_enabled(const char *hypervisor)
+{
+ hypervisor_status_t *h;
+
+ for (h = &hypervisor_list[0]; h != NULL; h++) {
+ if (strncasecmp(hypervisor, h->name, strlen(h->name)) == 0) {
+ return h->enabled;
+ }
+ }
+
+ return false;
+}
+
+static void set_hypervisor_disabled(const char *hypervisor)
+{
+ hypervisor_status_t *h;
+
+ for (h = &hypervisor_list[0]; h != NULL; h++) {
+ if (strncasecmp(hypervisor, h->name, strlen(h->name)) == 0) {
+ CU_DEBUG("Setting '%s' hypervisor as DISABLED", h->name);
+ h->enabled = false;
+ return;
+ }
+ }
+}
+
static const char *cn_to_uri(const char *classname)
{
if (STARTS_WITH(classname, "Xen"))
@@ -117,6 +158,9 @@ virConnectPtr connect_by_classname(const CMPIBroker *broker,
return NULL;
}
+ if (!get_hypervisor_enabled(classname))
+ return NULL;
+
CU_DEBUG("Connecting to libvirt with uri `%s'", uri);
pthread_mutex_lock(&libvirt_mutex);
@@ -129,6 +173,10 @@ virConnectPtr connect_by_classname(const CMPIBroker *broker,
pthread_mutex_unlock(&libvirt_mutex);
if (!conn) {
+ virErrorPtr error = virGetLastError();
+ if (error->code == VIR_ERR_NO_CONNECT)
+ set_hypervisor_disabled(classname);
+
CU_DEBUG("Unable to connect to `%s'", uri);
return NULL;
}
--
1.7.4.4
13 years
[PATCHv2] [TEST] Fix syntax errors, small tweaks
by Eduardo Lima (Etrunko)
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py:
- Unecessary virt param
suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py:
- Undefined symbols XFAIL, SKIP
suites/libvirt-cim/main.py
- options referenced in except block without being defined
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
.../08_modifyresource.py | 8 ++++----
.../31_unset_netrasd.py | 2 +-
suites/libvirt-cim/main.py | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
index 6661ef3..df58d1f 100644
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/08_modifyresource.py
@@ -47,7 +47,7 @@ new_mac1 = "11:%s:22:%s:33:%s" % (new_int, new_int, new_int)
new_int += 1
new_mac2 = "11:%s:22:%s:33:%s" % (new_int, new_int, new_int)
-def cleanup_env(ip, virt, cxml):
+def cleanup_env(ip, cxml):
cxml.destroy(ip)
cxml.undefine(ip)
@@ -82,13 +82,13 @@ def main():
ret = cxml.cim_define(options.ip)
if not ret:
logger.error("Failed to define the dom: %s", default_dom)
- cleanup_env(options.ip, options.virt, cxml)
+ cleanup_env(options.ip, cxml)
return FAIL
if case == "start":
ret = cxml.start(options.ip)
if not ret:
logger.error("Failed to start the dom: %s", default_dom)
- cleanup_env(options.ip, options.virt, cxml)
+ cleanup_env(options.ip, cxml)
return FAIL
status = vsms_util.mod_vcpu_res(options.ip, service, cxml, pasd, ncpu,
@@ -114,7 +114,7 @@ def main():
if status != PASS:
break
- cleanup_env(options.ip, options.virt, cxml)
+ cleanup_env(options.ip, cxml)
return status
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
index 417ad7f..9c78eb8 100755
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/31_unset_netrasd.py
@@ -28,7 +28,7 @@
import sys
import pywbem
-from CimTest.ReturnCodes import PASS, FAIL
+from CimTest.ReturnCodes import PASS, FAIL, XFAIL, SKIP
from CimTest.Globals import logger, CIM_USER, CIM_PASS, CIM_NS
from XenKvmLib.const import do_main
from XenKvmLib.classes import get_typed_class
diff --git a/suites/libvirt-cim/main.py b/suites/libvirt-cim/main.py
index 4e7d621..a4e33e6 100644
--- a/suites/libvirt-cim/main.py
+++ b/suites/libvirt-cim/main.py
@@ -306,8 +306,8 @@ def main(options, args):
if __name__ == '__main__':
ret = -1
+ options, args = parser.parse_args()
try:
- options, args = parser.parse_args()
ret = main(options, args)
except (KeyboardInterrupt, SystemExit):
print "\nKeyboardInterrupt. Cleaning up..."
--
1.7.4.4
13 years
[PATCH] [TEST] Fix syntax errors in VSMS/09_procrasd_persist.py
by eblima@linux.vnet.ibm.com
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
Traceback (most recent call last):
File "/usr/lib64/python2.7/logging/__init__.py", line 838, in emit
msg = self.format(record)
File "/usr/lib64/python2.7/logging/__init__.py", line 715, in format
return fmt.format(record)
File "/usr/lib64/python2.7/logging/__init__.py", line 464, in format
record.message = record.getMessage()
File "/usr/lib64/python2.7/logging/__init__.py", line 328, in getMessage
msg = msg % self.args
TypeError: %d format: a number is required, not NoneType
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
.../09_procrasd_persist.py | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
index cc5b71b..91415dd 100644
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/09_procrasd_persist.py
@@ -91,19 +91,19 @@ def check_proc_sched(server, virt, cn_name):
return FAIL
if proc_rasd["VirtualQuantity"] != nvcpu and virt != 'KVM':
- logger.error("VirtualQuantity is %i, expected %i",
+ logger.error("VirtualQuantity is %s, expected %s",
proc_rasd["VirtualQuantity"], nvcpu)
return FAIL
elif proc_rasd["VirtualQuantity"] != nvcpu and virt == "KVM":
return XFAIL_RC(libvirt_bug)
if proc_rasd["Limit"] != limit:
- logger.error("Limit is %i, expected %i",
+ logger.error("Limit is %s, expected %s",
proc_rasd["Limit"], limit)
return FAIL
if proc_rasd["Weight"] != weight:
- logger.error("Weight is %i, expected %i",
+ logger.error("Weight is %s, expected %s",
proc_rasd["Weight"], weight)
return FAIL
--
1.7.4.4
13 years
[PATCH] [TEST] Fix VSMS/32_modify_cdrom_media.py
by eblima@linux.vnet.ibm.com
From: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
This test depended on some modifications in the core classes that resulted in
many other tests failing. This patch fixed this issue by moving the necessary
bits to the testcase itself.
Signed-off-by: Eduardo Lima (Etrunko) <eblima(a)br.ibm.com>
---
.../32_modify_cdrom_media.py | 16 +++++++++++++++-
suites/libvirt-cim/lib/XenKvmLib/vxml.py | 17 +++--------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
index 9b42831..ff9d034 100755
--- a/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
+++ b/suites/libvirt-cim/cimtest/VirtualSystemManagementService/32_modify_cdrom_media.py
@@ -32,9 +32,10 @@ import pywbem
from CimTest.ReturnCodes import PASS, FAIL, XFAIL, SKIP
from CimTest.Globals import logger, CIM_USER, CIM_PASS, CIM_NS
-from XenKvmLib.const import do_main, _image_dir
+from XenKvmLib.const import do_main, _image_dir, KVM_default_cdrom_dev
from XenKvmLib.classes import get_typed_class
from XenKvmLib.vxml import get_class
+from XenKvmLib import vsms
supported = ['KVM',]
@@ -49,6 +50,19 @@ class CIMDomain(object):
self.server = server
self.virt = virt
self._domain = get_class(virt)(name)
+
+ # CIM Instance for cdrom
+ dasd = vsms.get_dasd_class(virt)
+ cdrom_dasd = dasd(dev=KVM_default_cdrom_dev, source="",
+ name=name, emu_type=1)
+ self._domain.res_settings.append(str(cdrom_dasd))
+
+ # cdrom XML description
+ devices = self._domain.get_node('/domain/devices')
+ cdrom = self._domain.add_sub_node(devices, 'disk', type='file',
+ device='cdrom')
+ self._domain.add_sub_node(cdrom, 'source', file="")
+ self._domain.add_sub_node(cdrom, 'target', dev=KVM_default_cdrom_dev)
#__init__
def define(self):
diff --git a/suites/libvirt-cim/lib/XenKvmLib/vxml.py b/suites/libvirt-cim/lib/XenKvmLib/vxml.py
index 6790036..15859c1 100644
--- a/suites/libvirt-cim/lib/XenKvmLib/vxml.py
+++ b/suites/libvirt-cim/lib/XenKvmLib/vxml.py
@@ -628,17 +628,13 @@ class VirtCIM:
self.iasd = vsms.get_iasd_class(virt)(name=dom_name,
res_sub_type=irstype,
bus_type=btype)
- if virt == "KVM":
- dasd = vsms.get_dasd_class(virt)
- self.cdrom_dasd = dasd(dev=const.KVM_default_cdrom_dev,
- source="",
- name=dom_name,
- emu_type=1)
+ self.res_settings = []
+
def cim_define(self, ip, ref_conf=None):
service = vsms.get_vsms_class(self.virt)(ip)
sys_settings = str(self.vssd)
- res_settings = []
+ res_settings = self.res_settings
if self.dasd is not None:
res_settings.append(str(self.dasd))
if self.pasd is not None:
@@ -651,10 +647,6 @@ class VirtCIM:
else:
res_settings.append(str(self.nasd))
- # CDROM device
- if self.virt == "KVM":
- res_settings.append(str(self.cdrom_dasd))
-
curr_cim_rev, changeset = get_provider_version(self.virt, ip)
if curr_cim_rev >= vsms_graphics_sup:
if self.gasd is not None:
@@ -952,9 +944,6 @@ class KVMXML(VirtXML, VirtCIM):
self.add_sub_node(disk, 'source', file=disk_img)
self.add_sub_node(disk, 'target', dev=disk_dev)
- cdrom = self.add_sub_node(devices, 'disk', type='file', device='cdrom')
- self.add_sub_node(cdrom, 'source', file="")
- self.add_sub_node(cdrom, 'target', dev=const.KVM_default_cdrom_dev)
self.add_sub_node(devices, 'input', type='mouse', bus='ps2')
self.add_sub_node(devices, 'graphics', type='vnc', port='5900',
--
1.7.4.4
13 years
[PATCH] Fix qos bug when retrieving SettingsDefineCapabilites RASDs for primordial Network/0 pool
by Gareth S. Bestor
# HG changeset patch
# User Gareth S. Bestor <bestor(a)us.ibm.com>
# Date 1320049754 25200
# Node ID e1660ac9b5fc44b863b438b6b483edf66784453e
# Parent 862bcd60ae449932205b15ba42b37e06e6834de4
Fix qos bug when retrieving SettingsDefineCapabilites RASDs for primordial Network/0 pool
For some reason, when retreiving at SettingsDefinesCapabilites for only the
primordial network pool 'Network/0' the qos code is called for the
'Minimum' RASDs (?!), which because the associated ID is a constant causes
the string substitution code for renaming the qos 'Point/...' RASDs to
crash. This patch fixes this qos code so that the InstanceID string is only
manipulated for Point RASDs.
"Signed-off-by: Gareth S. Bestor <bestor(a)us.ibm.com>"
diff -r 862bcd60ae44 -r e1660ac9b5fc src/Virt_SettingsDefineCapabilities.c
--- a/src/Virt_SettingsDefineCapabilities.c Wed Oct 26 03:41:56 2011 -0700
+++ b/src/Virt_SettingsDefineCapabilities.c Mon Oct 31 01:29:14 2011 -0700
@@ -756,34 +756,37 @@
if ((inst == NULL) || (s.rc != CMPI_RC_OK))
goto out;
+ if (strncmp("Point", id, 5) != 0)
+ CMSetProperty(inst, "InstanceID", (CMPIValue *)id, CMPI_chars);
+ else {
+ tmp_str = strtok(id, " ");
+ if (tmp_str == NULL) {
+ CU_DEBUG("Cannot set InstanceID");
+ goto out;
+ }
- tmp_str = strtok(id, " ");
- if (tmp_str == NULL) {
- CU_DEBUG("Cannot set InstanceID");
- goto out;
+ CU_DEBUG("InstanceID = %s", tmp_str);
+
+ CMSetProperty(inst, "InstanceID", (CMPIValue *)tmp_str,
+ CMPI_chars);
+ tmp_str = strtok('\0', " ");
+ if (tmp_str == NULL) {
+ CU_DEBUG("Cannot set Reservation");
+ goto out;
+ }
+
+ CU_DEBUG("Reservation = %s", tmp_str);
+
+ uint64_t val = atoi(tmp_str);
+
+ CMSetProperty(inst, "Reservation",
+ (CMPIValue *)&val, CMPI_uint64);
+
+ CMSetProperty(inst, "AllocationUnits",
+ (CMPIValue *)"Kilobits per Second",
+ CMPI_chars);
}
- CU_DEBUG("InstanceID = %s", tmp_str);
-
- CMSetProperty(inst, "InstanceID", (CMPIValue *)tmp_str,
- CMPI_chars);
- tmp_str = strtok('\0', " ");
- if (tmp_str == NULL) {
- CU_DEBUG("Cannot set Reservation");
- goto out;
- }
-
- CU_DEBUG("Reservation = %s", tmp_str);
-
- uint64_t val = atoi(tmp_str);
-
- CMSetProperty(inst, "Reservation",
- (CMPIValue *)&val, CMPI_uint64);
-
- CMSetProperty(inst, "AllocationUnits",
- (CMPIValue *)"Kilobits per Second",
- CMPI_chars);
-
CMSetProperty(inst, "Address",
(CMPIValue *)addr, CMPI_chars);
13 years
Unable to compile libvirt-cim : getting libgcrypt.la error
by Deepak Shetty
Hi,
I am getting the below error in trying to compile libvirt-cim
I m on a Ubuntu 11.04 desktop system.
dpkshetty@deepak-ThinkPad-T60p:~/work/libvirt-cim/libvirt-cim$ make
make all-recursive
make[1]: Entering directory `/home/dpkshetty/work/libvirt-cim/libvirt-cim'
Making all in libxkutil
make[2]: Entering directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil'
Making all in tests
make[3]: Entering directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil/tests'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil/tests'
make[3]: Entering directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil'
CC cs_util_instance.lo
CC misc_util.lo
CC device_parsing.lo
CC xmlgen.lo
CC infostore.lo
CC pool_parsing.lo
CC acl_parsing.lo
CCLD libxkutil.la
/bin/sed: can't read /lib/i386-linux-gnu/libgcrypt.la: No such file or
directory
libtool: link: `/lib/i386-linux-gnu/libgcrypt.la' is not a valid libtool
archive
make[3]: *** [libxkutil.la] Error 1
make[3]: Leaving directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory
`/home/dpkshetty/work/libvirt-cim/libvirt-cim/libxkutil'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/dpkshetty/work/libvirt-cim/libvirt-cim'
make: *** [all] Error 2
It first looked like the problem mentioned here @
https://bugs.launchpad.net/ubuntu/+source/libgcrypt11/+bug/751142
But trying to update libgcrypt via apt-get says I already have the latest
library installed and apt-get does nothing.
I also put this obs and some workarounds I tried to get over this issue in
the launchpad defect, hoping to see some response.
I would like to know if anybody can point me to what i am missing
thanx,
deepak
13 years
[PATCH] Patch to add network qos (bandwidth) support for KVM guests using tc
by Gareth S. Bestor
# HG changeset patch
# User Gareth S. Bestor <bestor(a)us.ibm.com>
# Date 1319625716 25200
# Node ID 862bcd60ae449932205b15ba42b37e06e6834de4
# Parent 2714b9a5e842cc1e8c2ae182c2adef083cc1ef1a
Patch to add network qos (bandwidth) support for KVM guests using tc
This patch adds network qos support into libvirt-cim for setting network
bandwidth limits on KVM guests' MAC addrs, using existing tc (traffic control)
host support. Patch is a bit hack-ish because it is mostly for older versions
of libvirt which do not have any qos support in libvirt itself. I am finishing
a new, and cleaner, patch to libvirt-cim that will exploit the native support
for qos present in latest libvirt versions.
Patch is a bit ugly because (1) it must manage all the qos data associated with
KVM guest's network device completely *outside* of libvirt (since no support
and existing mgmt data available to handle this in older libvirts).
And (2) because the tc commands themselves needed to query, retreive, add and
delete tc bandwidth setting for a MAC addr are themselves quite messy scripts.
This patch assume all the necessary tc performance classes have been setup
externally.
Because it must screen-scrape tc command output to get
performance class and associated bandwith values, this patch will be very
sensitive to change in output format of tc commands. It has been tested
successfully on RHEL6.1.
I dont not recommend exploiting this new feature unless you know
what you are doing...
Signed-off-by: Gareth Bestor <bestor(a)us.ibm.com>
diff -r 2714b9a5e842 -r 862bcd60ae44 src/Virt_RASD.c
--- a/src/Virt_RASD.c Mon Oct 03 02:51:26 2011 -0700
+++ b/src/Virt_RASD.c Wed Oct 26 03:41:56 2011 -0700
@@ -39,6 +39,16 @@
#include "svpc_types.h"
#include "Virt_Device.h"
+/* 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)\
+{m1=substr($24,1,2);m2=substr($24,3,2);m3=substr($24,5,2);m4=substr($24,7,2);\
+m5=substr($20,1,2);m6=substr($20,3,2);printf(\"%%s:%%s:%%s:%%s:%%s:%%s %%s\\n\",\
+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"
+
const static CMPIBroker *_BROKER;
static struct virt_device *_find_dev(struct virt_device *list,
@@ -449,7 +459,11 @@
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",
@@ -467,6 +481,33 @@
(CMPIValue *)dev->dev.net.source,
CMPI_chars);
+ /* Network QoS support */
+ if ((dev->dev.net.mac != NULL) && (dev->dev.net.source != NULL)) {
+ /* Get tc performance class bandwidth for this MAC addr */
+ i = asprintf(&cmd, QOSCMD_MAC2BANDWIDTH, dev->dev.net.source,
+ dev->dev.net.source,
+ dev->dev.net.mac,
+ dev->dev.net.source);
+ if (i == -1)
+ goto out;
+
+ if ((pipe = popen(cmd, "r")) != NULL) {
+ if (fscanf(pipe, "%u", (unsigned int *)&val) == 1) {
+ CU_DEBUG("pipe read. val = %d", val);
+
+ CMSetProperty(inst,
+ "Reservation",
+ (CMPIValue *)&val, CMPI_uint64);
+ CMSetProperty(inst,
+ "AllocationUnits",
+ (CMPIValue *)"KiloBits per Second",
+ CMPI_chars);
+ }
+ pclose(pipe);
+ }
+ free(cmd);
+ }
+
if ((dev->dev.net.source != NULL) &&
(STREQ(dev->dev.net.type, "direct")))
CMSetProperty(inst,
@@ -498,6 +539,7 @@
(CMPIValue *)dev->dev.net.poolid,
CMPI_chars);
+out:
return s;
}
diff -r 2714b9a5e842 -r 862bcd60ae44 src/Virt_SettingsDefineCapabilities.c
--- a/src/Virt_SettingsDefineCapabilities.c Mon Oct 03 02:51:26 2011 -0700
+++ b/src/Virt_SettingsDefineCapabilities.c Wed Oct 26 03:41:56 2011 -0700
@@ -73,6 +73,11 @@
#define POOL_RASD 1
#define NEW_VOL_RASD 2
+/* QoS Network support */
+#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"
+
static bool system_has_vt(virConnectPtr conn)
{
char *caps = NULL;
@@ -726,7 +731,7 @@
}
static CMPIStatus set_net_pool_props(const CMPIObjectPath *ref,
- const char *id,
+ char *id,
uint16_t pool_type,
struct inst_list *list)
{
@@ -738,6 +743,7 @@
const char *ip_stop = "192.168.122.254";
int dev_count;
int i;
+ char *tmp_str = NULL;
/* Isolated network pools don't have a forward device */
if (pool_type == NETPOOL_FORWARD_NONE)
@@ -750,7 +756,33 @@
if ((inst == NULL) || (s.rc != CMPI_RC_OK))
goto out;
- CMSetProperty(inst, "InstanceID", (CMPIValue *)id, CMPI_chars);
+
+ tmp_str = strtok(id, " ");
+ if (tmp_str == NULL) {
+ CU_DEBUG("Cannot set InstanceID");
+ goto out;
+ }
+
+ CU_DEBUG("InstanceID = %s", tmp_str);
+
+ CMSetProperty(inst, "InstanceID", (CMPIValue *)tmp_str,
+ CMPI_chars);
+ tmp_str = strtok('\0', " ");
+ if (tmp_str == NULL) {
+ CU_DEBUG("Cannot set Reservation");
+ goto out;
+ }
+
+ CU_DEBUG("Reservation = %s", tmp_str);
+
+ uint64_t val = atoi(tmp_str);
+
+ CMSetProperty(inst, "Reservation",
+ (CMPIValue *)&val, CMPI_uint64);
+
+ CMSetProperty(inst, "AllocationUnits",
+ (CMPIValue *)"Kilobits per Second",
+ CMPI_chars);
CMSetProperty(inst, "Address",
(CMPIValue *)addr, CMPI_chars);
@@ -779,11 +811,112 @@
return s;
}
+static char * get_bridge_name(virConnectPtr conn, const char *name)
+{
+ char *bridge = NULL;
+ virNetworkPtr network = NULL;
+
+ if (++name == NULL)
+ goto out;
+
+ CU_DEBUG("looking for network `%s'", name);
+ network = virNetworkLookupByName(conn, name);
+ if (network == NULL) {
+ CU_DEBUG("Could not find network");
+ goto out;
+ }
+
+ bridge = virNetworkGetBridgeName(network);
+ if (bridge == NULL) {
+ CU_DEBUG("Could not find bridge");
+ }
+
+ virNetworkFree(network);
+
+ out:
+ return bridge;
+}
+
+/* QoS Network support */
+static CMPIStatus qos_hack(
+ const CMPIObjectPath *ref,
+ struct inst_list *list)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ virConnectPtr conn = NULL;
+ FILE *pipe = NULL;
+ char buffer[1024];
+ char *bridge = NULL;
+ char *cmd = NULL;
+ const char *val = NULL;
+ int i;
+
+ conn = connect_by_classname(_BROKER, CLASSNAME(ref), &s);
+ if (s.rc != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Could not get connection");
+ goto out;
+ }
+
+ if (cu_get_str_path(ref, "InstanceID", &val) != CMPI_RC_OK) {
+ cu_statusf(_BROKER, &s,
+ CMPI_RC_ERR_FAILED,
+ "Could not get InstanceID");
+ goto out;
+ }
+
+ CU_DEBUG("InstanceID is %s", val);
+
+ bridge = get_bridge_name(conn, strstr(val, "/"));
+ if (bridge == NULL)
+ goto out;
+
+ i = asprintf(&cmd, QOSCMD_LISTCLASSES, bridge, bridge);
+ if (i == -1)
+ goto out;
+
+ CU_DEBUG("qos_hack() cmd = %s", cmd);
+
+ if ((pipe = popen(cmd, "r")) != NULL) {
+ CU_DEBUG("pipe open");
+ while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
+ char *name = NULL;
+ char *p = strstr(buffer, "Kbit");
+
+ /* trim string */
+ if (p)
+ *p = '\0';
+
+ CU_DEBUG("qos hack buffer = %s", buffer);
+
+ i = asprintf(&name, "Point/%s", buffer);
+ if (i != -1) {
+ s = set_net_pool_props(ref, name,
+ NETPOOL_FORWARD_NONE, list);
+
+ free(name);
+ }
+ }
+
+ pclose(pipe);
+ CU_DEBUG("pipe close");
+ }
+
+ out:
+ free(cmd);
+ free(bridge);
+ virConnectClose(conn);
+
+ return s;
+}
+
+
static CMPIStatus net_pool_template(const CMPIObjectPath *ref,
int template_type,
struct inst_list *list)
{
- const char *id;
+ char *id;
CMPIStatus s = {CMPI_RC_OK, NULL};
int type[3] = {NETPOOL_FORWARD_NONE,
NETPOOL_FORWARD_NAT,
@@ -1949,7 +2082,10 @@
goto out;
}
}
-
+
+ if (type == CIM_RES_TYPE_NET)
+ s = qos_hack(ref, list);
+
out:
return s;
}
@@ -2055,7 +2191,7 @@
{
CMPIInstance *ref_inst = NULL;
uint16_t valuerole = SDC_ROLE_SUPPORTED;
- uint16_t valuerange;
+ uint16_t valuerange = SDC_RANGE_POINT;
uint16_t ppolicy = SDC_POLICY_INDEPENDENT;
const char *iid = NULL;
diff -r 2714b9a5e842 -r 862bcd60ae44 src/Virt_VirtualSystemManagementService.c
--- a/src/Virt_VirtualSystemManagementService.c Mon Oct 03 02:51:26 2011 -0700
+++ b/src/Virt_VirtualSystemManagementService.c Wed Oct 26 03:41:56 2011 -0700
@@ -68,6 +68,35 @@
#define RASD_IND_DELETED "ResourceAllocationSettingDataDeletedIndication"
#define RASD_IND_MODIFIED "ResourceAllocationSettingDataModifiedIndication"
+/* 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 \
+'($4==\"parent\" && $5==rr && $13==bw){print $3}'\n"
+
+#define QOSCMD_RMVM "MAC=%s; ME1=$(echo $MAC | awk -F ':' '{ print $1$2$3$4 }'); \
+ME2=$(echo $MAC | awk -F ':' '{ print $5$6 }'); MI1=$(echo $MAC | awk -F ':' \
+'{ print $1$2 }'); MI2=$(echo $MAC | awk -F ':' '{ print $3$4$5$6 }'); \
+HDL=$(tc filter show dev %s | awk 'BEGIN {RS=\"\\nfilter\"} (NR>2)\
+{m1=substr($24,1,2);m2=substr($24,3,2);m3=substr($24,5,2);m4=substr($24,7,2);\
+m5=substr($20,1,2);m6=substr($20,3,2);printf(\"%%s:%%s:%%s:%%s:%%s:%%s %%s\\n\",\
+m1,m2,m3,m4,m5,m6,$9)}' | awk -v mm=%s '($1==mm){print $2}'); \
+U32=\"tc filter del dev %s protocol ip parent 1:0 prio 1 handle $HDL u32\"; \
+$U32 match u16 0x0800 0xFFFF at -2 match u16 0x$ME2 0xFFFF at -4 match u32 \
+0x$ME1 0xFFFFFFFF at -8 flowid %s; U32=\"tc filter del dev %s protocol ip parent \
+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"
+
+#define QOSCMD_ADDVM "MAC=%s; ME1=$(echo $MAC | awk -F ':' '{ print $1$2$3$4 }'); \
+ME2=$(echo $MAC | awk -F ':' '{ print $5$6 }'); MI1=$(echo $MAC | awk -F ':' \
+'{ print $1$2 }'); MI2=$(echo $MAC | awk -F ':' '{ print $3$4$5$6 }'); \
+U32=\"tc filter add dev %s protocol ip parent 1:0 prio 1 u32\"; \
+$U32 match u16 0x0800 0xFFFF at -2 match u16 0x$ME2 0xFFFF at -4 match u32 \
+0x$ME1 0xFFFFFFFF at -8 flowid %s; U32=\"tc filter add dev %s protocol ip parent \
+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"
+
const static CMPIBroker *_BROKER;
enum ResourceAction {
@@ -76,6 +105,104 @@
RESOURCE_MOD,
};
+/* Network QoS support */
+static CMPIStatus add_qos_for_mac(const uint64_t qos,
+ const char *mac,
+ const char *bridge)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ char *cmd = NULL;
+ int j;
+ FILE *pipe = NULL;
+ char id[16] = ""; /* should be adequate to hold short tc class ids... */
+
+ /* Find tc performance class id which matches requested qos bandwidth */
+ j = asprintf(&cmd, QOSCMD_BANDWIDTH2ID, bridge,
+ bridge,
+ (unsigned int)qos);
+ if (j == -1)
+ goto out;
+ CU_DEBUG("add_qos_for_mac(): cmd = %s", cmd);
+
+ if ((pipe = popen(cmd, "r")) != NULL) {
+ if (fgets(id, sizeof(id), pipe) != NULL) {
+ /* Strip off trailing newline */
+ char *p = index(id, '\n');
+ if (p) *p = '\0';
+ }
+ pclose(pipe);
+ }
+ free(cmd);
+ CU_DEBUG("qos id = '%s'", id);
+
+ /* Add tc performance class id for this MAC addr */
+ j = asprintf(&cmd, QOSCMD_ADDVM, mac,
+ bridge,
+ id,
+ bridge,
+ (unsigned int)qos);
+ if (j == -1)
+ goto out;
+ CU_DEBUG("add_qos_for_mac(): cmd = %s", cmd);
+
+ if (WEXITSTATUS(system(cmd)) != 0)
+ CU_DEBUG("add_qos_for_mac(): qos add failed.");
+
+ out:
+ free(cmd);
+ return s;
+}
+
+/* Network QoS support */
+static CMPIStatus remove_qos_for_mac(const uint64_t qos,
+ const char *mac,
+ const char *bridge)
+{
+ CMPIStatus s = {CMPI_RC_OK, NULL};
+ char *cmd = NULL;
+ int j;
+ FILE *pipe = NULL;
+ char id[16] = ""; /* should be adequate to hold short tc class ids... */
+
+ /* Find tc performance class id which matches requested qos bandwidth */
+ j = asprintf(&cmd, QOSCMD_BANDWIDTH2ID, bridge,
+ bridge,
+ (unsigned int)qos);
+ if (j == -1)
+ goto out;
+ CU_DEBUG("remove_qos_for_mac(): cmd = %s", cmd);
+
+ if ((pipe = popen(cmd, "r")) != NULL) {
+ if (fgets(id, sizeof(id), pipe) != NULL) {
+ /* Strip off trailing newline */
+ char *p = index(id, '\n');
+ if (p) *p = '\0';
+ }
+ pclose(pipe);
+ }
+ free(cmd);
+ CU_DEBUG("qos id = '%s'", id);
+
+ /* Remove tc perf class id for this MAC; ignore errors when none exists */
+ j = asprintf(&cmd, QOSCMD_RMVM, mac,
+ bridge,
+ mac,
+ bridge,
+ id,
+ bridge,
+ (unsigned int)qos);
+ if (j == -1)
+ goto out;
+ CU_DEBUG("remove_qos_for_mac(): cmd = %s", cmd);
+
+ if (WEXITSTATUS(system(cmd)) != 0)
+ CU_DEBUG("remove_qos_for_mac(): qos remove failed; ignoring...");
+
+ out:
+ free(cmd);
+ return s;
+}
+
static CMPIStatus check_uuid_in_use(const CMPIObjectPath *ref,
struct domain *domain)
{
@@ -1518,6 +1645,8 @@
} else if (type == CIM_RES_TYPE_NET) {
struct virt_device dev;
int ncount = count + domain->dev_net_ct;
+ uint64_t qos_val = 0;
+ const char *qos_unitstr;
memset(&dev, 0, sizeof(dev));
msg = rasd_to_vdev(inst,
@@ -1529,6 +1658,20 @@
domain->dev_net,
ncount,
&domain->dev_net_ct);
+
+ /* Network QoS support */
+ if (((&dev)->dev.net.mac != NULL) &&
+ ((&dev)->dev.net.source != NULL) &&
+ (cu_get_u64_prop(inst, "Reservation", &qos_val) == CMPI_RC_OK) &&
+ (cu_get_str_prop(inst, "AllocationUnits", &qos_unitstr) == CMPI_RC_OK) &&
+ STREQ(qos_unitstr,"KiloBits per Second")) {
+ remove_qos_for_mac(qos_val,
+ (&dev)->dev.net.mac,
+ (&dev)->dev.net.source);
+ add_qos_for_mac(qos_val,
+ (&dev)->dev.net.mac,
+ (&dev)->dev.net.source);
+ }
} else if (type == CIM_RES_TYPE_GRAPHICS) {
struct virt_device dev;
int gcount = count + domain->dev_graphics_ct;
@@ -2590,10 +2733,28 @@
(type == CIM_RES_TYPE_INPUT))
cu_statusf(_BROKER, &s, CMPI_RC_OK, "");
else {
+ uint64_t qos_val = 0;
+ const char *qos_unitstr;
+
s = _resource_dynamic(dominfo,
dev,
RESOURCE_MOD,
CLASSNAME(op));
+
+ /* Network QoS support */
+ if ((type == CIM_RES_TYPE_NET) &&
+ (dev->dev.net.mac != NULL) &&
+ (dev->dev.net.source != NULL) &&
+ (cu_get_u64_prop(rasd, "Reservation", &qos_val) == CMPI_RC_OK) &&
+ (cu_get_str_prop(rasd, "AllocationUnits", &qos_unitstr) == CMPI_RC_OK) &&
+ STREQ(qos_unitstr,"KiloBits per Second")) {
+ remove_qos_for_mac(qos_val,
+ dev->dev.net.mac,
+ dev->dev.net.source);
+ s = add_qos_for_mac(qos_val,
+ dev->dev.net.mac,
+ dev->dev.net.source);
+ }
}
break;
}
13 years
Re: [Libvirt-cim] cimtest results.
by Sharad Mishra
"Eduardo Lima (Etrunko)" <eblima(a)linux.vnet.ibm.com> wrote on 10/27/2011
05:17:58 AM:
> "Eduardo Lima (Etrunko)" <eblima(a)linux.vnet.ibm.com>
> 10/27/2011 05:17 AM
>
> Please respond to
> eblima(a)br.ibm.com
>
> To
>
> Sharad Mishra/Beaverton/IBM@IBMUS
>
> cc
>
> eblima(a)br.ibm.com, Chip Vincent/Raleigh/IBM@IBMUS, wayne
> <xiawenc(a)linux.vnet.ibm.com>, Gareth S Bestor/Poughkeepsie/IBM@IBMUS
>
> Subject
>
> Re: cimtest results.
>
> On 10/26/2011 08:07 PM, snmishra(a)us.ibm.com wrote:
> > Hi,
> >
> > I see bunch of tests failing after I get cimtest from upstream and
apply
> > the following patches -
> >
> > https://www.redhat.com/archives/libvirt-cim/2011-October/msg00051.html
> > https://www.redhat.com/archives/libvirt-cim/2011-October/msg00052.html
> > https://www.redhat.com/archives/libvirt-cim/2011-October/msg00045.html
> >
> >
> > If I run cimtest from rev 879 (which is upstream minus latest 4
patches)
> > and compare the results with the run using latest upstream plus above
> > three patches I see following extra failures -
> >
> > VirtualSystemManagementService - 08_modifyresource.py: FAIL
> > VirtualSystemManagementService - 09_procrasd_persist.py: FAIL
> > VirtualSystemManagementService - 11_define_memrasdunits.py: FAIL
> > VirtualSystemManagementService - 31_unset_netrasd.py: FAIL
> > VirtualSystemManagementService - 32_modify_cdrom_media.py: FAIL
> > KVMRedirectionSAP - 01_enum_KVMredSAP.py: FAIL
> >
> > I understand that 31_* and 32_* are new tests and that is the reason I
> > did not see them in my run with older rev. But we need to figure out
why
> > these tests are failing.
> >
>
> The buggy patch is 883 ([TEST] XenKvmLib: Add cdrom device description
> to domain) and it looks weird that you actually ran revision 879 as it
> should not include VSMS 31 and 32. Can you try again with revision 882?
When I wrote "older rev" above, I meant rev 879.
I did not see 31_ and 32_ in rev 879 and that is understandable since those
tests were added in later rev.
I am trying to understand why above tests are failing with 883 + cimtest
patches on list (the three I pointed out above)?
-Sharad
>
> Best regards, Etrunko
>
> --
> Eduardo de Barros Lima
> Software Engineer, Open Virtualization
> Linux Technology Center - IBM/Brazil
> eblima(a)br.ibm.com
>
13 years