[libvirt] [libvirt-test-API][PATCH 2/2] Add new case to test storagePoolLookupByVolume
Added a new case to validate storagePoolLookupByVolume api --- repos/storage/pool_lookup_by_volume.py | 46 ++ 1 file changed, 46 insertions(+) create mode 100644 repos/storage/pool_lookup_by_volume.py diff --git a/repos/storage/pool_lookup_by_volume.py b/repos/storage/pool_lookup_by_volume.py new file mode 100644 index 000..ee5c9c9 --- /dev/null +++ b/repos/storage/pool_lookup_by_volume.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +#test storagePoolLookupByVolume() API for libvirt + +import os +import libvirt +from libvirt import libvirtError +from src import sharedmod + +required_params = ('poolname','volname',) +optional_params = {} + +def pool_lookup_by_volume(params): +""" + test API for storagePoolLookupByVolume in class virStoragePool +""" +logger = params['logger'] +poolname = params['poolname'] +volname = params['volname'] +logger.info("The given pool name is %s" % (poolname)) +logger.info("The given vol name is %s" % (volname)) +conn = sharedmod.libvirtobj['conn'] +pool = conn.storagePoolLookupByName(poolname) +pre_vol = pool.storageVolLookupByName(volname) +volpath = pre_vol.path() +logger.info("The given volume path is %s" % (volpath)) +temp = volpath.split("/") +temp.pop(0) +temp.pop(-1) +temp1 = "/" + "/".join(temp) +if not os.path.exists(temp1): +logger.warning("volume path file %s is not exist" % temp1) + +try: +vol = conn.storageVolLookupByPath(volpath) +pool_name = vol.storagePoolLookupByVolume().name() +logger.info("The pool name is %s from API" % (pool_name)) + +if not pool_name == poolname: + return 1 + +except libvirtError, e: +logger.error("API error message: %s, error code is %s" \ + % (e.message, e.get_error_code())) +return 1 + +return 0 -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 0/2] Add a new case for storagePoolLookupByVolume API
This API will be tested in dir/logicl/netfs pool type. jiahu (2): Add pool_lookup_by_volume.py to conf Add new case to test storagePoolLookupByVolume cases/storage_dir.conf | 6 + cases/storage_logical.conf | 6 + cases/storage_netfs.conf | 6 + repos/storage/pool_lookup_by_volume.py | 46 ++ 4 files changed, 64 insertions(+) create mode 100644 repos/storage/pool_lookup_by_volume.py -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/2] Add pool_lookup_by_volume.py to conf
--- cases/storage_dir.conf | 6 ++ cases/storage_logical.conf | 6 ++ cases/storage_netfs.conf | 6 ++ 3 files changed, 18 insertions(+) diff --git a/cases/storage_dir.conf b/cases/storage_dir.conf index 38b349d..97e8676 100644 --- a/cases/storage_dir.conf +++ b/cases/storage_dir.conf @@ -20,6 +20,12 @@ storage:create_dir_volume capacity $defaultvolumesize +storage:pool_lookup_by_volume +poolname +$defaultpoolname +volname +$defaultvolumename + storage:vol_clone poolname $defaultpoolname diff --git a/cases/storage_logical.conf b/cases/storage_logical.conf index d374dfa..c4c8c79 100644 --- a/cases/storage_logical.conf +++ b/cases/storage_logical.conf @@ -22,6 +22,12 @@ storage:create_logical_volume capacity $defaultvolumesize +storage:pool_lookup_by_volume +poolname +$defaultpoolname +volname +$defaultvolumename + storage:vol_clone poolname $defaultpoolname diff --git a/cases/storage_netfs.conf b/cases/storage_netfs.conf index f486ff4..4fa9c88 100644 --- a/cases/storage_netfs.conf +++ b/cases/storage_netfs.conf @@ -24,6 +24,12 @@ storage:create_netfs_volume capacity $defaultvolumesize +storage:pool_lookup_by_volume +poolname +$defaultpoolname +volname +$defaultvolumename + storage:vol_clone poolname $defaultpoolname -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-test-api][PATCH 2/3] improve the way we get the standard deviation
On 05/18/2015 09:28 AM, Luyao Huang wrote: Signed-off-by: Luyao Huang --- utils/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/utils.py b/utils/utils.py index 954b2bf..a6e6965 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -906,9 +906,10 @@ def get_standard_deviation(cb1, cb2, opaque1, opaque2, number = 1000): """ D = 0 for i in range(number): -a = cb1(opaque1) +a1 = cb1(opaque1) b = cb2(opaque2) -D += (int(a) - int(b))**2 +a2 = cb1(opaque1) +D += ((int(a1) + int(a2))/2 - int(b))**2 return math.sqrt(D/number) ACK, this will spend a double time, whatever, we need a more accurate return. def param_to_tuple_nolength(paramlist): -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/3] Add two testing cases to test_connection.conf
Below 4 new APIs will be tested networkLookupByUUIDString/networkLookupByUUID storagePoolLookupByUUIDString/storagePoolLookupByUUID --- cases/test_connection.conf | 8 1 file changed, 8 insertions(+) diff --git a/cases/test_connection.conf b/cases/test_connection.conf index 5719937..5317d72 100644 --- a/cases/test_connection.conf +++ b/cases/test_connection.conf @@ -57,3 +57,11 @@ virconn:connection_getDomainCapabilities pc-i440fx-rhel7.0.0 virttype kvm + +network:network_uuid +networkname +default + +storage:pool_uuid +poolname +default -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 2/3] Modify the case to cover two new APIs
Test below 2 APIs in this case: networkLookupByUUIDString/networkLookupByUUID --- repos/network/network_uuid.py | 68 --- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/repos/network/network_uuid.py b/repos/network/network_uuid.py index 02a104c..8f2ca83 100644 --- a/repos/network/network_uuid.py +++ b/repos/network/network_uuid.py @@ -1,13 +1,18 @@ #!/usr/bin/env python -# To test "virsh net-uuid" command +#To test "virsh net-uuid" command and related APIs +#To test 2 APIs in this case: +# networkLookupByUUIDString +# networkLookupByUUID import os import sys import re import commands - +import binascii import libvirt + from libvirt import libvirtError +from xml.dom import minidom from src import sharedmod @@ -15,6 +20,7 @@ required_params = ('networkname',) optional_params = {} VIRSH_NETUUID = "virsh net-uuid" +NWPATH = "/etc/libvirt/qemu/networks/" def check_network_exists(conn, networkname, logger): """ check if the network exists, may or may not be active """ @@ -29,25 +35,43 @@ def check_network_exists(conn, networkname, logger): def check_network_uuid(networkname, UUIDString, logger): """ check UUID String of a network """ -status, ret = commands.getstatusoutput(VIRSH_NETUUID + ' %s' % networkname) +status, ret = commands.getstatusoutput(VIRSH_NETUUID + ' %s' \ +% networkname) if status: -logger.error("executing "+ "\"" + VIRSH_NETUUID + ' %s' % networkname + "\"" + " failed") +logger.error("executing "+ "\"" + VIRSH_NETUUID + ' %s' % networkname\ + + "\"" + " failed") logger.error(ret) return False else: UUIDString_virsh = ret[:-1] logger.debug("UUIDString from API is %s" % UUIDString) -logger.debug("UUIDString from " + "\"" + VIRSH_NETUUID + "\"" " is %s" % UUIDString_virsh) +logger.debug("UUIDString from " + "\"" + VIRSH_NETUUID + "\"" " is %s"\ + % UUIDString_virsh) if UUIDString_virsh == UUIDString: return True else: return False +def checking_uuid(logger,nwname,nwuuid): +""" compare two UUIDs, one is from API, another is from network XML""" +global NWPATH +NWPATH = NWPATH + nwname + ".xml" +xml = minidom.parse(NWPATH) +network = xml.getElementsByTagName('network')[0] +uuid = network.getElementsByTagName('uuid')[0].childNodes[0].data +if uuid == nwuuid: +return True +else: + return False -def netuuid(params): -""" call appropriate API to generate the UUIDStirng -of a network , then compared to the output of command -virsh net-uuid +def network_uuid(params): +""" 1.call appropriate API to generate the UUIDStirng + of a network , then compared to the output of command + virsh net-uuid +2.check below 2 new APIs: + networkLookupByUUIDString + networkLookupByUUID """ +global NWPATH logger = params['logger'] networkname = params['networkname'] @@ -61,7 +85,31 @@ def netuuid(params): try: UUIDString = netobj.UUIDString() -logger.info("the UUID string of network %s is %s" % (networkname, UUIDString)) + +#For a transient network, set another path +if not netobj.isPersistent() == 1: + NWPATH = "/var/run/libvirt/network/" + +logger.info("the UUID string of network \"%s\" is \"%s\""\ + % (networkname, UUIDString)) +#allowing '-' and ' ' anywhere between character pairs, just +#check one of them. +UUIDString1 = UUIDString.replace("-"," ") +network1 = conn.networkLookupByUUIDString(UUIDString1) +nw_name1 = network1.name() +logger.debug("The given UUID is \"%s\", the network is \"%s\" using\ + networkLookupByUUIDString" %(UUIDString1,nw_name1)) + +UUIDString2 = UUIDString.replace("-","") +UUID_ascii = binascii.a2b_hex(UUIDString2) +network2 = conn.networkLookupByUUID(UUID_ascii) +nw_name2 = network2.name() +logger.debug("The given UUID is \"%s\", the network is \"%s\" using \ +networkLookupByUUID" %(UUIDString2,nw_name2)) + +if nw_name1 == nw_name2 and checking_uuid(logger,nw_name1,UUIDString): +logger.info("Successed to get network name \"%s\" using \"%s\""\ + %(nw_name1,UUIDString)) if check_network_uuid(networkname, UUIDString, logger): logger.info(VIRSH_NETUUID + " test succeeded.") -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 0/3] Modify the existing cases to cover 4 new APIs
Modify the existing cases to cover below 4 new APIs: networkLookupByUUIDString/networkLookupByUUID storagePoolLookupByUUIDString/storagePoolLookupByUUID jiahu (3): Add two testing cases to test_connection.conf Modify the case to cover two new APIs Modify the case to cover two new APIs cases/test_connection.conf| 8 + repos/network/network_uuid.py | 68 --- repos/storage/pool_uuid.py| 49 ++- 3 files changed, 114 insertions(+), 11 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 3/3] Modify the case to cover two new APIs
Check two new APIs in this case: storagePoolLookupByUUIDString/storagePoolLookupByUUID --- repos/storage/pool_uuid.py | 49 +- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/repos/storage/pool_uuid.py b/repos/storage/pool_uuid.py index bb6bf63..2f371eb 100644 --- a/repos/storage/pool_uuid.py +++ b/repos/storage/pool_uuid.py @@ -1,4 +1,8 @@ #!/usr/bin/env python +#To test "virsh pool-uuid" command and related APIs +#To test 2 APIs in this case: +#storagePoolLookupByUUID +#storagePoolLookupByUUIDString import os import sys @@ -6,7 +10,10 @@ import re import time import commands +import binascii import libvirt + +from xml.dom import minidom from libvirt import libvirtError from src import sharedmod @@ -15,6 +22,7 @@ required_params = ('poolname',) optional_params = {} VIRSH_POOLUUID = "virsh pool-uuid" +POOLPATH = "/etc/libvirt/storage/" def check_pool_uuid(poolname, UUIDString, logger): """ check UUID String of a pool """ @@ -32,10 +40,25 @@ def check_pool_uuid(poolname, UUIDString, logger): else: return False +def checking_uuid(logger,poolname,pooluuid): +"""check two uuid of pool which are from API and pool's XML""" +global POOLPATH +POOLPATH = POOLPATH + poolname + ".xml" +xml = minidom.parse(POOLPATH) +pool = xml.getElementsByTagName('pool')[0] +uuid = pool.getElementsByTagName('uuid')[0].childNodes[0].data +if uuid == pooluuid: +return True +else: + return False + def pool_uuid(params): -""" call appropriate API to generate the UUIDStirng +""" 1. call appropriate API to generate the UUIDStirng of a pool , then compared to the output of command virsh pool-uuid +2. check 2 APIs in the case: + storagePoolLookupByUUID + storagePoolLookupByUUIDString """ logger = params['logger'] poolname = params['poolname'] @@ -53,6 +76,30 @@ def pool_uuid(params): try: UUIDString = poolobj.UUIDString() logger.info("the UUID string of pool %s is %s" % (poolname, UUIDString)) + +#For a transient pool, set another path +if not poolobj.isPersistent() == 1: +logger.info("Can not check a transient pool by now.") +return 0 +#allowing '-' and ' ' anywhere between character pairs,just check +#one of them +UUIDString1 = UUIDString.replace("-"," ") +pool1 = conn.storagePoolLookupByUUIDString(UUIDString1) +pool_name1 = pool1.name() +logger.debug("The given UUID is \"%s\", the pool is \"%s\" using\ + storagePoolLookupByUUIDString" %(UUIDString1,pool_name1)) + +UUIDString2 = UUIDString.replace("-","") +UUID_ascii = binascii.a2b_hex(UUIDString2) +pool2 = conn.storagePoolLookupByUUID(UUID_ascii) +pool_name2 = pool2.name() +logger.debug("The given UUID is \"%s\", the pool is \"%s\" using \ +storagePoolLookupByUUID" %(UUIDString2,pool_name2)) + +if pool_name1 == pool_name2 and checking_uuid(logger,pool_name1,UUIDString): +logger.info("Successed to get pool name \"%s\" using \"%s\""\ + %(pool_name1,UUIDString)) + if check_pool_uuid(poolname, UUIDString, logger): logger.info(VIRSH_POOLUUID + " test succeeded.") return 0 -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add connection_getDomainCapabilities test case
In the case, we will validate getDomainCapabilities API for libvirt. jiahu (1): Add connection_getDomainCapabilities test case cases/test_connection.conf| 10 + repos/virconn/connection_getDomainCapabilities.py | 438 ++ 2 files changed, 448 insertions(+) create mode 100644 repos/virconn/connection_getDomainCapabilities.py -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add connection_getDomainCapabilities test case
This case will test getDomainCapabilities API, and connection_getDomainCapabilities test case was added to test_connection.conf --- cases/test_connection.conf| 10 + repos/virconn/connection_getDomainCapabilities.py | 438 ++ 2 files changed, 448 insertions(+) create mode 100644 repos/virconn/connection_getDomainCapabilities.py diff --git a/cases/test_connection.conf b/cases/test_connection.conf index 7552024..5719937 100644 --- a/cases/test_connection.conf +++ b/cases/test_connection.conf @@ -47,3 +47,13 @@ virconn:free_pages 0 pagesize 4k,2M + +virconn:connection_getDomainCapabilities +emulatorbin +/usr/libexec/qemu-kvm +arch +x86_64 +machine +pc-i440fx-rhel7.0.0 +virttype +kvm diff --git a/repos/virconn/connection_getDomainCapabilities.py b/repos/virconn/connection_getDomainCapabilities.py new file mode 100644 index 000..f0cfa1f --- /dev/null +++ b/repos/virconn/connection_getDomainCapabilities.py @@ -0,0 +1,438 @@ +#!/usr/bin/env python +# test getDomainCapabilities() API for libvirtd + +import os +import libvirt +import hashlib +import fcntl + +from xml.dom import minidom +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = ('emulatorbin','arch','machine','virttype',) +optional_params = {} + +QEMU_CAPS = "" +API_FILE = "/tmp/caps_from_api.xml" +CMD = "rm -rf %s" +OVMF = "/usr/share/OVMF/OVMF_CODE.fd" +IOMMU = "/sys/kernel/iommu_groups/" +VFIO = "/dev/vfio/vfio" +KVM = "/dev/kvm" +KVM_CHECK_EXTENSION = 44547 +KVM_CAP_IOMMU = 18 +maxcpu = 0 + +ovmf_f = False +drive = False +drive_forma = False +drive_readonly = False +blk_sg_io = False +usb_storage = False +device = False +scsi_generic = False +vfio_pci = False + +def clean_env(logger): +""" + clean testing environment +""" +status, output = utils.exec_cmd(CMD % API_FILE, shell=True) +if status != 0: +logger.error("Can not delete %s" % API_FILE) +else: +logger.debug("Deleted %s successfully" % API_FILE) + +def get_hypervisor_ver(emulatorbin,logger): +""" + Obtain qemu-kvm's version, and return a number value of version +""" +RPM = "rpm -qf %s" +status, package = utils.exec_cmd(RPM % emulatorbin, shell=True) +if not status: +logger.debug("The package is %s" % package) +else: +logger.debug("The package is %s" % package) +return 0 +package = package[0].split('-') +version = "" +for item in package: +if not item.isalnum(): +for v in item.split("."): +version = version + v.rjust(3,"0") +break +return int(version) + +def validate_caps_from_hv(emulatorbin,logger): +""" +Validate the relative caps between libvirt and qemu-kvm +""" +F1 = "%s -h| grep \"\-drive\"" +F2 = "%s -h| grep \"format=\"" +F3 = "%s -h| grep \"readonly=\"" +F4 = "%s -h| grep \"^\\-device\"" +l = [F1,F2,F3,F4] +flags = [] +for item in l: +status, temp = utils.exec_cmd(item % emulatorbin, shell=True) +if not status: +flags.append(True) +logger.debug("Got: %s from vh" % temp) +else: +flags.append(False) +logger.debug("Got: %s from vh" % temp) +if get_hypervisor_ver(emulatorbin,logger) >= 11000: + flags.append(True) +else: + flags.append(False) +libvirt_f = [drive,drive_forma,drive_readonly,device,blk_sg_io] +if flags == libvirt_f: +return True +else: +return False + +def generate_hash(emulatorbin,logger): +""" + generate file name using sha256 +""" +global QEMU_CAPS +QEMU_CAPS = "/var/cache/libvirt/qemu/capabilities/" +file_name = hashlib.sha256(emulatorbin).hexdigest() +QEMU_CAPS = QEMU_CAPS + file_name + ".xml" +logger.debug("Cache file is %s" % QEMU_CAPS) + +def get_maxcpu(machine,logger): +""" + return maxcpu for given machine type from QEMU_CAPS xml +""" +global maxcpu +xml = minidom.parse(QEMU_CAPS) +qemu = xml.getElementsByTagName('qemuCaps')[0] +for item in qemu.getElementsByTagName('machine'): +if item.getAttribute('name') == machine: +maxcpu = int(item.getAttribute('maxCpus')) +return True + +def get_os_flags(logger): +""" + Read results from QEMU_CAPS file and set three flags +""" +global drive, drive_forma, drive_readonly +xml = minidom.parse(QEMU_CAPS) +qemu = xml.getElementsByTagName('qemuCaps')[0] +for item in qemu.getElementsByTagName('flag'): +if item.getAttribute('name') == "drive": +drive = True +if item.getAttribute('name') == "drive-format": +drive_forma = True +if item.getAttribute('name') == "drive-readonly": +drive_readonly = True +logger.debug("drive = %s; drive_format = %s; drive_readonly = %s
[libvirt] [libvirt-test-API][PATCH V2 2/2] Add connection_getAllDomainStats test case
The case will validate the getAllDomainStats and domainListGetStats two APIs in class virConnect --- repos/virconn/connection_getAllDomainStats.py | 549 ++ 1 file changed, 549 insertions(+) create mode 100644 repos/virconn/connection_getAllDomainStats.py diff --git a/repos/virconn/connection_getAllDomainStats.py b/repos/virconn/connection_getAllDomainStats.py new file mode 100644 index 000..d95004f --- /dev/null +++ b/repos/virconn/connection_getAllDomainStats.py @@ -0,0 +1,549 @@ +#!/usr/bin/env python +# test getAllDomainStats() API for libvirt + +import libvirt + +from xml.dom import minidom +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = () +optional_params = {'stats': '','flags': '','doms':''} + +ds = {"state": libvirt.VIR_DOMAIN_STATS_STATE, + "cpu": libvirt.VIR_DOMAIN_STATS_CPU_TOTAL, + "balloon": libvirt.VIR_DOMAIN_STATS_BALLOON, + "vcpu": libvirt.VIR_DOMAIN_STATS_VCPU, + "interface": libvirt.VIR_DOMAIN_STATS_INTERFACE, + "block": libvirt.VIR_DOMAIN_STATS_BLOCK} + +fg = {"active": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE, + "inactive": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE, + "persistent": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT, + "transient": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT, + "running": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING, + "paused": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED, + "shutoff": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF, + "other": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER, + "backing": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING, + "enforce": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS} + +def filer_domains(logger, flags): +""" + return a filtered domains set +""" +a = set(active_domains(logger)) +d = set(defined_domains(logger)) +if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT and \ + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT: +domains = a | d +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT: +domains = d +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT: +domains = a - d +else: +domains = a | d +if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE and \ + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE: +domains &= (a | d) +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE: +domains &= a +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE: +domains &= (d - a) +else: +domains &= a | d +return domains + +def active_domains(logger): +""" + return active domains on current uri +""" +NUM = "ls /run/libvirt/qemu|grep \".xml\"" +status, output = utils.exec_cmd(NUM, shell=True) +output = [item.replace(".xml","") for item in output] +if status == 0: +logger.debug("Got active domains: %s" % output) +return output +else: +logger.debug("Got active domains: %s" % output) +return output + +def defined_domains(logger): +""" + return defined domains on current uri +""" +NUM = "ls /etc/libvirt/qemu|grep \".xml\"" +status, output = utils.exec_cmd(NUM, shell=True) +output = [item.replace(".xml","") for item in output] +if status == 0: +logger.debug("Got defined domains: %s" % output) +return output +else: +logger.debug("Got defined domains: %s" % output) +return output + +def compare_value(logger,op1,op2): +""" + compare 2 variables value +""" +if op1 != op2: +logger.debug("Check %s: Fail" % op2) +return False +else: +logger.debug("Check %s: Pass" % op2) +return True + +def check_vcpu(logger,dom_name,dom_active,dom_eles): +""" + check vcpu info of given domain +""" +iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml" +aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml" +if dom_active: +xml = minidom.parse(aDOM_XML) +dom = xml.getElementsByTagName('domain')[0] +vcpu = dom.getElementsByTagName('vcpu')[0] +vcpu_max = int(vcpu.childNodes[0].data) +if not vcpu.getAttribute('current'): +vcpu_cur = vcpu_max +else: +vcpu_cur = int(vcpu.getAttribute('current')) + +logger.debug("Checking vcpu.current: %d" \ +% dom_eles.get("vcpu.current")) +if not compare_value(logger,vcpu_cur, \ +dom_eles.get("vcpu.current")): +return False +logger.debug("Checking vcpu.maximum: %d" \ +% dom_eles.get("vcpu.maximum")) +if not compare_value(logger,vcpu_max, \ +dom_eles.get("vcpu.maximum")): +return False +else: +xml =
[libvirt] [libvirt-test-API][PATCH V2 0/2] Add connection_getAllDomainStats test case
The testing case will validate the getAllDomainStats API in class virConnect V2: Added new domainListGetStats API in this case jiahu (2): Add connection_getAllDomainStats test case to linux_domain.conf Add connection_getAllDomainStats test case cases/linux_domain.conf | 14 + repos/virconn/connection_getAllDomainStats.py | 549 ++ 2 files changed, 563 insertions(+) create mode 100644 repos/virconn/connection_getAllDomainStats.py -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 1/2] Add connection_getAllDomainStats test case to linux_domain.conf
--- cases/linux_domain.conf | 14 ++ 1 file changed, 14 insertions(+) diff --git a/cases/linux_domain.conf b/cases/linux_domain.conf index 552f001..a2c01fa 100644 --- a/cases/linux_domain.conf +++ b/cases/linux_domain.conf @@ -34,6 +34,20 @@ domain:start guestname $defaultname +virconn:connection_getAllDomainStats +stats +state|cpu|balloon|vcpu|interface|block +flags + active|inactive|persistent|transient|running|paused|shutoff|other|backing|enforce + +virconn:connection_getAllDomainStats +stats +state|cpu|balloon|vcpu|interface|block +flags +backing|enforce +doms +$defaultname + domain:securitylabel guestname $defaultname -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-test-API][PATCH V2 1/2] Add freepage test
ACK Please pay attention to below format next time. Applying: Add freepage test /root/libvirt-test-API/.git/rebase-apply/patch:88: trailing whitespace. /root/libvirt-test-API/.git/rebase-apply/patch:90: trailing whitespace. /root/libvirt-test-API/.git/rebase-apply/patch:95: trailing whitespace. warning: 3 lines add whitespace errors. BR, Jianwei On 03/10/2015 05:29 PM, Jincheng Miao wrote: For system default pagesize, it's hard to calculate, and it changes all the time, so just skip it. For others, reading from sysfs to get free pages. Signed-off-by: Jincheng Miao --- repos/virconn/free_pages.py | 97 +++ 1 files changed, 97 insertions(+), 0 deletions(-) create mode 100644 repos/virconn/free_pages.py diff --git a/repos/virconn/free_pages.py b/repos/virconn/free_pages.py new file mode 100644 index 000..516b9f2 --- /dev/null +++ b/repos/virconn/free_pages.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# test libvirt free pages + +import os +import resource + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('cellid', 'pagesize',) +optional_params = {} + +HUGEPAGE_PATH = '/sys/devices/system/node/node%s/hugepages/hugepages-%skB/free_hugepages' + +def parse_unit(pagesz): +""" parse a integer value, its unit is KiB +""" +val = int(pagesz[0:len(pagesz)-1]) +unit = pagesz[-1] +if unit == 'K': +unit = 1 +elif unit == 'M': +unit = 1024 +elif unit == 'G': +unit = 1024*1024 +else: +return None + +return val * unit + +def parse_page_list(pagesize): +""" parse page size +""" +if pagesize == None: +return None + +l = list() +for ps in pagesize.split(','): +ps = ps.strip().upper() +val = parse_unit(ps) +if val == None: +return None +l.append(val) +return l + +def check_free_pages(page_list, cell_id, free_page, logger): +""" check page size +""" +for ps in page_list: +# if pagesize is equal to system pagesize, since it is hard to +# calculate, so we just pass it +if resource.getpagesize()/1024 == ps: +logger.info("skip to check default %sKB-page" % ps) +continue + +sysfs_path = HUGEPAGE_PATH % (cell_id, ps) +if not os.access(sysfs_path, os.R_OK): +logger.error("could not find %s" % sysfs_path) +return False +f= open(sysfs_path) +fp = int(f.read()) +f.close() +if not fp == free_page[0][ps]: +logger.error("Free %sKB page checking failed" % ps) +return False +logger.info("Free %sKB page: %s" % (ps, fp)) + +return True + +def free_pages(params): +""" test libvirt free pages +""" +logger = params['logger'] +cell_id = int(params['cellid']) + +conn = sharedmod.libvirtobj['conn'] + +page_list = parse_page_list(params['pagesize']) +if page_list == None: +logger.error("pagesize could not be recognized") +return 1 + +try: +free_page = conn.getFreePages(page_list, cell_id, 1) + +if check_free_pages(page_list, cell_id, free_page, logger): +logger.info("Success to check free page") +else: +logger.error("Failed to check free page") +return 1 +except libvirtError, e: +logger.error("API error message: %s, error code is %s" % + e.message) +return 1 +return 0 \ No newline at end of file -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 2/2] Add connection_getAllDomainStats test case
The case will validate the getAllDomainStats API in class virConnect --- repos/virconn/connection_getAllDomainStats.py | 528 ++ 1 file changed, 528 insertions(+) create mode 100644 repos/virconn/connection_getAllDomainStats.py diff --git a/repos/virconn/connection_getAllDomainStats.py b/repos/virconn/connection_getAllDomainStats.py new file mode 100644 index 000..023564a --- /dev/null +++ b/repos/virconn/connection_getAllDomainStats.py @@ -0,0 +1,528 @@ +#!/usr/bin/env python +# test getAllDomainStats() API for libvirt + +import libvirt + +from xml.dom import minidom +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = () +optional_params = {'stats': '','flags': ''} + +ds = {"state": libvirt.VIR_DOMAIN_STATS_STATE, + "cpu": libvirt.VIR_DOMAIN_STATS_CPU_TOTAL, + "balloon": libvirt.VIR_DOMAIN_STATS_BALLOON, + "vcpu": libvirt.VIR_DOMAIN_STATS_VCPU, + "interface": libvirt.VIR_DOMAIN_STATS_INTERFACE, + "block": libvirt.VIR_DOMAIN_STATS_BLOCK} + +fg = {"active": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE, + "inactive": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE, + "persistent": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT, + "transient": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT, + "running": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING, + "paused": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED, + "shutoff": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF, + "other": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER, + "backing": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING, + "enforce": libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS} + +def filer_domains(logger, flags): +""" + return a filtered domains set +""" +a = set(active_domains(logger)) +d = set(defined_domains(logger)) +if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT and \ + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT: +domains = a | d +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT: +domains = d +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT: +domains = a - d +else: +domains = a | d +if flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE and \ + flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE: +domains &= (a | d) +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE: +domains &= a +elif flags & libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE: +domains &= (d - a) +else: +domains &= a | d +return domains + +def active_domains(logger): +""" + return active domains on current uri +""" +NUM = "ls /run/libvirt/qemu|grep \".xml\"" +status, output = utils.exec_cmd(NUM, shell=True) +output = [item.replace(".xml","") for item in output] +if status == 0: +logger.debug("Got active domains: %s" % output) +return output +else: +logger.debug("Got active domains: %s" % output) +return output + +def defined_domains(logger): +""" + return defined domains on current uri +""" +NUM = "ls /etc/libvirt/qemu|grep \".xml\"" +status, output = utils.exec_cmd(NUM, shell=True) +output = [item.replace(".xml","") for item in output] +if status == 0: +logger.debug("Got defined domains: %s" % output) +return output +else: +logger.debug("Got defined domains: %s" % output) +return output + +def compare_value(logger,op1,op2): +""" + compare 2 variables value +""" +if op1 != op2: +logger.debug("Check %s: Fail" % op2) +return False +else: +logger.debug("Check %s: Pass" % op2) +return True + +def check_vcpu(logger,dom_name,dom_active,dom_eles): +""" + check vcpu info of given domain +""" +iDOM_XML = "/etc/libvirt/qemu/" + dom_name +".xml" +aDOM_XML = "/run/libvirt/qemu/" + dom_name +".xml" +if dom_active: +xml = minidom.parse(aDOM_XML) +dom = xml.getElementsByTagName('domain')[0] +vcpu = dom.getElementsByTagName('vcpu')[0] +vcpu_max = int(vcpu.childNodes[0].data) +if not vcpu.getAttribute('current'): +vcpu_cur = vcpu_max +else: +vcpu_cur = int(vcpu.getAttribute('current')) + +logger.debug("Checking vcpu.current: %d" \ +% dom_eles.get("vcpu.current")) +if not compare_value(logger,vcpu_cur, \ +dom_eles.get("vcpu.current")): +return False +logger.debug("Checking vcpu.maximum: %d" \ +% dom_eles.get("vcpu.maximum")) +if not compare_value(logger,vcpu_max, \ +dom_eles.get("vcpu.maximum")): +return False +else: +xml = minidom.parse(iDOM_XML) +vcpu
[libvirt] [libvirt-test-API][PATCH 0/2] Add connection_getAllDomainStats test case
The testing case will validate the getAllDomainStats API in class virConnect jiahu (2): Add connection_getAllDomainStats test case to linux_domain.conf Add connection_getAllDomainStats test case cases/linux_domain.conf | 6 + repos/virconn/connection_getAllDomainStats.py | 528 ++ 2 files changed, 534 insertions(+) create mode 100644 repos/virconn/connection_getAllDomainStats.py -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/2] Add connection_getAllDomainStats test case to linux_domain.conf
--- cases/linux_domain.conf | 6 ++ 1 file changed, 6 insertions(+) diff --git a/cases/linux_domain.conf b/cases/linux_domain.conf index a5ada35..d3d6aa5 100644 --- a/cases/linux_domain.conf +++ b/cases/linux_domain.conf @@ -34,6 +34,12 @@ domain:start guestname $defaultname +virconn:connection_getAllDomainStats +stats +state|cpu|balloon|vcpu|interface|block +flags + active|inactive|persistent|transient|running|paused|shutoff|other|backing|enforce + domain:destroy guestname $defaultname -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-test-API][PATCH 1/2] Add freepage test
On 02/15/2015 03:01 PM, Jincheng Miao wrote: For system default pagesize, it's hard to calculate, and it changes all the time, so just skip it. For others, reading from sysfs to get free pages. Signed-off-by: Jincheng Miao --- repos/virconn/free_pages.py | 97 +++ 1 files changed, 97 insertions(+), 0 deletions(-) create mode 100644 repos/virconn/free_pages.py diff --git a/repos/virconn/free_pages.py b/repos/virconn/free_pages.py new file mode 100644 index 000..7172dfe --- /dev/null +++ b/repos/virconn/free_pages.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# test libvirt free pages + +import os +import resource + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('cellid', 'pagesize',) +optional_params = {} + +HUGEPAGE_PATH = '/sys/devices/system/node/node%s/hugepages/hugepages-%skB/free_hugepages' + +def parse_unit(pagesz): +""" parse a integer value, its unit is KiB +""" +val = int(pagesz[0:len(pagesz)-1]) +unit = pagesz[-1] +if unit == 'K': +unit = 1 +elif unit == 'M': +unit = 1024 +elif unit == 'G': +unit = 1024*1024 +else: +return None + +return val * unit + +def parse_page_list(pagesize): +""" parse page size +""" +if pagesize == None: +return None + +l = list() +for ps in pagesize.split(','): +ps.strip().upper() string variable is immutable type, should assign it to a new. ps = ps.strip().upper() or parse_unit(ps.strip().upper()) jiahu +val = parse_unit(ps) +if val == None: +return None +l.append(val) +return l + +def check_free_pages(page_list, cell_id, free_page, logger): +""" check page size +""" +for ps in page_list: +# if pagesize is equal to system pagesize, since it is hard to +# calculate, so we just pass it +if resource.getpagesize()/1024 == ps: +logger.info("skip to check default %sKB-page" % ps) +continue + +sysfs_path = HUGEPAGE_PATH % (cell_id, ps) +if not os.access(sysfs_path, os.R_OK): +logger.error("could not find %s" % sysfs_path) +return False +f= open(sysfs_path) +fp = int(f.read()) +f.close() +if not fp == free_page[0][ps]: +logger.error("Free %sKB page checking failed" % ps) +return False +logger.info("Free %sKB page: %s" % (ps, fp)) + +return True + +def free_pages(params): +""" test libvirt free pages +""" +logger = params['logger'] +cell_id = int(params['cellid']) + +conn = sharedmod.libvirtobj['conn'] + +page_list = parse_page_list(params['pagesize']) +if page_list == None: +logger.error("pagesize could not be recognized") +return 1 + +try: +free_page = conn.getFreePages(page_list, cell_id, 1) + +if check_free_pages(page_list, cell_id, free_page, logger): +logger.info("Success to check free page") +else: +logger.error("Failed to check free page") +return 1 +except libvirtError, e: +logger.error("API error message: %s, error code is %s" % + e.message) +return 1 +return 0 \ No newline at end of file -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 0/2] Add coredump_with_format test case
The coredump_with_format.py uses coreDumpWithFormat() to validate new API virDomainCoreDumpWithFormat of libvirt. jiahu (2): Add coredump_with_format test case Add coredump_with_format test case to linux_domain conf cases/linux_domain.conf | 44 +++ repos/domain/coredump_with_format.py | 239 +++ 2 files changed, 283 insertions(+) create mode 100644 repos/domain/coredump_with_format.py -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/2] Add coredump_with_format test case
The coredump_with_format.py uses coreDumpWithFormat() to validate new API virDomainCoreDumpWithFormat of libvirt. --- repos/domain/coredump_with_format.py | 239 +++ 1 file changed, 239 insertions(+) create mode 100644 repos/domain/coredump_with_format.py diff --git a/repos/domain/coredump_with_format.py b/repos/domain/coredump_with_format.py new file mode 100644 index 000..f1f7c67 --- /dev/null +++ b/repos/domain/coredump_with_format.py @@ -0,0 +1,239 @@ +#!/usr/bin/env python +# test coreDumpWithFormat() API for libvirt + +import os +import libvirt +import thread + +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = ('guestname','topath','dumpformat','flags',) +optional_params = {} + +df = {"raw": libvirt.VIR_DOMAIN_CORE_DUMP_FORMAT_RAW, + "zlib": libvirt.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB, + "lzo": libvirt.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO, + "snappy": libvirt.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY} + +fg = {"mem": libvirt.VIR_DUMP_MEMORY_ONLY, + "reset": libvirt.VIR_DUMP_RESET, + "bypass": libvirt.VIR_DUMP_BYPASS_CACHE, + "live": libvirt.VIR_DUMP_LIVE, + "crash": libvirt.VIR_DUMP_CRASH} + +def check_crash_command(logger): +""" + check crash command on current OS +""" +CMD = "which crash" +status, output = utils.exec_cmd(CMD, shell=True) +if status != 0: +logger.info("Can not find crash command") +return False +else: +return True + +def check_dumpfile_type(topath,flags,logger): +""" + check file type of generated file +""" +GREP1 = "file %s |grep QEMU" +GREP2 = "file %s |grep ELF" +if flags < libvirt.VIR_DUMP_MEMORY_ONLY: +status, output = utils.exec_cmd(GREP1 % topath, shell=True) +if not status: +logger.info("Check type of %s: Pass, %s" % (topath, output[0])) +return True +else: +logger.info("Check type of %s: Fail, %s" % (topath, output[0])) +return False +elif flags >= libvirt.VIR_DUMP_MEMORY_ONLY: +status, output = utils.exec_cmd(GREP2 % topath, shell=True) +if not status: +logger.info("Check type of %s: Pass, %s" % (topath, output[0])) +return True +else: +logger.info("Check type of %s: Fail, %s" % (topath, output[0])) +return False + +def check_dump_file(*args): +""" + check whether core dump file is generated +""" +(core_file_path, logger) = args +if os.access(core_file_path, os.R_OK): +logger.info("Check core dump file %s: Pass" % core_file_path) +return True +else: +logger.info("Check core dump file %s: Fail" % core_file_path) +return False + +def compare_compress_type(topath,dumpformat,logger): +""" + check the compress type of file +""" +GREP = "crash -d1 %s | grep \"COMPRESSED\"" +status, output = utils.exec_cmd(GREP % topath, shell=True) +if not status: +temp1 = output[0].strip()[:-1].split("_")[-1] +if temp1 == dumpformat: +logger.info("Check compress type %s of %s: Pass" %(temp1,topath)) +return True +else: +logger.info("Check compress type %s of %s: Fail, %s" \ +%(temp1,topath,dumpformat)) +return False +else: +logger.error("Can not get compress type from given file %s" % topath) +return False + +def check_domain_state(vmstate,flags,logger): +""" + check domain state after doing coredump +""" +if libvirt.VIR_DUMP_CRASH == libvirt.VIR_DUMP_CRASH&flags: +if vmstate == [libvirt.VIR_DOMAIN_SHUTOFF,\ +libvirt.VIR_DOMAIN_SHUTOFF_CRASHED]: +logger.info("domain status is %s,shut off (crashed): Pass" \ +% vmstate) +return True +else: +logger.info("domain status is %s: Fail" % vmstate) +return False +else: +if vmstate == [libvirt.VIR_DOMAIN_RUNNING,\ +libvirt.VIR_DOMAIN_RUNNING_UNPAUSED]: +logger.info("domain status is %s,running (unpaused): Pass" \ +% vmstate) +return True +else: +logger.info("domain status is %s: Fail" % vmstate) +return False + +def get_fileflags(topath,logger): +""" + Get the file flags of coredump file +""" +CMD = "cat /proc/$(lsof -w %s|awk '/libvirt_i/{print $2}')/fdinfo/1 \ +|grep flags|awk '{print $NF}'" +global fileflags +while True: +(status, output) = utils.exec_cmd(CMD % topath, shell=True) +if status == 0: +if len(output) == 1: +logger.info("The flags of saved file %s " % output[0]) +fileflags = output[0][-5] +break +else: +logger.error("Fail to get the flags of saved file") +return 1 + +thread.exit_th
[libvirt] [libvirt-test-API][PATCH 2/2] Add coredump_with_format test case to linux_domain conf
--- cases/linux_domain.conf | 44 1 file changed, 44 insertions(+) diff --git a/cases/linux_domain.conf b/cases/linux_domain.conf index a5ada35..490ee90 100644 --- a/cases/linux_domain.conf +++ b/cases/linux_domain.conf @@ -34,6 +34,50 @@ domain:start guestname $defaultname +domain:coredump_with_format +guestname +$defaultname +topath +/root/test.dump +dumpformat +zlib +flags +mem + +domain:coredump_with_format +guestname +$defaultname +topath +/root/test.dump +dumpformat +raw +flags +mem|live|bypass + +domain:coredump_with_format +guestname +$defaultname +topath +/root/test.dump +dumpformat +snappy +flags +mem|reset + +domain:coredump_with_format +guestname +$defaultname +topath +/root/test.dump +dumpformat +lzo +flags +mem|crash|bypass + +domain:start +guestname +$defaultname + domain:destroy guestname $defaultname -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 0/2] Add securitylabel test case
The test case will check securityLabel() and securityLabelList() APIs. jiahu (2): Add securitylabel test case to linux_domain.conf Add securitylabel test case cases/linux_domain.conf | 4 + repos/domain/securitylabel.py | 170 ++ 2 files changed, 174 insertions(+) create mode 100644 repos/domain/securitylabel.py -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/2] Add securitylabel test case to linux_domain.conf
--- cases/linux_domain.conf | 4 1 file changed, 4 insertions(+) diff --git a/cases/linux_domain.conf b/cases/linux_domain.conf index a5ada35..552f001 100644 --- a/cases/linux_domain.conf +++ b/cases/linux_domain.conf @@ -34,6 +34,10 @@ domain:start guestname $defaultname +domain:securitylabel +guestname +$defaultname + domain:destroy guestname $defaultname -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 2/2] Add securitylabel test case
2 new APIs securityLabel and securityLabelList will be covered in securitylabel.py --- repos/domain/securitylabel.py | 170 ++ 1 file changed, 170 insertions(+) create mode 100644 repos/domain/securitylabel.py diff --git a/repos/domain/securitylabel.py b/repos/domain/securitylabel.py new file mode 100644 index 000..cf4aaf3 --- /dev/null +++ b/repos/domain/securitylabel.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# test securityLabel() and securityLabelList() API for libvirt + +import libvirt + +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = ('guestname',) +optional_params = {} + +def check_qemu_conf(logger): +""" + If security_driver is not equal to "selinux", report an error +""" +GREP = "grep \"^security_driver\" /etc/libvirt/qemu.conf" +status, output = utils.exec_cmd(GREP, shell=True) +if status: +return True +else: +if "selinux" in output[0]: +return True +else: +logger.error("Not a default setting in qemu.conf") +return False + +def get_security_policy(logger): +""" + get selinux type from host OS +""" +SELINUX = "getenforce" +status, output = utils.exec_cmd(SELINUX, shell=True) +if not status: +if output[0] == "Enforcing": +sevalue = True +elif output[0] == "Permissive": +sevalue = False +elif output[0] == "Disabled": +sevalue = False +else: +logger.error("Can not find any results") +else: +logger.error("\"" + SELINUX + "\"" + "error") +logger.error(output) +return False +return sevalue + +def get_pid(name,logger): +""" + get process id of specified domain. +""" +PID = "ps aux |grep -v grep | grep \" -name %s\" \ + |awk '{print $2}'" +status, output = utils.exec_cmd(PID % name, shell=True) +if not status: +pass +else: +logger.error("\"" + PID + "\"" + "error") +logger.error(output) +return False +return output[0] + +def get_pid_context(domain,logger): +""" + return context of domain's pid +""" +pid = get_pid(domain,logger) +CONTEXT = "ls -nZd /proc/%s" +status, output = utils.exec_cmd(CONTEXT % pid, shell=True) +if not status: +pass +else: +logger.error("\"" + CONTEXT + "\"" + "error") +logger.error(output) +return False +return pid,output[0] + +def check_selinux_label(api,domain,logger): +""" + check vaules in selinux mode +""" +pid,context = get_pid_context(domain,logger) +logger.debug("The context of %d is %s" % (int(pid), context)) +get_enforce = get_security_policy(logger) +if api[0] in context: +if api[1] == get_enforce: +logger.debug("PASS: '%s'" % api) +return True +else: +logger.debug("Fail: '%s'" % api[1]) +return False +else: + logger.debug("Fail: '%s'" % api[0]) + return False + +def check_DAC_label(api,domain,logger): +""" + check vaules in DAC mode +""" +tmp = [] +pid,context = get_pid_context(domain,logger) +logger.debug("The context of %d is %s" % (int(pid), context)) +#enforcing is always false in DAC mode +for item in api: + tmp.append(item) +get_enforce = False +tmp1 = tmp[0].strip().replace("+","") +tmp[0] = tmp1.split(':') +tmp1 = context.split() +context = str(tmp1.pop(1) +" "+ tmp1.pop(1)).split() +if tmp[0] == context: +if tmp[1] == get_enforce: +logger.debug("PASS: '%s'" % api) +return True +else: +logger.debug("Fail: '%s'" % api[1]) +return False +else: + logger.debug("Fail: '%s'" % api[0]) + return False + +def securitylabel(params): +""" + test APIs for securityLabel and securityLabelList in class virDomain +""" +logger = params['logger'] +domain_name = params['guestname'] +if not check_qemu_conf(logger): + return 1 +try: +conn = sharedmod.libvirtobj['conn'] + +if conn.lookupByName(domain_name): + dom = conn.lookupByName(domain_name) +else: + logger.error("Domain %s is not exist" % domain_name) + return 1 +if not dom.isActive(): + logger.error("Domain %s is not running" % domain_name) + return 1 + +first_label_api = dom.securityLabel() +logger.info("The first lable is %s" % first_label_api) + +if check_selinux_label(first_label_api, domain_name, logger): +logger.info("PASS, %s" % first_label_api) +else: +logger.error("FAIL, %s" % first_label_api) +return 1 + +all_label_api = dom.securityLabelList() +logger.info("The all lable is %s" % all_labe
Re: [libvirt] [libvirt-test-API][PATCH 0/2] Add API openGraphicsFD test case
On 01/06/2015 02:50 PM, Jincheng Miao wrote: Add API openGraphicsFD test case to linux_domain.conf Jincheng Miao (2): domain: add open_graphicsfd Add open_graphicsFD to linux_domain.conf cases/linux_domain.conf | 14 ++ repos/domain/open_graphicsfd.py | 89 +++ 2 files changed, 103 insertions(+), 0 deletions(-) create mode 100644 repos/domain/open_graphicsfd.py ACK BR, Jianwei -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 0/2] Fix some regression issues
Some issues were introduced by 137211d15 and efac4a3ec commits, fix them. jiahu (2): Give a default value on br variable in mac_to_ip Fix regression issues repos/domain/destroy.py | 4 ++-- repos/domain/install_linux_cdrom.py | 4 ++-- utils/utils.py | 7 ++- 3 files changed, 6 insertions(+), 9 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 2/2] Fix regression issues
1. Using .get method to get a optional dict value 2. Adjust variables sequence during call mac_to_ip --- repos/domain/destroy.py | 4 ++-- repos/domain/install_linux_cdrom.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/repos/domain/destroy.py b/repos/domain/destroy.py index 154ffaf..36f70db 100644 --- a/repos/domain/destroy.py +++ b/repos/domain/destroy.py @@ -32,7 +32,7 @@ def destroy(params): logger = params['logger'] params.pop('logger') guestname = params['guestname'] -br = params['bridgename'] +br = params.get('bridgename','virbr0') flags = "" if params.has_key('flags'): flags = params['flags'] @@ -59,7 +59,7 @@ def destroy(params): # Get domain ip mac = utils.get_dom_mac_addr(guestname) logger.info("get ip by mac address") -ip = utils.mac_to_ip(mac,br,180) +ip = utils.mac_to_ip(mac,180,br) logger.info("the ip address of guest is %s" % ip) # Destroy domain diff --git a/repos/domain/install_linux_cdrom.py b/repos/domain/install_linux_cdrom.py index 9d3a7e9..412712b 100644 --- a/repos/domain/install_linux_cdrom.py +++ b/repos/domain/install_linux_cdrom.py @@ -147,7 +147,7 @@ def install_linux_cdrom(params): guestname = params.get('guestname') guestos = params.get('guestos') guestarch = params.get('guestarch') -br = params['bridgename'] +br = params.get('bridgename','virbr0') xmlstr = params['xml'] logger.info("the name of guest is %s" % guestname) @@ -304,7 +304,7 @@ def install_linux_cdrom(params): time.sleep(10) timeout -= 10 -ip = utils.mac_to_ip(mac,br,180) +ip = utils.mac_to_ip(mac,180,br) if not ip: logger.info(str(timeout) + "s left") -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH 1/2] Give a default value on br variable in mac_to_ip
Set 'virbr0' as defult value --- utils/utils.py | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utils/utils.py b/utils/utils.py index f841c27..c3e46f6 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -349,17 +349,14 @@ def locate_utils(): result = re.search('(.*)libvirt-test-API(.*)', pwd) return result.group(0) + "/utils" -def mac_to_ip(mac,br,timeout): -"""Map mac address to ip +def mac_to_ip(mac, timeout, br = 'virbr0'): +"""Map mac address to ip under a specified brige Return None on FAILURE and the mac address on SUCCESS """ if not mac: return None -if not br: -return None - if timeout < 10: timeout = 10 -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 05/11] Add xml file for of IPv6 family
Added a new file to store static host of IPv6 --- repos/network/xmls/ipv6-dhcp-host.xml | 1 + 1 file changed, 1 insertion(+) create mode 100644 repos/network/xmls/ipv6-dhcp-host.xml diff --git a/repos/network/xmls/ipv6-dhcp-host.xml b/repos/network/xmls/ipv6-dhcp-host.xml new file mode 100644 index 000..6198815 --- /dev/null +++ b/repos/network/xmls/ipv6-dhcp-host.xml @@ -0,0 +1 @@ + -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 07/11] Change bridge name as a variable in functions
The function can get ip when domain has a non-default virual network --- utils/ipget.sh | 7 ++- utils/utils.py | 7 +-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/utils/ipget.sh b/utils/ipget.sh index 8d44b14..c2e0983 100755 --- a/utils/ipget.sh +++ b/utils/ipget.sh @@ -1,17 +1,22 @@ #!/bin/sh mac=$1 +br=$2 if [[ -z $mac ]]; then echo "mac address is null." exit 1 fi +if [[ -z $br ]]; then + echo "bridge name is null." + exit 1 +fi if ! type nmap >/dev/null 2>&1; then echo "nmap package needs to be installed." exit 1 fi -ipaddr=`ip route |grep virbr0 |sed -n 1p|awk {'print $1'}` +ipaddr=`ip route |grep $br |sed -n 1p|awk {'print $1'}` #if lsmod | grep kvm > /dev/null ;then # ipaddr=`ip route |grep switch |sed -n 1p|awk {'print $1'}` diff --git a/utils/utils.py b/utils/utils.py index 147c1ef..f841c27 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -349,7 +349,7 @@ def locate_utils(): result = re.search('(.*)libvirt-test-API(.*)', pwd) return result.group(0) + "/utils" -def mac_to_ip(mac, timeout): +def mac_to_ip(mac,br,timeout): """Map mac address to ip Return None on FAILURE and the mac address on SUCCESS @@ -357,10 +357,13 @@ def mac_to_ip(mac, timeout): if not mac: return None +if not br: +return None + if timeout < 10: timeout = 10 -cmd = "sh " + locate_utils() + "/ipget.sh " + mac +cmd = "sh " + locate_utils() + "/ipget.sh " + mac + " " + br while timeout > 0: (ret, out) = commands.getstatusoutput(cmd) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 11/11] Add network_dhcp_leases test case to conf
For running the case, should setup testing environment before the case, and clean up the environment after the case. --- cases/basic_network.conf | 100 +++ 1 file changed, 100 insertions(+) diff --git a/cases/basic_network.conf b/cases/basic_network.conf index e9abd57..b617320 100644 --- a/cases/basic_network.conf +++ b/cases/basic_network.conf @@ -216,3 +216,103 @@ network:destroy networkname $defaultnetname +network:define +networkname +$defaultnetname +bridgename +$defaultbridgename +bridgeip +$defaultnetip +bridgenetmask +$defaultnetmask +netstart +$defaultnetstart +netend +$defaultnetend +netmode +nat +netip6addr +$netip6addr +netip6prefix +$netip6prefix +netip6start +$netip6start +netip6end +$netip6end + +network:start +networkname +$defaultnetname + +network:update +networkname +$defaultnetname +command +add-first +section +ip-dhcp-host +xml +xmls/ip-dhcp-host.xml + +network:update +networkname + $defaultnetname +command +add-first +section +ip-dhcp-host +parentIndex +1 +xml + xmls/ipv6-dhcp-host.xml + +domain:install_linux_cdrom +guestname +$defaultname +guestos +rhel6 +guestarch +$defaultarch +vcpu +$defaultvcpu +memory +$defaultmem +hddriver +$defaulthd +nicdriver +$defaultnic +macaddr +00:16:3e:77:e2:ed +networksource +$defaultnetname +bridgename +$defaultbridgename + +network:network_dhcp_leases +networkname +$defaultnetname + +network:network_dhcp_leases +networkname +$defaultnetname +macaddr +00:16:3e:77:e2:ed + +domain:destroy +guestname +$defaultname +bridgename +$defaultbridgename + +domain:undefine +guestname +$defaultname + +network:destroy +networkname +$defaultnetname + +network:undefine +networkname +$defaultnetname + -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 06/11] Remove extra space from xml
--- repos/network/xmls/ip-dhcp-host.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/network/xmls/ip-dhcp-host.xml b/repos/network/xmls/ip-dhcp-host.xml index 50e7908..b323218 100644 --- a/repos/network/xmls/ip-dhcp-host.xml +++ b/repos/network/xmls/ip-dhcp-host.xml @@ -1 +1 @@ - + -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 04/11] Add IPv6 section into related network case
Added 4 IPv6 required parameters to case. --- repos/network/define.py | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/repos/network/define.py b/repos/network/define.py index dd054f7..6e50eb7 100644 --- a/repos/network/define.py +++ b/repos/network/define.py @@ -17,7 +17,12 @@ required_params = ('networkname', 'bridgenetmask', 'netstart', 'netend', - 'netmode',) + 'netmode', + 'netip6addr', + 'netip6prefix', + 'netip6start', + 'netip6end', + ) optional_params = {'xml' : 'xmls/network.xml', } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 09/11] Change bridge name as a variable in XML
--- repos/domain/xmls/kvm_linux_guest_install_cdrom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/domain/xmls/kvm_linux_guest_install_cdrom.xml b/repos/domain/xmls/kvm_linux_guest_install_cdrom.xml index cb59e76..1e7999b 100644 --- a/repos/domain/xmls/kvm_linux_guest_install_cdrom.xml +++ b/repos/domain/xmls/kvm_linux_guest_install_cdrom.xml @@ -28,7 +28,7 @@ - + -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 10/11] Support brige name argument in cases
--- repos/domain/destroy.py | 5 +++-- repos/domain/install_linux_cdrom.py | 5 - 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/repos/domain/destroy.py b/repos/domain/destroy.py index 91e83ea..154ffaf 100644 --- a/repos/domain/destroy.py +++ b/repos/domain/destroy.py @@ -12,7 +12,7 @@ from src import sharedmod from utils import utils required_params = ('guestname',) -optional_params = {'flags' : 'noping'} +optional_params = {'flags' : 'noping','bridgename' : 'virbr0',} def destroy(params): """destroy domain @@ -32,6 +32,7 @@ def destroy(params): logger = params['logger'] params.pop('logger') guestname = params['guestname'] +br = params['bridgename'] flags = "" if params.has_key('flags'): flags = params['flags'] @@ -58,7 +59,7 @@ def destroy(params): # Get domain ip mac = utils.get_dom_mac_addr(guestname) logger.info("get ip by mac address") -ip = utils.mac_to_ip(mac, 180) +ip = utils.mac_to_ip(mac,br,180) logger.info("the ip address of guest is %s" % ip) # Destroy domain diff --git a/repos/domain/install_linux_cdrom.py b/repos/domain/install_linux_cdrom.py index 239f85e..9d3a7e9 100644 --- a/repos/domain/install_linux_cdrom.py +++ b/repos/domain/install_linux_cdrom.py @@ -30,6 +30,8 @@ optional_params = { 'type' : 'define', 'xml': 'xmls/kvm_linux_guest_install_cdrom.xml', 'guestmachine': 'pc', + 'networksource': 'default', + 'bridgename': 'virbr0', } VIRSH_QUIET_LIST = "virsh --quiet list --all|awk '{print $2}'|grep \"^%s$\"" @@ -145,6 +147,7 @@ def install_linux_cdrom(params): guestname = params.get('guestname') guestos = params.get('guestos') guestarch = params.get('guestarch') +br = params['bridgename'] xmlstr = params['xml'] logger.info("the name of guest is %s" % guestname) @@ -301,7 +304,7 @@ def install_linux_cdrom(params): time.sleep(10) timeout -= 10 -ip = utils.mac_to_ip(mac, 180) +ip = utils.mac_to_ip(mac,br,180) if not ip: logger.info(str(timeout) + "s left") -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 08/11] Obtain a IPv6 addr on interface
--- kickstart.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kickstart.cfg b/kickstart.cfg index 446adf0..d4b40a8 100644 --- a/kickstart.cfg +++ b/kickstart.cfg @@ -6,7 +6,7 @@ url --url=http://fileshare.englab.nay.redhat.com/pub/redhat/rhel/released/RHEL-6 lang en_US.UTF-8 keyboard us -network --device eth0 --bootproto dhcp +network --device eth0 --bootproto dhcp --ipv6 dhcp rootpw --iscrypted $6$45lFuCoyFZwpy3Gn$kvCuoEVXyK0q6ow7qBmo9vaEyajunJ62LR5HlmAKRAOpK/Z2ZyrSSbaPsSHnhZU2P1MF5e.QDu2wkOOo661It. zerombr clearpart --all --initlabel -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 01/11] Add network_dhcp_leases test case
The network_dhcp_leases.py uses DHCPLeases() to validate new API virNetworkGetDHCPLeases of libvirt. --- repos/network/network_dhcp_leases.py | 277 +++ 1 file changed, 277 insertions(+) create mode 100644 repos/network/network_dhcp_leases.py diff --git a/repos/network/network_dhcp_leases.py b/repos/network/network_dhcp_leases.py new file mode 100644 index 000..4a39579 --- /dev/null +++ b/repos/network/network_dhcp_leases.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python +#test DHCPLeases() API for libvirt + +import os +import time +import libvirt +from libvirt import libvirtError +from utils import utils +from src import sharedmod + +required_params = ('networkname',) +optional_params = {'macaddr': ''} + +LEASE_FILE = "/var/lib/libvirt/dnsmasq/" + +def check_ip(ipaddr, logger): +""" + return a string according to ip address type, return 'ipv4' for ipv4, + return 'ipv6' for ipv6, return False for others +""" +addr4 = ipaddr.strip().split('.') +addr6 = ipaddr.strip().split(':') +if len(addr4) == 4: +iptype = "ipv4" +elif len(addr6) == 6: +iptype = "ipv6" +else: +return False +return iptype + +def get_network_type(ipaddr,logger): +""" + return 0 or 1 for ipv4/ipv6, this function will be used in + check_ipv4_values()/check_ipv6_values() +""" +if check_ip(ipaddr, logger) == "ipv4": +return 0 +elif check_ip(ipaddr, logger) == "ipv6": +return 1 + +def get_bridge_name(network,logger): +""" + get bridge name under specified network from specified network conf +""" +CONF_NETWORK = LEASE_FILE + network + ".conf" +GREP_BRIDGE = "grep \"^interface=\" %s | awk -F\"=\" '{print $2}'" +status, output = utils.exec_cmd(GREP_BRIDGE % CONF_NETWORK, shell=True) +if not status: +pass +else: +logger.error("\"" + GREP_BRIDGE + "\"" + "error") +logger.error(output) +return False +return output[0] + +def get_ip_prefix(network, iptype, logger): +""" + get ip prefix according to IP type +""" +br = get_bridge_name(network, logger) +PREFIX = "ip -4 -o ad show %s | awk '{print $4}'|awk -F\"/\" '{print $2}'" +PREFIX_6 = "ip -6 -o ad show %s|awk '{print $4}'|awk -F\"/\" '{print $2}'" +if iptype == "ipv4": +status, output = utils.exec_cmd(PREFIX % br, shell=True) +elif iptype == "ipv6": +status, output = utils.exec_cmd(PREFIX_6 % br, shell=True) +if not status: +pass +else: +logger.error("\"" + GREP_BRIDGE + "\"" + "error") +logger.error(output) +return False +return output[0] + +def get_info_from_dnsmasq(network,macaddr,logger): +""" + generate dict for lease info from virtual network's lease file +""" +title = ['expirytime','mac','ipaddr','hostname','clientid'] +output_list = [] +lease_dnsmasq = [] +temp = [] +remove_list = [] +GREP_MAC = "grep -w %s" + " " + LEASE_FILE_DNSMASQ +CAT_FILE = "cat" + " " + LEASE_FILE_DNSMASQ + +status, output = utils.exec_cmd(CAT_FILE, shell=True) +if not status: +for i in range(0, len(output)): +output_list = [] +output_str = output[i] +for item in output_str.split(" "): +output_list.append(item) +lease_dnsmasq.append(dict(zip(title,output_list))) + +#due to no mac field in IPv6 line, so do nothing here temporarily. +if macaddr != None: + pass + +#remove bridge duid line +for i in range(0, len(lease_dnsmasq)): +if lease_dnsmasq[i]['expirytime'] == 'duid': +remove_list.append(lease_dnsmasq[i]) + +for i in range(0, len(remove_list)): +lease_dnsmasq.remove(remove_list[i]) + +#remove expiry leases +for i in range(0, len(lease_dnsmasq)): +temp = int(lease_dnsmasq[i]['expirytime']) +lease_dnsmasq[i]['expirytime'] = temp + +remove_list = [] +for i in range(0, len(lease_dnsmasq)): +if time.time() >= int(lease_dnsmasq[i]['expirytime']): +remove_list.append(lease_dnsmasq[i]) + +for i in range(0, len(remove_list)): +lease_dnsmasq.remove(remove_list[i]) + +#replace * to None +for i in range(0, len(lease_dnsmasq)): +if lease_dnsmasq[i]['hostname'] == "*": +lease_dnsmasq[i]['hostname'] = None +if lease_dnsmasq[i]['clientid'] == "*": +lease_dnsmasq[i]['clientid'] = None + +return lease_dnsmasq +else: +logger.error("\"" + CAT_FILE + "\"" + "error") +logger.error(output) +return False + +def compare_values(op1, op2, network, iptype, logger): +""" + check all printed values from API +""" +dnsmasq = op1 +api = op2 +temp = int(api['expirytime']) +api['expirytime'] =
[libvirt] [libvirt-test-API][PATCH V2 02/11] Add global IPv6 default values to network part
Added below variables into global.cfg. netip6addr/netip6prefix/netip6start/netip6end --- global.cfg | 9 + 1 file changed, 9 insertions(+) diff --git a/global.cfg b/global.cfg index db8f71e..56677a5 100644 --- a/global.cfg +++ b/global.cfg @@ -195,6 +195,15 @@ defaultnetstart = 192.168.111.2 # default the ending address ip defaultnetend = 192.168.111.254 +# default bridge ipv6 addr +netip6addr = 2001:db8:ca2:99::1 +# default bridge ipv6 prefix +netip6prefix = 64 +# default the starting ipv6 address +netip6start = 2001:db8:ca2:99::11 +# default the ending ipv6 address +netip6end = 2001:db8:ca2:99::ff + # # host interface -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 03/11] Add IPv6 section into network template xml
--- repos/network/xmls/network.xml | 5 + 1 file changed, 5 insertions(+) diff --git a/repos/network/xmls/network.xml b/repos/network/xmls/network.xml index 220169b..97e3517 100644 --- a/repos/network/xmls/network.xml +++ b/repos/network/xmls/network.xml @@ -7,4 +7,9 @@ + + + + + -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH V2 00/11] Add network_dhcp_leases test case
For checking IPv6 address, libvirt need a IPv6 testing environment, so modified some cases and configuration files, also there are some small changes for other requirements. There are 9 new commits after comparing with the V1: Add global IPv6 default values to network part Add IPv6 section into network template xml Add IPv6 section into related network case Add xml file for of IPv6 family Remove extra space from xml Change bridge name as a variable in functions Obtain a IPv6 addr on interface Change bridge name as a variable in XML Support brige name argument in cases According to those new commits in V2, updated its conf. Add network_dhcp_leases test case to conf jiahu (11): Add network_dhcp_leases test case Add global IPv6 default values to network part Add IPv6 section into network template xml Add IPv6 section into related network case Add xml file for of IPv6 family Remove extra space from xml Change bridge name as a variable in functions Obtain a IPv6 addr on interface Change bridge name as a variable in XML Support brige name argument in cases Add network_dhcp_leases test case to conf cases/basic_network.conf | 100 global.cfg | 9 + kickstart.cfg | 2 +- repos/domain/destroy.py| 5 +- repos/domain/install_linux_cdrom.py| 5 +- .../domain/xmls/kvm_linux_guest_install_cdrom.xml | 2 +- repos/network/define.py| 7 +- repos/network/network_dhcp_leases.py | 277 + repos/network/xmls/ip-dhcp-host.xml| 2 +- repos/network/xmls/ipv6-dhcp-host.xml | 1 + repos/network/xmls/network.xml | 5 + utils/ipget.sh | 7 +- utils/utils.py | 7 +- 13 files changed, 419 insertions(+), 10 deletions(-) create mode 100644 repos/network/network_dhcp_leases.py create mode 100644 repos/network/xmls/ipv6-dhcp-host.xml -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add global IPv6 default values to network part
Added below variables into global.cfg. netip6addr/netip6prefix/netip6start/netip6end --- global.cfg | 9 + 1 file changed, 9 insertions(+) diff --git a/global.cfg b/global.cfg index db8f71e..56677a5 100644 --- a/global.cfg +++ b/global.cfg @@ -195,6 +195,15 @@ defaultnetstart = 192.168.111.2 # default the ending address ip defaultnetend = 192.168.111.254 +# default bridge ipv6 addr +netip6addr = 2001:db8:ca2:99::1 +# default bridge ipv6 prefix +netip6prefix = 64 +# default the starting ipv6 address +netip6start = 2001:db8:ca2:99::11 +# default the ending ipv6 address +netip6end = 2001:db8:ca2:99::ff + # # host interface -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add IPv6 section into network case
Add IPv6 family related scenarios to virtual network case --- cases/basic_network.conf | 8 repos/network/define.py| 7 ++- repos/network/xmls/network.xml | 5 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cases/basic_network.conf b/cases/basic_network.conf index e9abd57..5d1438e 100644 --- a/cases/basic_network.conf +++ b/cases/basic_network.conf @@ -13,6 +13,14 @@ network:define $defaultnetend netmode nat +netip6addr +$netip6addr +netip6prefix +$netip6prefix +netip6start +$netip6start +netip6end +$netip6end network:network_list flags diff --git a/repos/network/define.py b/repos/network/define.py index dd054f7..6e50eb7 100644 --- a/repos/network/define.py +++ b/repos/network/define.py @@ -17,7 +17,12 @@ required_params = ('networkname', 'bridgenetmask', 'netstart', 'netend', - 'netmode',) + 'netmode', + 'netip6addr', + 'netip6prefix', + 'netip6start', + 'netip6end', + ) optional_params = {'xml' : 'xmls/network.xml', } diff --git a/repos/network/xmls/network.xml b/repos/network/xmls/network.xml index 220169b..97e3517 100644 --- a/repos/network/xmls/network.xml +++ b/repos/network/xmls/network.xml @@ -7,4 +7,9 @@ + + + + + -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add network_dhcp_leases test case to conf
For running the case, should setup testing environment before the case, and clean up the environment after the case. --- cases/basic_network.conf | 55 1 file changed, 55 insertions(+) diff --git a/cases/basic_network.conf b/cases/basic_network.conf index e9abd57..3ab9cb1 100644 --- a/cases/basic_network.conf +++ b/cases/basic_network.conf @@ -216,3 +216,58 @@ network:destroy networkname $defaultnetname +network:update +networkname +default +command +add-first +section +ip-dhcp-host +xml +xmls/ip-dhcp-host.xml + +domain:install_linux_cdrom +guestname +dhcplease +guestos +rhel6 +guestarch +$defaultarch +vcpu +$defaultvcpu +memory +$defaultmem +hddriver +$defaulthd +nicdriver +$defaultnic +macaddr +00:16:3e:77:e2:ed + +network:network_dhcp_leases +networkname +default + +network:network_dhcp_leases +networkname +default +macaddr +00:16:3e:77:e2:ed + +network:update +networkname +default +command +delete +section +ip-dhcp-host +xml +xmls/ip-dhcp-host.xml + +domain:destroy +guestname +dhcplease + +domain:undefine +guestname +dhcplease -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Add network_dhcp_leases test case
The network_dhcp_leases.py uses DHCPLeases() to validate new API virNetworkGetDHCPLeases of libvirt. --- repos/network/network_dhcp_leases.py | 277 +++ 1 file changed, 277 insertions(+) create mode 100644 repos/network/network_dhcp_leases.py diff --git a/repos/network/network_dhcp_leases.py b/repos/network/network_dhcp_leases.py new file mode 100644 index 000..29ee529 --- /dev/null +++ b/repos/network/network_dhcp_leases.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python +#test DHCPLeases() API for libvirt + +import os +import time +import libvirt +from libvirt import libvirtError +from utils import utils +from src import sharedmod + +required_params = ('networkname',) +optional_params = {'macaddr': ''} + +LEASE_FILE = "/var/lib/libvirt/dnsmasq/" + +def check_ip(ipaddr, logger): +""" + return a string according to ip address type, return 'ipv4' for ipv4, + return 'ipv6' for ipv6, return False for others +""" +addr4 = ipaddr.strip().split('.') +addr6 = ipaddr.strip().split(':') +if len(addr4) == 4: +iptype = "ipv4" +elif len(addr6) == 6: +iptype = "ipv6" +else: +return False +return iptype + +def get_network_type(ipaddr,logger): +""" + return 0 or 1 for ipv4/ipv6, this function will be used in + check_ipv4_values()/check_ipv6_values() +""" +if check_ip(ipaddr, logger) == "ipv4": +return 0 +elif check_ip(ipaddr, logger) == "ipv6": +return 1 + +def get_bridge_name(network,logger): +""" + get bridge name under specified network from specified network conf +""" +CONF_NETWORK = LEASE_FILE + network + ".conf" +GREP_BRIDGE = "grep \"^interface=\" %s | awk -F\"=\" '{print $2}'" +status, output = utils.exec_cmd(GREP_BRIDGE % CONF_NETWORK, shell=True) +if not status: +pass +else: +logger.error("\"" + GREP_BRIDGE + "\"" + "error") +logger.error(output) +return False +return output[0] + +def get_ip_prefix(network, iptype, logger): +""" + get ip prefix according to IP type +""" +br = get_bridge_name(network, logger) +PREFIX = "ip -4 -o ad show %s | awk '{print $4}'|awk -F\"/\" '{print $2}'" +PREFIX_6 = "ip -6 -o ad show %s|awk '{print $4}'|awk -F\"/\" '{print $2}'" +if iptype == "ipv4": +status, output = utils.exec_cmd(PREFIX % br, shell=True) +elif iptype == "ipv6": +status, output = utils.exec_cmd(PREFIX_6 % br, shell=True) +if not status: +pass +else: +logger.error("\"" + GREP_BRIDGE + "\"" + "error") +logger.error(output) +return False +return output[0] + +def get_info_from_dnsmasq(network,macaddr,logger): +""" + generate dict for lease info from virtual network's lease file +""" +title = ['expirytime','mac','ipaddr','hostname','clientid'] +output_list = [] +lease_dnsmasq = [] +temp = [] +remove_list = [] +GREP_MAC = "grep -w %s" + " " + LEASE_FILE_DNSMASQ +CAT_FILE = "cat" + " " + LEASE_FILE_DNSMASQ + +status, output = utils.exec_cmd(CAT_FILE, shell=True) +if not status: +for i in range(0, len(output)): +output_list = [] +output_str = output[i] +for item in output_str.split(" "): +output_list.append(item) +lease_dnsmasq.append(dict(zip(title,output_list))) + +#due to no mac field in IPv6 line, so do nothing here temporarily. +if macaddr != None: + pass + +#remove bridge duid line +for i in range(0, len(lease_dnsmasq)): +if lease_dnsmasq[i]['expirytime'] == 'duid': +remove_list.append(lease_dnsmasq[i]) + +for i in range(0, len(remove_list)): +lease_dnsmasq.remove(remove_list[i]) + +#remove expiry leases +for i in range(0, len(lease_dnsmasq)): +temp = int(lease_dnsmasq[i]['expirytime']) +lease_dnsmasq[i]['expirytime'] = temp + +remove_list = [] +for i in range(0, len(lease_dnsmasq)): +if time.time() >= int(lease_dnsmasq[i]['expirytime']): +remove_list.append(lease_dnsmasq[i]) + +for i in range(0, len(remove_list)): +lease_dnsmasq.remove(remove_list[i]) + +#replace * to None +for i in range(0, len(lease_dnsmasq)): +if lease_dnsmasq[i]['hostname'] == "*": +lease_dnsmasq[i]['hostname'] = None +if lease_dnsmasq[i]['clientid'] == "*": +lease_dnsmasq[i]['clientid'] = None + +return lease_dnsmasq +else: +logger.error("\"" + CAT_FILE + "\"" + "error") +logger.error(output) +return False + +def compare_values(op1, op2, network, iptype, logger): +""" + check all printed values from API +""" +dnsmasq = op1 +api = op2 +temp = int(api['expirytime']) +api['expirytime'] =
[libvirt] [libvirt-test-API][PATCH] Add connection_cpu_models test case
The connection_cpu_models.py uses getCPUModelNames() to validate new API virConnectGetCPUModelNames of libvirt. --- cases/test_connection.conf | 12 + repos/virconn/connection_cpu_models.py | 82 ++ 2 files changed, 94 insertions(+) create mode 100644 repos/virconn/connection_cpu_models.py diff --git a/cases/test_connection.conf b/cases/test_connection.conf index ccde119..e916886 100644 --- a/cases/test_connection.conf +++ b/cases/test_connection.conf @@ -29,3 +29,15 @@ virconn:connection_nodeinfo virconn:connection_version conn lxc:/// + +virconn:connection_cpu_models +arch +x86_64 + +virconn:connection_cpu_models +arch +i686 + +virconn:connection_cpu_models +arch +ppc64 diff --git a/repos/virconn/connection_cpu_models.py b/repos/virconn/connection_cpu_models.py new file mode 100644 index 000..4588188 --- /dev/null +++ b/repos/virconn/connection_cpu_models.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# test getCPUModelNames() API for libvirt + +import os +import libvirt + +from xml.dom import minidom +from libvirt import libvirtError +from src import sharedmod +from utils import utils + +required_params = ('arch',) +optional_params = {} + +CPU_MAP_FILE = "/usr/share/libvirt/cpu_map.xml" + +def get_cpu_archs_from_xml(logger): +""" + return supported cpu archs from cpu_map.xml +""" +cpu_archs_from_xml = [] +xml = minidom.parse(CPU_MAP_FILE) +for arch in xml.getElementsByTagName('arch'): +cpu_archs_from_xml.append(str(arch.getAttribute('name'))) +return cpu_archs_from_xml + +def get_cpu_models_from_xml(arch, logger): +""" + return supported cpu models from cpu_map.xml +""" +cpu_models_from_xml = [] +if arch == 'x86_64' or arch == 'i686': + real_arch = 'x86' +else: + real_arch = arch + +xml = minidom.parse(CPU_MAP_FILE) +for model in xml.getElementsByTagName('model'): +if model.parentNode.getAttribute('name') == real_arch: +cpu_models_from_xml.append(str(model.getAttribute('name'))) +return cpu_models_from_xml + +def connection_cpu_models(params): +""" + test API for getCPUModelNames in class virConnect +""" +logger = params['logger'] +arch_value = params['arch'] +try: +logger.info("get cpu archs from cpu_map.xml") +if not os.path.exists(CPU_MAP_FILE): + logger.error("%s is not exist" % CPU_MAP_FILE) + return 1 +cpu_archs_from_xml = get_cpu_archs_from_xml(logger) +logger.info("The supported cpu archs in xml are %s" \ + % cpu_archs_from_xml) +cpu_models_from_xml = get_cpu_models_from_xml(arch_value, logger) +logger.info("The supported cpu models in xml are %s" \ + % cpu_models_from_xml) + +conn = sharedmod.libvirtobj['conn'] + +cpu_models_from_libvirt = conn.getCPUModelNames(arch_value ,0) +logger.info("The specified architecture is %s" \ +% arch_value) +logger.info("The supported cpu models is %s" \ +% cpu_models_from_libvirt) + +#compare with cpu_map.xml +for cpu_model in cpu_models_from_libvirt: +if cpu_model in cpu_models_from_xml: +logger.debug("'%s' model: PASS" % cpu_model) +else: +logger.debug("'%s' model: FAIL, not in libvirt"\ + % cpu_model) +return 1 +logger.debug("check all cpu models: PASS") +except libvirtError, e: +logger.error("API error message: %s" % e.message) +return 1 + +return 0 -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [libvirt-test-API][PATCH] Rewrite case for listAllInterfaces() API
Using actual python API to validate test case, rather than use virsh iface-* command lines. --- cases/basic_interface.conf| 12 ++ repos/interface/iface_list.py | 299 -- 2 files changed, 99 insertions(+), 212 deletions(-) diff --git a/cases/basic_interface.conf b/cases/basic_interface.conf index e2125bb..43e37e8 100644 --- a/cases/basic_interface.conf +++ b/cases/basic_interface.conf @@ -15,3 +15,15 @@ interface:define interface:create ifacename $testnic + +interface:iface_list +flags +all + +interface:iface_list +flags +active + +interface:iface_list +flags +inactive diff --git a/repos/interface/iface_list.py b/repos/interface/iface_list.py index 49f0c05..85f9df9 100644 --- a/repos/interface/iface_list.py +++ b/repos/interface/iface_list.py @@ -1,65 +1,26 @@ #!/usr/bin/env python +# test listAllInterfaces() API import os -import sys -import re -import commands +import libvirt -required_params = ('ifaceopt',) -optional_params = {} - -VIRSH_QUIET_IFACE_LIST = "virsh --quiet iface-list %s | awk '{print ""$%s""}'" -NETWORK_CONFIG = "/etc/sysconfig/network-scripts/" -IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'" -GET_MAC = "ip link show %s |sed -n '2p'| awk '{print $2}'" -VIRSH_IFACE_LIST = "virsh iface-list %s" - -names = [] -state = [] -macs = [] - -def get_option_list(params): -"""return options we need to test -""" -logger = params['logger'] -option_list=[] +from libvirt import libvirtError +from src import sharedmod +from utils import utils -value = params['ifaceopt'] -if value == 'all': -option_list = [' ', '--all', '--inactive'] -elif value == '--all' or value == '--inactive': -option_list.append(value) -else: -logger.error("value %s is not supported" % value) -return 1, option_list +required_params = ('flags',) +optional_params = {} -return 0, option_list +NETWORK_CONFIG = "/etc/sysconfig/network-scripts/" +IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'| cut -d \":\" -f -1" -def get_output(command, logger): -"""execute shell command +def get_inteface_list_from_ifcfg(logger): +""" + return host interface list from ifcfg-* """ -status, ret = commands.getstatusoutput(command) -if status: -logger.error("executing "+ "\"" + command + "\"" + " failed") -logger.error(ret) -return status, ret - -def get_interface_list(option, logger): -""" return active host interface list """ -interface_list = [] -status, interface_str = get_output(IFCONFIG_DRIVER % option, logger) -if not status: -interface_list = interface_str.split('\n') -return interface_list -else: -logger.error("\"" + IFCONFIG_DRIVER % option + "\"" + "error") -logger.error(interface_str) -return interface_list - -def check_ifacename(names, option, logger): -""" verify the validity of output data """ ifcfg_files = [] +nic_names = [] for f in os.listdir(NETWORK_CONFIG): if f.startswith("ifcfg-"): f_path = os.path.join(NETWORK_CONFIG, f) @@ -67,18 +28,6 @@ def check_ifacename(names, option, logger): ifcfg_files.append(f_path) else: logger.warn("%s is not a regular file" % f_path) - -interface_active = get_interface_list('', logger) -logger.debug("list of active host interface: %s" % interface_active) -if interface_active == None: -return 1 - -interface_all = get_interface_list('-a', logger) -logger.debug("list of all host interface: %s" % interface_all) -if interface_all == None: -return 1 - - for ifcfg_file in ifcfg_files: fp = open(ifcfg_file, 'r') fp.seek(0,0) @@ -87,165 +36,91 @@ def check_ifacename(names, option, logger): device_str = eachLine.rstrip() nic_string = device_str.split("=")[1] if nic_string.startswith("\""): -nic_name = nic_string[1:-1] +nic_names = nic_string[1:-1] else: -nic_name = nic_string +nic_names.append(nic_string) break - fp.close() +return list(set(nic_names)) -if option == ' ': -if nic_name not in interface_active: -continue -else: -if nic_name in names: -logger.info("it contains interface %s in %s" % (nic_name, ifcfg_file)) -else: -logger.error("interface %s in %s couldn't \n\ - be in the output of virsh iface-list with option %s" % \ - (nic_name, ifcfg_file, option)) -return 1 -elif option == '--all': -if nic_name in names: -logger.info("it contains interface %
[libvirt] [libvirt-test-API][PATCH] Remove redundant colon in inteface list
The interface list should be: ['em1', 'lo', 'virbr0', 'wlp3s0'] rather than below: ['em1:', 'lo:', 'virbr0:', 'wlp3s0:'] --- repos/interface/iface_list.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/repos/interface/iface_list.py b/repos/interface/iface_list.py index 49f0c05..7041535 100644 --- a/repos/interface/iface_list.py +++ b/repos/interface/iface_list.py @@ -10,7 +10,8 @@ optional_params = {} VIRSH_QUIET_IFACE_LIST = "virsh --quiet iface-list %s | awk '{print ""$%s""}'" NETWORK_CONFIG = "/etc/sysconfig/network-scripts/" -IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'" +IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'\ +|awk -F\":\" '{print $1}'" GET_MAC = "ip link show %s |sed -n '2p'| awk '{print $2}'" VIRSH_IFACE_LIST = "virsh iface-list %s" -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Error out on missing address in 'server' type interface
On 08/15/2014 04:21 PM, Ján Tomko wrote: It was possible to add the following interface: Resulting in: error: internal error Process exited while reading console log output: char device redirected to /dev/pts/4 2014-08-15T05:59:17.348271Z qemu-kvm: -netdev socket,listen=(null):5558,id=hostnet0: Device 'socket' could not be initialized We already do this check for NET_TYPE_CLIENT and NET_TYPE_MCAST, do it also for NET_TYPE_SERVER. https://bugzilla.redhat.com/show_bug.cgi?id=1130390 --- src/conf/domain_conf.c | 11 --- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5c762fa..7ea628c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7118,13 +7118,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, } if (address == NULL) { -if (def->type == VIR_DOMAIN_NET_TYPE_CLIENT || -def->type == VIR_DOMAIN_NET_TYPE_MCAST) { -virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("No 'address' attribute " - "specified with socket interface")); -goto error; -} +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No 'address' attribute " + "specified with socket interface")); +goto error; } else { def->data.socket.address = address; address = NULL; I think domaincommon.rng should have a sync change, address element is a mandatory in client and mcast type. Is it necessary? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Clear bandwidth settings for a shutoff domain using domiftune
On 08/11/2014 06:05 PM, Michal Privoznik wrote: On 11.08.2014 08:41, Jianwei Hu wrote: qemu: To clear bandwidth settings for a shutoff domain by using domiftune. After applying this patch, we can use virsh domiftune command to clear inbound or/and outbound setting for a shutoff domain. for example: virsh domiftune $domain $interface 0 0 Thanks for catching this. Please refer to below virsh help message: man virsh: To clear inbound or outbound settings, use --inbound or --outbound respectfully with average value of zero. --- src/qemu/qemu_driver.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 82a82aa..7db2e9c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9983,11 +9983,17 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, VIR_FREE(persistentNet->bandwidth->in); persistentNet->bandwidth->in = bandwidth->in; bandwidth->in = NULL; +} else { +VIR_FREE(persistentNet->bandwidth->in); +persistentNet->bandwidth->in = 0; We like NULL for pointer more than 0. Moreover, there's no need to explicitly set pointer freed to NULL as the VIR_FREE() macro does that already for you (in fact virFree() function does that, whatever). } if (bandwidth->out) { VIR_FREE(persistentNet->bandwidth->out); persistentNet->bandwidth->out = bandwidth->out; bandwidth->out = NULL; +} else { +VIR_FREE(persistentNet->bandwidth->out); +persistentNet->bandwidth->out = 0; } } But the fix isn't quite right. For instance: virsh # domiftune dummy 52:54:00:89:3a:c2 --config inbound.average: 10 inbound.peak : 0 inbound.burst : 0 outbound.average: 10 outbound.peak : 0 outbound.burst : 0 virsh # domiftune dummy 52:54:00:89:3a:c2 --config 100 virsh # domiftune dummy 52:54:00:89:3a:c2 --config inbound.average: 100 inbound.peak : 0 inbound.burst : 0 outbound.average: 0 outbound.peak : 0 outbound.burst : 0 The bandwidth is cleared unconditionally. What we really need is: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 82a82aa..2c3f179 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9983,11 +9983,15 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, VIR_FREE(persistentNet->bandwidth->in); persistentNet->bandwidth->in = bandwidth->in; bandwidth->in = NULL; +} else if (inboundSpecified) { +VIR_FREE(persistentNet->bandwidth->in); } if (bandwidth->out) { VIR_FREE(persistentNet->bandwidth->out); persistentNet->bandwidth->out = bandwidth->out; bandwidth->out = NULL; +} else if (outboundSpecified) { +VIR_FREE(persistentNet->bandwidth->out); } } I'm fixing this patch though and pushing. ACK. Thanks for your advice and correction. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list