blob: 7c3b1ed223fd24a9da6f40031d974e33b04ac692 [file] [log] [blame]
Chris Fries79f33842013-09-05 13:19:21 -05001/*
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>
William Roberts875476d2016-05-13 11:19:42 -070026
Tao Bao6d881d62016-10-05 17:53:30 -070027#include <ext4_utils/ext4_utils.h>
28#include <ext4_utils/ext4.h>
29#include <ext4_utils/make_ext4fs.h>
William Roberts875476d2016-05-13 11:19:42 -070030#include <selinux/selinux.h>
31#include <selinux/label.h>
32#include <selinux/android.h>
33
Chris Fries79f33842013-09-05 13:19:21 -050034#include "fs_mgr_priv.h"
Chuanxiao Dongd78dff12016-03-08 15:54:55 +010035#include "cryptfs.h"
Chris Fries79f33842013-09-05 13:19:21 -050036
37extern struct fs_info info; /* magic global from ext4_utils */
38extern void reset_ext4fs_info();
39
Chuanxiao Dongd78dff12016-03-08 15:54:55 +010040static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
Chris Fries79f33842013-09-05 13:19:21 -050041{
Keith Mokd93adf52016-02-16 09:50:22 -080042 uint64_t dev_sz;
Chris Fries79f33842013-09-05 13:19:21 -050043 int fd, rc = 0;
44
George Burgess IVe7aa2b22016-03-02 14:02:55 -080045 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
Chris Fries79f33842013-09-05 13:19:21 -050046 ERROR("Cannot open block device. %s\n", strerror(errno));
47 return -1;
48 }
49
Keith Mokd93adf52016-02-16 09:50:22 -080050 if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) {
Chris Fries79f33842013-09-05 13:19:21 -050051 ERROR("Cannot get block device size. %s\n", strerror(errno));
52 close(fd);
53 return -1;
54 }
55
William Roberts875476d2016-05-13 11:19:42 -070056 struct selabel_handle *sehandle = selinux_android_file_context_handle();
57 if (!sehandle) {
58 /* libselinux logs specific error */
59 ERROR("Cannot initialize android file_contexts");
60 close(fd);
61 return -1;
62 }
63
Chris Fries79f33842013-09-05 13:19:21 -050064 /* Format the partition using the calculated length */
65 reset_ext4fs_info();
Keith Mokd93adf52016-02-16 09:50:22 -080066 info.len = (off64_t)dev_sz;
Chuanxiao Dongd78dff12016-03-08 15:54:55 +010067 if (crypt_footer) {
68 info.len -= CRYPT_FOOTER_OFFSET;
69 }
Chris Fries79f33842013-09-05 13:19:21 -050070
71 /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
Jeff Vander Stoepc1b98542016-06-01 11:46:42 -070072 rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL, NULL, NULL);
Chris Fries79f33842013-09-05 13:19:21 -050073 if (rc) {
74 ERROR("make_ext4fs returned %d.\n", rc);
75 }
76 close(fd);
77
William Roberts875476d2016-05-13 11:19:42 -070078 if (sehandle) {
79 selabel_close(sehandle);
80 }
81
Chris Fries79f33842013-09-05 13:19:21 -050082 return rc;
83}
84
85static int format_f2fs(char *fs_blkdev)
86{
87 char * args[3];
88 int pid;
89 int rc = 0;
90
91 args[0] = (char *)"/sbin/mkfs.f2fs";
92 args[1] = fs_blkdev;
93 args[2] = (char *)0;
94
95 pid = fork();
96 if (pid < 0) {
97 return pid;
98 }
99 if (!pid) {
100 /* This doesn't return */
101 execv("/sbin/mkfs.f2fs", args);
102 exit(1);
103 }
104 for(;;) {
105 pid_t p = waitpid(pid, &rc, 0);
106 if (p != pid) {
107 ERROR("Error waiting for child process - %d\n", p);
108 rc = -1;
109 break;
110 }
111 if (WIFEXITED(rc)) {
112 rc = WEXITSTATUS(rc);
113 INFO("%s done, status %d\n", args[0], rc);
114 if (rc) {
115 rc = -1;
116 }
117 break;
118 }
119 ERROR("Still waiting for %s...\n", args[0]);
120 }
121
122 return rc;
123}
124
Chuanxiao Dongd78dff12016-03-08 15:54:55 +0100125int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer)
Chris Fries79f33842013-09-05 13:19:21 -0500126{
127 int rc = -EINVAL;
128
129 ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type);
130
131 if (!strncmp(fstab->fs_type, "f2fs", 4)) {
132 rc = format_f2fs(fstab->blk_device);
133 } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
Chuanxiao Dongd78dff12016-03-08 15:54:55 +0100134 rc = format_ext4(fstab->blk_device, fstab->mount_point, crypt_footer);
Chris Fries79f33842013-09-05 13:19:21 -0500135 } else {
136 ERROR("File system type '%s' is not supported\n", fstab->fs_type);
137 }
138
139 return rc;
140}