summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Fries2013-09-05 13:19:21 -0500
committerEd Tam2015-04-10 17:01:16 -0500
commit79f338465213885900cea5a39f3aeeea083bbe51 (patch)
treec2514aecb7030491246a006870f3bd6ecbeda5d0
parent317b4024a2a46b8c57abfa08f2a649df13572bd3 (diff)
downloadplatform-system-core-android-5.1.1_r5.tar.gz
platform-system-core-android-5.1.1_r5.tar.xz
platform-system-core-android-5.1.1_r5.zip
fs_mgr: introduce fs_mgr_format to format wiped partitionsandroid-5.1.1_r5android-5.1.1_r12
Move fastboot's format logic into fs_mgr, to consolidate the knowledge about how to do this (and when to wipe metadata). Try to format these formattable paritions if they are wiped. If formatting fails, we will fall out to let recovery mode handle it. Bug: 20082763 Change-Id: I397cc197550e78d932e8a154fd234695c46dbe7b
-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);