fs_mgr: overlay: resize other OTA partitions to zero to make space

If we do not have at least the minimum space to create a scratch
partition, let's resize the other partitions to zero to make the
space and try again.

Specify additional shared library dependencies for remount command.
margin_size could never be calculated because "scratch" partition
does not exist, so use super partition instead as argument to
GetBlockDeviceInfo.

Add a "Now reboot your device for settings to take effect" message
if the -R argument was not supplied.  Adjust some of the messages
to be clearer.

Manual test: On a full DAP device, resize or flash both a and b side
for system, vendor and product with fastboot to duplicate failure
conditions of limited space and check remount command resizes other
side partitions to mitigate.

Test: manual and adb_remount_test.sh
Bug: 131390072
Change-Id: I34c4a973f88a5e1e06b64af9589a84721dd1bbbd
This commit is contained in:
Mark Salyzyn 2019-04-30 13:21:04 -07:00 committed by David Anderson
parent 6bc132846a
commit c3fc2aa964
3 changed files with 50 additions and 6 deletions

View file

@ -121,9 +121,14 @@ cc_binary {
shared_libs: [
"libbootloader_message",
"libbase",
"libcutils",
"libcrypto",
"libext4_utils",
"libfec",
"libfs_mgr",
"liblog",
"liblp",
"libselinux",
],
header_libs: [
"libcutils_headers",

View file

@ -646,6 +646,25 @@ bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std:
return true;
}
static void TruncatePartitionsWithSuffix(MetadataBuilder* builder, const std::string& suffix) {
auto& dm = DeviceMapper::Instance();
// Remove <other> partitions
for (const auto& group : builder->ListGroups()) {
for (const auto& part : builder->ListPartitionsInGroup(group)) {
const auto& name = part->name();
if (!android::base::EndsWith(name, suffix)) {
continue;
}
if (dm.GetState(name) != DmDeviceState::INVALID && !DestroyLogicalPartition(name, 2s)) {
continue;
}
builder->ResizePartition(builder->FindPartition(name), 0);
}
}
}
// This is where we find and steal backing storage from the system.
bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device,
bool* partition_exists, bool* change) {
*scratch_device = fs_mgr_overlayfs_scratch_device();
@ -692,15 +711,24 @@ bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_de
// the adb remount overrides :-( .
auto margin_size = uint64_t(3 * 256 * 1024);
BlockDeviceInfo info;
if (builder->GetBlockDeviceInfo(partition_name, &info)) {
if (builder->GetBlockDeviceInfo(fs_mgr_get_super_partition_name(slot_number), &info)) {
margin_size = 3 * info.logical_block_size;
}
partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
partition_size / 2);
if (partition_size > partition->size()) {
if (!builder->ResizePartition(partition, partition_size)) {
LERROR << "resize " << partition_name;
return false;
// Try to free up space by deallocating partitions in the other slot.
TruncatePartitionsWithSuffix(builder.get(), fs_mgr_get_other_slot_suffix());
partition_size =
builder->AllocatableSpace() - builder->UsedSpace() + partition->size();
partition_size = std::max(std::min(kMinimumSize, partition_size - margin_size),
partition_size / 2);
if (!builder->ResizePartition(partition, partition_size)) {
LERROR << "resize " << partition_name;
return false;
}
}
if (!partition_create) DestroyLogicalPartition(partition_name, 10s);
changed = true;

View file

@ -249,6 +249,7 @@ int main(int argc, char* argv[]) {
// Check verity and optionally setup overlayfs backing.
auto reboot_later = false;
auto user_please_reboot_later = false;
auto uses_overlayfs = fs_mgr_overlayfs_valid() != OverlayfsValidResult::kNotSupported;
for (auto it = partitions.begin(); it != partitions.end();) {
auto& entry = *it;
@ -262,7 +263,7 @@ int main(int argc, char* argv[]) {
false);
avb_ops_user_free(ops);
if (ret) {
LOG(WARNING) << "Disable verity for " << mount_point;
LOG(WARNING) << "Disabling verity for " << mount_point;
reboot_later = can_reboot;
if (reboot_later) {
// w/o overlayfs available, also check for dedupe
@ -272,20 +273,22 @@ int main(int argc, char* argv[]) {
}
reboot(false);
}
user_please_reboot_later = true;
} else if (fs_mgr_set_blk_ro(entry.blk_device, false)) {
fec::io fh(entry.blk_device.c_str(), O_RDWR);
if (fh && fh.set_verity_status(false)) {
LOG(WARNING) << "Disable verity for " << mount_point;
LOG(WARNING) << "Disabling verity for " << mount_point;
reboot_later = can_reboot;
if (reboot_later && !uses_overlayfs) {
++it;
continue;
}
user_please_reboot_later = true;
}
}
}
}
LOG(ERROR) << "Skipping " << mount_point;
LOG(ERROR) << "Skipping " << mount_point << " for remount";
it = partitions.erase(it);
continue;
}
@ -307,6 +310,10 @@ int main(int argc, char* argv[]) {
if (partitions.empty()) {
if (reboot_later) reboot(false);
if (user_please_reboot_later) {
LOG(INFO) << "Now reboot your device for settings to take effect";
return 0;
}
LOG(WARNING) << "No partitions to remount";
return retval;
}
@ -383,6 +390,10 @@ int main(int argc, char* argv[]) {
}
if (reboot_later) reboot(false);
if (user_please_reboot_later) {
LOG(INFO) << "Now reboot your device for settings to take effect";
return 0;
}
return retval;
}