Pre-create userdata metadata encryption device.

CreateDevice() implicitly calls WaitForDevice(), which can impact boot
time if there are many uevents waiting to be processed. To alleviate
this, create an empty "userdata" device when vold starts (if metada
encryption is enabled). When it comes time to actually enable metadata
encryption, the device can be re-used and the subsequent Wait should be
much faster.

Bug: 198405417
Test: manual test; device boots
Change-Id: Iaacd10858272f17353475e25075ea1dda13f8fc4
This commit is contained in:
David Anderson 2021-09-21 17:21:57 -07:00
parent 8bd25f8e74
commit 156d9d2293
3 changed files with 32 additions and 2 deletions

View file

@ -52,6 +52,7 @@ using android::fs_mgr::GetEntryForMountPoint;
using android::fscrypt::GetFirstApiLevel; using android::fscrypt::GetFirstApiLevel;
using android::vold::KeyBuffer; using android::vold::KeyBuffer;
using namespace android::dm; using namespace android::dm;
using namespace std::chrono_literals;
// Parsed from metadata options // Parsed from metadata options
struct CryptoOptions { struct CryptoOptions {
@ -81,6 +82,17 @@ const KeyGeneration makeGen(const CryptoOptions& options) {
return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key}; return KeyGeneration{options.cipher.get_keysize(), true, options.use_hw_wrapped_key};
} }
void defaultkey_precreate_dm_device() {
auto& dm = DeviceMapper::Instance();
if (dm.GetState(kDmNameUserdata) != DmDeviceState::INVALID) {
LOG(INFO) << "Not pre-creating userdata encryption device; device already exists";
return;
}
if (!dm.CreateEmptyDevice(kDmNameUserdata)) {
LOG(ERROR) << "Failed to pre-create userdata metadata encryption device";
}
}
static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) { static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
// fs_mgr_do_mount runs fsck. Use setexeccon to run trusted // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
// partitions in the fsck domain. // partitions in the fsck domain.
@ -171,8 +183,19 @@ static bool create_crypto_blk_dev(const std::string& dm_name, const std::string&
table.AddTarget(std::move(target)); table.AddTarget(std::move(target));
auto& dm = DeviceMapper::Instance(); auto& dm = DeviceMapper::Instance();
if (!dm.CreateDevice(dm_name, table, crypto_blkdev, std::chrono::seconds(5))) { if (dm_name == kDmNameUserdata && dm.GetState(dm_name) == DmDeviceState::SUSPENDED) {
PLOG(ERROR) << "Could not create default-key device " << dm_name; // The device was created in advance, populate it now.
std::string path;
if (!dm.WaitForDevice(dm_name, 5s, crypto_blkdev)) {
LOG(ERROR) << "Failed to wait for default-key device " << dm_name;
return false;
}
if (!dm.LoadTableAndActivate(dm_name, table)) {
LOG(ERROR) << "Failed to populate default-key device " << dm_name;
return false;
}
} else if (!dm.CreateDevice(dm_name, table, crypto_blkdev, 5s)) {
LOG(ERROR) << "Could not create default-key device " << dm_name;
return false; return false;
} }
return true; return true;

View file

@ -25,6 +25,7 @@
namespace android { namespace android {
namespace vold { namespace vold {
void defaultkey_precreate_dm_device();
bool fscrypt_mount_metadata_encrypted(const std::string& block_device, bool fscrypt_mount_metadata_encrypted(const std::string& block_device,
const std::string& mount_point, bool needs_encrypt, const std::string& mount_point, bool needs_encrypt,
bool should_format, const std::string& fs_type); bool should_format, const std::string& fs_type);

View file

@ -16,6 +16,7 @@
#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
#include "MetadataCrypt.h"
#include "NetlinkManager.h" #include "NetlinkManager.h"
#include "VoldNativeService.h" #include "VoldNativeService.h"
#include "VoldUtil.h" #include "VoldUtil.h"
@ -247,6 +248,11 @@ static int process_config(VolumeManager* vm, VoldConfigs* configs) {
PLOG(FATAL) << "could not find logical partition " << entry.blk_device; PLOG(FATAL) << "could not find logical partition " << entry.blk_device;
} }
if (entry.mount_point == "/data" && !entry.metadata_encryption.empty()) {
// Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417).
android::vold::defaultkey_precreate_dm_device();
}
if (entry.fs_mgr_flags.vold_managed) { if (entry.fs_mgr_flags.vold_managed) {
if (entry.fs_mgr_flags.nonremovable) { if (entry.fs_mgr_flags.nonremovable) {
LOG(WARNING) << "nonremovable no longer supported; ignoring volume"; LOG(WARNING) << "nonremovable no longer supported; ignoring volume";