A build only device cannot be used to run this target.

本文介绍了“Abuildonlydevicecannotbeusedtorunthistarget”错误的原因及解决方法。此错误通常出现在尝试在不支持的虚拟机上运行目标时。文章提供了解决方案,即如何正确选择与虚拟机兼容的版本号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A build only device cannot be used to run this target.
造成这个错误的原因是,你选择的版本号,在虚拟机中没有,
所以我们要重新选择版本号
这里写图片描述
这里写图片描述

Return SnapshotManager::CreateUpdateSnapshots(const DeltaArchiveManifest& manifest) { auto lock = LockExclusive(); if (!lock) return Return::Error(); auto update_state = ReadUpdateState(lock.get()); if (update_state != UpdateState::Initiated) { LOG(ERROR) << "Cannot create update snapshots in state " << update_state; return Return::Error(); } // TODO(b/134949511): remove this check. Right now, with overlayfs mounted, the scratch // partition takes up a big chunk of space in super, causing COW images to be created on // retrofit Virtual A/B devices. if (device_->IsOverlayfsSetup()) { LOG(ERROR) << "Cannot create update snapshots with overlayfs setup. Run `adb enable-verity`" << ", reboot, then try again."; return Return::Error(); } const auto& opener = device_->GetPartitionOpener(); auto current_suffix = device_->GetSlotSuffix(); uint32_t current_slot = SlotNumberForSlotSuffix(current_suffix); auto target_suffix = device_->GetOtherSlotSuffix(); uint32_t target_slot = SlotNumberForSlotSuffix(target_suffix); auto current_super = device_->GetSuperDevice(current_slot); auto current_metadata = MetadataBuilder::New(opener, current_super, current_slot); if (current_metadata == nullptr) { LOG(ERROR) << "Cannot create metadata builder."; return Return::Error(); } auto target_metadata = MetadataBuilder::NewForUpdate(opener, current_super, current_slot, target_slot); if (target_metadata == nullptr) { LOG(ERROR) << "Cannot create target metadata builder."; return Return::Error(); } // Delete partitions with target suffix in |current_metadata|. Otherwise, // partition_cow_creator recognizes these left-over partitions as used space. for (const auto& group_name : current_metadata->ListGroups()) { if (android::base::EndsWith(group_name, target_suffix)) { current_metadata->RemoveGroupAndPartitions(group_name); } } SnapshotMetadataUpdater metadata_updater(target_metadata.get(), target_slot, manifest); if (!metadata_updater.Update()) { LOG(ERROR) << "Cannot calculate new metadata."; return Return::Error(); } // Delete previous COW partitions in current_metadata so that PartitionCowCreator marks those as // free regions. UnmapAndDeleteCowPartition(current_metadata.get()); // Check that all these metadata is not retrofit dynamic partitions. Snapshots on // devices with retrofit dynamic partitions does not make sense. // This ensures that current_metadata->GetFreeRegions() uses the same device // indices as target_metadata (i.e. 0 -> "super"). // This is also assumed in MapCowDevices() call below. CHECK(current_metadata->GetBlockDevicePartitionName(0) == LP_METADATA_DEFAULT_PARTITION_NAME && target_metadata->GetBlockDevicePartitionName(0) == LP_METADATA_DEFAULT_PARTITION_NAME); std::map<std::string, SnapshotStatus> all_snapshot_status; // In case of error, automatically delete devices that are created along the way. // Note that "lock" is destroyed after "created_devices", so it is safe to use |lock| for // these devices. AutoDeviceList created_devices; const auto& dap_metadata = manifest.dynamic_partition_metadata(); CowOptions options; CowWriter writer(options); bool cow_format_support = true; if (dap_metadata.cow_version() < writer.GetCowVersion()) { cow_format_support = false; } LOG(INFO) << " dap_metadata.cow_version(): " << dap_metadata.cow_version() << " writer.GetCowVersion(): " << writer.GetCowVersion(); bool use_compression = IsCompressionEnabled() && dap_metadata.vabc_enabled() && !device_->IsRecovery() && cow_format_support; std::string compression_algorithm; if (use_compression) { compression_algorithm = dap_metadata.vabc_compression_param(); if (compression_algorithm.empty()) { // Older OTAs don't set an explicit compression type, so default to gz. compression_algorithm = "gz"; } } else { compression_algorithm = "none"; } PartitionCowCreator cow_creator{ .target_metadata = target_metadata.get(), .target_suffix = target_suffix, .target_partition = nullptr, .current_metadata = current_metadata.get(), .current_suffix = current_suffix, .update = nullptr, .extra_extents = {}, .compression_enabled = use_compression, .compression_algorithm = compression_algorithm, }; auto ret = CreateUpdateSnapshotsInternal(lock.get(), manifest, &cow_creator, &created_devices, &all_snapshot_status); if (!ret.is_ok()) return ret; auto exported_target_metadata = target_metadata->Export(); if (exported_target_metadata == nullptr) { LOG(ERROR) << "Cannot export target metadata"; return Return::Error(); } ret = InitializeUpdateSnapshots(lock.get(), target_metadata.get(), exported_target_metadata.get(), target_suffix, all_snapshot_status); if (!ret.is_ok()) return ret; if (!UpdatePartitionTable(opener, device_->GetSuperDevice(target_slot), *exported_target_metadata, target_slot)) { LOG(ERROR) << "Cannot write target metadata"; return Return::Error(); } // If compression is enabled, we need to retain a copy of the old metadata // so we can access original blocks in case they are moved around. We do // not want to rely on the old super metadata slot because we don't // guarantee its validity after the slot switch is successful. if (cow_creator.compression_enabled) { auto metadata = current_metadata->Export(); if (!metadata) { LOG(ERROR) << "Could not export current metadata"; return Return::Error(); } auto path = GetOldPartitionMetadataPath(); if (!android::fs_mgr::WriteToImageFile(path, *metadata.get())) { LOG(ERROR) << "Cannot write old metadata to " << path; return Return::Error(); } } SnapshotUpdateStatus status = ReadSnapshotUpdateStatus(lock.get()); status.set_state(update_state); status.set_compression_enabled(cow_creator.compression_enabled); if (cow_creator.compression_enabled) { if (!device()->IsTestDevice()) { bool userSnapshotsEnabled = IsUserspaceSnapshotsEnabled(); const std::string UNKNOWN = "unknown"; const std::string vendor_release = android::base::GetProperty( "ro.vendor.build.version.release_or_codename", UNKNOWN); // No user-space snapshots if vendor partition is on Android 12 if (vendor_release.find("12") != std::string::npos) { LOG(INFO) << "Userspace snapshots disabled as vendor partition is on Android: " << vendor_release; userSnapshotsEnabled = false; } // Userspace snapshots is enabled only if compression is enabled status.set_userspace_snapshots(userSnapshotsEnabled); if (userSnapshotsEnabled) { is_snapshot_userspace_ = true; status.set_io_uring_enabled(IsIouringEnabled()); LOG(INFO) << "Userspace snapshots enabled"; } else { is_snapshot_userspace_ = false; LOG(INFO) << "Userspace snapshots disabled"; } // Terminate stale daemon if any std::unique_ptr<SnapuserdClient> snapuserd_client = SnapuserdClient::Connect(kSnapuserdSocket, 5s); if (snapuserd_client) { snapuserd_client->DetachSnapuserd(); snapuserd_client->CloseConnection(); snapuserd_client = nullptr; } // Clear the cached client if any if (snapuserd_client_) { snapuserd_client_->CloseConnection(); snapuserd_client_ = nullptr; } } else { bool userSnapshotsEnabled = true; const std::string UNKNOWN = "unknown"; const std::string vendor_release = android::base::GetProperty( "ro.vendor.build.version.release_or_codename", UNKNOWN); // No user-space snapshots if vendor partition is on Android 12 if (vendor_release.find("12") != std::string::npos) { LOG(INFO) << "Userspace snapshots disabled as vendor partition is on Android: " << vendor_release; userSnapshotsEnabled = false; } userSnapshotsEnabled = (userSnapshotsEnabled && !IsDmSnapshotTestingEnabled()); status.set_userspace_snapshots(userSnapshotsEnabled); if (!userSnapshotsEnabled) { is_snapshot_userspace_ = false; LOG(INFO) << "User-space snapshots disabled for testing"; } else { is_snapshot_userspace_ = true; LOG(INFO) << "User-space snapshots enabled for testing"; } } } if (!WriteSnapshotUpdateStatus(lock.get(), status)) { LOG(ERROR) << "Unable to write new update state"; return Return::Error(); } created_devices.Release(); LOG(INFO) << "Successfully created all snapshots for target slot " << target_suffix; return Return::Ok(); }解析王法
最新发布
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值