summaryrefslogtreecommitdiffstats
path: root/roots.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--roots.cpp148
1 files changed, 108 insertions, 40 deletions
diff --git a/roots.cpp b/roots.cpp
index 6e5ef9810..29f55b96f 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -27,7 +27,9 @@
#include <fcntl.h>
#include <android-base/logging.h>
-#include <ext4_utils/make_ext4fs.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>
@@ -172,6 +174,23 @@ static int exec_cmd(const char* path, char* const argv[]) {
return WEXITSTATUS(status);
}
+static ssize_t get_file_size(int fd, uint64_t reserve_len) {
+ struct stat buf;
+ int ret = fstat(fd, &buf);
+ if (ret) return 0;
+
+ ssize_t computed_size;
+ if (S_ISREG(buf.st_mode)) {
+ computed_size = buf.st_size - reserve_len;
+ } else if (S_ISBLK(buf.st_mode)) {
+ computed_size = get_block_device_size(fd) - reserve_len;
+ } else {
+ computed_size = 0;
+ }
+
+ return computed_size;
+}
+
int format_volume(const char* volume, const char* directory) {
Volume* v = volume_for_path(volume);
if (v == NULL) {
@@ -211,35 +230,81 @@ int format_volume(const char* volume, const char* directory) {
if (v->length != 0) {
length = v->length;
} else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
- length = -CRYPT_FOOTER_OFFSET;
+ android::base::unique_fd fd(open(v->blk_device, O_RDONLY));
+ if (fd < 0) {
+ PLOG(ERROR) << "get_file_size: failed to open " << v->blk_device;
+ return -1;
+ }
+ length = get_file_size(fd.get(), CRYPT_FOOTER_OFFSET);
+ if (length <= 0) {
+ LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device;
+ return -1;
+ }
}
int result;
if (strcmp(v->fs_type, "ext4") == 0) {
- if (v->erase_blk_size != 0 && v->logical_blk_size != 0) {
- result = make_ext4fs_directory_align(v->blk_device, length, volume, sehandle,
- directory, v->erase_blk_size, v->logical_blk_size);
- } else {
- result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory);
- }
+ static constexpr int block_size = 4096;
+ int raid_stride = v->logical_blk_size / block_size;
+ int raid_stripe_width = v->erase_blk_size / block_size;
+
+ // stride should be the max of 8kb and logical block size
+ if (v->logical_blk_size != 0 && v->logical_blk_size < 8192) {
+ raid_stride = 8192 / block_size;
+ }
+
+ const char* mke2fs_argv[] = { "/sbin/mke2fs_static",
+ "-F",
+ "-t",
+ "ext4",
+ "-b",
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr };
+
+ int i = 5;
+ std::string block_size_str = std::to_string(block_size);
+ mke2fs_argv[i++] = block_size_str.c_str();
+
+ std::string ext_args;
+ if (v->erase_blk_size != 0 && v->logical_blk_size != 0) {
+ ext_args = android::base::StringPrintf("stride=%d,stripe-width=%d", raid_stride,
+ raid_stripe_width);
+ mke2fs_argv[i++] = "-E";
+ mke2fs_argv[i++] = ext_args.c_str();
+ }
+
+ mke2fs_argv[i++] = v->blk_device;
+
+ std::string size_str = std::to_string(length / block_size);
+ if (length != 0) {
+ mke2fs_argv[i++] = size_str.c_str();
+ }
+
+ result = exec_cmd(mke2fs_argv[0], const_cast<char**>(mke2fs_argv));
+ if (result == 0 && directory != nullptr) {
+ const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static",
+ "-e",
+ "-f",
+ directory,
+ "-a",
+ volume,
+ v->blk_device,
+ nullptr };
+
+ result = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv));
+ }
} else { /* Has to be f2fs because we checked earlier. */
- if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) {
- LOG(ERROR) << "format_volume: crypt footer + negative length (" << length
- << ") not supported on " << v->fs_type;
- return -1;
- }
- if (length < 0) {
- LOG(ERROR) << "format_volume: negative length (" << length
- << ") not supported on " << v->fs_type;
- return -1;
- }
- char *num_sectors;
- if (asprintf(&num_sectors, "%zd", length / 512) <= 0) {
+ char *num_sectors = nullptr;
+ if (length >= 512 && asprintf(&num_sectors, "%zd", length / 512) <= 0) {
LOG(ERROR) << "format_volume: failed to create " << v->fs_type
<< " command for " << v->blk_device;
return -1;
}
const char *f2fs_path = "/sbin/mkfs.f2fs";
- const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", v->blk_device, num_sectors, NULL};
+ const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", v->blk_device, num_sectors, nullptr};
result = exec_cmd(f2fs_path, (char* const*)f2fs_argv);
free(num_sectors);
@@ -260,26 +325,29 @@ int format_volume(const char* volume) {
}
int setup_install_mounts() {
- if (fstab == NULL) {
- LOG(ERROR) << "can't set up install mounts: no fstab loaded";
- return -1;
- }
- for (int i = 0; i < fstab->num_entries; ++i) {
- Volume* v = fstab->recs + i;
+ if (fstab == nullptr) {
+ LOG(ERROR) << "can't set up install mounts: no fstab loaded";
+ return -1;
+ }
+ for (int i = 0; i < fstab->num_entries; ++i) {
+ const Volume* v = fstab->recs + i;
- if (strcmp(v->mount_point, "/tmp") == 0 ||
- strcmp(v->mount_point, "/cache") == 0) {
- if (ensure_path_mounted(v->mount_point) != 0) {
- LOG(ERROR) << "failed to mount " << v->mount_point;
- return -1;
- }
+ // We don't want to do anything with "/".
+ if (strcmp(v->mount_point, "/") == 0) {
+ continue;
+ }
- } else {
- if (ensure_path_unmounted(v->mount_point) != 0) {
- LOG(ERROR) << "failed to unmount " << v->mount_point;
- return -1;
- }
- }
+ if (strcmp(v->mount_point, "/tmp") == 0 || strcmp(v->mount_point, "/cache") == 0) {
+ if (ensure_path_mounted(v->mount_point) != 0) {
+ LOG(ERROR) << "failed to mount " << v->mount_point;
+ return -1;
+ }
+ } else {
+ if (ensure_path_unmounted(v->mount_point) != 0) {
+ LOG(ERROR) << "failed to unmount " << v->mount_point;
+ return -1;
+ }
}
- return 0;
+ }
+ return 0;
}