Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0126e08 authored by Greg Hackmann's avatar Greg Hackmann
Browse files

AlarmManagerService: explain some timerfd_create() failures



When AlarmManagerService is broken, starting the framework fails in
weird and inconsistent ways.  So if we detect your kernel is missing the
required timerfd support, give up immediately and explain why.

Bug: 28357356

Test: manually break timerfd_create syscall, check adb logcat during boot
Change-Id: Iaa153fca38e9cd8e801f3e71c3e1ae2351907828
Signed-off-by: default avatarGreg Hackmann <ghackmann@google.com>
parent d7151c06
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -298,6 +298,32 @@ static int wall_clock_rtc()
    return -1;
}

static void log_timerfd_create_error(clockid_t id)
{
    if (errno == EINVAL) {
        switch (id) {
        case CLOCK_REALTIME_ALARM:
        case CLOCK_BOOTTIME_ALARM:
            ALOGE("kernel missing required commits:");
            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6cffe00f7d4e24679eae6b7aae4caaf915288256");
            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=11ffa9d6065f344a9bd769a2452f26f2f671e5f8");
            LOG_ALWAYS_FATAL("kernel does not support timerfd_create() with alarm timers");
            break;

        case CLOCK_BOOTTIME:
            ALOGE("kernel missing required commit:");
            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4a2378a943f09907fb1ae35c15de917f60289c14");
            LOG_ALWAYS_FATAL("kernel does not support timerfd_create(CLOCK_BOOTTIME)");
            break;

        default:
            break;
        }
    }

    ALOGE("timerfd_create(%u) failed: %s", id, strerror(errno));
}

static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject)
{
    int epollfd;
@@ -313,8 +339,7 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject)
    for (size_t i = 0; i < fds.size(); i++) {
        fds[i] = timerfd_create(android_alarm_to_clockid[i], 0);
        if (fds[i] < 0) {
            ALOGE("timerfd_create(%u) failed: %s",  android_alarm_to_clockid[i],
                    strerror(errno));
            log_timerfd_create_error(android_alarm_to_clockid[i]);
            close(epollfd);
            for (size_t j = 0; j < i; j++) {
                close(fds[j]);