diff options
-rw-r--r-- | fs_mgr/Android.mk | 7 | ||||
-rw-r--r-- | fs_mgr/fs_mgr.c | 37 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_format.c | 119 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_fstab.c | 6 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_priv.h | 1 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr.h | 4 | ||||
-rw-r--r-- | init/Android.mk | 4 | ||||
-rw-r--r-- | init/devices.c | 2 | ||||
-rw-r--r-- | init/util.c | 2 | ||||
-rw-r--r-- | init/util.h | 2 |
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) | |||
4 | include $(CLEAR_VARS) | 4 | include $(CLEAR_VARS) |
5 | 5 | ||
6 | LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c fs_mgr_fstab.c | 6 | LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c fs_mgr_fstab.c |
7 | LOCAL_SRC_FILES += fs_mgr_format.c | ||
7 | 8 | ||
8 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include | 9 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \ |
10 | system/vold \ | ||
11 | system/extras/ext4_utils \ | ||
12 | external/openssl/include | ||
9 | 13 | ||
10 | LOCAL_MODULE:= libfs_mgr | 14 | LOCAL_MODULE:= libfs_mgr |
11 | LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static | 15 | LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static |
@@ -35,6 +39,7 @@ LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin | |||
35 | LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) | 39 | LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) |
36 | 40 | ||
37 | LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static | 41 | LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static |
42 | LOCAL_STATIC_LIBRARIES += libsparse_static libz libselinux | ||
38 | 43 | ||
39 | LOCAL_CFLAGS := -Werror | 44 | LOCAL_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 | |||
31 | extern struct fs_info info; /* magic global from ext4_utils */ | ||
32 | extern void reset_ext4fs_info(); | ||
33 | |||
34 | static 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 | |||
64 | static 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 | |||
104 | int 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 | |||
437 | int 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); | |||
84 | int fs_mgr_is_verified(struct fstab_rec *fstab); | 84 | int fs_mgr_is_verified(struct fstab_rec *fstab); |
85 | int fs_mgr_is_encryptable(struct fstab_rec *fstab); | 85 | int fs_mgr_is_encryptable(struct fstab_rec *fstab); |
86 | int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); | 86 | int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab); |
87 | int fs_mgr_is_formattable(struct fstab_rec *fstab); | ||
87 | int fs_mgr_swapon_all(struct fstab *fstab); | 88 | int fs_mgr_swapon_all(struct fstab *fstab); |
89 | |||
90 | int 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 | ||
50 | LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk | 52 | LOCAL_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 | ||
338 | void make_link(const char *oldpath, const char *newpath) | 338 | void 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 | ||
34 | int mkdir_recursive(const char *pathname, mode_t mode); | 34 | int mkdir_recursive(const char *pathname, mode_t mode); |
35 | void sanitize(char *p); | 35 | void sanitize(char *p); |
36 | void make_link(const char *oldpath, const char *newpath); | 36 | void make_link_init(const char *oldpath, const char *newpath); |
37 | void remove_link(const char *oldpath, const char *newpath); | 37 | void remove_link(const char *oldpath, const char *newpath); |
38 | int wait_for_file(const char *filename, int timeout); | 38 | int wait_for_file(const char *filename, int timeout); |
39 | void open_devnull_stdio(void); | 39 | void open_devnull_stdio(void); |