blob: 421c091250b107beeafd6cfd2c9c7a23db153d68 [file] [log] [blame]
Alex Deymob17327c2015-09-04 10:29:00 -07001//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
Alex Deymo1b03f9f2015-12-09 00:38:36 -080017#include "update_engine/boot_control_android.h"
Alex Deymob17327c2015-09-04 10:29:00 -070018
Sen Jiangd944faa2018-08-22 18:46:39 -070019#include <memory>
20#include <utility>
Yifan Hongd4db07e2018-10-18 17:46:27 -070021#include <vector>
Sen Jiangd944faa2018-08-22 18:46:39 -070022
Alex Deymoaa26f622015-09-16 18:21:27 -070023#include <base/bind.h>
Alex Deymoaa26f622015-09-16 18:21:27 -070024#include <base/logging.h>
Yifan Hongd4db07e2018-10-18 17:46:27 -070025#include <base/strings/string_util.h>
Sen Jiangd944faa2018-08-22 18:46:39 -070026#include <bootloader_message/bootloader_message.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070027#include <brillo/message_loops/message_loop.h>
David Andersond63cb3c2018-10-01 14:15:00 -070028#include <fs_mgr.h>
Mark Salyzyn62b42c82018-12-05 13:33:17 -080029#include <fs_mgr_overlayfs.h>
Alex Deymob17327c2015-09-04 10:29:00 -070030
Alex Deymo39910dc2015-11-09 17:04:30 -080031#include "update_engine/common/utils.h"
Yifan Hong537802d2018-08-15 13:15:42 -070032#include "update_engine/dynamic_partition_control_android.h"
Alex Deymob17327c2015-09-04 10:29:00 -070033
34using std::string;
35
Yifan Hong537802d2018-08-15 13:15:42 -070036using android::dm::DmDeviceState;
Yifan Hong537802d2018-08-15 13:15:42 -070037using android::fs_mgr::Partition;
Yifan Hong537802d2018-08-15 13:15:42 -070038using android::hardware::hidl_string;
Connor O'Briencee6ad92016-11-21 13:53:52 -080039using android::hardware::Return;
40using android::hardware::boot::V1_0::BoolResult;
41using android::hardware::boot::V1_0::CommandResult;
42using android::hardware::boot::V1_0::IBootControl;
Yifan Hong537802d2018-08-15 13:15:42 -070043using Slot = chromeos_update_engine::BootControlInterface::Slot;
Yifan Hong6b0a9842018-10-16 16:54:18 -070044using PartitionMetadata =
45 chromeos_update_engine::BootControlInterface::PartitionMetadata;
Connor O'Briencee6ad92016-11-21 13:53:52 -080046
47namespace {
Yifan Hong537802d2018-08-15 13:15:42 -070048
Connor O'Briencee6ad92016-11-21 13:53:52 -080049auto StoreResultCallback(CommandResult* dest) {
50 return [dest](const CommandResult& result) { *dest = result; };
51}
52} // namespace
Alex Deymo44348e02016-07-29 16:22:26 -070053
Alex Deymob17327c2015-09-04 10:29:00 -070054namespace chromeos_update_engine {
55
56namespace boot_control {
57
58// Factory defined in boot_control.h.
59std::unique_ptr<BootControlInterface> CreateBootControl() {
Yifan Hong537802d2018-08-15 13:15:42 -070060 auto boot_control = std::make_unique<BootControlAndroid>();
David Zeuthen753fadc2015-09-15 16:34:09 -040061 if (!boot_control->Init()) {
62 return nullptr;
63 }
Alex Vakulenkoce8c8ee2016-04-08 08:59:26 -070064 return std::move(boot_control);
Alex Deymob17327c2015-09-04 10:29:00 -070065}
66
67} // namespace boot_control
68
David Zeuthen753fadc2015-09-15 16:34:09 -040069bool BootControlAndroid::Init() {
Chris Phoenixafde8e82017-01-17 23:14:58 -080070 module_ = IBootControl::getService();
Connor O'Briencee6ad92016-11-21 13:53:52 -080071 if (module_ == nullptr) {
Steven Moreland927e00d2017-01-04 12:58:40 -080072 LOG(ERROR) << "Error getting bootctrl HIDL module.";
David Zeuthen753fadc2015-09-15 16:34:09 -040073 return false;
74 }
75
Steven Moreland927e00d2017-01-04 12:58:40 -080076 LOG(INFO) << "Loaded boot control hidl hal.";
David Zeuthen753fadc2015-09-15 16:34:09 -040077
Yifan Hong537802d2018-08-15 13:15:42 -070078 dynamic_control_ = std::make_unique<DynamicPartitionControlAndroid>();
79
David Zeuthen753fadc2015-09-15 16:34:09 -040080 return true;
81}
Alex Deymob17327c2015-09-04 10:29:00 -070082
Yifan Hong537802d2018-08-15 13:15:42 -070083void BootControlAndroid::Cleanup() {
84 dynamic_control_->Cleanup();
85}
86
Alex Deymob17327c2015-09-04 10:29:00 -070087unsigned int BootControlAndroid::GetNumSlots() const {
Connor O'Briencee6ad92016-11-21 13:53:52 -080088 return module_->getNumberSlots();
Alex Deymob17327c2015-09-04 10:29:00 -070089}
90
91BootControlInterface::Slot BootControlAndroid::GetCurrentSlot() const {
Connor O'Briencee6ad92016-11-21 13:53:52 -080092 return module_->getCurrentSlot();
Alex Deymob17327c2015-09-04 10:29:00 -070093}
94
Yifan Hong537802d2018-08-15 13:15:42 -070095bool BootControlAndroid::GetSuffix(Slot slot, string* suffix) const {
Connor O'Briencee6ad92016-11-21 13:53:52 -080096 auto store_suffix_cb = [&suffix](hidl_string cb_suffix) {
Yifan Hong537802d2018-08-15 13:15:42 -070097 *suffix = cb_suffix.c_str();
Connor O'Briencee6ad92016-11-21 13:53:52 -080098 };
99 Return<void> ret = module_->getSuffix(slot, store_suffix_cb);
100
Yifan Hong7b514b42016-12-21 13:02:00 -0800101 if (!ret.isOk()) {
Alex Deymo31d95ac2015-09-17 11:56:18 -0700102 LOG(ERROR) << "boot_control impl returned no suffix for slot "
103 << SlotName(slot);
David Zeuthen753fadc2015-09-15 16:34:09 -0400104 return false;
105 }
Yifan Hong537802d2018-08-15 13:15:42 -0700106 return true;
107}
108
Yifan Hong124a4602018-11-14 13:17:01 -0800109bool BootControlAndroid::IsSuperBlockDevice(
110 const base::FilePath& device_dir,
111 Slot slot,
112 const string& partition_name_suffix) const {
113 string source_device =
114 device_dir.Append(fs_mgr_get_super_partition_name(slot)).value();
115 auto source_metadata = dynamic_control_->LoadMetadataBuilder(
116 source_device, slot, BootControlInterface::kInvalidSlot);
117 return source_metadata->HasBlockDevice(partition_name_suffix);
118}
Yifan Hongae04e192018-10-29 11:00:28 -0700119
Yifan Hong124a4602018-11-14 13:17:01 -0800120BootControlAndroid::DynamicPartitionDeviceStatus
121BootControlAndroid::GetDynamicPartitionDevice(
122 const base::FilePath& device_dir,
Yifan Hongae04e192018-10-29 11:00:28 -0700123 const string& partition_name_suffix,
124 Slot slot,
Yifan Hong124a4602018-11-14 13:17:01 -0800125 string* device) const {
Yifan Hong124a4602018-11-14 13:17:01 -0800126 string super_device =
127 device_dir.Append(fs_mgr_get_super_partition_name(slot)).value();
128
129 auto builder = dynamic_control_->LoadMetadataBuilder(
Yifan Hong6e706b12018-11-09 16:50:51 -0800130 super_device, slot, BootControlInterface::kInvalidSlot);
Yifan Hongae04e192018-10-29 11:00:28 -0700131
132 if (builder == nullptr) {
Yifan Hongae04e192018-10-29 11:00:28 -0700133 LOG(ERROR) << "No metadata in slot "
134 << BootControlInterface::SlotName(slot);
135 return DynamicPartitionDeviceStatus::ERROR;
136 }
137
138 if (builder->FindPartition(partition_name_suffix) == nullptr) {
139 LOG(INFO) << partition_name_suffix
140 << " is not in super partition metadata.";
Yifan Hong124a4602018-11-14 13:17:01 -0800141
142 Slot current_slot = GetCurrentSlot();
143 if (IsSuperBlockDevice(device_dir, current_slot, partition_name_suffix)) {
144 LOG(ERROR) << "The static partition " << partition_name_suffix
145 << " is a block device for current metadata ("
146 << fs_mgr_get_super_partition_name(current_slot) << ", slot "
147 << BootControlInterface::SlotName(current_slot)
148 << "). It cannot be used as a logical partition.";
149 return DynamicPartitionDeviceStatus::ERROR;
150 }
151
Yifan Hongae04e192018-10-29 11:00:28 -0700152 return DynamicPartitionDeviceStatus::TRY_STATIC;
153 }
154
Yifan Hong124a4602018-11-14 13:17:01 -0800155 DmDeviceState state = dynamic_control_->GetState(partition_name_suffix);
Yifan Hongae04e192018-10-29 11:00:28 -0700156
Yifan Hong35410ed2018-12-05 03:30:10 +0000157 // Device is mapped in the previous GetPartitionDevice() call. Just return
158 // the path.
Yifan Hongae04e192018-10-29 11:00:28 -0700159 if (state == DmDeviceState::ACTIVE) {
Yifan Hong124a4602018-11-14 13:17:01 -0800160 if (dynamic_control_->GetDmDevicePathByName(partition_name_suffix,
161 device)) {
Yifan Hongae04e192018-10-29 11:00:28 -0700162 LOG(INFO) << partition_name_suffix
163 << " is mapped on device mapper: " << *device;
164 return DynamicPartitionDeviceStatus::SUCCESS;
165 }
166 LOG(ERROR) << partition_name_suffix << " is mapped but path is unknown.";
167 return DynamicPartitionDeviceStatus::ERROR;
168 }
169
Yifan Hongae04e192018-10-29 11:00:28 -0700170 if (state == DmDeviceState::INVALID) {
Yifan Hong35410ed2018-12-05 03:30:10 +0000171 bool force_writable = slot != GetCurrentSlot();
Yifan Hong124a4602018-11-14 13:17:01 -0800172 if (dynamic_control_->MapPartitionOnDeviceMapper(super_device,
173 partition_name_suffix,
174 slot,
Yifan Hong35410ed2018-12-05 03:30:10 +0000175 force_writable,
Yifan Hong124a4602018-11-14 13:17:01 -0800176 device)) {
Yifan Hongae04e192018-10-29 11:00:28 -0700177 return DynamicPartitionDeviceStatus::SUCCESS;
178 }
179 return DynamicPartitionDeviceStatus::ERROR;
180 }
181
182 LOG(ERROR) << partition_name_suffix
183 << " is mapped on device mapper but state is unknown: "
184 << static_cast<std::underlying_type_t<DmDeviceState>>(state);
185 return DynamicPartitionDeviceStatus::ERROR;
186}
Yifan Hongae04e192018-10-29 11:00:28 -0700187
Yifan Hong537802d2018-08-15 13:15:42 -0700188bool BootControlAndroid::GetPartitionDevice(const string& partition_name,
189 Slot slot,
190 string* device) const {
191 string suffix;
192 if (!GetSuffix(slot, &suffix)) {
193 return false;
194 }
Yifan Hongae04e192018-10-29 11:00:28 -0700195 const string partition_name_suffix = partition_name + suffix;
Yifan Hong537802d2018-08-15 13:15:42 -0700196
197 string device_dir_str;
198 if (!dynamic_control_->GetDeviceDir(&device_dir_str)) {
199 return false;
200 }
Yifan Hongae04e192018-10-29 11:00:28 -0700201 base::FilePath device_dir(device_dir_str);
David Zeuthen753fadc2015-09-15 16:34:09 -0400202
Yifan Hong1d9077f2018-12-07 12:09:37 -0800203 // When looking up target partition devices, treat them as static if the
204 // current payload doesn't encode them as dynamic partitions. This may happen
205 // when applying a retrofit update on top of a dynamic-partitions-enabled
206 // build.
207 if (dynamic_control_->IsDynamicPartitionsEnabled() &&
208 (slot == GetCurrentSlot() || is_target_dynamic_)) {
209 switch (GetDynamicPartitionDevice(
210 device_dir, partition_name_suffix, slot, device)) {
211 case DynamicPartitionDeviceStatus::SUCCESS:
212 return true;
213 case DynamicPartitionDeviceStatus::TRY_STATIC:
214 break;
215 case DynamicPartitionDeviceStatus::ERROR: // fallthrough
216 default:
217 return false;
218 }
Yifan Hongae04e192018-10-29 11:00:28 -0700219 }
220
221 base::FilePath path = device_dir.Append(partition_name_suffix);
Yifan Hong537802d2018-08-15 13:15:42 -0700222 if (!dynamic_control_->DeviceExists(path.value())) {
David Zeuthen753fadc2015-09-15 16:34:09 -0400223 LOG(ERROR) << "Device file " << path.value() << " does not exist.";
224 return false;
225 }
226
227 *device = path.value();
228 return true;
Alex Deymob17327c2015-09-04 10:29:00 -0700229}
230
231bool BootControlAndroid::IsSlotBootable(Slot slot) const {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800232 Return<BoolResult> ret = module_->isSlotBootable(slot);
Yifan Hong7b514b42016-12-21 13:02:00 -0800233 if (!ret.isOk()) {
Alex Deymo31d95ac2015-09-17 11:56:18 -0700234 LOG(ERROR) << "Unable to determine if slot " << SlotName(slot)
Connor O'Briencee6ad92016-11-21 13:53:52 -0800235 << " is bootable: "
Yifan Hong7b514b42016-12-21 13:02:00 -0800236 << ret.description();
David Zeuthen753fadc2015-09-15 16:34:09 -0400237 return false;
238 }
Connor O'Briencee6ad92016-11-21 13:53:52 -0800239 if (ret == BoolResult::INVALID_SLOT) {
240 LOG(ERROR) << "Invalid slot: " << SlotName(slot);
241 return false;
242 }
243 return ret == BoolResult::TRUE;
Alex Deymob17327c2015-09-04 10:29:00 -0700244}
245
246bool BootControlAndroid::MarkSlotUnbootable(Slot slot) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800247 CommandResult result;
248 auto ret = module_->setSlotAsUnbootable(slot, StoreResultCallback(&result));
Yifan Hong7b514b42016-12-21 13:02:00 -0800249 if (!ret.isOk()) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800250 LOG(ERROR) << "Unable to call MarkSlotUnbootable for slot "
251 << SlotName(slot) << ": "
Yifan Hong7b514b42016-12-21 13:02:00 -0800252 << ret.description();
David Zeuthen753fadc2015-09-15 16:34:09 -0400253 return false;
254 }
Connor O'Briencee6ad92016-11-21 13:53:52 -0800255 if (!result.success) {
256 LOG(ERROR) << "Unable to mark slot " << SlotName(slot)
257 << " as unbootable: " << result.errMsg.c_str();
258 }
259 return result.success;
Alex Deymob17327c2015-09-04 10:29:00 -0700260}
261
Alex Deymo31d95ac2015-09-17 11:56:18 -0700262bool BootControlAndroid::SetActiveBootSlot(Slot slot) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800263 CommandResult result;
264 auto ret = module_->setActiveBootSlot(slot, StoreResultCallback(&result));
Yifan Hong7b514b42016-12-21 13:02:00 -0800265 if (!ret.isOk()) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800266 LOG(ERROR) << "Unable to call SetActiveBootSlot for slot " << SlotName(slot)
Yifan Hong7b514b42016-12-21 13:02:00 -0800267 << ": " << ret.description();
Connor O'Briencee6ad92016-11-21 13:53:52 -0800268 return false;
Alex Deymo29dcbf32016-10-06 13:33:20 -0700269 }
Connor O'Briencee6ad92016-11-21 13:53:52 -0800270 if (!result.success) {
271 LOG(ERROR) << "Unable to set the active slot to slot " << SlotName(slot)
272 << ": " << result.errMsg.c_str();
273 }
274 return result.success;
Alex Deymo31d95ac2015-09-17 11:56:18 -0700275}
276
Alex Deymoaa26f622015-09-16 18:21:27 -0700277bool BootControlAndroid::MarkBootSuccessfulAsync(
278 base::Callback<void(bool)> callback) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800279 CommandResult result;
280 auto ret = module_->markBootSuccessful(StoreResultCallback(&result));
Yifan Hong7b514b42016-12-21 13:02:00 -0800281 if (!ret.isOk()) {
Connor O'Briencee6ad92016-11-21 13:53:52 -0800282 LOG(ERROR) << "Unable to call MarkBootSuccessful: "
Yifan Hong7b514b42016-12-21 13:02:00 -0800283 << ret.description();
Connor O'Briencee6ad92016-11-21 13:53:52 -0800284 return false;
285 }
286 if (!result.success) {
287 LOG(ERROR) << "Unable to mark boot successful: " << result.errMsg.c_str();
Alex Deymoaa26f622015-09-16 18:21:27 -0700288 }
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700289 return brillo::MessageLoop::current()->PostTask(
Connor O'Briencee6ad92016-11-21 13:53:52 -0800290 FROM_HERE, base::Bind(callback, result.success)) !=
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700291 brillo::MessageLoop::kTaskIdNull;
Alex Deymoaa26f622015-09-16 18:21:27 -0700292}
293
Yifan Hong537802d2018-08-15 13:15:42 -0700294namespace {
295
Yifan Hong1d9077f2018-12-07 12:09:37 -0800296bool UpdatePartitionMetadata(DynamicPartitionControlInterface* dynamic_control,
297 Slot source_slot,
298 Slot target_slot,
299 const string& target_suffix,
300 const PartitionMetadata& partition_metadata) {
301 string device_dir_str;
302 if (!dynamic_control->GetDeviceDir(&device_dir_str)) {
303 return false;
304 }
305 base::FilePath device_dir(device_dir_str);
306 auto source_device =
307 device_dir.Append(fs_mgr_get_super_partition_name(source_slot)).value();
308
Yifan Hong6e706b12018-11-09 16:50:51 -0800309 auto builder = dynamic_control->LoadMetadataBuilder(
Yifan Hongb97e3ab2018-11-14 13:50:39 -0800310 source_device, source_slot, target_slot);
Yifan Hongd4db07e2018-10-18 17:46:27 -0700311 if (builder == nullptr) {
312 // TODO(elsk): allow reconstructing metadata from partition_metadata
313 // in recovery sideload.
314 LOG(ERROR) << "No metadata at "
315 << BootControlInterface::SlotName(source_slot);
Yifan Hong537802d2018-08-15 13:15:42 -0700316 return false;
317 }
318
Yifan Hongd4db07e2018-10-18 17:46:27 -0700319 std::vector<string> groups = builder->ListGroups();
320 for (const auto& group_name : groups) {
321 if (base::EndsWith(
322 group_name, target_suffix, base::CompareCase::SENSITIVE)) {
323 LOG(INFO) << "Removing group " << group_name;
324 builder->RemoveGroupAndPartitions(group_name);
325 }
326 }
327
328 uint64_t total_size = 0;
329 for (const auto& group : partition_metadata.groups) {
330 total_size += group.size;
331 }
332
Yifan Hong6e38b352018-11-19 14:12:37 -0800333 string expr;
334 uint64_t allocatable_space = builder->AllocatableSpace();
335 if (!dynamic_control->IsDynamicPartitionsRetrofit()) {
336 allocatable_space /= 2;
337 expr = "half of ";
338 }
339 if (total_size > allocatable_space) {
340 LOG(ERROR) << "The maximum size of all groups with suffix " << target_suffix
341 << " (" << total_size << ") has exceeded " << expr
Yifan Hong1d9077f2018-12-07 12:09:37 -0800342 << " allocatable space for dynamic partitions "
Yifan Hong6e38b352018-11-19 14:12:37 -0800343 << allocatable_space << ".";
Yifan Hong537802d2018-08-15 13:15:42 -0700344 return false;
345 }
346
Yifan Hongd4db07e2018-10-18 17:46:27 -0700347 for (const auto& group : partition_metadata.groups) {
348 auto group_name_suffix = group.name + target_suffix;
349 if (!builder->AddGroup(group_name_suffix, group.size)) {
350 LOG(ERROR) << "Cannot add group " << group_name_suffix << " with size "
351 << group.size;
352 return false;
353 }
354 LOG(INFO) << "Added group " << group_name_suffix << " with size "
355 << group.size;
356
357 for (const auto& partition : group.partitions) {
Yifan Honga7897f32018-11-15 14:28:50 -0800358 auto partition_name_suffix = partition.name + target_suffix;
Yifan Hongd4db07e2018-10-18 17:46:27 -0700359 Partition* p = builder->AddPartition(
Yifan Honga7897f32018-11-15 14:28:50 -0800360 partition_name_suffix, group_name_suffix, LP_PARTITION_ATTR_READONLY);
Yifan Hongd4db07e2018-10-18 17:46:27 -0700361 if (!p) {
Yifan Honga7897f32018-11-15 14:28:50 -0800362 LOG(ERROR) << "Cannot add partition " << partition_name_suffix
Yifan Hongd4db07e2018-10-18 17:46:27 -0700363 << " to group " << group_name_suffix;
364 return false;
365 }
366 if (!builder->ResizePartition(p, partition.size)) {
Yifan Honga7897f32018-11-15 14:28:50 -0800367 LOG(ERROR) << "Cannot resize partition " << partition_name_suffix
Yifan Hongd4db07e2018-10-18 17:46:27 -0700368 << " to size " << partition.size << ". Not enough space?";
369 return false;
370 }
Yifan Honga7897f32018-11-15 14:28:50 -0800371 LOG(INFO) << "Added partition " << partition_name_suffix << " to group "
Yifan Hongd4db07e2018-10-18 17:46:27 -0700372 << group_name_suffix << " with size " << partition.size;
373 }
Yifan Hong537802d2018-08-15 13:15:42 -0700374 }
375
Yifan Hong1d9077f2018-12-07 12:09:37 -0800376 auto target_device =
377 device_dir.Append(fs_mgr_get_super_partition_name(target_slot)).value();
Yifan Hongd4db07e2018-10-18 17:46:27 -0700378 return dynamic_control->StoreMetadata(
Yifan Hongb97e3ab2018-11-14 13:50:39 -0800379 target_device, builder.get(), target_slot);
Yifan Hong537802d2018-08-15 13:15:42 -0700380}
381
Yifan Hong1d9077f2018-12-07 12:09:37 -0800382bool UnmapTargetPartitions(DynamicPartitionControlInterface* dynamic_control,
383 const string& target_suffix,
384 const PartitionMetadata& partition_metadata) {
Yifan Hongd4db07e2018-10-18 17:46:27 -0700385 for (const auto& group : partition_metadata.groups) {
386 for (const auto& partition : group.partitions) {
387 if (!dynamic_control->UnmapPartitionOnDeviceMapper(
388 partition.name + target_suffix, true /* wait */)) {
389 return false;
390 }
Yifan Hong537802d2018-08-15 13:15:42 -0700391 }
Yifan Hong537802d2018-08-15 13:15:42 -0700392 }
393 return true;
394}
395
Yifan Hong537802d2018-08-15 13:15:42 -0700396} // namespace
397
398bool BootControlAndroid::InitPartitionMetadata(
Tao Bao3406c772019-01-02 15:34:35 -0800399 Slot target_slot,
400 const PartitionMetadata& partition_metadata,
401 bool update_metadata) {
Mark Salyzyn62b42c82018-12-05 13:33:17 -0800402 if (fs_mgr_overlayfs_is_setup()) {
403 // Non DAP devices can use overlayfs as well.
404 LOG(WARNING)
405 << "overlayfs overrides are active and can interfere with our "
406 "resources.\n"
407 << "run adb enable-verity to deactivate if required and try again.";
408 }
Yifan Hong537802d2018-08-15 13:15:42 -0700409 if (!dynamic_control_->IsDynamicPartitionsEnabled()) {
410 return true;
411 }
412
Yifan Hong1d9077f2018-12-07 12:09:37 -0800413 auto source_slot = GetCurrentSlot();
414 if (target_slot == source_slot) {
Yifan Hong537802d2018-08-15 13:15:42 -0700415 LOG(ERROR) << "Cannot call InitPartitionMetadata on current slot.";
416 return false;
417 }
418
Yifan Hong1d9077f2018-12-07 12:09:37 -0800419 // Although the current build supports dynamic partitions, the given payload
420 // doesn't use it for target partitions. This could happen when applying a
421 // retrofit update. Skip updating the partition metadata for the target slot.
422 is_target_dynamic_ = !partition_metadata.groups.empty();
423 if (!is_target_dynamic_) {
424 return true;
425 }
426
Tao Bao3406c772019-01-02 15:34:35 -0800427 if (!update_metadata) {
428 return true;
429 }
430
431 string target_suffix;
432 if (!GetSuffix(target_slot, &target_suffix)) {
433 return false;
434 }
435
Yifan Hong1d9077f2018-12-07 12:09:37 -0800436 // Unmap all the target dynamic partitions because they would become
437 // inconsistent with the new metadata.
438 if (!UnmapTargetPartitions(
439 dynamic_control_.get(), target_suffix, partition_metadata)) {
Yifan Hong537802d2018-08-15 13:15:42 -0700440 return false;
441 }
442
Tao Bao3406c772019-01-02 15:34:35 -0800443 return UpdatePartitionMetadata(dynamic_control_.get(),
444 source_slot,
445 target_slot,
446 target_suffix,
447 partition_metadata);
Yifan Hong537802d2018-08-15 13:15:42 -0700448}
449
Alex Deymob17327c2015-09-04 10:29:00 -0700450} // namespace chromeos_update_engine