wolfcw / libfaketime

libfaketime modifies the system time for a single application
https://github.com/wolfcw/libfaketime
GNU General Public License v2.0
2.62k stars 319 forks source link

Dynamic change of FAKETIME is not taking effect #471

Open faayizm opened 1 month ago

faayizm commented 1 month ago

I configured the FAKETIME environment variable to

FAKETIME="+0 x2"

Then started by program in background. In the middle i changed the environment variable to

FAKETIME="+0 x10"

But still my SW is running at 2x speed not 10x speed.

I set the FAKETIME_NO_CACHE=1 to avoid caching.

wolfcw commented 1 month ago

My first guess is that changes made to the environment variable are not picked up by programs sent into the background previously. Have you tried, e.g., with FAKETIME_TIMESTAMP_FILE?

Other than that, FAKETIME_XRESET might be worth experimenting with here.

faayizm commented 1 month ago

Hi thanks for the quick reply. I tried using /etc/faketimerc. It is picking up dynamically It is working fine for sleep But not working for createtimerfd which will trigger timer expiry event.

faayizm commented 1 month ago

Below is the program which is not working when the value in /etc/faketimerc is changed during run time.

I disabled cache, enabled XRESET.

Any input would be really helpful.

Thanks

include

include

include

include

include <sys/timerfd.h>

include <sys/epoll.h>

include

define TIMER_INTERVAL_SEC 10

void print_current_utc_time() { struct timespec ts; struct tm *utc_time; char time_str[100];

clock_gettime(CLOCK_REALTIME, &ts);
time_t now = ts.tv_sec;
utc_time = gmtime(&now);
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", utc_time);
printf("Timer event occurred. Current UTC time: %s\n", time_str);

}

int main() { int timer_fd; struct itimerspec timer_spec; struct epoll_event event; int epoll_fd;

// Create a timer file descriptor
timer_fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timer_fd == -1) {
    perror("timerfd_create");
    return EXIT_FAILURE;
}

// Set up the timer to expire periodically
timer_spec.it_interval.tv_sec = TIMER_INTERVAL_SEC;
timer_spec.it_interval.tv_nsec = 0;
timer_spec.it_value.tv_sec = TIMER_INTERVAL_SEC;
timer_spec.it_value.tv_nsec = 0;

if (timerfd_settime(timer_fd, 0, &timer_spec, NULL) == -1) {
    perror("timerfd_settime");
    close(timer_fd);
    return EXIT_FAILURE;
}

// Create an epoll instance
epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
    perror("epoll_create1");
    close(timer_fd);
    return EXIT_FAILURE;
}

// Add the timer file descriptor to the epoll instance
event.events = EPOLLIN;
event.data.fd = timer_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, timer_fd, &event) == -1) {
    perror("epoll_ctl");
    close(timer_fd);
    close(epoll_fd);
    return EXIT_FAILURE;
}

printf("Timer started. Press Ctrl+C to exit.\n");

// Main event loop
while (1) {
    int num_events = epoll_wait(epoll_fd, &event, 1, -1);
    if (num_events == -1) {
        perror("epoll_wait");
        break;
    }

    if (num_events > 0 && event.events & EPOLLIN) {
        // Timer event occurred, read from the timer file descriptor to clear the event
        uint64_t expirations;
        ssize_t bytes_read = read(timer_fd, &expirations, sizeof(expirations));
        if (bytes_read == -1) {
            perror("read");
            break;
        }

        // Print the current UTC time
        print_current_utc_time();

        // Add your code to handle the timer event here
    }
}

// Clean up
close(timer_fd);
close(epoll_fd);

return EXIT_SUCCESS;

}

wolfcw commented 1 month ago

libfaketime does not keep track of opened files, created timers, and so on. If you call timerfd_settime also in your "Main event loop", changes to the speed factor will be picked up as you expect.

faayizm commented 1 month ago

Understood, it is working now.

Thanks