• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include <fcntl.h>
18 #include <stdint.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 
22 #if defined(__linux__)
23 #include <linux/fs.h>
24 #include <sys/ioctl.h>
25 #endif
26 
27 #include <android-base/file.h>
28 #include <ext4_utils/ext4_utils.h>
29 #include <openssl/sha.h>
30 
31 #ifdef __ANDROID__
32 #include <cutils/android_get_control_file.h>
33 #endif
34 
35 #include "utility.h"
36 
37 namespace android {
38 namespace fs_mgr {
39 
GetDescriptorSize(int fd,uint64_t * size)40 bool GetDescriptorSize(int fd, uint64_t* size) {
41 #if !defined(_WIN32)
42     struct stat s;
43     if (fstat(fd, &s) < 0) {
44         PERROR << __PRETTY_FUNCTION__ << "fstat failed";
45         return false;
46     }
47 
48     if (S_ISBLK(s.st_mode)) {
49         *size = get_block_device_size(fd);
50         return *size != 0;
51     }
52 #endif
53 
54     int64_t result = SeekFile64(fd, 0, SEEK_END);
55     if (result == -1) {
56         PERROR << __PRETTY_FUNCTION__ << "lseek failed";
57         return false;
58     }
59 
60     *size = result;
61     return true;
62 }
63 
SeekFile64(int fd,int64_t offset,int whence)64 int64_t SeekFile64(int fd, int64_t offset, int whence) {
65     static_assert(sizeof(off_t) == sizeof(int64_t), "Need 64-bit lseek");
66     return lseek(fd, offset, whence);
67 }
68 
GetPrimaryGeometryOffset()69 int64_t GetPrimaryGeometryOffset() {
70     return LP_PARTITION_RESERVED_BYTES;
71 }
72 
GetBackupGeometryOffset()73 int64_t GetBackupGeometryOffset() {
74     return GetPrimaryGeometryOffset() + LP_METADATA_GEOMETRY_SIZE;
75 }
76 
GetPrimaryMetadataOffset(const LpMetadataGeometry & geometry,uint32_t slot_number)77 int64_t GetPrimaryMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
78     CHECK(slot_number < geometry.metadata_slot_count);
79     int64_t offset = LP_PARTITION_RESERVED_BYTES + (LP_METADATA_GEOMETRY_SIZE * 2) +
80                      geometry.metadata_max_size * slot_number;
81     return offset;
82 }
83 
GetBackupMetadataOffset(const LpMetadataGeometry & geometry,uint32_t slot_number)84 int64_t GetBackupMetadataOffset(const LpMetadataGeometry& geometry, uint32_t slot_number) {
85     CHECK(slot_number < geometry.metadata_slot_count);
86     int64_t start = LP_PARTITION_RESERVED_BYTES + (LP_METADATA_GEOMETRY_SIZE * 2) +
87                     int64_t(geometry.metadata_max_size) * geometry.metadata_slot_count;
88     return start + int64_t(geometry.metadata_max_size * slot_number);
89 }
90 
GetTotalMetadataSize(uint32_t metadata_max_size,uint32_t max_slots)91 uint64_t GetTotalMetadataSize(uint32_t metadata_max_size, uint32_t max_slots) {
92     return LP_PARTITION_RESERVED_BYTES +
93            (LP_METADATA_GEOMETRY_SIZE + metadata_max_size * max_slots) * 2;
94 }
95 
GetMetadataSuperBlockDevice(const LpMetadata & metadata)96 const LpMetadataBlockDevice* GetMetadataSuperBlockDevice(const LpMetadata& metadata) {
97     if (metadata.block_devices.empty()) {
98         return nullptr;
99     }
100     return &metadata.block_devices[0];
101 }
102 
SHA256(const void * data,size_t length,uint8_t out[32])103 void SHA256(const void* data, size_t length, uint8_t out[32]) {
104     SHA256_CTX c;
105     SHA256_Init(&c);
106     SHA256_Update(&c, data, length);
107     SHA256_Final(out, &c);
108 }
109 
SlotNumberForSlotSuffix(const std::string & suffix)110 uint32_t SlotNumberForSlotSuffix(const std::string& suffix) {
111     if (suffix.empty() || suffix == "a" || suffix == "_a") {
112         return 0;
113     } else if (suffix == "b" || suffix == "_b") {
114         return 1;
115     } else {
116         LERROR << __PRETTY_FUNCTION__ << "slot '" << suffix
117                << "' does not have a recognized format.";
118         return 0;
119     }
120 }
121 
GetTotalSuperPartitionSize(const LpMetadata & metadata)122 uint64_t GetTotalSuperPartitionSize(const LpMetadata& metadata) {
123     uint64_t size = 0;
124     for (const auto& block_device : metadata.block_devices) {
125         size += block_device.size;
126     }
127     return size;
128 }
129 
GetBlockDevicePartitionNames(const LpMetadata & metadata)130 std::vector<std::string> GetBlockDevicePartitionNames(const LpMetadata& metadata) {
131     std::vector<std::string> list;
132     for (const auto& block_device : metadata.block_devices) {
133         list.emplace_back(GetBlockDevicePartitionName(block_device));
134     }
135     return list;
136 }
137 
GetPartitionSlotSuffix(const std::string & partition_name)138 std::string GetPartitionSlotSuffix(const std::string& partition_name) {
139     if (partition_name.size() <= 2) {
140         return "";
141     }
142     std::string suffix = partition_name.substr(partition_name.size() - 2);
143     return (suffix == "_a" || suffix == "_b") ? suffix : "";
144 }
145 
SlotSuffixForSlotNumber(uint32_t slot_number)146 std::string SlotSuffixForSlotNumber(uint32_t slot_number) {
147     CHECK(slot_number == 0 || slot_number == 1);
148     return (slot_number == 0) ? "_a" : "_b";
149 }
150 
UpdateBlockDevicePartitionName(LpMetadataBlockDevice * device,const std::string & name)151 bool UpdateBlockDevicePartitionName(LpMetadataBlockDevice* device, const std::string& name) {
152     if (name.size() > sizeof(device->partition_name)) {
153         return false;
154     }
155     strncpy(device->partition_name, name.c_str(), sizeof(device->partition_name));
156     return true;
157 }
158 
UpdatePartitionGroupName(LpMetadataPartitionGroup * group,const std::string & name)159 bool UpdatePartitionGroupName(LpMetadataPartitionGroup* group, const std::string& name) {
160     if (name.size() > sizeof(group->name)) {
161         return false;
162     }
163     strncpy(group->name, name.c_str(), sizeof(group->name));
164     return true;
165 }
166 
SetBlockReadonly(int fd,bool readonly)167 bool SetBlockReadonly(int fd, bool readonly) {
168 #if defined(__linux__)
169     int val = readonly;
170     return ioctl(fd, BLKROSET, &val) == 0;
171 #else
172     (void)fd;
173     (void)readonly;
174     return true;
175 #endif
176 }
177 
GetControlFileOrOpen(const char * path,int flags)178 base::unique_fd GetControlFileOrOpen(const char* path, int flags) {
179 #if defined(__ANDROID__)
180     int fd = android_get_control_file(path);
181     if (fd >= 0) {
182         int newfd = TEMP_FAILURE_RETRY(dup(fd));
183         if (newfd >= 0) {
184             return base::unique_fd(newfd);
185         }
186         PERROR << "Cannot dup fd for already controlled file: " << path << ", reopening...";
187     }
188 #endif
189     return base::unique_fd(open(path, flags));
190 }
191 
192 }  // namespace fs_mgr
193 }  // namespace android
194