VirtualBox

Ticket #11980: 37-save-system-time-to-rtc.patch

File 37-save-system-time-to-rtc.patch, 3.4 KB (added by Sam Morris, 9 years ago)
  • src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp

    old new  
    8686#ifdef RT_OS_WINDOWS
    8787# include <Windows.h>
    8888#else
     89# ifdef RT_OS_LINUX
     90#  include <fcntl.h>
     91#  include <linux/rtc.h>
     92#  include <stdio.h>
     93#  include <stdlib.h>
     94#  include <sys/ioctl.h>
     95#  include <sys/stat.h>
     96#  include <sys/types.h>
     97# endif /* RT_OS_LINUX */
    8998# include <unistd.h>
    9099# include <errno.h>
    91100# include <time.h>
    static void vgsvcTimeSyncCancelAdjust(vo  
    450459#endif /* !RT_OS_WINDOWS */
    451460}
    452461
     462/**
     463 * Updates "hardware" RTC, so that time is correct during early boot.
     464 *
     465 */
     466static void vgsvcTimeSyncSaveToRTC() {
     467#ifdef RT_OS_LINUX
     468    FILE *adjtime_f = NULL;
     469    char *adjtime_line = NULL;
     470    size_t adjtime_buffer_len = 0;
     471    ssize_t adjtime_line_len;
     472    struct tm * (*xtime) (const time_t *) = NULL;
     473    time_t now;
     474    struct tm *now_tm = NULL;
     475    int rtc_fd = -1;
     476
     477    if (!(adjtime_f = fopen("/etc/adjtime", "re")))
     478    {
     479        VGSvcError("vgsvcTimeSyncSaveToRTC: open(/etc/adjtime) failed, error=%d\n", errno);
     480        goto out;
     481    }
     482
     483    getline(&adjtime_line, &adjtime_buffer_len, adjtime_f);
     484    getline(&adjtime_line, &adjtime_buffer_len, adjtime_f);
     485    if ((adjtime_line_len = getline(&adjtime_line, &adjtime_buffer_len, adjtime_f)) == -1) {
     486        VGSvcError("vgsvcTimeSyncSaveToRTC: could not read /etc/adjtime, assuming UTC is in use, error=%d\n", errno);
     487        xtime = &gmtime;
     488    }
     489    else
     490    {
     491        if (adjtime_line[adjtime_line_len-1] == '\n')
     492            adjtime_line[adjtime_line_len-1] = '\0';
     493
     494        if (strcmp(adjtime_line, "LOCAL") == 0)
     495        {
     496            VGSvcVerbose(3, "RTC using local time\n");
     497            xtime = &localtime;
     498        }
     499        else if (strcmp(adjtime_line, "UTC") == 0)
     500        {
     501            VGSvcVerbose(3, "RTC using UTC\n");
     502            xtime = &gmtime;
     503        }
     504        else
     505        {
     506            VGSvcError("vgsvcTimeSyncSaveToRTC: unknown time standard '%s', not setting RTC\n", adjtime_line);
     507            goto out;
     508        }
     509    }
     510
     511    if ((now = time(NULL)) == (time_t)-1)
     512    {
     513        VGSvcError("vgsvcTimeSyncSaveToRTC: time() failed, error=%d\n", errno);
     514        goto out;
     515    }
     516    if (!(now_tm = (*xtime)(&now)))
     517    {
     518        VGSvcError("vgsvcTimeSyncSaveToRTC: {gm|local}time() failed\n");
     519        goto out;
     520    }
     521
     522    if ((rtc_fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC)) == -1)
     523    {
     524        VGSvcError("vgsvcTimeSyncSaveToRTC: open(/dev/rtc) failed, error=%d\n", errno);
     525        goto out;
     526    }
     527
     528    if (ioctl(rtc_fd, RTC_SET_TIME, now_tm) == -1)
     529    {
     530        VGSvcError("vgsvcTimeSyncSaveToRTC: ioctl(RTC_SET_TIME) failed, errno=%d\n", errno);
     531        goto out;
     532    }
     533
     534    VGSvcVerbose(3, "RTC updated\n");
     535
     536out:
     537    close(rtc_fd);
     538    free(adjtime_line);
     539    if (adjtime_f)
     540        fclose(adjtime_f);
     541    return;
     542#endif /* !RT_OS_LINUX */
     543}
     544
    453545
    454546/**
    455547 * Try adjust the time using adjtime or similar.
    DECLCALLBACK(int) vgsvcTimeSyncWorker(bo  
    585677                        vgsvcTimeSyncCancelAdjust();
    586678                        vgsvcTimeSyncSet(&Drift);
    587679                    }
     680                    vgsvcTimeSyncSaveToRTC();
    588681                }
    589682                else
    590683                    vgsvcTimeSyncCancelAdjust();

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy