Merge pull request #14010 from poettering/localtime-symlink

tweaks to /etc/localtime management
This commit is contained in:
Lennart Poettering
2019-11-13 16:38:41 +01:00
committed by GitHub
3 changed files with 36 additions and 15 deletions
-3
View File
@@ -30,9 +30,6 @@ Before v244:
Features:
* localed: if UTC is selected but timezone file for it doesn't exist, delete
/etc/localtime instead of creating a symlink
* socket units: allow creating a udev monitor socket with ListenDevices= or so,
with matches, then actviate app thorugh that passing socket oveer
+11 -2
View File
@@ -1391,13 +1391,22 @@ bool clock_supported(clockid_t clock) {
}
}
int get_timezone(char **tz) {
int get_timezone(char **ret) {
_cleanup_free_ char *t = NULL;
const char *e;
char *z;
int r;
r = readlink_malloc("/etc/localtime", &t);
if (r == -ENOENT) {
/* If the symlink does not exist, assume "UTC", like glibc does*/
z = strdup("UTC");
if (!z)
return -ENOMEM;
*ret = z;
return 0;
}
if (r < 0)
return r; /* returns EINVAL if not a symlink */
@@ -1412,7 +1421,7 @@ int get_timezone(char **tz) {
if (!z)
return -ENOMEM;
*tz = z;
*ret = z;
return 0;
}
+25 -10
View File
@@ -277,20 +277,35 @@ static int context_read_data(Context *c) {
static int context_write_data_timezone(Context *c) {
_cleanup_free_ char *p = NULL;
const char *source;
assert(c);
if (isempty(c->zone)) {
if (unlink("/etc/localtime") < 0 && errno != ENOENT)
return -errno;
return 0;
/* No timezone is very similar to UTC. Hence in either of these cases link the UTC file in. Except if
* it isn't installed, in which case we remove the symlink altogether. Since glibc defaults to an
* internal version of UTC in that case behaviour is mostly equivalent. We still prefer creating the
* symlink though, since things are more self explanatory then. */
if (isempty(c->zone) || streq(c->zone, "UTC")) {
if (access("/usr/share/zoneinfo/UTC", F_OK) < 0) {
if (unlink("/etc/localtime") < 0 && errno != ENOENT)
return -errno;
return 0;
}
source = "../usr/share/zoneinfo/UTC";
} else {
p = path_join("../usr/share/zoneinfo", c->zone);
if (!p)
return -ENOMEM;
source = p;
}
p = path_join("../usr/share/zoneinfo", c->zone);
if (!p)
return log_oom();
return symlink_atomic(p, "/etc/localtime");
return symlink_atomic(source, "/etc/localtime");
}
static int context_write_data_local_rtc(Context *c) {
@@ -638,7 +653,7 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *
return r;
if (!timezone_is_valid(z, LOG_DEBUG))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid or not installed time zone '%s'", z);
if (streq_ptr(z, c->zone))
return sd_bus_reply_method_return(m, NULL);