예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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