Merge "Make fs_mgr_overlayfs_mount_fstab_entry() available for user builds"
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index d5b8a61..c4874b8 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -35,6 +35,10 @@
#include "utility.h"
+#ifndef DM_DEFERRED_REMOVE
+#define DM_DEFERRED_REMOVE (1 << 17)
+#endif
+
namespace android {
namespace dm {
@@ -133,6 +137,25 @@
return DeleteDevice(name, 0ms);
}
+bool DeviceMapper::DeleteDeviceDeferred(const std::string& name) {
+ struct dm_ioctl io;
+ InitIo(&io, name);
+
+ io.flags |= DM_DEFERRED_REMOVE;
+ if (ioctl(fd_, DM_DEV_REMOVE, &io)) {
+ PLOG(ERROR) << "DM_DEV_REMOVE with DM_DEFERRED_REMOVE failed for [" << name << "]";
+ return false;
+ }
+ return true;
+}
+
+bool DeviceMapper::DeleteDeviceIfExistsDeferred(const std::string& name) {
+ if (GetState(name) == DmDeviceState::INVALID) {
+ return true;
+ }
+ return DeleteDeviceDeferred(name);
+}
+
static std::string GenerateUuid() {
uuid_t uuid_bytes;
uuid_generate(uuid_bytes);
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 41d3145..8006db2 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -35,6 +35,7 @@
#include <libdm/dm.h>
#include <libdm/loop_control.h>
#include "test_util.h"
+#include "utility.h"
using namespace std;
using namespace std::chrono_literals;
@@ -617,3 +618,64 @@
auto sub_block_device = dm.GetParentBlockDeviceByPath(dev.path());
ASSERT_EQ(loop.device(), *sub_block_device);
}
+
+TEST(libdm, DeleteDeviceDeferredNoReferences) {
+ unique_fd tmp(CreateTempFile("file_1", 4096));
+ ASSERT_GE(tmp, 0);
+ LoopDevice loop(tmp, 10s);
+ ASSERT_TRUE(loop.valid());
+
+ DmTable table;
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop.device(), 0));
+ ASSERT_TRUE(table.valid());
+ TempDevice dev("libdm-test-dm-linear", table);
+ ASSERT_TRUE(dev.valid());
+
+ DeviceMapper& dm = DeviceMapper::Instance();
+
+ std::string path;
+ ASSERT_TRUE(dm.GetDmDevicePathByName("libdm-test-dm-linear", &path));
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+
+ ASSERT_TRUE(dm.DeleteDeviceDeferred("libdm-test-dm-linear"));
+
+ ASSERT_TRUE(WaitForFileDeleted(path, 5s));
+ ASSERT_EQ(DmDeviceState::INVALID, dm.GetState("libdm-test-dm-linear"));
+ ASSERT_NE(0, access(path.c_str(), F_OK));
+ ASSERT_EQ(ENOENT, errno);
+}
+
+TEST(libdm, DeleteDeviceDeferredWaitsForLastReference) {
+ unique_fd tmp(CreateTempFile("file_1", 4096));
+ ASSERT_GE(tmp, 0);
+ LoopDevice loop(tmp, 10s);
+ ASSERT_TRUE(loop.valid());
+
+ DmTable table;
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop.device(), 0));
+ ASSERT_TRUE(table.valid());
+ TempDevice dev("libdm-test-dm-linear", table);
+ ASSERT_TRUE(dev.valid());
+
+ DeviceMapper& dm = DeviceMapper::Instance();
+
+ std::string path;
+ ASSERT_TRUE(dm.GetDmDevicePathByName("libdm-test-dm-linear", &path));
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+
+ {
+ // Open a reference to block device.
+ unique_fd fd(TEMP_FAILURE_RETRY(open(dev.path().c_str(), O_RDONLY | O_CLOEXEC)));
+ ASSERT_GE(fd.get(), 0);
+
+ ASSERT_TRUE(dm.DeleteDeviceDeferred("libdm-test-dm-linear"));
+
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+ }
+
+ // After release device will be removed.
+ ASSERT_TRUE(WaitForFileDeleted(path, 5s));
+ ASSERT_EQ(DmDeviceState::INVALID, dm.GetState("libdm-test-dm-linear"));
+ ASSERT_NE(0, access(path.c_str(), F_OK));
+ ASSERT_EQ(ENOENT, errno);
+}
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index 5d6db46..70b14fa 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -95,6 +95,12 @@
bool DeleteDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms);
bool DeleteDeviceIfExists(const std::string& name, const std::chrono::milliseconds& timeout_ms);
+ // Enqueues a deletion of device mapper device with the given name once last reference is
+ // closed.
+ // Returns 'true' on success, false otherwise.
+ bool DeleteDeviceDeferred(const std::string& name);
+ bool DeleteDeviceIfExistsDeferred(const std::string& name);
+
// Fetches and returns the complete state of the underlying device mapper
// device with given name.
std::optional<Info> GetDetailedInfo(const std::string& name) const;
diff --git a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
index 3888eb1..767cd04 100644
--- a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
@@ -103,6 +103,7 @@
void ReadSnapshotDeviceAndValidate();
void Shutdown();
void MergeInterrupt();
+ void ReadDmUserBlockWithoutDaemon();
std::string snapshot_dev() const { return snapshot_dev_->path(); }
@@ -481,6 +482,36 @@
ASSERT_TRUE(android::fs_mgr::WaitForFile(misc_device, 10s));
}
+void CowSnapuserdTest::ReadDmUserBlockWithoutDaemon() {
+ DmTable dmuser_table;
+ std::string dm_user_name = "dm-test-device";
+ unique_fd fd;
+
+ // Create a dm-user block device
+ ASSERT_TRUE(dmuser_table.AddTarget(std::make_unique<DmTargetUser>(0, 123456, dm_user_name)));
+ ASSERT_TRUE(dmuser_table.valid());
+
+ dmuser_dev_ = std::make_unique<TempDevice>(dm_user_name, dmuser_table);
+ ASSERT_TRUE(dmuser_dev_->valid());
+ ASSERT_FALSE(dmuser_dev_->path().empty());
+
+ fd.reset(open(dmuser_dev_->path().c_str(), O_RDONLY));
+ ASSERT_GE(fd, 0);
+
+ std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(1_MiB);
+
+ loff_t offset = 0;
+ // Every IO should fail as there is no daemon to process the IO
+ for (size_t j = 0; j < 10; j++) {
+ ASSERT_EQ(ReadFullyAtOffset(fd, (char*)buffer.get() + offset, BLOCK_SZ, offset), false);
+
+ offset += BLOCK_SZ;
+ }
+
+ fd = {};
+ ASSERT_TRUE(dmuser_dev_->Destroy());
+}
+
void CowSnapuserdTest::InitDaemon() {
bool ok = client_->AttachDmUser(system_device_ctrl_name_);
ASSERT_TRUE(ok);
@@ -909,6 +940,11 @@
harness.Shutdown();
}
+TEST(Snapuserd_Test, ReadDmUserBlockWithoutDaemon) {
+ CowSnapuserdTest harness;
+ harness.ReadDmUserBlockWithoutDaemon();
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/snapshotctl.cpp b/fs_mgr/libsnapshot/snapshotctl.cpp
index 5eb2003..67189d4 100644
--- a/fs_mgr/libsnapshot/snapshotctl.cpp
+++ b/fs_mgr/libsnapshot/snapshotctl.cpp
@@ -36,7 +36,9 @@
" dump\n"
" Print snapshot states.\n"
" merge\n"
- " Deprecated.\n";
+ " Deprecated.\n"
+ " map\n"
+ " Map all partitions at /dev/block/mapper\n";
return EX_USAGE;
}
diff --git a/init/reboot.cpp b/init/reboot.cpp
index ab0e48e..0e788e4 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -478,6 +478,11 @@
// cut the last "\n"
backing_dev.erase(backing_dev.length() - 1);
+ if (android::base::StartsWith(backing_dev, "none")) {
+ LOG(INFO) << "No zram backing device configured";
+ return {};
+ }
+
// shutdown zram handle
Timer swap_timer;
LOG(INFO) << "swapoff() start...";
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 8f22d89..c471fa0 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -127,7 +127,7 @@
#define AID_EXT_DATA_RW 1078 /* GID for app-private data directories on external storage */
#define AID_EXT_OBB_RW 1079 /* GID for OBB directories on external storage */
#define AID_CONTEXT_HUB 1080 /* GID for access to the Context Hub */
-#define AID_VIRTMANAGER 1081 /* VirtManager daemon */
+#define AID_VIRTUALIZATIONSERVICE 1081 /* VirtualizationService daemon */
#define AID_ARTD 1082 /* ART Service daemon */
#define AID_UWB 1083 /* UWB subsystem */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 56e774b..3101974 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -67,9 +67,9 @@
# CDMA radio interface MUX
/dev/ppp 0660 radio vpn
-# Virtualisation is managed by Virt Manager
-/dev/kvm 0600 virtmanager root
-/dev/vhost-vsock 0600 virtmanager root
+# Virtualization is managed by VirtualizationService.
+/dev/kvm 0600 virtualizationservice root
+/dev/vhost-vsock 0600 virtualizationservice root
# sysfs properties
/sys/devices/platform/trusty.* trusty_version 0440 root log