blob: 6c66f471871f32d77811119113984ef755202d89 [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
27#include <selinux/selinux.h>
28#include <selinux/label.h>
29#include <selinux/android.h>
30
Chris Fries79f33842013-09-05 13:19:21 -050031#include "ext4_utils.h"
32#include "ext4.h"
33#include "make_ext4fs.h"
34#include "fs_mgr_priv.h"
35
36extern struct fs_info info; /* magic global from ext4_utils */
37extern void reset_ext4fs_info();
38
39static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
40{
Keith Mokd93adf52016-02-16 09:50:22 -080041 uint64_t dev_sz;
Chris Fries79f33842013-09-05 13:19:21 -050042 int fd, rc = 0;
43
George Burgess IVe7aa2b22016-03-02 14:02:55 -080044 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
Chris Fries79f33842013-09-05 13:19:21 -050045 ERROR("Cannot open block device. %s\n", strerror(errno));
46 return -1;
47 }
48
Keith Mokd93adf52016-02-16 09:50:22 -080049 if ((ioctl(fd, BLKGETSIZE64, &dev_sz)) == -1) {
Chris Fries79f33842013-09-05 13:19:21 -050050 ERROR("Cannot get block device size. %s\n", strerror(errno));
51 close(fd);
52 return -1;
53 }
54
William Roberts875476d2016-05-13 11:19:42 -070055 struct selabel_handle *sehandle = selinux_android_file_context_handle();
56 if (!sehandle) {
57 /* libselinux logs specific error */
58 ERROR("Cannot initialize android file_contexts");
59 close(fd);
60 return -1;
61 }
62
Chris Fries79f33842013-09-05 13:19:21 -050063 /* Format the partition using the calculated length */
64 reset_ext4fs_info();
Keith Mokd93adf52016-02-16 09:50:22 -080065 info.len = (off64_t)dev_sz;
Chris Fries79f33842013-09-05 13:19:21 -050066
67 /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
Jeff Vander Stoepc1b98542016-06-01 11:46:42 -070068 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 -050069 if (rc) {
70 ERROR("make_ext4fs returned %d.\n", rc);
71 }
72 close(fd);
73
William Roberts875476d2016-05-13 11:19:42 -070074 if (sehandle) {
75 selabel_close(sehandle);
76 }
77
Chris Fries79f33842013-09-05 13:19:21 -050078 return rc;
79}
80
81static int format_f2fs(char *fs_blkdev)
82{
83 char * args[3];
84 int pid;
85 int rc = 0;
86
87 args[0] = (char *)"/sbin/mkfs.f2fs";
88 args[1] = fs_blkdev;
89 args[2] = (char *)0;
90
91 pid = fork();
92 if (pid < 0) {
93 return pid;
94 }
95 if (!pid) {
96 /* This doesn't return */
97 execv("/sbin/mkfs.f2fs", args);
98 exit(1);
99 }
100 for(;;) {
101 pid_t p = waitpid(pid, &rc, 0);
102 if (p != pid) {
103 ERROR("Error waiting for child process - %d\n", p);
104 rc = -1;
105 break;
106 }
107 if (WIFEXITED(rc)) {
108 rc = WEXITSTATUS(rc);
109 INFO("%s done, status %d\n", args[0], rc);
110 if (rc) {
111 rc = -1;
112 }
113 break;
114 }
115 ERROR("Still waiting for %s...\n", args[0]);
116 }
117
118 return rc;
119}
120
121int fs_mgr_do_format(struct fstab_rec *fstab)
122{
123 int rc = -EINVAL;
124
125 ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type);
126
127 if (!strncmp(fstab->fs_type, "f2fs", 4)) {
128 rc = format_f2fs(fstab->blk_device);
129 } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
130 rc = format_ext4(fstab->blk_device, fstab->mount_point);
131 } else {
132 ERROR("File system type '%s' is not supported\n", fstab->fs_type);
133 }
134
135 return rc;
136}