From patchwork Wed Aug 12 15:59:53 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Goldish X-Patchwork-Id: 40905 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7CFwLLP005478 for ; Wed, 12 Aug 2009 15:58:21 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754009AbZHLP5U (ORCPT ); Wed, 12 Aug 2009 11:57:20 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754000AbZHLP5T (ORCPT ); Wed, 12 Aug 2009 11:57:19 -0400 Received: from mx2.redhat.com ([66.187.237.31]:42753 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754003AbZHLP5S (ORCPT ); Wed, 12 Aug 2009 11:57:18 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n7CFvJus005495; Wed, 12 Aug 2009 11:57:19 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n7CFvIRb004528; Wed, 12 Aug 2009 11:57:18 -0400 Received: from localhost.localdomain (dhcp-1-31.tlv.redhat.com [10.35.1.31]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n7CFvFCD029667; Wed, 12 Aug 2009 11:57:17 -0400 From: Michael Goldish To: autotest@test.kernel.org, kvm@vger.kernel.org Cc: Michael Goldish Subject: [KVM-AUTOTEST PATCH v2 01/11] KVM test: add some MAC/IP address utilities to kvm_utils Date: Wed, 12 Aug 2009 18:59:53 +0300 Message-Id: <10a541e518180735e86a4dbc8e759912d0ec314c.1250091576.git.mgoldish@redhat.com> In-Reply-To: <1250092803-32477-1-git-send-email-mgoldish@redhat.com> References: <1250092803-32477-1-git-send-email-mgoldish@redhat.com> X-Scanned-By: MIMEDefang 2.58 on 172.16.27.26 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add function get_mac_ip_pair_from_dict() which gets a dict (specified in the config file by the user) and fetches a MAC-IP address pair according to a certain syntax. The syntax allows the user to specify a group of MAC-IP address ranges. For example: address_ranges = r1 r2 r3 address_range_base_mac_r1 = 55:44:33:22:11:00 address_range_base_ip_r1 = 10.0.0.0 address_range_size_r1 = 16 address_range_base_mac_r2 = 55:44:33:22:11:40 address_range_base_ip_r2 = 10.0.0.60 address_range_size_r2 = 25 address_range_base_mac_r3 = 55:44:33:22:12:10 address_range_base_ip_r3 = 10.0.1.20 address_range_size_r3 = 230 The lines above may be specified globally, so that they apply to all VMs and all NICs. However, a line similar to the following must be specified per NIC (each VM may have several NICs): address_index = 0 Currently, we usually use a single VM and a single NIC, so specifying address_index once should suffice. If a test requires an additional NIC the user should add something like: address_index_nic2 = 1 The index is simply the index in the MAC-IP table that consists of all the specified ranges. In the above example, if the user specifies an index of 18, the MAC-IP pair will be taken from the second range, because the first range has only 16 entries. When running migration, both the source and destination VMs should have the same address_index, because they should have the same MAC and IP addresses. Note that different copies of the KVM test, running simultaneously in the same network environment, _must_ specify different MAC-IP pools. This can be done in several ways: - By specifying the ranges (as in the example above) in an external file such as /etc/kvm-autotest/client_mac_ip_pool.cfg, and setting up that file for each host manually - By keeping several .cfg files with different names that match the hostname of each host, e.g. mac_ip_pool_hostname1.cfg, mac_ip_pool_hostname2.cfg (hostname1 and hostname2 should be replaced by actual hostnames), and parsing the right file in the control file at runtime - By defining all the different pools in a variants block in a single file, and specifying 'only ' at runtime in the control file (using config.parse_string()) When we start running in server mode, assigning MAC and IP addresses to hosts can be done automatically by the server, but the user will still be required to specify a single global pool for the server (which the server will divide among the hosts). The address_index parameter will be specified inside the regular config file, and does not need to be different for each host. This patch also adds some small utility functions used by get_mac_ip_pair_from_dict(). Signed-off-by: Michael Goldish --- client/tests/kvm/kvm_utils.py | 106 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 106 insertions(+), 0 deletions(-) diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py index e897e78..4891592 100644 --- a/client/tests/kvm/kvm_utils.py +++ b/client/tests/kvm/kvm_utils.py @@ -46,6 +46,112 @@ def get_sub_dict_names(dict, keyword): return [] +# Functions related to MAC/IP addresses + +def mac_str_to_int(addr): + """ + Convert MAC address string to integer. + + @param addr: String representing the MAC address. + """ + return sum(int(s, 16) * 256 ** i + for i, s in enumerate(reversed(addr.split(":")))) + + +def mac_int_to_str(addr): + """ + Convert MAC address integer to string. + + @param addr: Integer representing the MAC address. + """ + return ":".join("%02x" % (addr >> 8 * i & 0xFF) + for i in reversed(range(6))) + + +def ip_str_to_int(addr): + """ + Convert IP address string to integer. + + @param addr: String representing the IP address. + """ + return sum(int(s) * 256 ** i + for i, s in enumerate(reversed(addr.split(".")))) + + +def ip_int_to_str(addr): + """ + Convert IP address integer to string. + + @param addr: Integer representing the IP address. + """ + return ".".join(str(addr >> 8 * i & 0xFF) + for i in reversed(range(4))) + + +def offset_mac(base, offset): + """ + Add offset to a given MAC address. + + @param base: String representing a MAC address. + @param offset: Offset to add to base (integer) + @return: A string representing the offset MAC address. + """ + return mac_int_to_str(mac_str_to_int(base) + offset) + + +def offset_ip(base, offset): + """ + Add offset to a given IP address. + + @param base: String representing an IP address. + @param offset: Offset to add to base (integer) + @return: A string representing the offset IP address. + """ + return ip_int_to_str(ip_str_to_int(base) + offset) + + +def get_mac_ip_pair_from_dict(dict): + """ + Fetch a MAC-IP address pair from dict and return it. + + The parameters in dict are expected to conform to a certain syntax. + Typical usage may be: + + address_ranges = r1 r2 r3 + + address_range_base_mac_r1 = 55:44:33:22:11:00 + address_range_base_ip_r1 = 10.0.0.0 + address_range_size_r1 = 16 + + address_range_base_mac_r2 = 55:44:33:22:11:40 + address_range_base_ip_r2 = 10.0.0.60 + address_range_size_r2 = 25 + + address_range_base_mac_r3 = 55:44:33:22:12:10 + address_range_base_ip_r3 = 10.0.1.20 + address_range_size_r3 = 230 + + address_index = 0 + + All parameters except address_index specify a MAC-IP address pool. The + pool consists of several MAC-IP address ranges. + address_index specified the index of the desired MAC-IP pair from the pool. + + @param dict: The dictionary from which to fetch the addresses. + """ + index = int(dict.get("address_index", 0)) + for mac_range_name in get_sub_dict_names(dict, "address_ranges"): + mac_range_params = get_sub_dict(dict, mac_range_name) + mac_base = mac_range_params.get("address_range_base_mac") + ip_base = mac_range_params.get("address_range_base_ip") + size = int(mac_range_params.get("address_range_size", 1)) + if index < size: + return (mac_base and offset_mac(mac_base, index), + ip_base and offset_ip(ip_base, index)) + index -= size + return (None, None) + + # Functions for working with the environment (a dict-like object) def is_vm(obj):