From 9004f362d30e4ef443e2e9fd2bcf1b859fcff12e Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Thu, 23 May 2024 13:26:31 +0100 Subject: Only unmap snapshots if we have mapped snapshots. When setting up the chroot for a Mainline update, we don't map snapshots. In this case, we shouldn't unmap snapshots when tearing down chroot. Although calling `snapshotctl unmap` is a no-op when there is no snapshot mapped, we may accidentally unmap the snapshots mapped by update_engine. Bug: 311377497 Test: atest art_standalone_dexopt_chroot_setup_tests Test: Run Pre-reboot Dexopt. Change-Id: I1f7adc084c7c46011527f1e390a052f0c81a380d --- dexopt_chroot_setup/dexopt_chroot_setup.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'dexopt_chroot_setup') diff --git a/dexopt_chroot_setup/dexopt_chroot_setup.cc b/dexopt_chroot_setup/dexopt_chroot_setup.cc index 6f01851e3d..976252d110 100644 --- a/dexopt_chroot_setup/dexopt_chroot_setup.cc +++ b/dexopt_chroot_setup/dexopt_chroot_setup.cc @@ -82,6 +82,8 @@ const NoDestructor kBindMountTmpDir( std::string(DexoptChrootSetup::PRE_REBOOT_DEXOPT_DIR) + "/mount_tmp"); const NoDestructor kOtaSlotFile(std::string(DexoptChrootSetup::PRE_REBOOT_DEXOPT_DIR) + "/ota_slot"); +const NoDestructor kSnapshotMappedFile( + std::string(DexoptChrootSetup::PRE_REBOOT_DEXOPT_DIR) + "/snapshot_mapped"); constexpr mode_t kChrootDefaultMode = 0755; constexpr std::chrono::milliseconds kSnapshotCtlTimeout = std::chrono::seconds(60); @@ -392,6 +394,12 @@ Result DexoptChrootSetup::SetUpChroot(const std::optional& ot } else { CHECK(ota_slot.value() == "_a" || ota_slot.value() == "_b"); + // Write the file early in case `snapshotctl map` fails in the middle, leaving some devices + // mapped. We don't assume that `snapshotctl map` is transactional. + if (!WriteStringToFile("", *kSnapshotMappedFile)) { + return ErrnoErrorf("Failed to write '{}'", *kSnapshotMappedFile); + } + // Run `snapshotctl map` through init to map block devices. We can't run it ourselves because it // requires the UID to be 0. See `sys.snapshotctl.map` in `init.rc`. if (!SetProperty("sys.snapshotctl.map", "requested")) { @@ -524,11 +532,17 @@ Result DexoptChrootSetup::TearDownChroot() const { return Errorf("Failed to remove file '{}': {}", *kOtaSlotFile, ec.message()); } - if (!SetProperty("sys.snapshotctl.unmap", "requested")) { - return Errorf("Failed to request snapshotctl unmap"); - } - if (!WaitForProperty("sys.snapshotctl.unmap", "finished", kSnapshotCtlTimeout)) { - return Errorf("snapshotctl timed out"); + if (OS::FileExists(kSnapshotMappedFile->c_str())) { + if (!SetProperty("sys.snapshotctl.unmap", "requested")) { + return Errorf("Failed to request snapshotctl unmap"); + } + if (!WaitForProperty("sys.snapshotctl.unmap", "finished", kSnapshotCtlTimeout)) { + return Errorf("snapshotctl timed out"); + } + std::filesystem::remove(*kSnapshotMappedFile, ec); + if (ec) { + return Errorf("Failed to remove file '{}': {}", *kSnapshotMappedFile, ec.message()); + } } return {}; -- cgit v1.2.3-59-g8ed1b