def Start(self): if self._host: self._WaitUntilReady() else: should_provision = False if self.__Discover(): self._WaitUntilReady() if self._os_check != 'ignore': if self._SDKHashMatches(): if self._os_check == 'update': logging.info( 'SDK hash does not match; rebooting and repaving.' ) self.RunCommand(['dm', 'reboot']) should_provision = True elif self._os_check == 'check': raise Exception( 'Target device SDK version does not match.') else: should_provision = True if should_provision: boot_data.AssertBootImagesExist(self._GetTargetSdkArch(), 'generic') self.__ProvisionDevice() assert self._node_name assert self._host
def _BuildQemuConfig(self): boot_data.AssertBootImagesExist(self._GetTargetSdkArch(), 'qemu') emu_command = [ '-kernel', EnsurePathExists( boot_data.GetTargetFile('qemu-kernel.kernel', self._GetTargetSdkArch(), boot_data.TARGET_TYPE_QEMU)), '-initrd', EnsurePathExists( boot_data.GetBootImage(self._output_dir, self._GetTargetSdkArch(), boot_data.TARGET_TYPE_QEMU)), '-m', str(self._ram_size_mb), '-smp', str(self._cpu_cores), # Attach the blobstore and data volumes. Use snapshot mode to discard # any changes. '-snapshot', '-drive', 'file=%s,format=qcow2,if=none,id=blobstore,snapshot=on' % _EnsureBlobstoreQcowAndReturnPath(self._output_dir, self._GetTargetSdkArch(), self._qemu_img_retries), '-device', 'virtio-blk-pci,drive=blobstore', # Use stdio for the guest OS only; don't attach the QEMU interactive # monitor. '-serial', 'stdio', '-monitor', 'none', ] # Configure the machine to emulate, based on the target architecture. if self._target_cpu == 'arm64': emu_command.extend([ '-machine', 'virt,gic_version=3', ]) netdev_type = 'virtio-net-pci' else: emu_command.extend([ '-machine', 'q35', ]) netdev_type = 'e1000' # Configure virtual network. It is used in the tests to connect to # testserver running on the host. netdev_config = 'user,id=net0,net=%s,dhcpstart=%s,host=%s' % \ (GUEST_NET, GUEST_IP_ADDRESS, HOST_IP_ADDRESS) self._host_ssh_port = common.GetAvailableTcpPort() netdev_config += ",hostfwd=tcp::%s-:22" % self._host_ssh_port emu_command.extend([ '-netdev', netdev_config, '-device', '%s,netdev=net0,mac=%s' % (netdev_type, GUEST_MAC_ADDRESS), ]) # Configure the CPU to emulate. # On Linux, we can enable lightweight virtualization (KVM) if the host and # guest architectures are the same. if self._IsKvmEnabled(): kvm_command = ['-enable-kvm', '-cpu'] if self._target_cpu == 'arm64': kvm_command.append('host') else: kvm_command.append('host,migratable=no') else: logging.warning('Unable to launch %s with KVM acceleration.' % (self._emu_type) + 'The guest VM will be slow.') if self._target_cpu == 'arm64': kvm_command = ['-cpu', 'cortex-a53'] else: kvm_command = ['-cpu', 'Haswell,+smap,-check,-fsgsbase'] emu_command.extend(kvm_command) kernel_args = boot_data.GetKernelArgs(self._output_dir) # TERM=dumb tells the guest OS to not emit ANSI commands that trigger # noisy ANSI spew from the user's terminal emulator. kernel_args.append('TERM=dumb') # Construct kernel cmd line kernel_args.append('kernel.serial=legacy') # Don't 'reboot' the emulator if the kernel crashes kernel_args.append('kernel.halt-on-panic=true') emu_command.extend(['-append', ' '.join(kernel_args)]) return emu_command
def Start(self): boot_data.AssertBootImagesExist(self._GetTargetSdkArch(), 'qemu') qemu_path = os.path.join( GetQemuRootForPlatform(), 'bin', 'qemu-system-' + self._GetTargetSdkLegacyArch()) kernel_args = boot_data.GetKernelArgs(self._output_dir) # TERM=dumb tells the guest OS to not emit ANSI commands that trigger # noisy ANSI spew from the user's terminal emulator. kernel_args.append('TERM=dumb') # Enable logging to the serial port. This is a temporary fix to investigate # the root cause for https://crbug.com/869753 . kernel_args.append('kernel.serial=legacy') qemu_command = [ qemu_path, '-m', str(self._ram_size_mb), '-nographic', '-kernel', EnsurePathExists( boot_data.GetTargetFile('qemu-kernel.kernel', self._GetTargetSdkArch(), boot_data.TARGET_TYPE_QEMU)), '-initrd', EnsurePathExists( boot_data.GetBootImage(self._output_dir, self._GetTargetSdkArch(), boot_data.TARGET_TYPE_QEMU)), '-smp', str(self._cpu_cores), # Attach the blobstore and data volumes. Use snapshot mode to discard # any changes. '-snapshot', '-drive', 'file=%s,format=qcow2,if=none,id=blobstore,snapshot=on' % _EnsureBlobstoreQcowAndReturnPath(self._output_dir, self._GetTargetSdkArch()), '-device', 'virtio-blk-pci,drive=blobstore', # Use stdio for the guest OS only; don't attach the QEMU interactive # monitor. '-serial', 'stdio', '-monitor', 'none', '-append', ' '.join(kernel_args) ] # Configure the machine to emulate, based on the target architecture. if self._target_cpu == 'arm64': qemu_command.extend([ '-machine', 'virt', ]) netdev_type = 'virtio-net-pci' else: qemu_command.extend([ '-machine', 'q35', ]) netdev_type = 'e1000' # Configure the CPU to emulate. # On Linux, we can enable lightweight virtualization (KVM) if the host and # guest architectures are the same. enable_kvm = self._require_kvm or ( sys.platform.startswith('linux') and ((self._target_cpu == 'arm64' and platform.machine() == 'aarch64') or (self._target_cpu == 'x64' and platform.machine() == 'x86_64')) and os.access('/dev/kvm', os.R_OK | os.W_OK)) if enable_kvm: qemu_command.extend(['-enable-kvm', '-cpu', 'host,migratable=no']) else: logging.warning('Unable to launch QEMU with KVM acceleration.') if self._target_cpu == 'arm64': qemu_command.extend(['-cpu', 'cortex-a53']) else: qemu_command.extend(['-cpu', 'Haswell,+smap,-check,-fsgsbase']) # Configure virtual network. It is used in the tests to connect to # testserver running on the host. netdev_config = 'user,id=net0,net=%s,dhcpstart=%s,host=%s' % \ (GUEST_NET, GUEST_IP_ADDRESS, HOST_IP_ADDRESS) self._host_ssh_port = common.GetAvailableTcpPort() netdev_config += ",hostfwd=tcp::%s-:22" % self._host_ssh_port qemu_command.extend([ '-netdev', netdev_config, '-device', '%s,netdev=net0,mac=%s' % (netdev_type, GUEST_MAC_ADDRESS), ]) # We pass a separate stdin stream to qemu. Sharing stdin across processes # leads to flakiness due to the OS prematurely killing the stream and the # Python script panicking and aborting. # The precise root cause is still nebulous, but this fix works. # See crbug.com/741194. logging.debug('Launching QEMU.') logging.debug(' '.join(qemu_command)) # Zircon sends debug logs to serial port (see kernel.serial=legacy flag # above). Serial port is redirected to a file through QEMU stdout. # Unless a |_system_log_file| is explicitly set, we output the kernel serial # log to a temporary file, and print that out if we are unable to connect to # the QEMU guest, to make it easier to diagnose connectivity issues. temporary_system_log_file = None if self._system_log_file: stdout = self._system_log_file stderr = subprocess.STDOUT else: temporary_system_log_file = tempfile.NamedTemporaryFile('w') stdout = temporary_system_log_file stderr = sys.stderr self._qemu_process = subprocess.Popen(qemu_command, stdin=open(os.devnull), stdout=stdout, stderr=stderr) try: self._WaitUntilReady() except target.FuchsiaTargetException: if temporary_system_log_file: logging.info("Kernel logs:\n" + open(temporary_system_log_file.name, 'r').read()) raise