summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs_mgr/Android.mk7
-rw-r--r--fs_mgr/fs_mgr.c37
-rw-r--r--fs_mgr/fs_mgr_format.c119
-rw-r--r--fs_mgr/fs_mgr_fstab.c6
-rw-r--r--fs_mgr/fs_mgr_priv.h1
-rw-r--r--fs_mgr/include/fs_mgr.h4
-rw-r--r--init/Android.mk4
-rw-r--r--init/devices.c2
-rw-r--r--init/util.c2
-rw-r--r--init/util.h2
10 files changed, 177 insertions, 7 deletions
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 61bf1ee6a..0ec6c4b1a 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -4,8 +4,12 @@ LOCAL_PATH:= $(call my-dir)
4include $(CLEAR_VARS) 4include $(CLEAR_VARS)
5 5
6LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c fs_mgr_fstab.c 6LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c fs_mgr_fstab.c
7LOCAL_SRC_FILES += fs_mgr_format.c
7 8
8LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 9LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
10 system/vold \
11 system/extras/ext4_utils \
12 external/openssl/include
9 13
10LOCAL_MODULE:= libfs_mgr 14LOCAL_MODULE:= libfs_mgr
11LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static 15LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static
@@ -35,6 +39,7 @@ LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
35LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) 39LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
36 40
37LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static 41LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static
42LOCAL_STATIC_LIBRARIES += libsparse_static libz libselinux
38 43
39LOCAL_CFLAGS := -Werror 44LOCAL_CFLAGS := -Werror
40 45
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index ad029222c..8533ff605 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -40,6 +40,9 @@
40#include "mincrypt/sha.h" 40#include "mincrypt/sha.h"
41#include "mincrypt/sha256.h" 41#include "mincrypt/sha256.h"
42 42
43#include "ext4_utils.h"
44#include "wipe.h"
45
43#include "fs_mgr_priv.h" 46#include "fs_mgr_priv.h"
44#include "fs_mgr_priv_verity.h" 47#include "fs_mgr_priv_verity.h"
45 48
@@ -380,6 +383,8 @@ int fs_mgr_mount_all(struct fstab *fstab)
380 } 383 }
381 } 384 }
382 int last_idx_inspected; 385 int last_idx_inspected;
386 int top_idx = i;
387
383 mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); 388 mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
384 i = last_idx_inspected; 389 i = last_idx_inspected;
385 mount_errno = errno; 390 mount_errno = errno;
@@ -409,10 +414,38 @@ int fs_mgr_mount_all(struct fstab *fstab)
409 continue; 414 continue;
410 } 415 }
411 416
412 /* mount(2) returned an error, check if it's encryptable and deal with it */ 417 /* mount(2) returned an error, handle the encryptable/formattable case */
418 bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
419 if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
420 fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
421 /* top_idx and attempted_idx point at the same partition, but sometimes
422 * at two different lines in the fstab. Use the top one for formatting
423 * as that is the preferred one.
424 */
425 ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
426 fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
427 fstab->recs[top_idx].fs_type);
428 if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
429 strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
430 int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
431 if (fd >= 0) {
432 INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
433 wipe_block_device(fd, get_file_size(fd));
434 close(fd);
435 } else {
436 ERROR("%s(): %s wouldn't open (%s)\n", __func__,
437 fstab->recs[top_idx].key_loc, strerror(errno));
438 }
439 }
440 if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
441 /* Let's replay the mount actions. */
442 i = top_idx - 1;
443 continue;
444 }
445 }
413 if (mret && mount_errno != EBUSY && mount_errno != EACCES && 446 if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
414 fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { 447 fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
415 if(partition_wiped(fstab->recs[attempted_idx].blk_device)) { 448 if (wiped) {
416 ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__, 449 ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
417 fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, 450 fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
418 fstab->recs[attempted_idx].fs_type); 451 fstab->recs[attempted_idx].fs_type);
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
new file mode 100644
index 000000000..b5b92b53c
--- /dev/null
+++ b/fs_mgr/fs_mgr_format.c
@@ -0,0 +1,119 @@
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#include "ext4_utils.h"
27#include "ext4.h"
28#include "make_ext4fs.h"
29#include "fs_mgr_priv.h"
30
31extern struct fs_info info; /* magic global from ext4_utils */
32extern void reset_ext4fs_info();
33
34static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
35{
36 unsigned int nr_sec;
37 int fd, rc = 0;
38
39 if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
40 ERROR("Cannot open block device. %s\n", strerror(errno));
41 return -1;
42 }
43
44 if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
45 ERROR("Cannot get block device size. %s\n", strerror(errno));
46 close(fd);
47 return -1;
48 }
49
50 /* Format the partition using the calculated length */
51 reset_ext4fs_info();
52 info.len = ((off64_t)nr_sec * 512);
53
54 /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
55 rc = make_ext4fs_internal(fd, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
56 if (rc) {
57 ERROR("make_ext4fs returned %d.\n", rc);
58 }
59 close(fd);
60
61 return rc;
62}
63
64static int format_f2fs(char *fs_blkdev)
65{
66 char * args[3];
67 int pid;
68 int rc = 0;
69
70 args[0] = (char *)"/sbin/mkfs.f2fs";
71 args[1] = fs_blkdev;
72 args[2] = (char *)0;
73
74 pid = fork();
75 if (pid < 0) {
76 return pid;
77 }
78 if (!pid) {
79 /* This doesn't return */
80 execv("/sbin/mkfs.f2fs", args);
81 exit(1);
82 }
83 for(;;) {
84 pid_t p = waitpid(pid, &rc, 0);
85 if (p != pid) {
86 ERROR("Error waiting for child process - %d\n", p);
87 rc = -1;
88 break;
89 }
90 if (WIFEXITED(rc)) {
91 rc = WEXITSTATUS(rc);
92 INFO("%s done, status %d\n", args[0], rc);
93 if (rc) {
94 rc = -1;
95 }
96 break;
97 }
98 ERROR("Still waiting for %s...\n", args[0]);
99 }
100
101 return rc;
102}
103
104int fs_mgr_do_format(struct fstab_rec *fstab)
105{
106 int rc = -EINVAL;
107
108 ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type);
109
110 if (!strncmp(fstab->fs_type, "f2fs", 4)) {
111 rc = format_f2fs(fstab->blk_device);
112 } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
113 rc = format_ext4(fstab->blk_device, fstab->mount_point);
114 } else {
115 ERROR("File system type '%s' is not supported\n", fstab->fs_type);
116 }
117
118 return rc;
119}
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index ab8f128ce..edd959116 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -68,6 +68,7 @@ static struct flag_list fs_mgr_flags[] = {
68 { "zramsize=", MF_ZRAMSIZE }, 68 { "zramsize=", MF_ZRAMSIZE },
69 { "verify", MF_VERIFY }, 69 { "verify", MF_VERIFY },
70 { "noemulatedsd", MF_NOEMULATEDSD }, 70 { "noemulatedsd", MF_NOEMULATEDSD },
71 { "formattable", MF_FORMATTABLE },
71 { "defaults", 0 }, 72 { "defaults", 0 },
72 { 0, 0 }, 73 { 0, 0 },
73}; 74};
@@ -432,3 +433,8 @@ int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab)
432{ 433{
433 return fstab->fs_mgr_flags & MF_NOEMULATEDSD; 434 return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
434} 435}
436
437int fs_mgr_is_formattable(struct fstab_rec *fstab)
438{
439 return fstab->fs_mgr_flags & (MF_FORMATTABLE);
440}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 34938fad7..fd5830652 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -75,6 +75,7 @@
75#define MF_FORCECRYPT 0x400 75#define MF_FORCECRYPT 0x400
76#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only 76#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only
77 external storage */ 77 external storage */
78#define MF_FORMATTABLE 0x1000
78 79
79#define DM_BUF_SIZE 4096 80#define DM_BUF_SIZE 4096
80 81
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 5e2ff416a..5a6ad2d60 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -84,7 +84,11 @@ int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
84int fs_mgr_is_verified(struct fstab_rec *fstab); 84int fs_mgr_is_verified(struct fstab_rec *fstab);
85int fs_mgr_is_encryptable(struct fstab_rec *fstab); 85int fs_mgr_is_encryptable(struct fstab_rec *fstab);
86int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); 86int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab);
87int fs_mgr_is_formattable(struct fstab_rec *fstab);
87int fs_mgr_swapon_all(struct fstab *fstab); 88int fs_mgr_swapon_all(struct fstab *fstab);
89
90int fs_mgr_do_format(struct fstab_rec *fstab);
91
88#ifdef __cplusplus 92#ifdef __cplusplus
89} 93}
90#endif 94#endif
diff --git a/init/Android.mk b/init/Android.mk
index 489dc93e1..228e645e9 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -45,7 +45,9 @@ LOCAL_STATIC_LIBRARIES := \
45 libc \ 45 libc \
46 libselinux \ 46 libselinux \
47 libmincrypt \ 47 libmincrypt \
48 libext4_utils_static 48 libext4_utils_static \
49 libsparse_static \
50 libz
49 51
50LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk 52LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
51 53
diff --git a/init/devices.c b/init/devices.c
index 1012fee41..73fe223a2 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -564,7 +564,7 @@ static void handle_device(const char *action, const char *devpath,
564 make_device(devpath, path, block, major, minor, (const char **)links); 564 make_device(devpath, path, block, major, minor, (const char **)links);
565 if (links) { 565 if (links) {
566 for (i = 0; links[i]; i++) 566 for (i = 0; links[i]; i++)
567 make_link(devpath, links[i]); 567 make_link_init(devpath, links[i]);
568 } 568 }
569 } 569 }
570 570
diff --git a/init/util.c b/init/util.c
index e1a3ee33a..12cb11d66 100644
--- a/init/util.c
+++ b/init/util.c
@@ -335,7 +335,7 @@ void sanitize(char *s)
335 } 335 }
336} 336}
337 337
338void make_link(const char *oldpath, const char *newpath) 338void make_link_init(const char *oldpath, const char *newpath)
339{ 339{
340 int ret; 340 int ret;
341 char buf[256]; 341 char buf[256];
diff --git a/init/util.h b/init/util.h
index 04b8129ba..a7e7c8b20 100644
--- a/init/util.h
+++ b/init/util.h
@@ -33,7 +33,7 @@ unsigned int decode_uid(const char *s);
33 33
34int mkdir_recursive(const char *pathname, mode_t mode); 34int mkdir_recursive(const char *pathname, mode_t mode);
35void sanitize(char *p); 35void sanitize(char *p);
36void make_link(const char *oldpath, const char *newpath); 36void make_link_init(const char *oldpath, const char *newpath);
37void remove_link(const char *oldpath, const char *newpath); 37void remove_link(const char *oldpath, const char *newpath);
38int wait_for_file(const char *filename, int timeout); 38int wait_for_file(const char *filename, int timeout);
39void open_devnull_stdio(void); 39void open_devnull_stdio(void);