[systemd-devel] [PATCH] timedated: gather timezone from /etc/localtime sym target

Lennart Poettering lennart at poettering.net
Wed Aug 8 09:51:40 PDT 2012


On Tue, 07.08.12 00:31, Shawn Landen (shawnlandden at gmail.com) wrote:

> keep other method for now, consider dropping later.
> 
> Supporting relative links here could be problematic as timezones in
> /usr/share/zoneinfo are often themselves symlinks (and symlinks to
> symlinks), so this implamentation only only support absolute links.

Hmm, I am not entirely sure this is really the best thing to do. Always
requiring a symlink for /etc/localtime breaks a couple of things: we
can't just bind mount things over in an nspawn container, embedded
devices have to ship /usr/share/zoneinfo/, which is probably something
they might want to avoid.

So, dunno, I think this is something to think about first, discuss the
pros and cons. I see that just having this as symlink is much simpler,
no doubt, but does it have more benefits? And possibly more
disadvantages?

Lennart

> ---
>  src/timedate/timedated.c |   28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
> index 09fd808..456e409 100644
> --- a/src/timedate/timedated.c
> +++ b/src/timedate/timedated.c
> @@ -24,6 +24,7 @@
>  #include <errno.h>
>  #include <string.h>
>  #include <unistd.h>
> +#include <sys/stat.h>
>  
>  #include "util.h"
>  #include "strv.h"
> @@ -174,9 +175,35 @@ static void verify_timezone(void) {
>  
>  static int read_data(void) {
>          int r;
> +        struct stat st;
>  
>          free_data();
>  
> +        r = lstat("/etc/localtime", &st);
> +        if (r < 0) {
> +                log_warning("lstat() of %s failed: %m", "/etc/localtime");
> +        } else if (!S_ISLNK(st.st_mode)) {
> +                log_warning("/etc/localtime should be an absolute symlink to a timezone data file in /usr/share/zoneinfo/");
> +        } else {
> +                char *t;
> +
> +                r = readlink_malloc("/etc/localtime", &t);
> +                if (r < 0) {
> +                        log_warning("Failed to get target of %s: %m", "/etc/localtime");
> +                } else if (!startswith(t, "/usr/share/zoneinfo/")) {
> +                        log_warning("/etc/localtime should be an absolute symlink to a timezone data file in /usr/share/zoneinfo/");
> +                } else {
> +                        tz.zone = strdup(t + strlen("/usr/share/zoneinfo/"));
> +                        free(t);
> +                        if (!tz.zone)
> +                                return log_oom();
> +
> +                        goto have_timezone;
> +                }
> +
> +                free(t);
> +        }
> +
>          r = read_one_line_file("/etc/timezone", &tz.zone);
>          if (r < 0) {
>                  if (r != -ENOENT)
> @@ -192,6 +219,7 @@ static int read_data(void) {
>  #endif
>          }
>  
> +have_timezone:
>          if (isempty(tz.zone)) {
>                  free(tz.zone);
>                  tz.zone = NULL;


Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the systemd-devel mailing list