Пример #1
0
/* Remounting filesystems read-only is difficult when there are files
 * opened for writing or pending deletes on the filesystem.  There is
 * no way to force the remount with the mount(2) syscall.  The magic sysrq
 * 'u' command does an emergency remount read-only on all writable filesystems
 * that have a block device (i.e. not tmpfs filesystems) by calling
 * emergency_remount(), which knows how to force the remount to read-only.
 * Unfortunately, that is asynchronous, and just schedules the work and
 * returns.  The best way to determine if it is done is to read /proc/mounts
 * repeatedly until there are no more writable filesystems mounted on
 * block devices.
 */
void emergency_remount_ro(void)
{
    int fd, cnt = 0;

    sync();

    /* Trigger the remount of the filesystems as read-only,
     * which also marks them clean.
     */
    fd = open("/proc/sysrq-trigger", O_WRONLY|O_CLOEXEC);
    if (fd < 0) {
        return;
    }
    write(fd, "u", 1);
    close(fd);


    /* Now poll /proc/mounts till it's done */
    while (!remount_ro_done() && (cnt < 3600)) {
        usleep(100000);
        cnt++;
    }

    return;
}
Пример #2
0
/* Remounting filesystems read-only is difficult when there are files
 * opened for writing or pending deletes on the filesystem.  There is
 * no way to force the remount with the mount(2) syscall.  The magic sysrq
 * 'u' command does an emergency remount read-only on all writable filesystems
 * that have a block device (i.e. not tmpfs filesystems) by calling
 * emergency_remount(), which knows how to force the remount to read-only.
 * Unfortunately, that is asynchronous, and just schedules the work and
 * returns.  The best way to determine if it is done is to read /proc/mounts
 * repeatedly until there are no more writable filesystems mounted on
 * block devices.
 */
static void remount_ro(void)
{
    int fd, cnt = 0;

    /* Trigger the remount of the filesystems as read-only,
     * which also marks them clean.
     */
    fd = open("/proc/sysrq-trigger", O_WRONLY);
    if (fd < 0) {
        return;
    }
    write(fd, "u", 1);
    close(fd);


    /* Now poll /proc/mounts till it's done */
#ifdef STE_HARDWARE
    while (!remount_ro_done() && (cnt < 50)) {
#else
    while (!remount_ro_done() && (cnt < 3600)) {
#endif
        usleep(100000);
        cnt++;
    }

    return;
}


int android_reboot(int cmd, int flags, char *arg)
{
    int ret = 0;
    int reason = -1;

#ifdef RECOVERY_PRE_COMMAND
    if (cmd == (int) ANDROID_RB_RESTART2) {
        if (arg && strlen(arg) > 0) {
            char cmd[PATH_MAX];
            sprintf(cmd, RECOVERY_PRE_COMMAND " %s", arg);
            system(cmd);
        }
    }
#endif

    sync();
    remount_ro();

    switch (cmd) {
        case ANDROID_RB_RESTART:
            reason = RB_AUTOBOOT;
            break;

        case ANDROID_RB_POWEROFF:
            ret = reboot(RB_POWER_OFF);
            return ret;

        case ANDROID_RB_RESTART2:
            // REBOOT_MAGIC
            break;

        default:
            return -1;
    }

#ifdef RECOVERY_PRE_COMMAND_CLEAR_REASON
    reason = RB_AUTOBOOT;
#endif

    if (reason != -1)
        ret = reboot(reason);
    else
        ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                           LINUX_REBOOT_CMD_RESTART2, arg);

    return ret;
}