2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <sys/reboot.h>
19 #include <sys/types.h>
25 #include "android_reboot.h"
27 /* Check to see if /proc/mounts contains any writeable filesystems
28 * backed by a block device.
29 * Return true if none found, else return false.
31 static int remount_ro_done(void)
43 f = fopen("/proc/mounts", "r");
45 /* If we can't read /proc/mounts, just give up */
50 match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
51 mount_dev, mount_dir, mount_type,
52 mount_opts, &mount_freq, &mount_passno);
57 if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw")) {
61 } while (match != EOF);
68 /* Remounting filesystems read-only is difficult when there are files
69 * opened for writing or pending deletes on the filesystem. There is
70 * no way to force the remount with the mount(2) syscall. The magic sysrq
71 * 'u' command does an emergency remount read-only on all writable filesystems
72 * that have a block device (i.e. not tmpfs filesystems) by calling
73 * emergency_remount(), which knows how to force the remount to read-only.
74 * Unfortunately, that is asynchronous, and just schedules the work and
75 * returns. The best way to determine if it is done is to read /proc/mounts
76 * repeatedly until there are no more writable filesystems mounted on
79 static void remount_ro(void)
83 /* Trigger the remount of the filesystems as read-only,
84 * which also marks them clean.
86 fd = open("/proc/sysrq-trigger", O_WRONLY);
90 len = write(fd, "u", 1);
93 /* Now poll /proc/mounts till it's done */
94 while (!remount_ro_done() && (cnt < 50)) {
103 int android_reboot(int cmd, int flags, char *arg)
107 if (!(flags & ANDROID_RB_FLAG_NO_SYNC))
110 if (!(flags & ANDROID_RB_FLAG_NO_REMOUNT_RO))
114 case ANDROID_RB_RESTART:
115 ret = reboot(RB_AUTOBOOT);
118 case ANDROID_RB_POWEROFF:
119 ret = reboot(RB_POWER_OFF);
121 #if 0 /* tizen specific */
122 case ANDROID_RB_RESTART2:
123 ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
124 LINUX_REBOOT_CMD_RESTART2, arg);