system/core
修订版 | 89003f4358cee5c2ea641b1990e655d450a371de (tree) |
---|---|
时间 | 2016-09-15 04:03:14 |
作者 | Jaap Jan Meijer <jjmeijer88@gmai...> |
Commiter | Jaap Jan Meijer |
init: revert using fsck -a for boot time optimisation
This is causing the data partition to get dirty / damaged very regularly
and make the data partition to be mounted ro.
This is a combination of 2 commits:
Revert "init: Allow devices to opt-out of fsck'ing on power off"
This reverts commit 516d6913dc5acd695581b3999fab0b5192353022.
Revert "Use fsck.f2fs -a instead of -f for faster boot"
This reverts commit 784c22c8388e50db243ac4ca3871747cd3eefadc.
Conflicts:
init/builtins.cpp
@@ -163,10 +163,10 @@ static void check_fs(char *blk_device, char *fs_type, char *target) | ||
163 | 163 | } else if (!strcmp(fs_type, "f2fs")) { |
164 | 164 | char *f2fs_fsck_argv[] = { |
165 | 165 | F2FS_FSCK_BIN, |
166 | - "-a", | |
166 | + "-f", | |
167 | 167 | blk_device |
168 | 168 | }; |
169 | - INFO("Running %s -a %s\n", F2FS_FSCK_BIN, blk_device); | |
169 | + INFO("Running %s -f %s\n", F2FS_FSCK_BIN, blk_device); | |
170 | 170 | |
171 | 171 | ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv, |
172 | 172 | &status, true, LOG_KLOG | LOG_FILE, |
@@ -17,8 +17,6 @@ | ||
17 | 17 | #ifndef __CUTILS_ANDROID_REBOOT_H__ |
18 | 18 | #define __CUTILS_ANDROID_REBOOT_H__ |
19 | 19 | |
20 | -#include <mntent.h> | |
21 | - | |
22 | 20 | __BEGIN_DECLS |
23 | 21 | |
24 | 22 | /* Commands */ |
@@ -30,9 +28,6 @@ __BEGIN_DECLS | ||
30 | 28 | #define ANDROID_RB_PROPERTY "sys.powerctl" |
31 | 29 | |
32 | 30 | int android_reboot(int cmd, int flags, const char *arg); |
33 | -int android_reboot_with_callback( | |
34 | - int cmd, int flags, const char *arg, | |
35 | - void (*cb_on_remount)(const struct mntent*)); | |
36 | 31 | |
37 | 32 | __END_DECLS |
38 | 33 |
@@ -69,10 +69,6 @@ ifneq ($(TARGET_IGNORE_RO_BOOT_REVISION),) | ||
69 | 69 | LOCAL_CFLAGS += -DIGNORE_RO_BOOT_REVISION |
70 | 70 | endif |
71 | 71 | |
72 | -ifneq ($(TARGET_INIT_UMOUNT_AND_FSCK_IS_UNSAFE),) | |
73 | -LOCAL_CFLAGS += -DUMOUNT_AND_FSCK_IS_UNSAFE | |
74 | -endif | |
75 | - | |
76 | 72 | LOCAL_MODULE:= init |
77 | 73 | LOCAL_C_INCLUDES += \ |
78 | 74 | external/zlib \ |
@@ -16,9 +16,7 @@ | ||
16 | 16 | |
17 | 17 | #include <errno.h> |
18 | 18 | #include <fcntl.h> |
19 | -#include <mntent.h> | |
20 | 19 | #include <net/if.h> |
21 | -#include <signal.h> | |
22 | 20 | #include <stdio.h> |
23 | 21 | #include <stdlib.h> |
24 | 22 | #include <string.h> |
@@ -42,7 +40,6 @@ | ||
42 | 40 | #include <base/stringprintf.h> |
43 | 41 | #include <cutils/partition_utils.h> |
44 | 42 | #include <cutils/android_reboot.h> |
45 | -#include <logwrap/logwrap.h> | |
46 | 43 | #include <cutils/probe_module.h> |
47 | 44 | #include <private/android_filesystem_config.h> |
48 | 45 |
@@ -55,8 +52,6 @@ | ||
55 | 52 | #include "log.h" |
56 | 53 | |
57 | 54 | #define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW |
58 | -#define UNMOUNT_CHECK_MS 5000 | |
59 | -#define UNMOUNT_CHECK_TIMES 10 | |
60 | 55 | |
61 | 56 | int add_environment(const char *name, const char *value); |
62 | 57 |
@@ -117,69 +112,6 @@ static void service_start_if_not_disabled(struct service *svc) | ||
117 | 112 | } |
118 | 113 | } |
119 | 114 | |
120 | -static void unmount_and_fsck(const struct mntent *entry) | |
121 | -{ | |
122 | -#ifndef UMOUNT_AND_FSCK_IS_UNSAFE | |
123 | - if (strcmp(entry->mnt_type, "f2fs") && strcmp(entry->mnt_type, "ext4")) | |
124 | - return; | |
125 | - | |
126 | - /* First, lazily unmount the directory. This unmount request finishes when | |
127 | - * all processes that open a file or directory in |entry->mnt_dir| exit. | |
128 | - */ | |
129 | - TEMP_FAILURE_RETRY(umount2(entry->mnt_dir, MNT_DETACH)); | |
130 | - | |
131 | - /* Next, kill all processes except init, kthreadd, and kthreadd's | |
132 | - * children to finish the lazy unmount. Killing all processes here is okay | |
133 | - * because this callback function is only called right before reboot(). | |
134 | - * It might be cleaner to selectively kill processes that actually use | |
135 | - * |entry->mnt_dir| rather than killing all, probably by reusing a function | |
136 | - * like killProcessesWithOpenFiles() in vold/, but the selinux policy does | |
137 | - * not allow init to scan /proc/<pid> files which the utility function | |
138 | - * heavily relies on. The policy does not allow the process to execute | |
139 | - * killall/pkill binaries either. Note that some processes might | |
140 | - * automatically restart after kill(), but that is not really a problem | |
141 | - * because |entry->mnt_dir| is no longer visible to such new processes. | |
142 | - */ | |
143 | - service_for_each(service_stop); | |
144 | - TEMP_FAILURE_RETRY(kill(-1, SIGKILL)); | |
145 | - | |
146 | - int count = 0; | |
147 | - while (count++ < UNMOUNT_CHECK_TIMES) { | |
148 | - int fd = TEMP_FAILURE_RETRY(open(entry->mnt_fsname, O_RDONLY | O_EXCL)); | |
149 | - if (fd >= 0) { | |
150 | - /* |entry->mnt_dir| has sucessfully been unmounted. */ | |
151 | - close(fd); | |
152 | - break; | |
153 | - } else if (errno == EBUSY) { | |
154 | - /* Some processes using |entry->mnt_dir| are still alive. Wait for a | |
155 | - * while then retry. | |
156 | - */ | |
157 | - TEMP_FAILURE_RETRY( | |
158 | - usleep(UNMOUNT_CHECK_MS * 1000 / UNMOUNT_CHECK_TIMES)); | |
159 | - continue; | |
160 | - } else { | |
161 | - /* Cannot open the device. Give up. */ | |
162 | - return; | |
163 | - } | |
164 | - } | |
165 | - | |
166 | - int st; | |
167 | - if (!strcmp(entry->mnt_type, "f2fs")) { | |
168 | - const char *f2fs_argv[] = { | |
169 | - "/system/bin/fsck.f2fs", "-f", entry->mnt_fsname, | |
170 | - }; | |
171 | - android_fork_execvp_ext(ARRAY_SIZE(f2fs_argv), (char **)f2fs_argv, | |
172 | - &st, true, LOG_KLOG, true, NULL); | |
173 | - } else if (!strcmp(entry->mnt_type, "ext4")) { | |
174 | - const char *ext4_argv[] = { | |
175 | - "/system/bin/e2fsck", "-f", "-y", entry->mnt_fsname, | |
176 | - }; | |
177 | - android_fork_execvp_ext(ARRAY_SIZE(ext4_argv), (char **)ext4_argv, | |
178 | - &st, true, LOG_KLOG, true, NULL); | |
179 | - } | |
180 | -#endif | |
181 | -} | |
182 | - | |
183 | 115 | int do_class_start(int nargs, char **args) |
184 | 116 | { |
185 | 117 | char prop[PROP_NAME_MAX]; |
@@ -705,7 +637,6 @@ int do_powerctl(int nargs, char **args) | ||
705 | 637 | int len = 0; |
706 | 638 | int cmd = 0; |
707 | 639 | const char *reboot_target; |
708 | - void (*callback_on_ro_remount)(const struct mntent*) = NULL; | |
709 | 640 | |
710 | 641 | res = expand_props(command, args[1], sizeof(command)); |
711 | 642 | if (res) { |
@@ -719,7 +650,6 @@ int do_powerctl(int nargs, char **args) | ||
719 | 650 | } |
720 | 651 | cmd = ANDROID_RB_POWEROFF; |
721 | 652 | len = 8; |
722 | - callback_on_ro_remount = unmount_and_fsck; | |
723 | 653 | } else if (strncmp(command, "reboot", 6) == 0) { |
724 | 654 | cmd = ANDROID_RB_RESTART2; |
725 | 655 | len = 6; |
@@ -744,8 +674,7 @@ int do_powerctl(int nargs, char **args) | ||
744 | 674 | return -EINVAL; |
745 | 675 | } |
746 | 676 | |
747 | - return android_reboot_with_callback(cmd, 0, reboot_target, | |
748 | - callback_on_ro_remount); | |
677 | + return android_reboot(cmd, 0, reboot_target); | |
749 | 678 | } |
750 | 679 | |
751 | 680 | int do_trigger(int nargs, char **args) |
@@ -14,108 +14,43 @@ | ||
14 | 14 | * limitations under the License. |
15 | 15 | */ |
16 | 16 | |
17 | -#include <errno.h> | |
17 | +#include <unistd.h> | |
18 | +#include <sys/reboot.h> | |
19 | +#include <sys/syscall.h> | |
20 | +#include <sys/types.h> | |
21 | +#include <sys/stat.h> | |
18 | 22 | #include <fcntl.h> |
19 | 23 | #include <mntent.h> |
20 | -#include <stdbool.h> | |
21 | 24 | #include <stdio.h> |
22 | -#include <stdlib.h> | |
23 | 25 | #include <string.h> |
24 | -#include <sys/cdefs.h> | |
25 | -#include <sys/mount.h> | |
26 | -#include <sys/reboot.h> | |
27 | -#include <sys/stat.h> | |
28 | -#include <sys/syscall.h> | |
29 | -#include <sys/types.h> | |
30 | -#include <unistd.h> | |
31 | 26 | |
32 | 27 | #include <cutils/android_reboot.h> |
33 | -#include <cutils/klog.h> | |
34 | -#include <cutils/list.h> | |
35 | 28 | |
36 | -#define TAG "android_reboot" | |
37 | -#define READONLY_CHECK_MS 5000 | |
38 | -#define READONLY_CHECK_TIMES 50 | |
29 | +#define UNUSED __attribute__((unused)) | |
39 | 30 | |
40 | -typedef struct { | |
41 | - struct listnode list; | |
42 | - struct mntent entry; | |
43 | -} mntent_list; | |
44 | - | |
45 | -static bool has_mount_option(const char* opts, const char* opt_to_find) | |
46 | -{ | |
47 | - bool ret = false; | |
48 | - char* copy = NULL; | |
49 | - char* opt; | |
50 | - char* rem; | |
51 | - | |
52 | - while ((opt = strtok_r(copy ? NULL : (copy = strdup(opts)), ",", &rem))) { | |
53 | - if (!strcmp(opt, opt_to_find)) { | |
54 | - ret = true; | |
55 | - break; | |
56 | - } | |
57 | - } | |
58 | - | |
59 | - free(copy); | |
60 | - return ret; | |
61 | -} | |
62 | - | |
63 | -static bool is_block_device(const char* fsname) | |
64 | -{ | |
65 | - return !strncmp(fsname, "/dev/block", 10); | |
66 | -} | |
67 | - | |
68 | -/* Find all read+write block devices in /proc/mounts and add them to | |
69 | - * |rw_entries|. | |
31 | +/* Check to see if /proc/mounts contains any writeable filesystems | |
32 | + * backed by a block device. | |
33 | + * Return true if none found, else return false. | |
70 | 34 | */ |
71 | -static void find_rw(struct listnode* rw_entries) | |
35 | +static int remount_ro_done(void) | |
72 | 36 | { |
73 | 37 | FILE* fp; |
74 | 38 | struct mntent* mentry; |
39 | + int found_rw_fs = 0; | |
75 | 40 | |
76 | 41 | if ((fp = setmntent("/proc/mounts", "r")) == NULL) { |
77 | - KLOG_WARNING(TAG, "Failed to open /proc/mounts.\n"); | |
78 | - return; | |
42 | + /* If we can't read /proc/mounts, just give up. */ | |
43 | + return 1; | |
79 | 44 | } |
80 | 45 | while ((mentry = getmntent(fp)) != NULL) { |
81 | - if (is_block_device(mentry->mnt_fsname) && | |
82 | - has_mount_option(mentry->mnt_opts, "rw")) { | |
83 | - mntent_list* item = (mntent_list*)calloc(1, sizeof(mntent_list)); | |
84 | - item->entry = *mentry; | |
85 | - item->entry.mnt_fsname = strdup(mentry->mnt_fsname); | |
86 | - item->entry.mnt_dir = strdup(mentry->mnt_dir); | |
87 | - item->entry.mnt_type = strdup(mentry->mnt_type); | |
88 | - item->entry.mnt_opts = strdup(mentry->mnt_opts); | |
89 | - list_add_tail(rw_entries, &item->list); | |
46 | + if (!strncmp(mentry->mnt_fsname, "/dev/block", 10) && strstr(mentry->mnt_opts, "rw,")) { | |
47 | + found_rw_fs = 1; | |
48 | + break; | |
90 | 49 | } |
91 | 50 | } |
92 | 51 | endmntent(fp); |
93 | -} | |
94 | - | |
95 | -static void free_entries(struct listnode* entries) | |
96 | -{ | |
97 | - struct listnode* node; | |
98 | - struct listnode* n; | |
99 | - list_for_each_safe(node, n, entries) { | |
100 | - mntent_list* item = node_to_item(node, mntent_list, list); | |
101 | - free(item->entry.mnt_fsname); | |
102 | - free(item->entry.mnt_dir); | |
103 | - free(item->entry.mnt_type); | |
104 | - free(item->entry.mnt_opts); | |
105 | - free(item); | |
106 | - } | |
107 | -} | |
108 | 52 | |
109 | -static mntent_list* find_item(struct listnode* rw_entries, const char* fsname_to_find) | |
110 | -{ | |
111 | - struct listnode* node; | |
112 | - list_for_each(node, rw_entries) { | |
113 | - mntent_list* item = node_to_item(node, mntent_list, list); | |
114 | - if (!strcmp(item->entry.mnt_fsname, fsname_to_find)) { | |
115 | - return item; | |
116 | - } | |
117 | - } | |
118 | - return NULL; | |
53 | + return !found_rw_fs; | |
119 | 54 | } |
120 | 55 | |
121 | 56 | /* Remounting filesystems read-only is difficult when there are files |
@@ -129,92 +64,38 @@ static mntent_list* find_item(struct listnode* rw_entries, const char* fsname_to | ||
129 | 64 | * repeatedly until there are no more writable filesystems mounted on |
130 | 65 | * block devices. |
131 | 66 | */ |
132 | -static void remount_ro(void (*cb_on_remount)(const struct mntent*)) | |
67 | +static void remount_ro(void) | |
133 | 68 | { |
134 | - int fd, cnt; | |
135 | - FILE* fp; | |
136 | - struct mntent* mentry; | |
137 | - struct listnode* node; | |
138 | - | |
139 | - list_declare(rw_entries); | |
140 | - list_declare(ro_entries); | |
141 | - | |
142 | - sync(); | |
143 | - find_rw(&rw_entries); | |
69 | + int fd, cnt = 0; | |
144 | 70 | |
145 | 71 | /* Trigger the remount of the filesystems as read-only, |
146 | 72 | * which also marks them clean. |
147 | 73 | */ |
148 | - fd = TEMP_FAILURE_RETRY(open("/proc/sysrq-trigger", O_WRONLY)); | |
74 | + fd = open("/proc/sysrq-trigger", O_WRONLY); | |
149 | 75 | if (fd < 0) { |
150 | - KLOG_WARNING(TAG, "Failed to open sysrq-trigger.\n"); | |
151 | - /* TODO: Try to remount each rw parition manually in readonly mode. | |
152 | - * This may succeed if no process is using the partition. | |
153 | - */ | |
154 | - goto out; | |
155 | - } | |
156 | - if (TEMP_FAILURE_RETRY(write(fd, "u", 1)) != 1) { | |
157 | - close(fd); | |
158 | - KLOG_WARNING(TAG, "Failed to write to sysrq-trigger.\n"); | |
159 | - /* TODO: The same. Manually remount the paritions. */ | |
160 | - goto out; | |
76 | + return; | |
161 | 77 | } |
78 | + write(fd, "u", 1); | |
162 | 79 | close(fd); |
163 | 80 | |
81 | + | |
164 | 82 | /* Now poll /proc/mounts till it's done */ |
165 | - cnt = 0; | |
166 | - while (cnt < READONLY_CHECK_TIMES) { | |
167 | - if ((fp = setmntent("/proc/mounts", "r")) == NULL) { | |
168 | - /* If we can't read /proc/mounts, just give up. */ | |
169 | - KLOG_WARNING(TAG, "Failed to open /proc/mounts.\n"); | |
170 | - goto out; | |
171 | - } | |
172 | - while ((mentry = getmntent(fp)) != NULL) { | |
173 | - if (!is_block_device(mentry->mnt_fsname) || | |
174 | - !has_mount_option(mentry->mnt_opts, "ro")) { | |
175 | - continue; | |
176 | - } | |
177 | - mntent_list* item = find_item(&rw_entries, mentry->mnt_fsname); | |
178 | - if (item) { | |
179 | - /* |item| has now been ro remounted. */ | |
180 | - list_remove(&item->list); | |
181 | - list_add_tail(&ro_entries, &item->list); | |
182 | - } | |
183 | - } | |
184 | - endmntent(fp); | |
185 | - if (list_empty(&rw_entries)) { | |
186 | - /* All rw block devices are now readonly. */ | |
187 | - break; | |
188 | - } | |
189 | - TEMP_FAILURE_RETRY( | |
190 | - usleep(READONLY_CHECK_MS * 1000 / READONLY_CHECK_TIMES)); | |
83 | + while (!remount_ro_done() && (cnt < 50)) { | |
84 | + usleep(100000); | |
191 | 85 | cnt++; |
192 | 86 | } |
193 | 87 | |
194 | - list_for_each(node, &rw_entries) { | |
195 | - mntent_list* item = node_to_item(node, mntent_list, list); | |
196 | - KLOG_WARNING(TAG, "Failed to remount %s in readonly mode.\n", | |
197 | - item->entry.mnt_fsname); | |
198 | - } | |
199 | - | |
200 | - if (cb_on_remount) { | |
201 | - list_for_each(node, &ro_entries) { | |
202 | - mntent_list* item = node_to_item(node, mntent_list, list); | |
203 | - cb_on_remount(&item->entry); | |
204 | - } | |
205 | - } | |
206 | - | |
207 | -out: | |
208 | - free_entries(&rw_entries); | |
209 | - free_entries(&ro_entries); | |
88 | + return; | |
210 | 89 | } |
211 | 90 | |
212 | -int android_reboot_with_callback( | |
213 | - int cmd, int flags __unused, const char *arg, | |
214 | - void (*cb_on_remount)(const struct mntent*)) | |
91 | + | |
92 | +int android_reboot(int cmd, int flags UNUSED, const char *arg) | |
215 | 93 | { |
216 | 94 | int ret; |
217 | - remount_ro(cb_on_remount); | |
95 | + | |
96 | + sync(); | |
97 | + remount_ro(); | |
98 | + | |
218 | 99 | switch (cmd) { |
219 | 100 | case ANDROID_RB_RESTART: |
220 | 101 | ret = reboot(RB_AUTOBOOT); |
@@ -236,7 +117,3 @@ int android_reboot_with_callback( | ||
236 | 117 | return ret; |
237 | 118 | } |
238 | 119 | |
239 | -int android_reboot(int cmd, int flags, const char *arg) | |
240 | -{ | |
241 | - return android_reboot_with_callback(cmd, flags, arg, NULL); | |
242 | -} |
@@ -355,8 +355,7 @@ static int parent(const char *tag, int parent_read, pid_t pid, | ||
355 | 355 | } |
356 | 356 | |
357 | 357 | if (poll_fds[0].revents & POLLIN) { |
358 | - sz = TEMP_FAILURE_RETRY( | |
359 | - read(parent_read, &buffer[b], sizeof(buffer) - 1 - b)); | |
358 | + sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b); | |
360 | 359 | |
361 | 360 | sz += b; |
362 | 361 | // Log one line at a time |
@@ -491,7 +490,7 @@ int android_fork_execvp_ext(int argc, char* argv[], int *status, bool ignore_int | ||
491 | 490 | } |
492 | 491 | |
493 | 492 | /* Use ptty instead of socketpair so that STDOUT is not buffered */ |
494 | - parent_ptty = TEMP_FAILURE_RETRY(open("/dev/ptmx", O_RDWR)); | |
493 | + parent_ptty = open("/dev/ptmx", O_RDWR); | |
495 | 494 | if (parent_ptty < 0) { |
496 | 495 | ERROR("Cannot create parent ptty\n"); |
497 | 496 | rc = -1; |
@@ -506,7 +505,7 @@ int android_fork_execvp_ext(int argc, char* argv[], int *status, bool ignore_int | ||
506 | 505 | goto err_ptty; |
507 | 506 | } |
508 | 507 | |
509 | - child_ptty = TEMP_FAILURE_RETRY(open(child_devname, O_RDWR)); | |
508 | + child_ptty = open(child_devname, O_RDWR); | |
510 | 509 | if (child_ptty < 0) { |
511 | 510 | ERROR("Cannot open child_ptty\n"); |
512 | 511 | rc = -1; |