def close(self, sig=signal.SIGKILL): """ Kill the child process if it's alive and remove temporary files. @param sig: The signal to send the process when attempting to kill it. """ # Kill it if it's alive if self.is_alive(): kvm_utils.kill_process_tree(self.get_pid(), sig) # Wait for the server to exit _wait(self.lock_server_running_filename) # Call all cleanup routines for hook in self.close_hooks: hook(self) # Close reader file descriptors for fd in self.reader_fds.values(): try: os.close(fd) except: pass self.reader_fds = {} # Remove all used files for filename in (_get_filenames("/tmp/kvm_spawn", self.id) + self.reader_filenames.values()): try: os.unlink(filename) except OSError: pass
def destroy(self, gracefully=True): """ Destroy the VM. If gracefully is True, first attempt to shutdown the VM with a shell command. Then, attempt to destroy the VM via the monitor with a 'quit' command. If that fails, send SIGKILL to the qemu process. @param gracefully: Whether an attempt will be made to end the VM using a shell command before trying to end the qemu process with a 'quit' or a kill signal. """ try: # Is it already dead? if self.is_dead(): logging.debug("VM is already down") return logging.debug("Destroying VM with PID %s...", self.get_pid()) if gracefully and self.params.get("shutdown_command"): # Try to destroy with shell command logging.debug("Trying to shutdown VM with shell command...") session = self.remote_login() if session: try: # Send the shutdown command session.sendline(self.params.get("shutdown_command")) logging.debug("Shutdown command sent; waiting for VM " "to go down...") if kvm_utils.wait_for(self.is_dead, 60, 1, 1): logging.debug("VM is down, freeing mac address.") return finally: session.close() if self.monitor: # Try to destroy with a monitor command logging.debug("Trying to kill VM with monitor command...") try: self.monitor.quit() except kvm_monitor.MonitorError, e: logging.warn(e) else: # 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") return # If the VM isn't dead yet... logging.debug("Cannot quit normally; sending a kill to close the " "deal...") kvm_utils.kill_process_tree(self.process.get_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") return logging.error("Process %s is a zombie!" % self.process.get_pid())
def raw_ping(command, timeout, session, output_func): """ Low-level ping command execution. @param command: Ping command. @param timeout: Timeout of the ping command. @param session: Local executon hint or session to execute the ping command. """ if session is None: process = kvm_subprocess.run_bg(command, output_func=output_func, timeout=timeout) # Send SIGINT signal to notify the timeout of running ping process, # Because ping have the ability to catch the SIGINT signal so we can # always get the packet loss ratio even if timeout. if process.is_alive(): kvm_utils.kill_process_tree(process.get_pid(), signal.SIGINT) status = process.get_status() output = process.get_output() process.close() return status, output else: output = "" try: output = session.cmd_output(command, timeout=timeout, print_func=output_func) except kvm_subprocess.ShellTimeoutError: # Send ctrl+c (SIGINT) through ssh session session.send("\003") try: output2 = session.read_up_to_prompt(print_func=output_func) output += output2 except kvm_subprocess.ExpectTimeoutError, e: output += e.output # We also need to use this session to query the return value session.send("\003") session.sendline(session.status_test_command) try: o2 = session.read_up_to_prompt() except kvm_subprocess.ExpectError: status = -1 else: try: status = int(re.findall("\d+", o2)[0]) except: status = -1 return status, output