KVM-test: Add a new macaddress pool algorithm
PATCH 1/1 KVM-test: Add a new macaddress pool algorithm
Previous verison uses the mac prefix in the configuration files which could lead serious problem when multiple tests running in different hosts.
This patch adds a new macaddress pool algorithm, it generates the mac prefix based on mac address of the host which could eliminate the duplicated mac addresses between machines.
When user have set the mac_prefix in the configuration file, we should use it in stead of the dynamic generated mac prefix.
Other change:
. Fix randomly generating mac address so that it correspond to IEEE802. . Update clone function to decide clone mac address or not. . Update get_macaddr function.
. Add set_mac_address function.
New auto mac address pool algorithm:
If address_index is defined, VM will get mac from config file then record mac in to address_pool. If address_index is not defined, VM will call get_mac_from_pool to auto create mac then recored mac to address_pool in following format:
{'macpool': {'AE:9D:94:6A:9b:f9': ['20100310-165222-Wt7l:0']}}
AE:9D:94:6A:9b:f9 : mac address
20100310-165222-Wt7l : instance attribute of VM
0 : index of NIC
---
0 files changed, 0 insertions(+), 0 deletions(-)
client/tests/kvm/kvm_utils.py +99 -0
@@ -5,6 +5,7 @@ KVM test utility functions. """ import time, string, random, socket, os, signal, re, logging, commands, cPickle +import fcntl, shelve from autotest_lib.client.bin import utils from autotest_lib.client.common_lib import error, logging_config import kvm_subprocess
@@ -76,6 +77,104 @@ def get_sub_dict_names(dict, keyword): # Functions related to MAC/IP addresses +def get_mac_from_pool(root_dir, vm, nic_index, prefix='00:11:22:33:'): + """ + random generated mac address. + + 1) First try to generate macaddress based on the mac address prefix. + 2) And then try to use total random generated mac address. + + @param root_dir: Root dir for kvm + @param vm: Here we use instance of vm + @param nic_index: The index of nic. + @param prefix: Prefix of mac address. + @Return: Return mac address. + """ + + lock_filename = os.path.join(root_dir, "mac_lock") + lock_file = open(lock_filename, 'w') + fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX) + mac_filename = os.path.join(root_dir, "address_pool") + mac_shelve = shelve.open(mac_filename, writeback=False) + + mac_pool = mac_shelve.get("macpool") + + if not mac_pool: + mac_pool = {} + found = False + + val = "%s:%s" % (vm, nic_index) + for key in mac_pool.keys(): + if val in mac_pool[key]: + mac_pool[key].append(val) + found = True + mac = key + + while not found: + postfix = "%02x:%02x" % (random.randint(0x00,0xfe), + random.randint(0x00,0xfe)) + mac = prefix + postfix + mac_list = mac.split(":") + # Clear multicast bit + mac_list[0] = int(mac_list[0],16) & 0xfe + # Set local assignment bit (IEEE802) + mac_list[0] = mac_list[0] | 0x02 + mac_list[0] = "%02x" % mac_list[0] + mac = ":".join(mac_list) + if mac not in mac_pool.keys() or 0 == len(mac_pool[mac]): + mac_pool[mac] = ["%s:%s" % (vm,nic_index)] + found = True + mac_shelve["macpool"] = mac_pool + logging.debug("generating mac addr %s " % mac) + + mac_shelve.close() + fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN) + lock_file.close() + return mac + + +def put_mac_to_pool(root_dir, mac, vm): + """ + Put the macaddress back to address pool + + @param root_dir: Root dir for kvm + @param vm: Here we use instance attribute of vm + @param mac: mac address will be put. + @Return: mac address. + """ + + lock_filename = os.path.join(root_dir, "mac_lock") + lock_file = open(lock_filename, 'w') + fcntl.lockf(lock_file.fileno() ,fcntl.LOCK_EX) + mac_filename = os.path.join(root_dir, "address_pool") + mac_shelve = shelve.open(mac_filename, writeback=False) + + mac_pool = mac_shelve.get("macpool") + + if not mac_pool or (not mac in mac_pool): + logging.debug("Try to free a macaddress does no in pool") + logging.debug("macaddress is %s" % mac) + logging.debug("pool is %s" % mac_pool) + else: + if len(mac_pool[mac]) <= 1: + mac_pool.pop(mac) + else: + for value in mac_pool[mac]: + if vm in value: + mac_pool[mac].remove(value) + break + if len(mac_pool[mac]) == 0: + mac_pool.pop(mac) + + mac_shelve["macpool"] = mac_pool + logging.debug("freeing mac addr %s " % mac) + + mac_shelve.close() + fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN) + lock_file.close() + return mac + + def mac_str_to_int(addr): """ Convert MAC address string to integer.
client/tests/kvm/kvm_vm.py +112 -7
207 lines not on this page · raw message
client/tests/kvm/tests_base.cfg.sample +1 -1
@@ -51,7 +51,7 @@ guest_port_remote_shell = 22 nic_mode = user #nic_mode = tap nic_script = scripts/qemu-ifup -address_index = 0 +#address_index = 0 run_tcpdump = yes # Misc