diff options
author | Bowgo Tsai | 2017-05-08 07:45:50 -0500 |
---|---|---|
committer | Bowgo Tsai | 2017-05-15 03:49:37 -0500 |
commit | d7846a2c53a0f462dc29b83ff2e46e252d6e9937 (patch) | |
tree | de6ffa9ecb453700a32a53e731da0128fcd33096 | |
parent | 1fa0251930371aa0069e6ea20602b604c02f4f48 (diff) | |
download | platform-system-core-d7846a2c53a0f462dc29b83ff2e46e252d6e9937.tar.gz platform-system-core-d7846a2c53a0f462dc29b83ff2e46e252d6e9937.tar.xz platform-system-core-d7846a2c53a0f462dc29b83ff2e46e252d6e9937.zip |
first stage mount: removing the requirement of by-name prefix for AVB
Current first stage mount for AVB requires specifying a common prefix of
by-name symlink for all AVB partitions. It limits all AVB partitions to be on
the same block device.
firmware {
android {
compatible = "android,firmware";
vbmeta {
compatible = "android,vbmeta";
parts = "vbmeta,boot,system,vendor";
by_name_prefix="/dev/block/platform/soc.0/f9824900.sdhci/by-name" <-- *removing this*
};
fstab {
compatible = "android,fstab";
vendor {
compatible = "android,vendor";
dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
fsmgr_flags = "wait,avb";
};
};
};
};
For normal mount with AVB, it extracts the by-name prefix of /misc
partition and use it as the prefix for all other partitions:
- /dev/block/platform/soc.0/f9824900.sdhci/by-name/misc ->
- /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a
Fix this by adding an internal map in FsManagerAvbOps to record the mapping
from partition name to its by-name symlink:
ByNameSymlinkMap["vendor_a"] = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a"
Two overloaded factory methods are then provided for FsManagerAvbUniquePtr:
- FsManagerAvbUniquePtr Open(ByNameSymlinkMap&& by_name_symlink_map):
for first stage mount, where the by-name symlink map will be
constructed externally, from the uevents processed by init, before
invoking this factory method.
- FsManagerAvbUniquePtr Open(const fstab& fstab): for normal mount,
where the by-name symlink map will be constructed from the input fstab
internally.
Bug: 37552224
Test: first stage mount /vendor with vboot 1.0
Test: first stage mount /vendor with vboot 2.0 (AVB)
Test: normal mount /vendor with vboot 2.0 (AVB)
Change-Id: Id17e8566da87ea22b8923fcd6e47db8d45bc7d6a
Merged-In: Id17e8566da87ea22b8923fcd6e47db8d45bc7d6a
(cherry picked from commit 20651f62d081c88596e70b3b589863a75e2a9c35)
-rw-r--r-- | fs_mgr/fs_mgr.cpp | 21 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_avb.cpp | 23 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_avb_ops.cpp | 40 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_priv_avb_ops.h (renamed from fs_mgr/fs_mgr_avb_ops.h) | 16 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr_avb.h | 19 | ||||
-rw-r--r-- | init/init_first_stage.cpp | 204 |
6 files changed, 189 insertions, 134 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index abdd4986d..e224aec9b 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp | |||
@@ -744,23 +744,6 @@ static int handle_encryptable(const struct fstab_rec* rec) | |||
744 | } | 744 | } |
745 | } | 745 | } |
746 | 746 | ||
747 | static std::string extract_by_name_prefix(struct fstab* fstab) { | ||
748 | // We assume that there's an entry for the /misc mount point in the | ||
749 | // fstab file and use that to get the device file by-name prefix. | ||
750 | // The device needs not to have an actual /misc partition. | ||
751 | // e.g., | ||
752 | // - /dev/block/platform/soc.0/7824900.sdhci/by-name/misc -> | ||
753 | // - /dev/block/platform/soc.0/7824900.sdhci/by-name/ | ||
754 | struct fstab_rec* fstab_entry = fs_mgr_get_entry_for_mount_point(fstab, "/misc"); | ||
755 | if (fstab_entry == nullptr) { | ||
756 | LERROR << "/misc mount point not found in fstab"; | ||
757 | return ""; | ||
758 | } | ||
759 | std::string full_path(fstab_entry->blk_device); | ||
760 | size_t end_slash = full_path.find_last_of("/"); | ||
761 | return full_path.substr(0, end_slash + 1); | ||
762 | } | ||
763 | |||
764 | // TODO: add ueventd notifiers if they don't exist. | 747 | // TODO: add ueventd notifiers if they don't exist. |
765 | // This is just doing a wait_for_device for maximum of 1s | 748 | // This is just doing a wait_for_device for maximum of 1s |
766 | int fs_mgr_test_access(const char *device) { | 749 | int fs_mgr_test_access(const char *device) { |
@@ -850,7 +833,7 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) | |||
850 | 833 | ||
851 | if (fstab->recs[i].fs_mgr_flags & MF_AVB) { | 834 | if (fstab->recs[i].fs_mgr_flags & MF_AVB) { |
852 | if (!avb_handle) { | 835 | if (!avb_handle) { |
853 | avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab)); | 836 | avb_handle = FsManagerAvbHandle::Open(*fstab); |
854 | if (!avb_handle) { | 837 | if (!avb_handle) { |
855 | LERROR << "Failed to open FsManagerAvbHandle"; | 838 | LERROR << "Failed to open FsManagerAvbHandle"; |
856 | return -1; | 839 | return -1; |
@@ -1061,7 +1044,7 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device, | |||
1061 | 1044 | ||
1062 | if (fstab->recs[i].fs_mgr_flags & MF_AVB) { | 1045 | if (fstab->recs[i].fs_mgr_flags & MF_AVB) { |
1063 | if (!avb_handle) { | 1046 | if (!avb_handle) { |
1064 | avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab)); | 1047 | avb_handle = FsManagerAvbHandle::Open(*fstab); |
1065 | if (!avb_handle) { | 1048 | if (!avb_handle) { |
1066 | LERROR << "Failed to open FsManagerAvbHandle"; | 1049 | LERROR << "Failed to open FsManagerAvbHandle"; |
1067 | return -1; | 1050 | return -1; |
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp index d4dd76aa6..36883e677 100644 --- a/fs_mgr/fs_mgr_avb.cpp +++ b/fs_mgr/fs_mgr_avb.cpp | |||
@@ -14,6 +14,8 @@ | |||
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "fs_mgr_avb.h" | ||
18 | |||
17 | #include <errno.h> | 19 | #include <errno.h> |
18 | #include <fcntl.h> | 20 | #include <fcntl.h> |
19 | #include <inttypes.h> | 21 | #include <inttypes.h> |
@@ -38,9 +40,8 @@ | |||
38 | #include <utils/Compat.h> | 40 | #include <utils/Compat.h> |
39 | 41 | ||
40 | #include "fs_mgr.h" | 42 | #include "fs_mgr.h" |
41 | #include "fs_mgr_avb.h" | ||
42 | #include "fs_mgr_avb_ops.h" | ||
43 | #include "fs_mgr_priv.h" | 43 | #include "fs_mgr_priv.h" |
44 | #include "fs_mgr_priv_avb_ops.h" | ||
44 | #include "fs_mgr_priv_dm_ioctl.h" | 45 | #include "fs_mgr_priv_dm_ioctl.h" |
45 | #include "fs_mgr_priv_sha.h" | 46 | #include "fs_mgr_priv_sha.h" |
46 | 47 | ||
@@ -457,12 +458,21 @@ static bool get_hashtree_descriptor(const std::string& partition_name, | |||
457 | return true; | 458 | return true; |
458 | } | 459 | } |
459 | 460 | ||
460 | FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const std::string& device_file_by_name_prefix) { | 461 | FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) { |
461 | if (device_file_by_name_prefix.empty()) { | 462 | FsManagerAvbOps avb_ops(fstab); |
462 | LERROR << "Missing device file by-name prefix"; | 463 | return DoOpen(&avb_ops); |
464 | } | ||
465 | |||
466 | FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlink_map) { | ||
467 | if (by_name_symlink_map.empty()) { | ||
468 | LERROR << "Empty by_name_symlink_map when opening FsManagerAvbHandle"; | ||
463 | return nullptr; | 469 | return nullptr; |
464 | } | 470 | } |
471 | FsManagerAvbOps avb_ops(std::move(by_name_symlink_map)); | ||
472 | return DoOpen(&avb_ops); | ||
473 | } | ||
465 | 474 | ||
475 | FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { | ||
466 | // Gets the expected hash value of vbmeta images from kernel cmdline. | 476 | // Gets the expected hash value of vbmeta images from kernel cmdline. |
467 | std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); | 477 | std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create(); |
468 | if (!avb_verifier) { | 478 | if (!avb_verifier) { |
@@ -476,8 +486,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const std::string& device_file_by | |||
476 | return nullptr; | 486 | return nullptr; |
477 | } | 487 | } |
478 | 488 | ||
479 | FsManagerAvbOps avb_ops(device_file_by_name_prefix); | 489 | AvbSlotVerifyResult verify_result = avb_ops->AvbSlotVerify( |
480 | AvbSlotVerifyResult verify_result = avb_ops.AvbSlotVerify( | ||
481 | fs_mgr_get_slot_suffix(), avb_verifier->IsDeviceUnlocked(), &avb_handle->avb_slot_data_); | 490 | fs_mgr_get_slot_suffix(), avb_verifier->IsDeviceUnlocked(), &avb_handle->avb_slot_data_); |
482 | 491 | ||
483 | // Only allow two verify results: | 492 | // Only allow two verify results: |
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp index 981e9fc04..47df861a0 100644 --- a/fs_mgr/fs_mgr_avb_ops.cpp +++ b/fs_mgr/fs_mgr_avb_ops.cpp | |||
@@ -22,6 +22,8 @@ | |||
22 | * SOFTWARE. | 22 | * SOFTWARE. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "fs_mgr_priv_avb_ops.h" | ||
26 | |||
25 | #include <errno.h> | 27 | #include <errno.h> |
26 | #include <fcntl.h> | 28 | #include <fcntl.h> |
27 | #include <stdlib.h> | 29 | #include <stdlib.h> |
@@ -36,7 +38,6 @@ | |||
36 | #include <utils/Compat.h> | 38 | #include <utils/Compat.h> |
37 | 39 | ||
38 | #include "fs_mgr.h" | 40 | #include "fs_mgr.h" |
39 | #include "fs_mgr_avb_ops.h" | ||
40 | #include "fs_mgr_priv.h" | 41 | #include "fs_mgr_priv.h" |
41 | 42 | ||
42 | static AvbIOResult read_from_partition(AvbOps* ops, const char* partition, int64_t offset, | 43 | static AvbIOResult read_from_partition(AvbOps* ops, const char* partition, int64_t offset, |
@@ -88,11 +89,7 @@ static AvbIOResult dummy_get_unique_guid_for_partition(AvbOps* ops ATTRIBUTE_UNU | |||
88 | return AVB_IO_RESULT_OK; | 89 | return AVB_IO_RESULT_OK; |
89 | } | 90 | } |
90 | 91 | ||
91 | FsManagerAvbOps::FsManagerAvbOps(const std::string& device_file_by_name_prefix) | 92 | void FsManagerAvbOps::InitializeAvbOps() { |
92 | : device_file_by_name_prefix_(device_file_by_name_prefix) { | ||
93 | if (device_file_by_name_prefix_.back() != '/') { | ||
94 | device_file_by_name_prefix_ += '/'; | ||
95 | } | ||
96 | // We only need to provide the implementation of read_from_partition() | 93 | // We only need to provide the implementation of read_from_partition() |
97 | // operation since that's all what is being used by the avb_slot_verify(). | 94 | // operation since that's all what is being used by the avb_slot_verify(). |
98 | // Other I/O operations are only required in bootloader but not in | 95 | // Other I/O operations are only required in bootloader but not in |
@@ -107,13 +104,31 @@ FsManagerAvbOps::FsManagerAvbOps(const std::string& device_file_by_name_prefix) | |||
107 | avb_ops_.user_data = this; | 104 | avb_ops_.user_data = this; |
108 | } | 105 | } |
109 | 106 | ||
107 | FsManagerAvbOps::FsManagerAvbOps(std::map<std::string, std::string>&& by_name_symlink_map) | ||
108 | : by_name_symlink_map_(std::move(by_name_symlink_map)) { | ||
109 | InitializeAvbOps(); | ||
110 | } | ||
111 | |||
112 | FsManagerAvbOps::FsManagerAvbOps(const fstab& fstab) { | ||
113 | // Constructs the by-name symlink map for each fstab record. | ||
114 | // /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a => | ||
115 | // by_name_symlink_map_["system_a"] = "/dev/block/platform/soc.0/7824900.sdhci/by-name/system_a" | ||
116 | for (int i = 0; i < fstab.num_entries; i++) { | ||
117 | std::string partition_name = basename(fstab.recs[i].blk_device); | ||
118 | by_name_symlink_map_[partition_name] = fstab.recs[i].blk_device; | ||
119 | } | ||
120 | InitializeAvbOps(); | ||
121 | } | ||
122 | |||
110 | AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t offset, | 123 | AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t offset, |
111 | size_t num_bytes, void* buffer, | 124 | size_t num_bytes, void* buffer, |
112 | size_t* out_num_read) { | 125 | size_t* out_num_read) { |
113 | // Appends |partition| to the device_file_by_name_prefix_, e.g., | 126 | const auto iter = by_name_symlink_map_.find(partition); |
114 | // - /dev/block/platform/soc.0/7824900.sdhci/by-name/ -> | 127 | if (iter == by_name_symlink_map_.end()) { |
115 | // - /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a | 128 | LERROR << "by-name symlink not found for partition: '" << partition << "'"; |
116 | std::string path = device_file_by_name_prefix_ + partition; | 129 | return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; |
130 | } | ||
131 | std::string path = iter->second; | ||
117 | 132 | ||
118 | // Ensures the device path (a symlink created by init) is ready to | 133 | // Ensures the device path (a symlink created by init) is ready to |
119 | // access. fs_mgr_test_access() will test a few iterations if the | 134 | // access. fs_mgr_test_access() will test a few iterations if the |
@@ -124,7 +139,7 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of | |||
124 | 139 | ||
125 | android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC))); | 140 | android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC))); |
126 | if (fd < 0) { | 141 | if (fd < 0) { |
127 | PERROR << "Failed to open " << path.c_str(); | 142 | PERROR << "Failed to open " << path; |
128 | return AVB_IO_RESULT_ERROR_IO; | 143 | return AVB_IO_RESULT_ERROR_IO; |
129 | } | 144 | } |
130 | 145 | ||
@@ -148,8 +163,7 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of | |||
148 | // for EOF). | 163 | // for EOF). |
149 | ssize_t num_read = TEMP_FAILURE_RETRY(pread64(fd, buffer, num_bytes, offset)); | 164 | ssize_t num_read = TEMP_FAILURE_RETRY(pread64(fd, buffer, num_bytes, offset)); |
150 | if (num_read < 0 || (size_t)num_read != num_bytes) { | 165 | if (num_read < 0 || (size_t)num_read != num_bytes) { |
151 | PERROR << "Failed to read " << num_bytes << " bytes from " << path.c_str() << " offset " | 166 | PERROR << "Failed to read " << num_bytes << " bytes from " << path << " offset " << offset; |
152 | << offset; | ||
153 | return AVB_IO_RESULT_ERROR_IO; | 167 | return AVB_IO_RESULT_ERROR_IO; |
154 | } | 168 | } |
155 | 169 | ||
diff --git a/fs_mgr/fs_mgr_avb_ops.h b/fs_mgr/fs_mgr_priv_avb_ops.h index ec4a8c94e..a6b52e43f 100644 --- a/fs_mgr/fs_mgr_avb_ops.h +++ b/fs_mgr/fs_mgr_priv_avb_ops.h | |||
@@ -22,8 +22,11 @@ | |||
22 | * SOFTWARE. | 22 | * SOFTWARE. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifndef __CORE_FS_MGR_AVB_OPS_H | 25 | #ifndef __CORE_FS_MGR_PRIV_AVB_OPS_H |
26 | #define __CORE_FS_MGR_AVB_OPS_H | 26 | #define __CORE_FS_MGR_PRIV_AVB_OPS_H |
27 | |||
28 | #include <map> | ||
29 | #include <string> | ||
27 | 30 | ||
28 | #include <libavb/libavb.h> | 31 | #include <libavb/libavb.h> |
29 | 32 | ||
@@ -43,7 +46,8 @@ | |||
43 | // | 46 | // |
44 | class FsManagerAvbOps { | 47 | class FsManagerAvbOps { |
45 | public: | 48 | public: |
46 | FsManagerAvbOps(const std::string& device_file_by_name_prefix); | 49 | FsManagerAvbOps(const fstab& fstab); |
50 | FsManagerAvbOps(std::map<std::string, std::string>&& by_name_symlink_map); | ||
47 | 51 | ||
48 | static FsManagerAvbOps* GetInstanceFromAvbOps(AvbOps* ops) { | 52 | static FsManagerAvbOps* GetInstanceFromAvbOps(AvbOps* ops) { |
49 | return reinterpret_cast<FsManagerAvbOps*>(ops->user_data); | 53 | return reinterpret_cast<FsManagerAvbOps*>(ops->user_data); |
@@ -56,7 +60,9 @@ class FsManagerAvbOps { | |||
56 | AvbSlotVerifyData** out_data); | 60 | AvbSlotVerifyData** out_data); |
57 | 61 | ||
58 | private: | 62 | private: |
63 | void InitializeAvbOps(); | ||
64 | |||
59 | AvbOps avb_ops_; | 65 | AvbOps avb_ops_; |
60 | std::string device_file_by_name_prefix_; | 66 | std::map<std::string, std::string> by_name_symlink_map_; |
61 | }; | 67 | }; |
62 | #endif /* __CORE_FS_MGR_AVB_OPS_H */ | 68 | #endif /* __CORE_FS_MGR_PRIV_AVB_OPS_H */ |
diff --git a/fs_mgr/include/fs_mgr_avb.h b/fs_mgr/include/fs_mgr_avb.h index 65ff99417..bbafe1a03 100644 --- a/fs_mgr/include/fs_mgr_avb.h +++ b/fs_mgr/include/fs_mgr_avb.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #ifndef __CORE_FS_MGR_AVB_H | 17 | #ifndef __CORE_FS_MGR_AVB_H |
18 | #define __CORE_FS_MGR_AVB_H | 18 | #define __CORE_FS_MGR_AVB_H |
19 | 19 | ||
20 | #include <map> | ||
20 | #include <memory> | 21 | #include <memory> |
21 | #include <string> | 22 | #include <string> |
22 | 23 | ||
@@ -31,9 +32,13 @@ enum FsManagerAvbHandleStatus { | |||
31 | kFsManagerAvbHandleErrorVerification = 2, | 32 | kFsManagerAvbHandleErrorVerification = 2, |
32 | }; | 33 | }; |
33 | 34 | ||
35 | class FsManagerAvbOps; | ||
36 | |||
34 | class FsManagerAvbHandle; | 37 | class FsManagerAvbHandle; |
35 | using FsManagerAvbUniquePtr = std::unique_ptr<FsManagerAvbHandle>; | 38 | using FsManagerAvbUniquePtr = std::unique_ptr<FsManagerAvbHandle>; |
36 | 39 | ||
40 | using ByNameSymlinkMap = std::map<std::string, std::string>; | ||
41 | |||
37 | // Provides a factory method to return a unique_ptr pointing to itself and the | 42 | // Provides a factory method to return a unique_ptr pointing to itself and the |
38 | // SetUpAvb() function to extract dm-verity parameters from AVB metadata to | 43 | // SetUpAvb() function to extract dm-verity parameters from AVB metadata to |
39 | // load verity table into kernel through ioctl. | 44 | // load verity table into kernel through ioctl. |
@@ -49,6 +54,13 @@ class FsManagerAvbHandle { | |||
49 | // A typical usage will be: | 54 | // A typical usage will be: |
50 | // - FsManagerAvbUniquePtr handle = FsManagerAvbHandle::Open(); | 55 | // - FsManagerAvbUniquePtr handle = FsManagerAvbHandle::Open(); |
51 | // | 56 | // |
57 | // There are two overloaded Open() functions with a single parameter. | ||
58 | // The argument can be a ByNameSymlinkMap describing the mapping from partition | ||
59 | // name to by-name symlink, or a fstab file to which the ByNameSymlinkMap is | ||
60 | // constructed from. e.g., | ||
61 | // - /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a -> | ||
62 | // - ByNameSymlinkMap["system_a"] = "/dev/block/platform/soc.0/7824900.sdhci/by-name/system_a" | ||
63 | // | ||
52 | // Possible return values: | 64 | // Possible return values: |
53 | // - nullptr: any error when reading and verifying the metadata, | 65 | // - nullptr: any error when reading and verifying the metadata, |
54 | // e.g., I/O error, digest value mismatch, size mismatch, etc. | 66 | // e.g., I/O error, digest value mismatch, size mismatch, etc. |
@@ -61,7 +73,8 @@ class FsManagerAvbHandle { | |||
61 | // - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata | 73 | // - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata |
62 | // is verified and can be trusted. | 74 | // is verified and can be trusted. |
63 | // | 75 | // |
64 | static FsManagerAvbUniquePtr Open(const std::string& device_file_by_name_prefix); | 76 | static FsManagerAvbUniquePtr Open(const fstab& fstab); |
77 | static FsManagerAvbUniquePtr Open(ByNameSymlinkMap&& by_name_symlink_map); | ||
65 | 78 | ||
66 | // Sets up dm-verity on the given fstab entry. | 79 | // Sets up dm-verity on the given fstab entry. |
67 | // The 'wait_for_verity_dev' parameter makes this function wait for the | 80 | // The 'wait_for_verity_dev' parameter makes this function wait for the |
@@ -88,10 +101,10 @@ class FsManagerAvbHandle { | |||
88 | } | 101 | } |
89 | }; | 102 | }; |
90 | 103 | ||
91 | protected: | 104 | private: |
92 | FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {} | 105 | FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {} |
106 | static FsManagerAvbUniquePtr DoOpen(FsManagerAvbOps* avb_ops); | ||
93 | 107 | ||
94 | private: | ||
95 | AvbSlotVerifyData* avb_slot_data_; | 108 | AvbSlotVerifyData* avb_slot_data_; |
96 | FsManagerAvbHandleStatus status_; | 109 | FsManagerAvbHandleStatus status_; |
97 | std::string avb_version_; | 110 | std::string avb_version_; |
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp index a139e349b..bcc8d1b1a 100644 --- a/init/init_first_stage.cpp +++ b/init/init_first_stage.cpp | |||
@@ -47,18 +47,22 @@ class FirstStageMount { | |||
47 | bool InitDevices(); | 47 | bool InitDevices(); |
48 | 48 | ||
49 | protected: | 49 | protected: |
50 | void InitRequiredDevices(std::set<std::string>* devices_partition_names); | 50 | void InitRequiredDevices(); |
51 | void InitVerityDevice(const std::string& verity_device); | 51 | void InitVerityDevice(const std::string& verity_device); |
52 | bool MountPartitions(); | 52 | bool MountPartitions(); |
53 | 53 | ||
54 | virtual bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names, | 54 | virtual coldboot_action_t ColdbootCallback(uevent* uevent); |
55 | bool* out_need_dm_verity) = 0; | 55 | |
56 | // Pure virtual functions. | ||
57 | virtual bool GetRequiredDevices() = 0; | ||
56 | virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; | 58 | virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; |
57 | 59 | ||
60 | bool need_dm_verity_; | ||
58 | // Device tree fstab entries. | 61 | // Device tree fstab entries. |
59 | std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; | 62 | std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_; |
60 | // Eligible first stage mount candidates, only allow /system, /vendor and/or /odm. | 63 | // Eligible first stage mount candidates, only allow /system, /vendor and/or /odm. |
61 | std::vector<fstab_rec*> mount_fstab_recs_; | 64 | std::vector<fstab_rec*> mount_fstab_recs_; |
65 | std::set<std::string> required_devices_partition_names_; | ||
62 | }; | 66 | }; |
63 | 67 | ||
64 | class FirstStageMountVBootV1 : public FirstStageMount { | 68 | class FirstStageMountVBootV1 : public FirstStageMount { |
@@ -67,27 +71,26 @@ class FirstStageMountVBootV1 : public FirstStageMount { | |||
67 | ~FirstStageMountVBootV1() override = default; | 71 | ~FirstStageMountVBootV1() override = default; |
68 | 72 | ||
69 | protected: | 73 | protected: |
70 | bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names, | 74 | bool GetRequiredDevices() override; |
71 | bool* out_need_dm_verity) override; | ||
72 | bool SetUpDmVerity(fstab_rec* fstab_rec) override; | 75 | bool SetUpDmVerity(fstab_rec* fstab_rec) override; |
73 | }; | 76 | }; |
74 | 77 | ||
75 | class FirstStageMountVBootV2 : public FirstStageMount { | 78 | class FirstStageMountVBootV2 : public FirstStageMount { |
76 | public: | 79 | public: |
80 | friend void SetInitAvbVersionInRecovery(); | ||
81 | |||
77 | FirstStageMountVBootV2(); | 82 | FirstStageMountVBootV2(); |
78 | ~FirstStageMountVBootV2() override = default; | 83 | ~FirstStageMountVBootV2() override = default; |
79 | 84 | ||
80 | const std::string& by_name_prefix() const { return device_tree_by_name_prefix_; } | ||
81 | |||
82 | protected: | 85 | protected: |
83 | bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names, | 86 | coldboot_action_t ColdbootCallback(uevent* uevent) override; |
84 | bool* out_need_dm_verity) override; | 87 | bool GetRequiredDevices() override; |
85 | bool SetUpDmVerity(fstab_rec* fstab_rec) override; | 88 | bool SetUpDmVerity(fstab_rec* fstab_rec) override; |
86 | bool InitAvbHandle(); | 89 | bool InitAvbHandle(); |
87 | 90 | ||
88 | std::string device_tree_vbmeta_parts_; | 91 | std::string device_tree_vbmeta_parts_; |
89 | std::string device_tree_by_name_prefix_; | ||
90 | FsManagerAvbUniquePtr avb_handle_; | 92 | FsManagerAvbUniquePtr avb_handle_; |
93 | ByNameSymlinkMap by_name_symlink_map_; | ||
91 | }; | 94 | }; |
92 | 95 | ||
93 | // Static Functions | 96 | // Static Functions |
@@ -102,7 +105,8 @@ static bool inline IsRecoveryMode() { | |||
102 | 105 | ||
103 | // Class Definitions | 106 | // Class Definitions |
104 | // ----------------- | 107 | // ----------------- |
105 | FirstStageMount::FirstStageMount() : device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) { | 108 | FirstStageMount::FirstStageMount() |
109 | : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) { | ||
106 | if (!device_tree_fstab_) { | 110 | if (!device_tree_fstab_) { |
107 | LOG(ERROR) << "Failed to read fstab from device tree"; | 111 | LOG(ERROR) << "Failed to read fstab from device tree"; |
108 | return; | 112 | return; |
@@ -136,72 +140,71 @@ bool FirstStageMount::DoFirstStageMount() { | |||
136 | } | 140 | } |
137 | 141 | ||
138 | bool FirstStageMount::InitDevices() { | 142 | bool FirstStageMount::InitDevices() { |
139 | bool need_dm_verity; | 143 | if (!GetRequiredDevices()) return false; |
140 | std::set<std::string> devices_partition_names; | 144 | |
145 | InitRequiredDevices(); | ||
146 | |||
147 | // InitRequiredDevices() will remove found partitions from required_devices_partition_names_. | ||
148 | // So if it isn't empty here, it means some partitions are not found. | ||
149 | if (!required_devices_partition_names_.empty()) { | ||
150 | LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: " | ||
151 | << android::base::Join(required_devices_partition_names_, ", "); | ||
152 | return false; | ||
153 | } else { | ||
154 | return true; | ||
155 | } | ||
156 | } | ||
141 | 157 | ||
142 | // The partition name in devices_partition_names MUST have A/B suffix when A/B is used. | 158 | // Creates devices with uevent->partition_name matching one in the member variable |
143 | if (!GetRequiredDevices(&devices_partition_names, &need_dm_verity)) return false; | 159 | // required_devices_partition_names_. Found partitions will then be removed from it |
160 | // for the subsequent member function to check which devices are NOT created. | ||
161 | void FirstStageMount::InitRequiredDevices() { | ||
162 | if (required_devices_partition_names_.empty()) { | ||
163 | return; | ||
164 | } | ||
144 | 165 | ||
145 | if (need_dm_verity) { | 166 | if (need_dm_verity_) { |
146 | const std::string dm_path = "/devices/virtual/misc/device-mapper"; | 167 | const std::string dm_path = "/devices/virtual/misc/device-mapper"; |
147 | device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t { | 168 | device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t { |
148 | if (uevent->path == dm_path) return COLDBOOT_STOP; | 169 | if (uevent->path && uevent->path == dm_path) return COLDBOOT_STOP; |
149 | return COLDBOOT_CONTINUE; // dm_path not found, continue to find it. | 170 | return COLDBOOT_CONTINUE; // dm_path not found, continue to find it. |
150 | }); | 171 | }); |
151 | } | 172 | } |
152 | 173 | ||
153 | bool success = false; | 174 | device_init(nullptr, |
154 | InitRequiredDevices(&devices_partition_names); | 175 | [this](uevent* uevent) -> coldboot_action_t { return ColdbootCallback(uevent); }); |
155 | |||
156 | // InitRequiredDevices() will remove found partitions from devices_partition_names. | ||
157 | // So if it isn't empty here, it means some partitions are not found. | ||
158 | if (!devices_partition_names.empty()) { | ||
159 | LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: " | ||
160 | << android::base::Join(devices_partition_names, ", "); | ||
161 | } else { | ||
162 | success = true; | ||
163 | } | ||
164 | 176 | ||
165 | device_close(); | 177 | device_close(); |
166 | return success; | ||
167 | } | 178 | } |
168 | 179 | ||
169 | // Creates devices with uevent->partition_name matching one in the in/out | 180 | coldboot_action_t FirstStageMount::ColdbootCallback(uevent* uevent) { |
170 | // devices_partition_names. Found partitions will then be removed from the | 181 | // We need platform devices to create symlinks. |
171 | // devices_partition_names for the caller to check which devices are NOT created. | 182 | if (!strncmp(uevent->subsystem, "platform", 8)) { |
172 | void FirstStageMount::InitRequiredDevices(std::set<std::string>* devices_partition_names) { | 183 | return COLDBOOT_CREATE; |
173 | if (devices_partition_names->empty()) { | ||
174 | return; | ||
175 | } | 184 | } |
176 | device_init(nullptr, [=](uevent* uevent) -> coldboot_action_t { | ||
177 | // We need platform devices to create symlinks. | ||
178 | if (!strncmp(uevent->subsystem, "platform", 8)) { | ||
179 | return COLDBOOT_CREATE; | ||
180 | } | ||
181 | 185 | ||
182 | // Ignores everything that is not a block device. | 186 | // Ignores everything that is not a block device. |
183 | if (strncmp(uevent->subsystem, "block", 5)) { | 187 | if (strncmp(uevent->subsystem, "block", 5)) { |
184 | return COLDBOOT_CONTINUE; | 188 | return COLDBOOT_CONTINUE; |
185 | } | 189 | } |
186 | 190 | ||
187 | if (uevent->partition_name) { | 191 | if (uevent->partition_name) { |
188 | // Matches partition name to create device nodes. | 192 | // Matches partition name to create device nodes. |
189 | // Both devices_partition_names and uevent->partition_name have A/B | 193 | // Both required_devices_partition_names_ and uevent->partition_name have A/B |
190 | // suffix when A/B is used. | 194 | // suffix when A/B is used. |
191 | auto iter = devices_partition_names->find(uevent->partition_name); | 195 | auto iter = required_devices_partition_names_.find(uevent->partition_name); |
192 | if (iter != devices_partition_names->end()) { | 196 | if (iter != required_devices_partition_names_.end()) { |
193 | LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter; | 197 | LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter; |
194 | devices_partition_names->erase(iter); | 198 | required_devices_partition_names_.erase(iter); |
195 | if (devices_partition_names->empty()) { | 199 | if (required_devices_partition_names_.empty()) { |
196 | return COLDBOOT_STOP; // Found all partitions, stop coldboot. | 200 | return COLDBOOT_STOP; // Found all partitions, stop coldboot. |
197 | } else { | 201 | } else { |
198 | return COLDBOOT_CREATE; // Creates this device and continue to find others. | 202 | return COLDBOOT_CREATE; // Creates this device and continue to find others. |
199 | } | ||
200 | } | 203 | } |
201 | } | 204 | } |
202 | // Not found a partition or find an unneeded partition, continue to find others. | 205 | } |
203 | return COLDBOOT_CONTINUE; | 206 | // Not found a partition or find an unneeded partition, continue to find others. |
204 | }); | 207 | return COLDBOOT_CONTINUE; |
205 | } | 208 | } |
206 | 209 | ||
207 | // Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. | 210 | // Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. |
@@ -210,7 +213,7 @@ void FirstStageMount::InitVerityDevice(const std::string& verity_device) { | |||
210 | const std::string syspath = "/sys/block/" + device_name; | 213 | const std::string syspath = "/sys/block/" + device_name; |
211 | 214 | ||
212 | device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t { | 215 | device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t { |
213 | if (uevent->device_name && device_name == uevent->device_name) { | 216 | if (uevent->device_name && uevent->device_name == device_name) { |
214 | LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; | 217 | LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; |
215 | return COLDBOOT_STOP; | 218 | return COLDBOOT_STOP; |
216 | } | 219 | } |
@@ -233,10 +236,9 @@ bool FirstStageMount::MountPartitions() { | |||
233 | return true; | 236 | return true; |
234 | } | 237 | } |
235 | 238 | ||
236 | bool FirstStageMountVBootV1::GetRequiredDevices(std::set<std::string>* out_devices_partition_names, | 239 | bool FirstStageMountVBootV1::GetRequiredDevices() { |
237 | bool* out_need_dm_verity) { | ||
238 | std::string verity_loc_device; | 240 | std::string verity_loc_device; |
239 | *out_need_dm_verity = false; | 241 | need_dm_verity_ = false; |
240 | 242 | ||
241 | for (auto fstab_rec : mount_fstab_recs_) { | 243 | for (auto fstab_rec : mount_fstab_recs_) { |
242 | // Don't allow verifyatboot in the first stage. | 244 | // Don't allow verifyatboot in the first stage. |
@@ -246,7 +248,7 @@ bool FirstStageMountVBootV1::GetRequiredDevices(std::set<std::string>* out_devic | |||
246 | } | 248 | } |
247 | // Checks for verified partitions. | 249 | // Checks for verified partitions. |
248 | if (fs_mgr_is_verified(fstab_rec)) { | 250 | if (fs_mgr_is_verified(fstab_rec)) { |
249 | *out_need_dm_verity = true; | 251 | need_dm_verity_ = true; |
250 | } | 252 | } |
251 | // Checks if verity metadata is on a separate partition. Note that it is | 253 | // Checks if verity metadata is on a separate partition. Note that it is |
252 | // not partition specific, so there must be only one additional partition | 254 | // not partition specific, so there must be only one additional partition |
@@ -265,11 +267,11 @@ bool FirstStageMountVBootV1::GetRequiredDevices(std::set<std::string>* out_devic | |||
265 | // Includes the partition names of fstab records and verity_loc_device (if any). | 267 | // Includes the partition names of fstab records and verity_loc_device (if any). |
266 | // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used. | 268 | // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used. |
267 | for (auto fstab_rec : mount_fstab_recs_) { | 269 | for (auto fstab_rec : mount_fstab_recs_) { |
268 | out_devices_partition_names->emplace(basename(fstab_rec->blk_device)); | 270 | required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); |
269 | } | 271 | } |
270 | 272 | ||
271 | if (!verity_loc_device.empty()) { | 273 | if (!verity_loc_device.empty()) { |
272 | out_devices_partition_names->emplace(basename(verity_loc_device.c_str())); | 274 | required_devices_partition_names_.emplace(basename(verity_loc_device.c_str())); |
273 | } | 275 | } |
274 | 276 | ||
275 | return true; | 277 | return true; |
@@ -292,15 +294,13 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { | |||
292 | } | 294 | } |
293 | 295 | ||
294 | // FirstStageMountVBootV2 constructor. | 296 | // FirstStageMountVBootV2 constructor. |
295 | // Gets the vbmeta configurations from device tree. | 297 | // Gets the vbmeta partitions from device tree. |
296 | // Specifically, the 'parts' and 'by_name_prefix' below. | ||
297 | // /{ | 298 | // /{ |
298 | // firmware { | 299 | // firmware { |
299 | // android { | 300 | // android { |
300 | // vbmeta { | 301 | // vbmeta { |
301 | // compatible = "android,vbmeta"; | 302 | // compatible = "android,vbmeta"; |
302 | // parts = "vbmeta,boot,system,vendor" | 303 | // parts = "vbmeta,boot,system,vendor" |
303 | // by_name_prefix = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/" | ||
304 | // }; | 304 | // }; |
305 | // }; | 305 | // }; |
306 | // }; | 306 | // }; |
@@ -310,31 +310,24 @@ FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) { | |||
310 | PLOG(ERROR) << "Failed to read vbmeta/parts from device tree"; | 310 | PLOG(ERROR) << "Failed to read vbmeta/parts from device tree"; |
311 | return; | 311 | return; |
312 | } | 312 | } |
313 | |||
314 | // TODO: removes by_name_prefix to allow partitions on different block devices. | ||
315 | if (!read_android_dt_file("vbmeta/by_name_prefix", &device_tree_by_name_prefix_)) { | ||
316 | PLOG(ERROR) << "Failed to read vbmeta/by_name_prefix from dt"; | ||
317 | return; | ||
318 | } | ||
319 | } | 313 | } |
320 | 314 | ||
321 | bool FirstStageMountVBootV2::GetRequiredDevices(std::set<std::string>* out_devices_partition_names, | 315 | bool FirstStageMountVBootV2::GetRequiredDevices() { |
322 | bool* out_need_dm_verity) { | 316 | need_dm_verity_ = false; |
323 | *out_need_dm_verity = false; | ||
324 | 317 | ||
325 | // fstab_rec->blk_device has A/B suffix. | 318 | // fstab_rec->blk_device has A/B suffix. |
326 | for (auto fstab_rec : mount_fstab_recs_) { | 319 | for (auto fstab_rec : mount_fstab_recs_) { |
327 | if (fs_mgr_is_avb(fstab_rec)) { | 320 | if (fs_mgr_is_avb(fstab_rec)) { |
328 | *out_need_dm_verity = true; | 321 | need_dm_verity_ = true; |
329 | } | 322 | } |
330 | out_devices_partition_names->emplace(basename(fstab_rec->blk_device)); | 323 | required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); |
331 | } | 324 | } |
332 | 325 | ||
333 | // libavb verifies AVB metadata on all verified partitions at once. | 326 | // libavb verifies AVB metadata on all verified partitions at once. |
334 | // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor" | 327 | // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor" |
335 | // for libavb to verify metadata, even if there is only /vendor in the | 328 | // for libavb to verify metadata, even if there is only /vendor in the |
336 | // above mount_fstab_recs_. | 329 | // above mount_fstab_recs_. |
337 | if (*out_need_dm_verity) { | 330 | if (need_dm_verity_) { |
338 | if (device_tree_vbmeta_parts_.empty()) { | 331 | if (device_tree_vbmeta_parts_.empty()) { |
339 | LOG(ERROR) << "Missing vbmeta parts in device tree"; | 332 | LOG(ERROR) << "Missing vbmeta parts in device tree"; |
340 | return false; | 333 | return false; |
@@ -342,16 +335,45 @@ bool FirstStageMountVBootV2::GetRequiredDevices(std::set<std::string>* out_devic | |||
342 | std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ","); | 335 | std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ","); |
343 | std::string ab_suffix = fs_mgr_get_slot_suffix(); | 336 | std::string ab_suffix = fs_mgr_get_slot_suffix(); |
344 | for (const auto& partition : partitions) { | 337 | for (const auto& partition : partitions) { |
345 | // out_devices_partition_names is of type std::set so it's not an issue to emplace | 338 | // required_devices_partition_names_ is of type std::set so it's not an issue |
346 | // a partition twice. e.g., /vendor might be in both places: | 339 | // to emplace a partition twice. e.g., /vendor might be in both places: |
347 | // - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor" | 340 | // - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor" |
348 | // - mount_fstab_recs_: /vendor_a | 341 | // - mount_fstab_recs_: /vendor_a |
349 | out_devices_partition_names->emplace(partition + ab_suffix); | 342 | required_devices_partition_names_.emplace(partition + ab_suffix); |
350 | } | 343 | } |
351 | } | 344 | } |
352 | return true; | 345 | return true; |
353 | } | 346 | } |
354 | 347 | ||
348 | coldboot_action_t FirstStageMountVBootV2::ColdbootCallback(uevent* uevent) { | ||
349 | // Invokes the parent function to see if any desired partition has been found. | ||
350 | // If yes, record the by-name symlink for creating FsManagerAvbHandle later. | ||
351 | coldboot_action_t parent_callback_ret = FirstStageMount::ColdbootCallback(uevent); | ||
352 | |||
353 | // Skips the uevent if the parent function returns COLDBOOT_CONTINUE (meaning | ||
354 | // that the uevent was skipped) or there is no uevent->partition_name to | ||
355 | // create the by-name symlink. | ||
356 | if (parent_callback_ret != COLDBOOT_CONTINUE && uevent->partition_name) { | ||
357 | // get_block_device_symlinks() will return three symlinks at most, depending on | ||
358 | // the content of uevent. by-name symlink will be at [0] if uevent->partition_name | ||
359 | // is not empty. e.g., | ||
360 | // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem | ||
361 | // - /dev/block/platform/soc.0/f9824900.sdhci/by-num/p1 | ||
362 | // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1 | ||
363 | char** links = get_block_device_symlinks(uevent); | ||
364 | if (links && links[0]) { | ||
365 | auto[it, inserted] = by_name_symlink_map_.emplace(uevent->partition_name, links[0]); | ||
366 | if (!inserted) { | ||
367 | LOG(ERROR) << "Partition '" << uevent->partition_name | ||
368 | << "' already existed in the by-name symlink map with a value of '" | ||
369 | << it->second << "', new value '" << links[0] << "' will be ignored."; | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | return parent_callback_ret; | ||
375 | } | ||
376 | |||
355 | bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { | 377 | bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { |
356 | if (fs_mgr_is_avb(fstab_rec)) { | 378 | if (fs_mgr_is_avb(fstab_rec)) { |
357 | if (!InitAvbHandle()) return false; | 379 | if (!InitAvbHandle()) return false; |
@@ -371,7 +393,14 @@ bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { | |||
371 | bool FirstStageMountVBootV2::InitAvbHandle() { | 393 | bool FirstStageMountVBootV2::InitAvbHandle() { |
372 | if (avb_handle_) return true; // Returns true if the handle is already initialized. | 394 | if (avb_handle_) return true; // Returns true if the handle is already initialized. |
373 | 395 | ||
374 | avb_handle_ = FsManagerAvbHandle::Open(device_tree_by_name_prefix_); | 396 | if (by_name_symlink_map_.empty()) { |
397 | LOG(ERROR) << "by_name_symlink_map_ is empty"; | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | avb_handle_ = FsManagerAvbHandle::Open(std::move(by_name_symlink_map_)); | ||
402 | by_name_symlink_map_.clear(); // Removes all elements after the above std::move(). | ||
403 | |||
375 | if (!avb_handle_) { | 404 | if (!avb_handle_) { |
376 | PLOG(ERROR) << "Failed to open FsManagerAvbHandle"; | 405 | PLOG(ERROR) << "Failed to open FsManagerAvbHandle"; |
377 | return false; | 406 | return false; |
@@ -427,7 +456,8 @@ void SetInitAvbVersionInRecovery() { | |||
427 | return; | 456 | return; |
428 | } | 457 | } |
429 | 458 | ||
430 | FsManagerAvbUniquePtr avb_handle = FsManagerAvbHandle::Open(avb_first_mount.by_name_prefix()); | 459 | FsManagerAvbUniquePtr avb_handle = |
460 | FsManagerAvbHandle::Open(std::move(avb_first_mount.by_name_symlink_map_)); | ||
431 | if (!avb_handle) { | 461 | if (!avb_handle) { |
432 | PLOG(ERROR) << "Failed to open FsManagerAvbHandle for INIT_AVB_VERSION"; | 462 | PLOG(ERROR) << "Failed to open FsManagerAvbHandle for INIT_AVB_VERSION"; |
433 | return; | 463 | return; |