Merge changes I99f292a0,I6a0f13d5,I2bf3bebf into rvc-dev
* changes: init: Forcefully mount system_ext on DAP devices if not present in fstab. init: Factor out first-stage uevent handling into a separate class. init: Remove special-case hacks for the super partition.
This commit is contained in:
commit
3a5e138964
6 changed files with 297 additions and 153 deletions
|
@ -36,6 +36,7 @@ init_common_sources = [
|
|||
"util.cpp",
|
||||
]
|
||||
init_device_sources = [
|
||||
"block_dev_initializer.cpp",
|
||||
"bootchart.cpp",
|
||||
"builtins.cpp",
|
||||
"devices.cpp",
|
||||
|
|
|
@ -48,6 +48,7 @@ ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_CPPFLAGS := $(init_cflags)
|
||||
LOCAL_SRC_FILES := \
|
||||
block_dev_initializer.cpp \
|
||||
devices.cpp \
|
||||
first_stage_init.cpp \
|
||||
first_stage_main.cpp \
|
||||
|
|
148
init/block_dev_initializer.cpp
Normal file
148
init/block_dev_initializer.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
// Copyright (C) 2020 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/chrono_utils.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <fs_mgr.h>
|
||||
|
||||
#include "block_dev_initializer.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
using android::base::Timer;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
BlockDevInitializer::BlockDevInitializer() : uevent_listener_(16 * 1024 * 1024) {
|
||||
auto boot_devices = android::fs_mgr::GetBootDevices();
|
||||
device_handler_ = std::make_unique<DeviceHandler>(
|
||||
std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
|
||||
std::move(boot_devices), false);
|
||||
}
|
||||
|
||||
bool BlockDevInitializer::InitDeviceMapper() {
|
||||
const std::string dm_path = "/devices/virtual/misc/device-mapper";
|
||||
bool found = false;
|
||||
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
|
||||
if (uevent.path == dm_path) {
|
||||
device_handler_->HandleUevent(uevent);
|
||||
found = true;
|
||||
return ListenerAction::kStop;
|
||||
}
|
||||
return ListenerAction::kContinue;
|
||||
};
|
||||
uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
|
||||
if (!found) {
|
||||
LOG(INFO) << "device-mapper device not found in /sys, waiting for its uevent";
|
||||
Timer t;
|
||||
uevent_listener_.Poll(dm_callback, 10s);
|
||||
LOG(INFO) << "Wait for device-mapper returned after " << t;
|
||||
}
|
||||
if (!found) {
|
||||
LOG(ERROR) << "device-mapper device not found after polling timeout";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ListenerAction BlockDevInitializer::HandleUevent(const Uevent& uevent,
|
||||
std::set<std::string>* devices) {
|
||||
// Ignore everything that is not a block device.
|
||||
if (uevent.subsystem != "block") {
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
auto name = uevent.partition_name;
|
||||
if (name.empty()) {
|
||||
size_t base_idx = uevent.path.rfind('/');
|
||||
if (base_idx == std::string::npos) {
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
name = uevent.path.substr(base_idx + 1);
|
||||
}
|
||||
|
||||
auto iter = devices->find(name);
|
||||
if (iter == devices->end()) {
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;
|
||||
|
||||
devices->erase(iter);
|
||||
device_handler_->HandleUevent(uevent);
|
||||
return devices->empty() ? ListenerAction::kStop : ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
bool BlockDevInitializer::InitDevices(std::set<std::string> devices) {
|
||||
auto uevent_callback = [&, this](const Uevent& uevent) -> ListenerAction {
|
||||
return HandleUevent(uevent, &devices);
|
||||
};
|
||||
uevent_listener_.RegenerateUevents(uevent_callback);
|
||||
|
||||
// UeventCallback() will remove found partitions from |devices|. So if it
|
||||
// isn't empty here, it means some partitions are not found.
|
||||
if (!devices.empty()) {
|
||||
LOG(INFO) << __PRETTY_FUNCTION__
|
||||
<< ": partition(s) not found in /sys, waiting for their uevent(s): "
|
||||
<< android::base::Join(devices, ", ");
|
||||
Timer t;
|
||||
uevent_listener_.Poll(uevent_callback, 10s);
|
||||
LOG(INFO) << "Wait for partitions returned after " << t;
|
||||
}
|
||||
|
||||
if (!devices.empty()) {
|
||||
LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found after polling timeout: "
|
||||
<< android::base::Join(devices, ", ");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Creates "/dev/block/dm-XX" for dm nodes by running coldboot on /sys/block/dm-XX.
|
||||
bool BlockDevInitializer::InitDmDevice(const std::string& device) {
|
||||
const std::string device_name(basename(device.c_str()));
|
||||
const std::string syspath = "/sys/block/" + device_name;
|
||||
bool found = false;
|
||||
|
||||
auto uevent_callback = [&device_name, &device, this, &found](const Uevent& uevent) {
|
||||
if (uevent.device_name == device_name) {
|
||||
LOG(VERBOSE) << "Creating device-mapper device : " << device;
|
||||
device_handler_->HandleUevent(uevent);
|
||||
found = true;
|
||||
return ListenerAction::kStop;
|
||||
}
|
||||
return ListenerAction::kContinue;
|
||||
};
|
||||
|
||||
uevent_listener_.RegenerateUeventsForPath(syspath, uevent_callback);
|
||||
if (!found) {
|
||||
LOG(INFO) << "dm device '" << device << "' not found in /sys, waiting for its uevent";
|
||||
Timer t;
|
||||
uevent_listener_.Poll(uevent_callback, 10s);
|
||||
LOG(INFO) << "wait for dm device '" << device << "' returned after " << t;
|
||||
}
|
||||
if (!found) {
|
||||
LOG(ERROR) << "dm device '" << device << "' not found after polling timeout";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
41
init/block_dev_initializer.h
Normal file
41
init/block_dev_initializer.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright (C) 2020 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "devices.h"
|
||||
#include "uevent_listener.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class BlockDevInitializer final {
|
||||
public:
|
||||
BlockDevInitializer();
|
||||
|
||||
bool InitDeviceMapper();
|
||||
bool InitDevices(std::set<std::string> devices);
|
||||
bool InitDmDevice(const std::string& device);
|
||||
|
||||
private:
|
||||
ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);
|
||||
|
||||
std::unique_ptr<DeviceHandler> device_handler_;
|
||||
UeventListener uevent_listener_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
|
@ -42,6 +42,7 @@
|
|||
#include <liblp/liblp.h>
|
||||
#include <libsnapshot/snapshot.h>
|
||||
|
||||
#include "block_dev_initializer.h"
|
||||
#include "devices.h"
|
||||
#include "switch_root.h"
|
||||
#include "uevent.h"
|
||||
|
@ -84,11 +85,7 @@ class FirstStageMount {
|
|||
bool InitDevices();
|
||||
|
||||
protected:
|
||||
ListenerAction HandleBlockDevice(const std::string& name, const Uevent&,
|
||||
std::set<std::string>* required_devices);
|
||||
bool InitRequiredDevices(std::set<std::string> devices);
|
||||
bool InitMappedDevice(const std::string& verity_device);
|
||||
bool InitDeviceMapper();
|
||||
bool CreateLogicalPartitions();
|
||||
bool MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
|
||||
Fstab::iterator* end = nullptr);
|
||||
|
@ -97,7 +94,7 @@ class FirstStageMount {
|
|||
bool TrySwitchSystemAsRoot();
|
||||
bool TrySkipMountingPartitions();
|
||||
bool IsDmLinearEnabled();
|
||||
void GetDmLinearMetadataDevice(std::set<std::string>* devices);
|
||||
void GetSuperDeviceName(std::set<std::string>* devices);
|
||||
bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata);
|
||||
void UseDsuIfPresent();
|
||||
// Reads all fstab.avb_keys from the ramdisk for first-stage mount.
|
||||
|
@ -106,8 +103,6 @@ class FirstStageMount {
|
|||
// revocation check by DSU installation service.
|
||||
void CopyDsuAvbKeys();
|
||||
|
||||
ListenerAction UeventCallback(const Uevent& uevent, std::set<std::string>* required_devices);
|
||||
|
||||
// Pure virtual functions.
|
||||
virtual bool GetDmVerityDevices(std::set<std::string>* devices) = 0;
|
||||
virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
|
||||
|
@ -116,10 +111,10 @@ class FirstStageMount {
|
|||
bool dsu_not_on_userdata_ = false;
|
||||
|
||||
Fstab fstab_;
|
||||
std::string lp_metadata_partition_;
|
||||
// The super path is only set after InitDevices, and is invalid before.
|
||||
std::string super_path_;
|
||||
std::string super_partition_name_;
|
||||
std::unique_ptr<DeviceHandler> device_handler_;
|
||||
UeventListener uevent_listener_;
|
||||
BlockDevInitializer block_dev_init_;
|
||||
// Reads all AVB keys before chroot into /system, as they might be used
|
||||
// later when mounting other partitions, e.g., /vendor and /product.
|
||||
std::map<std::string, std::vector<std::string>> preload_avb_key_blobs_;
|
||||
|
@ -233,13 +228,7 @@ static bool IsStandaloneImageRollback(const AvbHandle& builtin_vbmeta,
|
|||
|
||||
// Class Definitions
|
||||
// -----------------
|
||||
FirstStageMount::FirstStageMount(Fstab fstab)
|
||||
: need_dm_verity_(false), fstab_(std::move(fstab)), uevent_listener_(16 * 1024 * 1024) {
|
||||
auto boot_devices = android::fs_mgr::GetBootDevices();
|
||||
device_handler_ = std::make_unique<DeviceHandler>(
|
||||
std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
|
||||
std::move(boot_devices), false);
|
||||
|
||||
FirstStageMount::FirstStageMount(Fstab fstab) : need_dm_verity_(false), fstab_(std::move(fstab)) {
|
||||
super_partition_name_ = fs_mgr_get_super_partition_name();
|
||||
}
|
||||
|
||||
|
@ -268,12 +257,23 @@ bool FirstStageMount::DoFirstStageMount() {
|
|||
|
||||
bool FirstStageMount::InitDevices() {
|
||||
std::set<std::string> devices;
|
||||
GetDmLinearMetadataDevice(&devices);
|
||||
GetSuperDeviceName(&devices);
|
||||
|
||||
if (!GetDmVerityDevices(&devices)) {
|
||||
return false;
|
||||
}
|
||||
return InitRequiredDevices(std::move(devices));
|
||||
if (!InitRequiredDevices(std::move(devices))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsDmLinearEnabled()) {
|
||||
auto super_symlink = "/dev/block/by-name/"s + super_partition_name_;
|
||||
if (!android::base::Realpath(super_symlink, &super_path_)) {
|
||||
PLOG(ERROR) << "realpath failed: " << super_symlink;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FirstStageMount::IsDmLinearEnabled() {
|
||||
|
@ -283,7 +283,7 @@ bool FirstStageMount::IsDmLinearEnabled() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void FirstStageMount::GetDmLinearMetadataDevice(std::set<std::string>* devices) {
|
||||
void FirstStageMount::GetSuperDeviceName(std::set<std::string>* devices) {
|
||||
// Add any additional devices required for dm-linear mappings.
|
||||
if (!IsDmLinearEnabled()) {
|
||||
return;
|
||||
|
@ -296,62 +296,13 @@ void FirstStageMount::GetDmLinearMetadataDevice(std::set<std::string>* devices)
|
|||
// Found partitions will then be removed from it for the subsequent member
|
||||
// function to check which devices are NOT created.
|
||||
bool FirstStageMount::InitRequiredDevices(std::set<std::string> devices) {
|
||||
if (!InitDeviceMapper()) {
|
||||
if (!block_dev_init_.InitDeviceMapper()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (devices.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto uevent_callback = [&, this](const Uevent& uevent) {
|
||||
return UeventCallback(uevent, &devices);
|
||||
};
|
||||
uevent_listener_.RegenerateUevents(uevent_callback);
|
||||
|
||||
// UeventCallback() will remove found partitions from |devices|. So if it
|
||||
// isn't empty here, it means some partitions are not found.
|
||||
if (!devices.empty()) {
|
||||
LOG(INFO) << __PRETTY_FUNCTION__
|
||||
<< ": partition(s) not found in /sys, waiting for their uevent(s): "
|
||||
<< android::base::Join(devices, ", ");
|
||||
Timer t;
|
||||
uevent_listener_.Poll(uevent_callback, 10s);
|
||||
LOG(INFO) << "Wait for partitions returned after " << t;
|
||||
}
|
||||
|
||||
if (!devices.empty()) {
|
||||
LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found after polling timeout: "
|
||||
<< android::base::Join(devices, ", ");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FirstStageMount::InitDeviceMapper() {
|
||||
const std::string dm_path = "/devices/virtual/misc/device-mapper";
|
||||
bool found = false;
|
||||
auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
|
||||
if (uevent.path == dm_path) {
|
||||
device_handler_->HandleUevent(uevent);
|
||||
found = true;
|
||||
return ListenerAction::kStop;
|
||||
}
|
||||
return ListenerAction::kContinue;
|
||||
};
|
||||
uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
|
||||
if (!found) {
|
||||
LOG(INFO) << "device-mapper device not found in /sys, waiting for its uevent";
|
||||
Timer t;
|
||||
uevent_listener_.Poll(dm_callback, 10s);
|
||||
LOG(INFO) << "Wait for device-mapper returned after " << t;
|
||||
}
|
||||
if (!found) {
|
||||
LOG(ERROR) << "device-mapper device not found after polling timeout";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return block_dev_init_.InitDevices(std::move(devices));
|
||||
}
|
||||
|
||||
bool FirstStageMount::InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata) {
|
||||
|
@ -375,7 +326,7 @@ bool FirstStageMount::CreateLogicalPartitions() {
|
|||
if (!IsDmLinearEnabled()) {
|
||||
return true;
|
||||
}
|
||||
if (lp_metadata_partition_.empty()) {
|
||||
if (super_path_.empty()) {
|
||||
LOG(ERROR) << "Could not locate logical partition tables in partition "
|
||||
<< super_partition_name_;
|
||||
return false;
|
||||
|
@ -392,92 +343,19 @@ bool FirstStageMount::CreateLogicalPartitions() {
|
|||
if (!InitRequiredDevices({"userdata"})) {
|
||||
return false;
|
||||
}
|
||||
return sm->CreateLogicalAndSnapshotPartitions(lp_metadata_partition_);
|
||||
return sm->CreateLogicalAndSnapshotPartitions(super_path_);
|
||||
}
|
||||
}
|
||||
|
||||
auto metadata = android::fs_mgr::ReadCurrentMetadata(lp_metadata_partition_);
|
||||
auto metadata = android::fs_mgr::ReadCurrentMetadata(super_path_);
|
||||
if (!metadata) {
|
||||
LOG(ERROR) << "Could not read logical partition metadata from " << lp_metadata_partition_;
|
||||
LOG(ERROR) << "Could not read logical partition metadata from " << super_path_;
|
||||
return false;
|
||||
}
|
||||
if (!InitDmLinearBackingDevices(*metadata.get())) {
|
||||
return false;
|
||||
}
|
||||
return android::fs_mgr::CreateLogicalPartitions(*metadata.get(), lp_metadata_partition_);
|
||||
}
|
||||
|
||||
ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent,
|
||||
std::set<std::string>* required_devices) {
|
||||
// Matches partition name to create device nodes.
|
||||
// Both required_devices_partition_names_ and uevent->partition_name have A/B
|
||||
// suffix when A/B is used.
|
||||
auto iter = required_devices->find(name);
|
||||
if (iter != required_devices->end()) {
|
||||
LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
|
||||
if (IsDmLinearEnabled() && name == super_partition_name_) {
|
||||
std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
|
||||
lp_metadata_partition_ = links[0];
|
||||
}
|
||||
required_devices->erase(iter);
|
||||
device_handler_->HandleUevent(uevent);
|
||||
if (required_devices->empty()) {
|
||||
return ListenerAction::kStop;
|
||||
} else {
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
}
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent,
|
||||
std::set<std::string>* required_devices) {
|
||||
// Ignores everything that is not a block device.
|
||||
if (uevent.subsystem != "block") {
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
if (!uevent.partition_name.empty()) {
|
||||
return HandleBlockDevice(uevent.partition_name, uevent, required_devices);
|
||||
} else {
|
||||
size_t base_idx = uevent.path.rfind('/');
|
||||
if (base_idx != std::string::npos) {
|
||||
return HandleBlockDevice(uevent.path.substr(base_idx + 1), uevent, required_devices);
|
||||
}
|
||||
}
|
||||
// Not found a partition or find an unneeded partition, continue to find others.
|
||||
return ListenerAction::kContinue;
|
||||
}
|
||||
|
||||
// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
|
||||
bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
|
||||
const std::string device_name(basename(dm_device.c_str()));
|
||||
const std::string syspath = "/sys/block/" + device_name;
|
||||
bool found = false;
|
||||
|
||||
auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
|
||||
if (uevent.device_name == device_name) {
|
||||
LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
|
||||
device_handler_->HandleUevent(uevent);
|
||||
found = true;
|
||||
return ListenerAction::kStop;
|
||||
}
|
||||
return ListenerAction::kContinue;
|
||||
};
|
||||
|
||||
uevent_listener_.RegenerateUeventsForPath(syspath, verity_callback);
|
||||
if (!found) {
|
||||
LOG(INFO) << "dm device '" << dm_device << "' not found in /sys, waiting for its uevent";
|
||||
Timer t;
|
||||
uevent_listener_.Poll(verity_callback, 10s);
|
||||
LOG(INFO) << "wait for dm device '" << dm_device << "' returned after " << t;
|
||||
}
|
||||
if (!found) {
|
||||
LOG(ERROR) << "dm device '" << dm_device << "' not found after polling timeout";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_path_);
|
||||
}
|
||||
|
||||
bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
|
||||
|
@ -491,7 +369,7 @@ bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_sa
|
|||
if (!fs_mgr_update_logical_partition(&(*begin))) {
|
||||
return false;
|
||||
}
|
||||
if (!InitMappedDevice(begin->blk_device)) {
|
||||
if (!block_dev_init_.InitDmDevice(begin->blk_device)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +536,9 @@ bool FirstStageMount::MountPartitions() {
|
|||
auto init_devices = [this](std::set<std::string> devices) -> bool {
|
||||
for (auto iter = devices.begin(); iter != devices.end();) {
|
||||
if (android::base::StartsWith(*iter, "/dev/block/dm-")) {
|
||||
if (!InitMappedDevice(*iter)) return false;
|
||||
if (!block_dev_init_.InitDmDevice(*iter)) {
|
||||
return false;
|
||||
}
|
||||
iter = devices.erase(iter);
|
||||
} else {
|
||||
iter++;
|
||||
|
@ -774,7 +654,7 @@ bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) {
|
|||
// The exact block device name (fstab_rec->blk_device) is changed to
|
||||
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
|
||||
// first stage.
|
||||
return InitMappedDevice(fstab_entry->blk_device);
|
||||
return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -894,7 +774,7 @@ bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
|
|||
// The exact block device name (fstab_rec->blk_device) is changed to
|
||||
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
|
||||
// first stage.
|
||||
return InitMappedDevice(fstab_entry->blk_device);
|
||||
return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -63,12 +63,15 @@
|
|||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/parseint.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <fs_avb/fs_avb.h>
|
||||
#include <fs_mgr.h>
|
||||
#include <libgsi/libgsi.h>
|
||||
#include <libsnapshot/snapshot.h>
|
||||
#include <selinux/android.h>
|
||||
|
||||
#include "block_dev_initializer.h"
|
||||
#include "debug_ramdisk.h"
|
||||
#include "reboot_utils.h"
|
||||
#include "util.h"
|
||||
|
@ -598,6 +601,74 @@ int SelinuxGetVendorAndroidVersion() {
|
|||
return vendor_android_version;
|
||||
}
|
||||
|
||||
// This is for R system.img/system_ext.img to work on old vendor.img as system_ext.img
|
||||
// is introduced in R. We mount system_ext in second stage init because the first-stage
|
||||
// init in boot.img won't be updated in the system-only OTA scenario.
|
||||
void MountMissingSystemPartitions() {
|
||||
android::fs_mgr::Fstab fstab;
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
LOG(ERROR) << "Could not read default fstab";
|
||||
}
|
||||
|
||||
android::fs_mgr::Fstab mounts;
|
||||
if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
|
||||
LOG(ERROR) << "Could not read /proc/mounts";
|
||||
}
|
||||
|
||||
static const std::vector<std::string> kPartitionNames = {"system_ext", "product"};
|
||||
|
||||
android::fs_mgr::Fstab extra_fstab;
|
||||
for (const auto& name : kPartitionNames) {
|
||||
if (GetEntryForMountPoint(&mounts, "/"s + name)) {
|
||||
// The partition is already mounted.
|
||||
continue;
|
||||
}
|
||||
|
||||
auto system_entry = GetEntryForMountPoint(&fstab, "/system");
|
||||
if (!system_entry) {
|
||||
LOG(ERROR) << "Could not find mount entry for /system";
|
||||
break;
|
||||
}
|
||||
if (!system_entry->fs_mgr_flags.logical) {
|
||||
LOG(INFO) << "Skipping mount of " << name << ", system is not dynamic.";
|
||||
break;
|
||||
}
|
||||
|
||||
auto entry = *system_entry;
|
||||
auto partition_name = name + fs_mgr_get_slot_suffix();
|
||||
auto replace_name = "system"s + fs_mgr_get_slot_suffix();
|
||||
|
||||
entry.mount_point = "/"s + name;
|
||||
entry.blk_device =
|
||||
android::base::StringReplace(entry.blk_device, replace_name, partition_name, false);
|
||||
if (!fs_mgr_update_logical_partition(&entry)) {
|
||||
LOG(ERROR) << "Could not update logical partition";
|
||||
continue;
|
||||
}
|
||||
|
||||
extra_fstab.emplace_back(std::move(entry));
|
||||
}
|
||||
|
||||
SkipMountingPartitions(&extra_fstab);
|
||||
if (extra_fstab.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockDevInitializer block_dev_init;
|
||||
for (auto& entry : extra_fstab) {
|
||||
if (access(entry.blk_device.c_str(), F_OK) != 0) {
|
||||
auto block_dev = android::base::Basename(entry.blk_device);
|
||||
if (!block_dev_init.InitDmDevice(block_dev)) {
|
||||
LOG(ERROR) << "Failed to find device-mapper node: " << block_dev;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fs_mgr_do_mount_one(entry)) {
|
||||
LOG(ERROR) << "Could not mount " << entry.mount_point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SetupSelinux(char** argv) {
|
||||
SetStdioToDevNull(argv);
|
||||
InitKernelLogging(argv);
|
||||
|
@ -608,6 +679,8 @@ int SetupSelinux(char** argv) {
|
|||
|
||||
boot_clock::time_point start_time = boot_clock::now();
|
||||
|
||||
MountMissingSystemPartitions();
|
||||
|
||||
// Set up SELinux, loading the SELinux policy.
|
||||
SelinuxSetupKernelLogging();
|
||||
SelinuxInitialize();
|
||||
|
|
Loading…
Reference in a new issue