Preserving time across A20-OLinuXino-LIME2 reboots

Started by bitwelder, November 15, 2014, 11:45:52 AM

Previous topic - Next topic

bitwelder

Hello,

I'm planning to replace my miniserver running on Cubieboard with a LIME2 board.
The unit runs on SDD, OS is Debian.

One issue I had with Cubieboard is that it doesn't have a battery-backup clock, and that was annoying with system reboots.

What should I do on the LIME2, should I add a MOD-RTC or would adding a LiPo battery work as well (although, I'd prefer to have just a button-battery cell) ?

Thanks

MBR

The easies way is to install fake-hwclock (it's a Debian package too), which stores the current time on a shutdown and restores it back on a poweron. This makes time at least monotonical (no "timeskips" back to 1970), which get rid of constant filesystem "modification in future" checks (this is probably the thing what you want). And if you are connected to Internet, it's makes easier to synchronize clock with ntpd or ntpdate (I reccomend to install them both). Use the RTC module only for a stand-alone system, not connected to network/Internet, or when you need the correct clock from the very begining (e.g. before connecting to the network). You can use a GPS module as a clocksource (with one second accuracy) too, some of them even have their own RTC with a battery/supercapacitor backup.

bitwelder

Thanks.
Good point about using fake-hwclock, which I found already installed in the Olimex image with Debian.
In the Cubieboard case I experience some weird lockups (or anyway the board is no longer accessible from ethernet, and I have no serial console available to check its status), so perhaps if that will still happen on the Olinuxino I should try to save the current time e.g. once per day.

MBR

Probably the easiest way is to put a script with fake-hwclock save to /etc/cron.d/ .

Also, if you want to store time but still have read-only filesystem, you can use my little program, which can store the time (as binary number) not only in a file, but in a block device at specified offset, for example between the partition table and firts partition (offset between 512 and 32255-sizeof(time_t)).


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

int main(int argc,char *argv[])
{
  char rw;
  long long int offset=0;
  FILE *f;
  time_t mytime;

  if (argc<3)
  {
    printf("Reads/writes system time from/to file or device at specified offset (default 0)\n"
           "Usage: %s <r(ead)|w(rite)> <file/device> [offset]\n",argv[0]);

    return(0);
  }

  rw=tolower(argv[1][0]);

  if ((rw!='r') && (rw!='w'))
  {
    fprintf(stderr,"First character of first argument must be either 'r' or 'w'\n");
    return(1);
  }

  if (argc>3)
  {
    offset=strtoll(argv[3],NULL,10);

    if (offset<0)
    {
      fprintf(stderr,"Offset cannot be negative (%lld)\n",offset);
      return(1);
    }
  }


  if (rw=='r')
  {
    if (offset!=0)
    {
      printf("Reading system time from '%s' (offset %lld)\n",argv[2],offset);
    }
    else
    {
      printf("Reading system time from '%s'\n",argv[2]);
    }

    if ((f=fopen(argv[2],"r"))==NULL)
    {
      perror("Cannot open file");
      return(1);
    }

    if (fseeko(f,offset,SEEK_SET)!=0)
    {
      perror("Cannot seek to offset");
      return(1);
    }

    if (fread(&mytime,1,sizeof(mytime),f)!=sizeof(mytime))
    {
      perror("Cannot read from file");
      return(1);
    }

    fclose(f);

    if (stime(&mytime)==0)
    {
      printf("Time set: %s",ctime(&mytime));
    }
    else
    {
      printf("Time read: %s",ctime(&mytime));
      perror("Cannot set system time");
    }
  }
  else
  {
    if (offset!=0)
    {
      printf("Writting system time to '%s' (offset %lld)\n",argv[2],offset);
    }
    else
    {
      printf("Writting system time to '%s'\n",argv[2]);
    }

    time(&mytime);

    if ((f=fopen(argv[2],"r+"))==NULL)
    {
      perror("Cannot open file");
      return(1);
    }

    if (fseeko(f,offset,SEEK_SET)!=0)
    {
      perror("Cannot seek to offset");
      return(1);
    }

    if (fwrite(&mytime,1,sizeof(mytime),f)!=sizeof(mytime))
    {
      perror("Cannot write to file");
      return(1);
    }

    fclose(f);

    printf("Time written: %s",ctime(&mytime));

  }

  return(0);
}