@@ -1,7 +1,7 @@
import sys, os, time, commands, re, logging
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
-import kvm_vm, kvm_utils
+import kvm_vm, kvm_utils, kvm_subprocess
def preprocess_image(test, params):
@@ -167,17 +167,6 @@ def preprocess(test, params, env):
@param params: A dict containing all VM and image parameters.
@param env: The environment (a dict-like object).
"""
- # Verify the identities of all living VMs
- for vm in env.values():
- if not kvm_utils.is_vm(vm):
- continue
- if vm.is_dead():
- continue
- if not vm.verify_process_identity():
- logging.debug("VM '%s' seems to have been replaced by another"
- " process" % vm.name)
- vm.pid = None
-
# Destroy and remove VMs that are no longer needed in the environment
requested_vms = kvm_utils.get_sub_dict_names(params, "vms")
for key in env.keys():
@@ -239,8 +228,8 @@ def postprocess(test, params, env):
# Remove them all
logging.debug("'keep_ppm_files' not specified; removing all PPM files"
" from results dir...")
- kvm_utils.run_bg("rm -vf %s" % os.path.join(test.debugdir, "*.ppm"),
- None, logging.debug, "(rm) ", timeout=5.0)
+ rm_cmd = "rm -vf %s" % os.path.join(test.debugdir, "*.ppm")
+ kvm_subprocess.run_fg(rm_cmd, logging.debug, "(rm) ", timeout=5.0)
def postprocess_on_error(test, params, env):
@@ -1,6 +1,6 @@
#!/usr/bin/python
import time, socket, os, logging, fcntl
-import kvm_utils
+import kvm_utils, kvm_subprocess
"""
Utility classes and functions to handle Virtual Machine creation using qemu.
@@ -54,17 +54,22 @@ def create_image(params, qemu_img_path, image_dir):
qemu_img_cmd += " %s" % size
logging.debug("Running qemu-img command:\n%s" % qemu_img_cmd)
- (status, pid, output) = kvm_utils.run_bg(qemu_img_cmd, None,
- logging.debug, "(qemu-img) ",
- timeout=30)
+ (status, output) = kvm_subprocess.run_fg(qemu_img_cmd, logging.debug,
+ "(qemu-img) ", timeout=30)
- if status:
- logging.debug("qemu-img exited with status %d" % status)
- logging.error("Could not create image %s" % image_filename)
+ if status is None:
+ logging.error("Timeout elapsed while waiting for qemu-img command "
+ "to complete:\n%s" % qemu_img_cmd)
+ return None
+ elif status != 0:
+ logging.error("Could not create image; "
+ "qemu-img command failed:\n%s" % qemu_img_cmd)
+ logging.error("Status: %s" % status)
+ logging.error("Output:" + kvm_utils.format_str_for_message(output))
return None
if not os.path.exists(image_filename):
- logging.debug("Image file does not exist for some reason")
- logging.error("Could not create image %s" % image_filename)
+ logging.error("Image could not be created for some reason; "
+ "qemu-img command:\n%s" % qemu_img_cmd)
return None
logging.info("Image created in %s" % image_filename)
@@ -106,7 +111,7 @@ class VM:
@param image_dir: The directory where images reside
@param iso_dir: The directory where ISOs reside
"""
- self.pid = None
+ self.process = None
self.name = name
self.params = params
@@ -153,28 +158,6 @@ class VM:
return VM(name, params, qemu_path, image_dir, iso_dir)
- def verify_process_identity(self):
- """
- Make sure .pid really points to the original qemu process. If .pid
- points to the same process that was created with the create method,
- or to a dead process, return True. Otherwise return False.
- """
- if self.is_dead():
- return True
- filename = "/proc/%d/cmdline" % self.pid
- if not os.path.exists(filename):
- logging.debug("Filename %s does not exist" % filename)
- return False
- file = open(filename)
- cmdline = file.read()
- file.close()
- if not self.qemu_path in cmdline:
- return False
- if not self.monitor_file_name in cmdline:
- return False
- return True
-
-
def make_qemu_command(self, name=None, params=None, qemu_path=None,
image_dir=None, iso_dir=None):
"""
@@ -378,25 +361,26 @@ class VM:
qemu_command += " -incoming tcp:0:%d" % self.migration_port
logging.debug("Running qemu command:\n%s", qemu_command)
- (status, pid, output) = kvm_utils.run_bg(qemu_command, None,
- logging.debug, "(qemu) ")
-
- if status:
- logging.debug("qemu exited with status %d", status)
- logging.error("VM could not be created -- qemu command"
- " failed:\n%s", qemu_command)
+ self.process = kvm_subprocess.run_bg(qemu_command, None,
+ logging.debug, "(qemu) ")
+
+ if not self.process.is_alive():
+ logging.error("VM could not be created; "
+ "qemu command failed:\n%s" % qemu_command)
+ logging.error("Status: %s" % self.process.get_status())
+ logging.error("Output:" + kvm_utils.format_str_for_message(
+ self.process.get_output()))
+ self.destroy()
return False
- self.pid = pid
-
if not kvm_utils.wait_for(self.is_alive, timeout, 0, 1):
- logging.debug("VM is not alive for some reason")
- logging.error("VM could not be created with"
- " command:\n%s", qemu_command)
+ logging.error("VM is not alive for some reason; "
+ "qemu command:\n%s" % qemu_command)
self.destroy()
return False
- logging.debug("VM appears to be alive with PID %d", self.pid)
+ logging.debug("VM appears to be alive with PID %d",
+ self.process.get_pid())
return True
finally:
@@ -495,9 +479,11 @@ class VM:
# Is it already dead?
if self.is_dead():
logging.debug("VM is already down")
+ if self.process:
+ self.process.close()
return
- logging.debug("Destroying VM with PID %d..." % self.pid)
+ logging.debug("Destroying VM with PID %d..." % self.process.get_pid())
if gracefully and self.params.get("cmd_shutdown"):
# Try to destroy with SSH command
@@ -510,7 +496,7 @@ class VM:
"down...")
if kvm_utils.wait_for(self.is_dead, 60, 1, 1):
logging.debug("VM is down")
- self.pid = None
+ self.process.close()
return
# Try to destroy with a monitor command
@@ -521,28 +507,21 @@ class VM:
# Wait for the VM to be really dead
if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5):
logging.debug("VM is down")
- self.pid = None
+ self.process.close()
return
# If the VM isn't dead yet...
- logging.debug("Cannot quit normally; Sending a kill to close the"
- " deal...")
- kvm_utils.safe_kill(self.pid, 9)
- # Wait for the VM to be really dead
- if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5):
- logging.debug("VM is down")
- self.pid = None
- return
-
- logging.error("We have a zombie! PID %d is a zombie!" % self.pid)
+ logging.debug("Cannot quit normally; Sending a kill to close the "
+ "deal...")
+ self.process.close(9)
def is_alive(self):
"""
Return True if the VM's monitor is responsive.
"""
- # Check if the process exists
- if not kvm_utils.pid_exists(self.pid):
+ # Check if the process is running
+ if self.is_dead():
return False
# Try sending a monitor command
(status, output) = self.send_monitor_cmd("help")
@@ -553,9 +532,9 @@ class VM:
def is_dead(self):
"""
- Return True iff the VM's PID does not exist.
+ Return True if the qemu process is dead.
"""
- return not kvm_utils.pid_exists(self.pid)
+ return not self.process or not self.process.is_alive()
def get_params(self):
Signed-off-by: Michael Goldish <mgoldish@redhat.com> --- client/tests/kvm/kvm_preprocessing.py | 17 +----- client/tests/kvm/kvm_vm.py | 103 +++++++++++++-------------------- 2 files changed, 44 insertions(+), 76 deletions(-)