From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 91FDD37A4 for ; Thu, 14 Jul 2016 15:17:48 +0200 (CEST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP; 14 Jul 2016 06:17:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,362,1464678000"; d="scan'208";a="139142068" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga004.fm.intel.com with ESMTP; 14 Jul 2016 06:17:47 -0700 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id u6EDHknb004476; Thu, 14 Jul 2016 21:17:46 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u6EDHiGV001340; Thu, 14 Jul 2016 21:17:46 +0800 Received: (from yliu84x@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id u6EDHhEE001336; Thu, 14 Jul 2016 21:17:43 +0800 From: Marvin Liu To: dts@dpdk.org Cc: Marvin Liu Date: Thu, 14 Jul 2016 21:17:30 +0800 Message-Id: <1468502253-1276-5-git-send-email-yong.liu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1468502253-1276-1-git-send-email-yong.liu@intel.com> References: <1468502253-1276-1-git-send-email-yong.liu@intel.com> Subject: [dts] [PATCH 4/7] framework qemu_kvm: support migration and serial port X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2016 13:17:49 -0000 1. Add vm status concept and status updated from qemu monitor 2. Support migration function and migration status checking 3. Support connect and close serial port which is the only available session after migration Signed-off-by: Marvin Liu diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py index 70730e2..96923e9 100644 --- a/framework/qemu_kvm.py +++ b/framework/qemu_kvm.py @@ -35,6 +35,7 @@ import re import os from virt_base import VirtBase +from virt_base import ST_NOTSTART, ST_PAUSE, ST_RUNNING, ST_UNKNOWN from exception import StartVMFailedException from settings import get_host_ip @@ -752,18 +753,60 @@ class QEMUKvm(VirtBase): else: self.qga_sock_path = '' + def add_vm_migration(self, **options): + """ + enable: yes + port: tcp port for live migration + """ + migrate_cmd = "-incoming tcp::%(migrate_port)s" + + if 'enable' in options.keys(): + if options['enable'] == 'yes': + if 'port' in options.keys(): + self.migrate_port = options['port'] + else: + self.migrate_port = str(self.virt_pool.alloc_port(self.vm_name)) + migrate_boot_line = migrate_cmd % {'migrate_port': self.migrate_port} + self.__add_boot_line(migrate_boot_line) + def add_vm_serial_port(self, **options): """ enable: 'yes' """ - SERAIL_SOCK_PATH = "/tmp/%s_serial.sock" % self.vm_name if 'enable' in options.keys(): if options['enable'] == 'yes': - serial_boot_line = '-serial unix:%s,server,nowait' % SERIAL_SOCK_PATH + self.serial_path = "/tmp/%s_serial.sock" % self.vm_name + serial_boot_line = '-serial unix:%s,server,nowait' % self.serial_path self.__add_boot_line(serial_boot_line) else: pass + def connect_serial_port(self, name="", first=True): + """ + Connect to serial port and return connected session for usage + if connected failed will return None + """ + if getattr(self, 'serial_path', None): + self.serial_session = self.host_dut.new_session(suite=name) + self.serial_session.send_command("nc -U %s" % self.serial_path) + if first: + # login into Fedora os, not sure can work on all distributions + self.serial_session.send_expect("", "login:") + self.serial_session.send_expect("%s" % self.username, "Password:") + self.serial_session.send_expect("%s" % self.password, "# ") + return self.serial_session + + return None + + def close_serial_port(self): + """ + Close serial session if it existed + """ + if getattr(self, 'serial_session', None): + # exit from nc first + self.serial_session.send_expect("^C", "# ") + self.host_dut.close_session(self.serial_session) + def add_vm_vnc(self, **options): """ displayNum: 1 @@ -822,12 +865,55 @@ class QEMUKvm(VirtBase): ret = self.host_session.send_expect(qemu_boot_line, '# ', verify=True) if type(ret) is int and ret != 0: raise StartVMFailedException('Start VM failed!!!') - out = self.__control_session('ping', '120') - if "Not responded" in out: - raise StartVMFailedException('Not response in 60 seconds!!!') self.__get_pci_mapping() - self.__wait_vmnet_ready() + + # query status + self.update_status() + + # when vm is waiting for migration, can't ping + if self.vm_status is not ST_PAUSE: + # if VM waiting for migration, can't return ping + out = self.__control_session('ping', '120') + if "Not responded" in out: + raise StartVMFailedException('Not response in 120 seconds!!!') + + self.__wait_vmnet_ready() + + def start_migration(self, remote_ip, remote_port): + """ + Send migration command to host and check whether start migration + """ + # send migration command + migration_port = 'tcp:%(IP)s:%(PORT)s' % {'IP': remote_ip, 'PORT': remote_port} + + self.__monitor_session('migrate', '-d', migration_port) + time.sleep(2) + out = self.__monitor_session('info', 'migrate') + if "Migration status: active" in out: + return True + else: + return False + + def wait_migration_done(self): + """ + Wait for migration done. If not finished after three minutes + will raise exception. + """ + # wait for migration done + count = 30 + while count: + out = self.__monitor_session('info', 'migrate') + if "completed" in out: + self.host_logger.info("%s" % out) + # after migration done, status is pause + self.vm_status = ST_PAUSE + return True + + time.sleep(6) + count -= 1 + + raise StartVMFailedException('Virtual machine can not finished in 180 seconds!!!') def generate_qemu_boot_line(self): """ @@ -1036,10 +1122,28 @@ class QEMUKvm(VirtBase): for arg in args: cmd += ' ' + str(arg) - out = self.host_session.send_expect('%s' % cmd, '(qemu)') + # after quit command, qemu will exit + if 'quit' in cmd: + out = self.host_session.send_expect('%s' % cmd, '# ') + else: + out = self.host_session.send_expect('%s' % cmd, '(qemu)') self.host_session.send_expect('^C', "# ") return out + def update_status(self): + """ + Query and update VM status + """ + out = self.__monitor_session('info', 'status') + self.host_logger.info("Virtual machine status: %s" % out) + + if 'paused' in out: + self.vm_status = ST_PAUSE + elif 'running' in out: + self.vm_status = ST_RUNNING + else: + self.vm_status = ST_UNKNOWN + def __strip_guest_pci(self): """ Strip all pci-passthrough device information, based on qemu monitor @@ -1105,5 +1209,8 @@ class QEMUKvm(VirtBase): """ Stop VM. """ - self.__control_session('powerdown') + if self.vm_status is ST_RUNNING: + self.__control_session('powerdown') + else: + self.__monitor_session('quit') time.sleep(5) -- 1.9.3