From patchwork Sun May 24 15:46:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Goldish X-Patchwork-Id: 25599 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 n4OFif1b012433 for ; Sun, 24 May 2009 15:44:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754951AbZEXPoe (ORCPT ); Sun, 24 May 2009 11:44:34 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754909AbZEXPoe (ORCPT ); Sun, 24 May 2009 11:44:34 -0400 Received: from mx2.redhat.com ([66.187.237.31]:49716 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754814AbZEXPob (ORCPT ); Sun, 24 May 2009 11:44:31 -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 n4OFiXLX029855 for ; Sun, 24 May 2009 11:44:33 -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 n4OFiXHP019938; Sun, 24 May 2009 11:44:33 -0400 Received: from localhost.localdomain (dhcp-1-188.tlv.redhat.com [10.35.1.188]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n4OFiMU1009023; Sun, 24 May 2009 11:44:32 -0400 From: Michael Goldish To: kvm@vger.kernel.org Cc: Michael Goldish Subject: [KVM-AUTOTEST PATCH] kvm_vm.py: make sure the bulk of VM.create() is not executed in parallel Date: Sun, 24 May 2009 18:46:43 +0300 Message-Id: <63bacaa214ccd95c18fb644056855acd72757ac4.1243179847.git.mgoldish@redhat.com> In-Reply-To: References: <8e37a36c044c20259dcd8a34d72a651e85b37d5f.1243179847.git.mgoldish@redhat.com> <838bcae1b49be011e2cde1294a391a296059464a.1243179847.git.mgoldish@redhat.com> <6a70cb56a775fdb688da0231073abb0ce4baa7b1.1243179847.git.mgoldish@redhat.com> In-Reply-To: <8e37a36c044c20259dcd8a34d72a651e85b37d5f.1243179847.git.mgoldish@redhat.com> References: <8e37a36c044c20259dcd8a34d72a651e85b37d5f.1243179847.git.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 VM.create() does a few things (such as finding free ports) which are not safe to execute in parallel. Use a lock file to make sure this doesn't happen. The lock is released only after the VM is started or fails to start. Signed-off-by: Michael Goldish --- client/tests/kvm_runtest_2/kvm_vm.py | 85 +++++++++++++++++++--------------- 1 files changed, 48 insertions(+), 37 deletions(-) diff --git a/client/tests/kvm_runtest_2/kvm_vm.py b/client/tests/kvm_runtest_2/kvm_vm.py index 3ce2003..af06693 100644 --- a/client/tests/kvm_runtest_2/kvm_vm.py +++ b/client/tests/kvm_runtest_2/kvm_vm.py @@ -3,6 +3,7 @@ import time import socket import os +import fcntl import kvm_utils import kvm_log @@ -289,48 +290,58 @@ class VM: kvm_log.error("Actual MD5 sum differs from expected one") return False - # Handle port redirections - redir_names = kvm_utils.get_sub_dict_names(params, "redirs") - host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names)) - self.redirs = {} - for i in range(len(redir_names)): - redir_params = kvm_utils.get_sub_dict(params, redir_names[i]) - guest_port = int(redir_params.get("guest_port")) - self.redirs[guest_port] = host_ports[i] - - # Find available VNC port, if needed - if params.get("display") == "vnc": - self.vnc_port = kvm_utils.find_free_port(5900, 6000) - - # Make qemu command - qemu_command = self.make_qemu_command() + # Make sure the following code is not executed by more than one thread + # at the same time + lockfile = open("/tmp/kvm-autotest-vm-create.lock", "w+") + fcntl.lockf(lockfile, fcntl.LOCK_EX) - # Is this VM supposed to accept incoming migrations? - if for_migration: - # Find available migration port - self.migration_port = kvm_utils.find_free_port(5200, 6000) - # Add -incoming option to the qemu command - qemu_command += " -incoming tcp:0:%d" % self.migration_port + try: + # Handle port redirections + redir_names = kvm_utils.get_sub_dict_names(params, "redirs") + host_ports = kvm_utils.find_free_ports(5000, 6000, len(redir_names)) + self.redirs = {} + for i in range(len(redir_names)): + redir_params = kvm_utils.get_sub_dict(params, redir_names[i]) + guest_port = int(redir_params.get("guest_port")) + self.redirs[guest_port] = host_ports[i] + + # Find available VNC port, if needed + if params.get("display") == "vnc": + self.vnc_port = kvm_utils.find_free_port(5900, 6000) + + # Make qemu command + qemu_command = self.make_qemu_command() + + # Is this VM supposed to accept incoming migrations? + if for_migration: + # Find available migration port + self.migration_port = kvm_utils.find_free_port(5200, 6000) + # Add -incoming option to the qemu command + qemu_command += " -incoming tcp:0:%d" % self.migration_port + + kvm_log.debug("Running qemu command:\n%s" % qemu_command) + (status, pid, output) = kvm_utils.run_bg(qemu_command, None, kvm_log.debug, "(qemu) ") + + if status: + kvm_log.debug("qemu exited with status %d" % status) + kvm_log.error("VM could not be created -- qemu command failed:\n%s" % qemu_command) + return False - kvm_log.debug("Running qemu command:\n%s" % qemu_command) - (status, pid, output) = kvm_utils.run_bg(qemu_command, None, kvm_log.debug, "(qemu) ") + self.pid = pid - if status: - kvm_log.debug("qemu exited with status %d" % status) - kvm_log.error("VM could not be created -- qemu command failed:\n%s" % qemu_command) - return False - - self.pid = pid + if not kvm_utils.wait_for(self.is_alive, timeout, 0, 1): + kvm_log.debug("VM is not alive for some reason") + kvm_log.error("VM could not be created with command:\n%s" % qemu_command) + self.destroy() + return False - if not kvm_utils.wait_for(self.is_alive, timeout, 0, 1): - kvm_log.debug("VM is not alive for some reason") - kvm_log.error("VM could not be created with command:\n%s" % qemu_command) - self.destroy() - return False + kvm_log.debug("VM appears to be alive with PID %d" % self.pid) - kvm_log.debug("VM appears to be alive with PID %d" % self.pid) + return True - return True + finally: + fcntl.lockf(lockfile, fcntl.LOCK_UN) + lockfile.close() def send_monitor_cmd(self, command, block=True, timeout=20.0): """Send command to the QEMU monitor.