1 /*
2  * Copyright (C) 2018 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 #pragma once
17 
18 #include <optional>
19 #include <string>
20 
21 #include <android-base/unique_fd.h>
22 #include <android/hardware/boot/1.0/IBootControl.h>
23 #include <fstab/fstab.h>
24 #include <liblp/liblp.h>
25 
26 // Logical partitions are only mapped to a block device as needed, and
27 // immediately unmapped when no longer needed. In order to enforce this we
28 // require accessing partitions through a Handle abstraction, which may perform
29 // additional operations after closing its file descriptor.
30 class PartitionHandle {
31   public:
PartitionHandle()32     PartitionHandle() {}
PartitionHandle(const std::string & path)33     explicit PartitionHandle(const std::string& path) : path_(path) {}
PartitionHandle(const std::string & path,std::function<void ()> && closer)34     PartitionHandle(const std::string& path, std::function<void()>&& closer)
35         : path_(path), closer_(std::move(closer)) {}
36     PartitionHandle(PartitionHandle&& other) = default;
37     PartitionHandle& operator=(PartitionHandle&& other) = default;
~PartitionHandle()38     ~PartitionHandle() {
39         if (closer_) {
40             // Make sure the device is closed first.
41             fd_ = {};
42             closer_();
43         }
44     }
path()45     const std::string& path() const { return path_; }
fd()46     int fd() const { return fd_.get(); }
set_fd(android::base::unique_fd && fd)47     void set_fd(android::base::unique_fd&& fd) { fd_ = std::move(fd); }
48 
49   private:
50     std::string path_;
51     android::base::unique_fd fd_;
52     std::function<void()> closer_;
53 };
54 
55 class AutoMountMetadata {
56   public:
57     AutoMountMetadata();
58     ~AutoMountMetadata();
59     explicit operator bool() const { return mounted_; }
60 
61   private:
62     android::fs_mgr::Fstab fstab_;
63     bool mounted_ = false;
64     bool should_unmount_ = false;
65 };
66 
67 class FastbootDevice;
68 
69 // On normal devices, the super partition is always named "super". On retrofit
70 // devices, the name must be derived from the partition name or current slot.
71 // This helper assists in choosing the correct super for a given partition
72 // name.
73 std::string GetSuperSlotSuffix(FastbootDevice* device, const std::string& partition_name);
74 
75 std::optional<std::string> FindPhysicalPartition(const std::string& name);
76 bool LogicalPartitionExists(FastbootDevice* device, const std::string& name,
77                             bool* is_zero_length = nullptr);
78 bool OpenPartition(FastbootDevice* device, const std::string& name, PartitionHandle* handle);
79 bool GetSlotNumber(const std::string& slot, android::hardware::boot::V1_0::Slot* number);
80 std::vector<std::string> ListPartitions(FastbootDevice* device);
81 bool GetDeviceLockStatus();
82 
83 // Update all copies of metadata.
84 bool UpdateAllPartitionMetadata(FastbootDevice* device, const std::string& super_name,
85                                 const android::fs_mgr::LpMetadata& metadata);
86