def _EnsureBlobstoreQcowAndReturnPath(output_dir, target_arch): """Returns a file containing the Fuchsia blobstore in a QCOW format, with extra buffer space added for growth.""" qimg_tool = os.path.join(common.GetEmuRootForPlatform('qemu'), 'bin', 'qemu-img') fvm_tool = common.GetHostToolPathFromPlatform('fvm') blobstore_path = boot_data.GetTargetFile('storage-full.blk', target_arch, 'qemu') qcow_path = os.path.join(output_dir, 'gen', 'blobstore.qcow') # Check a hash of the blobstore to determine if we can re-use an existing # extended version of it. blobstore_hash_path = os.path.join(output_dir, 'gen', 'blobstore.hash') current_blobstore_hash = _ComputeFileHash(blobstore_path) if os.path.exists(blobstore_hash_path) and os.path.exists(qcow_path): if current_blobstore_hash == open(blobstore_hash_path, 'r').read(): return qcow_path # Add some extra room for growth to the Blobstore volume. # Fuchsia is unable to automatically extend FVM volumes at runtime so the # volume enlargement must be performed prior to QEMU startup. # The 'fvm' tool only supports extending volumes in-place, so make a # temporary copy of 'blobstore.bin' before it's mutated. extended_blobstore = tempfile.NamedTemporaryFile() shutil.copyfile(blobstore_path, extended_blobstore.name) subprocess.check_call([ fvm_tool, extended_blobstore.name, 'extend', '--length', str(EXTENDED_BLOBSTORE_SIZE), blobstore_path ]) # Construct a QCOW image from the extended, temporary FVM volume. # The result will be retained in the build output directory for re-use. qemu_img_cmd = [ qimg_tool, 'convert', '-f', 'raw', '-O', 'qcow2', '-c', extended_blobstore.name, qcow_path ] # TODO(crbug.com/1046861): Remove arm64 call with retries when bug is fixed. if common.GetHostArchFromPlatform() == 'arm64': qemu_image.ExecQemuImgWithRetry(qemu_img_cmd) else: subprocess.check_call(qemu_img_cmd) # Write out a hash of the original blobstore file, so that subsequent runs # can trivially check if a cached extended FVM volume is available for reuse. with open(blobstore_hash_path, 'w') as blobstore_hash_file: blobstore_hash_file.write(current_blobstore_hash) return qcow_path
def _ConfigureEmulatorLog(self, emu_command): if self._log_manager.IsLoggingEnabled(): emu_command.extend([ '--emulator-log', os.path.join(self._log_manager.GetLogDirectory(), 'emulator_log') ]) env_flags = [ 'ANDROID_EMUGL_LOG_PRINT=1', 'ANDROID_EMUGL_VERBOSE=1', 'VK_LOADER_DEBUG=info,error', ] if self._hardware_gpu: vulkan_icd_file = os.path.join( common.GetEmuRootForPlatform(self.EMULATOR_NAME), 'lib64', 'vulkan', 'vk_swiftshader_icd.json') env_flags.append('VK_ICD_FILENAMES=%s' % vulkan_icd_file) for flag in env_flags: emu_command.extend(['--envs', flag])
def _BuildCommand(self): boot_data.ProvisionSSH() self._host_ssh_port = common.GetAvailableTcpPort() kernel_image = common.EnsurePathExists( boot_data.GetTargetFile('qemu-kernel.kernel', self._image_arch, self._image_type)) zbi_image = common.EnsurePathExists( boot_data.GetTargetFile('zircon-a.zbi', self._image_arch, self._image_type)) fvm_image = common.EnsurePathExists( boot_data.GetTargetFile('storage-full.blk', self._image_arch, self._image_type)) aemu_path = common.EnsurePathExists( os.path.join(common.GetEmuRootForPlatform(self.EMULATOR_NAME), 'emulator')) emu_command = [ self._FVDL_PATH, '--sdk', 'start', '--nointeractive', # Host port mapping for user-networking mode. '--port-map', 'hostfwd=tcp::{}-:22'.format(self._host_ssh_port), # no-interactive requires a --vdl-output flag to shutdown the emulator. '--vdl-output', self._vdl_output_file.name, '-c', ' '.join(boot_data.GetKernelArgs()), # Use existing images instead of downloading new ones. '--kernel-image', kernel_image, '--zbi-image', zbi_image, '--fvm-image', fvm_image, '--image-architecture', self._target_cpu, # Use an existing emulator checked out by Chromium. '--aemu-path', aemu_path, # Use this flag and temp file to define ram size. '--device-proto', self._device_proto_file.name, '--cpu-count', str(self._cpu_cores) ] self._ConfigureEmulatorLog(emu_command) if not self._require_kvm: emu_command.append('--noacceleration') if not self._enable_graphics: emu_command.append('--headless') if self._hardware_gpu: emu_command.append('--host-gpu') if self._with_network: emu_command.append('-N') return emu_command