1 /* 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 17 #include <stdio.h> 18 #include <unistd.h> 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <fcntl.h> 22 #include <sys/wait.h> 23 #include <errno.h> 24 #include <cutils/partition_utils.h> 25 #include <sys/mount.h> 26 27 #include <ext4_utils/ext4.h> 28 #include <ext4_utils/ext4_utils.h> 29 #include <logwrap/logwrap.h> 30 #include <selinux/android.h> 31 #include <selinux/label.h> 32 #include <selinux/selinux.h> 33 34 #include "fs_mgr_priv.h" 35 #include "cryptfs.h" 36 37 static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) 38 { 39 uint64_t dev_sz; 40 int fd, rc = 0; 41 42 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) { 43 PERROR << "Cannot open block device"; 44 return -1; 45 } 46 47 if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) { 48 PERROR << "Cannot get block device size"; 49 close(fd); 50 return -1; 51 } 52 53 close(fd); 54 55 /* Format the partition using the calculated length */ 56 if (crypt_footer) { 57 dev_sz -= CRYPT_FOOTER_OFFSET; 58 } 59 60 std::string size_str = std::to_string(dev_sz / 4096); 61 const char* const mke2fs_args[] = { 62 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr}; 63 64 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL, 65 true, LOG_KLOG, true, nullptr, nullptr, 0); 66 if (rc) { 67 LERROR << "mke2fs returned " << rc; 68 return rc; 69 } 70 71 const char* const e2fsdroid_args[] = { 72 "/system/bin/e2fsdroid", 73 "-e", 74 "-a", 75 fs_mnt_point, 76 fs_blkdev, 77 nullptr}; 78 79 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args), 80 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0); 81 if (rc) { 82 LERROR << "e2fsdroid returned " << rc; 83 } 84 85 return rc; 86 } 87 88 static int format_f2fs(char *fs_blkdev) 89 { 90 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr}; 91 92 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true, 93 LOG_KLOG, true, nullptr, nullptr, 0); 94 } 95 96 int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer) 97 { 98 int rc = -EINVAL; 99 100 LERROR << __FUNCTION__ << ": Format " << fstab->blk_device 101 << " as '" << fstab->fs_type << "'"; 102 103 if (!strncmp(fstab->fs_type, "f2fs", 4)) { 104 rc = format_f2fs(fstab->blk_device); 105 } else if (!strncmp(fstab->fs_type, "ext4", 4)) { 106 rc = format_ext4(fstab->blk_device, fstab->mount_point, crypt_footer); 107 } else { 108 LERROR << "File system type '" << fstab->fs_type << "' is not supported"; 109 } 110 111 return rc; 112 } 113