Integrating timedatectl//systemd-timesyncd with readonly root file system


One of the requirements in my project is to change timezone of the system. I am using timedatectl to achieve this.

My file system being read only I am unable to change the timezone on the device.

-rw-r--r-- 1 root root    10 Jul 17 21:48 timezone
lrwxrwxrwx 1 root root    29 Jul 17 21:48 localtime -> /usr/share/zoneinfo/Universal
-rw-r--r-- 1 root root    15 Aug 14 22:08 timestamp

Should I just create a symlink for timezone and timestamp ?

Edit1: I am currently looking at

I think they are facing somewhat similar situation. But they are suggesting to create a symlink of /etc/localtime as well. Which I don’t understand?

That is how I would start but it’s always a bit of trial and error to figure out everything that needs to be moved.

I haven’t tried this myself so I don’t have a definite answer though. Please let us know what you find.


meaning just create a symlink of timezone and timestamp?

I was able to create a symlink for localtime and timezone by editing the tzdata recipe file. But I am still unable to change the timezone.

Any suggestions?

@drewmoseley how do people change timezone on a read-only file system?

I don’t know. I can’t say I’ve ever tried that.

So I think. I know what the issue might be. The file timedated.c actually looks for \etc\localtime it read and writes using that file specifically. So I think irrespective of what symlink I create I will not be able to change the timezone unless I change that link in the c file. But I have some trouble understanding the c file

static int context_read_data(Context *c) {
        _cleanup_free_ char *t = NULL;
        int r;


        r = get_timezone(&t);
        if (r == -EINVAL)
                log_warning_errno(r, "/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
        else if (r < 0)
                log_warning_errno(r, "Failed to get target of /etc/localtime: %m");

        free_and_replace(c->zone, t);

        c->local_rtc = clock_is_localtime(NULL) > 0;

        return 0;

Where is the function get_timezone() defined?

I assume that is a standard system function provided by the C library or some such.
One possibility may be to use a bind mount of /etc/localtime into the /data partition. I have not tried it myself but that may work:

# mount -t bind /data/localtime /etc/localtime

And then /data/localtime is the symlink to the file in /usr/share/zoneinfo.


See this link for a discussion in the Yocto community about this.

I recently saw this link. But your method sounds less painful

So based on that link. I did create a volatile bind.
VOLATILE_BINDS ?= "\ /data/system/localtime /etc/localtime \ n\ "
I do see
/data/system/localtime -> /usr/share/zoneinfo/Universal But I am still unable to use timedatectl set-timezone "America/New_York"

Still the same error:
Failed to set timezone: failed to set timezone: Read only file system

So I am able to change the timezone. But my date command is still in UTC?

root@raspberrypi-cm3:~# timedatectl
               Local time: Fri 2020-08-21 17:55:02 EDT
           Universal time: Fri 2020-08-21 21:55:02 UTC
                 RTC time: Fri 2020-08-21 21:55:03
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
root@raspberrypi-cm3:~# date
Fri Aug 21 21:55:16 UTC 2020

Any help or pointers why this could be happening?

That’s just how the date command works. It does respect the TZ environment variable:

$ TZ=America/New_York date
Sat Aug 22 17:07:31 EDT 2020
$ TZ=America/Los_Angeles date
Sat Aug 22 14:07:44 PDT 2020

More details:

But that was not how my system was behaving before the read-only rootfs.
Below is an example of the system. That does not have a read-only rootfs

root@raspberrypi-cm3:~# date
Mon Aug 24 08:23:46 CDT 2020
root@raspberrypi-cm3:~# timedatectl
               Local time: Mon 2020-08-24 08:23:52 CDT
           Universal time: Mon 2020-08-24 13:23:52 UTC
                 RTC time: Mon 2020-08-24 13:23:53
                Time zone: America/Chicago (CDT, -0500)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

The problem with exporting TZ is I can execute it from a script. As it does not make a global change

FYI I am using this link as template

I got it working thanks a lot for all the help :slight_smile:

1 Like

@thesillywhat could you please share a solution for your problem? I’m facing the same issue now and do not want to reinvent the wheel… Thanks!

Look at the link in my comment above. I have currently marked that particular link as a solution.
Also please let me know if you have found a better way