From bbc98d32560cc456531bf254f7b69054921082bd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 May 2012 21:06:55 +0200 Subject: util: split-out hwclock.[ch] --- src/shared/hwclock.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 src/shared/hwclock.c (limited to 'src/shared/hwclock.c') diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c new file mode 100644 index 0000000000..d40bb2653f --- /dev/null +++ b/src/shared/hwclock.c @@ -0,0 +1,228 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010-2012 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "log.h" +#include "strv.h" +#include "hwclock.h" + +static int rtc_open(int flags) { + int fd; + DIR *d; + + /* First, we try to make use of the /dev/rtc symlink. If that + * doesn't exist, we open the first RTC which has hctosys=1 + * set. If we don't find any we just take the first RTC that + * exists at all. */ + + fd = open("/dev/rtc", flags); + if (fd >= 0) + return fd; + + d = opendir("/sys/class/rtc"); + if (!d) + goto fallback; + + for (;;) { + char *p, *v; + struct dirent buf, *de; + int r; + + r = readdir_r(d, &buf, &de); + if (r != 0) + goto fallback; + + if (!de) + goto fallback; + + if (ignore_file(de->d_name)) + continue; + + p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL); + if (!p) { + closedir(d); + return -ENOMEM; + } + + r = read_one_line_file(p, &v); + free(p); + + if (r < 0) + continue; + + r = parse_boolean(v); + free(v); + + if (r <= 0) + continue; + + p = strappend("/dev/", de->d_name); + fd = open(p, flags); + free(p); + + if (fd >= 0) { + closedir(d); + return fd; + } + } + +fallback: + if (d) + closedir(d); + + fd = open("/dev/rtc0", flags); + if (fd < 0) + return -errno; + + return fd; +} + +int hwclock_get_time(struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + /* This leaves the timezone fields of struct tm + * uninitialized! */ + if (ioctl(fd, RTC_RD_TIME, tm) < 0) + err = -errno; + + /* We don't know daylight saving, so we reset this in order not + * to confused mktime(). */ + tm->tm_isdst = -1; + + close_nointr_nofail(fd); + + return err; +} + +int hwclock_set_time(const struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, RTC_SET_TIME, tm) < 0) + err = -errno; + + close_nointr_nofail(fd); + + return err; +} +int hwclock_is_localtime(void) { + FILE *f; + bool local = false; + + /* + * The third line of adjtime is "UTC" or "LOCAL" or nothing. + * # /etc/adjtime + * 0.0 0 0 + * 0 + * UTC + */ + f = fopen("/etc/adjtime", "re"); + if (f) { + char line[LINE_MAX]; + bool b; + + b = fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f); + + fclose(f); + + if (!b) + return -EIO; + + truncate_nl(line); + local = streq(line, "LOCAL"); + + } else if (errno != -ENOENT) + return -errno; + + return local; +} + +int hwclock_apply_localtime_delta(int *min) { + const struct timeval *tv_null = NULL; + struct timespec ts; + struct tm *tm; + int minuteswest; + struct timezone tz; + + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + assert_se(tm = localtime(&ts.tv_sec)); + minuteswest = tm->tm_gmtoff / 60; + + tz.tz_minuteswest = -minuteswest; + tz.tz_dsttime = 0; /* DST_NONE*/ + + /* + * If the hardware clock does not run in UTC, but in local time: + * The very first time we set the kernel's timezone, it will warp + * the clock so that it runs in UTC instead of local time. + */ + if (settimeofday(tv_null, &tz) < 0) + return -errno; + if (min) + *min = minuteswest; + return 0; +} + +int hwclock_reset_localtime_delta(void) { + const struct timeval *tv_null = NULL; + struct timezone tz; + + tz.tz_minuteswest = 0; + tz.tz_dsttime = 0; /* DST_NONE*/ + + if (settimeofday(tv_null, &tz) < 0) + return -errno; + + return 0; +} -- cgit v1.2.3-54-g00ecf From b7def684941808600c344f0be7a2b9fcdda97e0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2012 13:41:01 +0200 Subject: util: rename join() to strjoin() This is to match strappend() and the other string related functions. --- TODO | 4 ++++ src/cgtop/cgtop.c | 2 +- src/core/cgroup.c | 4 ++-- src/core/dbus-manager.c | 2 +- src/core/load-dropin.c | 6 +++--- src/core/manager.c | 4 ++-- src/core/mount.c | 2 +- src/core/service.c | 14 +++++++------- src/core/unit.c | 4 ++-- src/cryptsetup/cryptsetup-generator.c | 10 +++++----- src/delta/delta.c | 4 ++-- src/fstab-generator/fstab-generator.c | 16 ++++++++-------- src/getty-generator/getty-generator.c | 2 +- src/journal/coredump.c | 4 ++-- src/journal/journald.c | 4 ++-- src/journal/sd-journal.c | 10 +++++----- src/shared/cgroup-util.c | 10 +++++----- src/shared/conf-parser.c | 2 +- src/shared/hwclock.c | 2 +- src/shared/path-util.c | 2 +- src/shared/unit-name.c | 4 ++-- src/shared/util.c | 4 ++-- src/shared/util.h | 2 +- src/tmpfiles/tmpfiles.c | 2 +- 24 files changed, 62 insertions(+), 58 deletions(-) (limited to 'src/shared/hwclock.c') diff --git a/TODO b/TODO index 25266b2845..c0a553bf82 100644 --- a/TODO +++ b/TODO @@ -34,6 +34,10 @@ Bugfixes: Features: +* logind: wakelock/opportunistic suspend support + +* seccomp filters for services + * replace BindTo= by BindsTo=, but keep old name for compat * switch-root: sockets need relabelling diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index f988adb363..5557094a4f 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -310,7 +310,7 @@ static int refresh_one( if (r <= 0) goto finish; - p = join(path, "/", fn, NULL); + p = strjoin(path, "/", fn, NULL); free(fn); if (!p) { diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5513f6560c..aaea96b820 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -120,7 +120,7 @@ int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffi assert(pid >= 0); if (cgroup_suffix) { - p = join(b->path, "/", cgroup_suffix, NULL); + p = strjoin(b->path, "/", cgroup_suffix, NULL); if (!p) return -ENOMEM; @@ -208,7 +208,7 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, bool rem, Set * return 0; if (cgroup_suffix) { - p = join(b->path, "/", cgroup_suffix, NULL); + p = strjoin(b->path, "/", cgroup_suffix, NULL); if (!p) return -ENOMEM; diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index f8a5400055..67b7b13eac 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1179,7 +1179,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, else { char *p; - p = join(switch_root, "/", switch_root_init, NULL); + p = strjoin(switch_root, "/", switch_root_init, NULL); if (!p) goto oom; diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index 4323147a01..86f81c7484 100644 --- a/src/core/load-dropin.c +++ b/src/core/load-dropin.c @@ -51,7 +51,7 @@ static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { if (ignore_file(de->d_name)) continue; - f = join(path, "/", de->d_name, NULL); + f = strjoin(path, "/", de->d_name, NULL); if (!f) { r = -ENOMEM; goto finish; @@ -80,7 +80,7 @@ static int process_dir(Unit *u, const char *unit_path, const char *name, const c assert(name); assert(suffix); - path = join(unit_path, "/", name, suffix, NULL); + path = strjoin(unit_path, "/", name, suffix, NULL); if (!path) return -ENOMEM; @@ -102,7 +102,7 @@ static int process_dir(Unit *u, const char *unit_path, const char *name, const c if (!template) return -ENOMEM; - path = join(unit_path, "/", template, suffix, NULL); + path = strjoin(unit_path, "/", template, suffix, NULL); free(template); if (!path) diff --git a/src/core/manager.c b/src/core/manager.c index 7bd484be6c..8f2635051e 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -590,7 +590,7 @@ static void manager_build_unit_path_cache(Manager *m) { if (ignore_file(de->d_name)) continue; - p = join(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL); + p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL); if (!p) { r = -ENOMEM; goto fail; @@ -2085,7 +2085,7 @@ static int create_generator_dir(Manager *m, char **generator, const char *name) return r; } } else { - p = join("/tmp/systemd-", name, ".XXXXXX", NULL); + p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL); if (!p) { log_error("Out of memory"); return -ENOMEM; diff --git a/src/core/mount.c b/src/core/mount.c index fab922ea9e..15d5f21530 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1534,7 +1534,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { goto clean_up; } - o = join(options, ",", options2, NULL); + o = strjoin(options, ",", options2, NULL); if (!o) { r = -ENOMEM; goto finish; diff --git a/src/core/service.c b/src/core/service.c index e57b0e970c..2be6ee5d99 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -722,7 +722,7 @@ static int service_load_sysv_path(Service *s, const char *path) { char *d = NULL; if (chkconfig_description) - d = join(chkconfig_description, " ", j, NULL); + d = strjoin(chkconfig_description, " ", j, NULL); else d = strdup(j); @@ -879,7 +879,7 @@ static int service_load_sysv_path(Service *s, const char *path) { char *d = NULL; if (long_description) - d = join(long_description, " ", t, NULL); + d = strjoin(long_description, " ", t, NULL); else d = strdup(j); @@ -1001,7 +1001,7 @@ static int service_load_sysv_name(Service *s, const char *name) { char *path; int r; - path = join(*p, "/", name, NULL); + path = strjoin(*p, "/", name, NULL); if (!path) return -ENOMEM; @@ -1023,7 +1023,7 @@ static int service_load_sysv_name(Service *s, const char *name) { if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { /* Try SUSE style boot.* init scripts */ - path = join(*p, "/boot.", name, NULL); + path = strjoin(*p, "/boot.", name, NULL); if (!path) return -ENOMEM; @@ -1038,7 +1038,7 @@ static int service_load_sysv_name(Service *s, const char *name) { if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { /* Try Frugalware style rc.* init scripts */ - path = join(*p, "/rc.", name, NULL); + path = strjoin(*p, "/rc.", name, NULL); if (!path) return -ENOMEM; @@ -3407,7 +3407,7 @@ static int service_enumerate(Manager *m) { struct dirent *de; free(path); - path = join(*p, "/", rcnd_table[i].path, NULL); + path = strjoin(*p, "/", rcnd_table[i].path, NULL); if (!path) { r = -ENOMEM; goto finish; @@ -3442,7 +3442,7 @@ static int service_enumerate(Manager *m) { continue; free(fpath); - fpath = join(path, "/", de->d_name, NULL); + fpath = strjoin(path, "/", de->d_name, NULL); if (!fpath) { r = -ENOMEM; goto finish; diff --git a/src/core/unit.c b/src/core/unit.c index 37711afeaf..516f4fad8b 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1891,10 +1891,10 @@ static char *default_cgroup_path(Unit *u) { if (!t) return NULL; - p = join(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL); + p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL); free(t); } else - p = join(u->manager->cgroup_hierarchy, "/", u->id, NULL); + p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL); return p; } diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index f714c8c241..7801de64b5 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -88,7 +88,7 @@ static int create_disk( goto fail; } - p = join(arg_dest, "/", n, NULL); + p = strjoin(arg_dest, "/", n, NULL); if (!p) { r = -ENOMEM; log_error("Failed to allocate unit file name."); @@ -175,7 +175,7 @@ static int create_disk( if (!noauto) { - to = join(arg_dest, "/", d, ".wants/", n, NULL); + to = strjoin(arg_dest, "/", d, ".wants/", n, NULL); if (!to) { r = -ENOMEM; goto fail; @@ -191,9 +191,9 @@ static int create_disk( free(to); if (!nofail) - to = join(arg_dest, "/cryptsetup.target.requires/", n, NULL); + to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL); else - to = join(arg_dest, "/cryptsetup.target.wants/", n, NULL); + to = strjoin(arg_dest, "/cryptsetup.target.wants/", n, NULL); if (!to) { r = -ENOMEM; goto fail; @@ -211,7 +211,7 @@ static int create_disk( } e = unit_name_escape(name); - to = join(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL); + to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL); if (!to) { r = -ENOMEM; goto fail; diff --git a/src/delta/delta.c b/src/delta/delta.c index 01c6335315..eef6536b01 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -192,7 +192,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { if (!dirent_is_file(de)) continue; - p = join(path, "/", de->d_name, NULL); + p = strjoin(path, "/", de->d_name, NULL); if (!p) { r = -ENOMEM; goto finish; @@ -254,7 +254,7 @@ static int process_suffix(const char *prefixes, const char *suffix) { NULSTR_FOREACH(p, prefixes) { char *t; - t = join(p, "/", suffix, NULL); + t = strjoin(p, "/", suffix, NULL); if (!t) { r = -ENOMEM; goto finish; diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index f832730b40..3a59b85d66 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -103,7 +103,7 @@ static int add_swap(const char *what, struct mntent *me) { goto finish; } - unit = join(arg_dest, "/", name, NULL); + unit = strjoin(arg_dest, "/", name, NULL); if (!unit) { log_error("Out of memory"); r = -ENOMEM; @@ -146,7 +146,7 @@ static int add_swap(const char *what, struct mntent *me) { } if (!noauto) { - lnk = join(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); + lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL); if (!lnk) { log_error("Out of memory"); r = -ENOMEM; @@ -169,7 +169,7 @@ static int add_swap(const char *what, struct mntent *me) { if (r > 0) { free(lnk); - lnk = join(arg_dest, "/", device, ".wants/", name, NULL); + lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); if (!lnk) { log_error("Out of memory"); r = -ENOMEM; @@ -261,7 +261,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) { goto finish; } - unit = join(arg_dest, "/", name, NULL); + unit = strjoin(arg_dest, "/", name, NULL); if (!unit) { log_error("Out of memory"); r = -ENOMEM; @@ -321,7 +321,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) { } if (!noauto) { - lnk = join(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); + lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL); if (!lnk) { log_error("Out of memory"); r = -ENOMEM; @@ -347,7 +347,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) { if (r > 0) { free(lnk); - lnk = join(arg_dest, "/", device, ".wants/", name, NULL); + lnk = strjoin(arg_dest, "/", device, ".wants/", name, NULL); if (!lnk) { log_error("Out of memory"); r = -ENOMEM; @@ -372,7 +372,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) { goto finish; } - automount_unit = join(arg_dest, "/", automount_name, NULL); + automount_unit = strjoin(arg_dest, "/", automount_name, NULL); if (!automount_unit) { log_error("Out of memory"); r = -ENOMEM; @@ -408,7 +408,7 @@ static int add_mount(const char *what, const char *where, struct mntent *me) { } free(lnk); - lnk = join(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL); + lnk = strjoin(arg_dest, "/", post, nofail ? ".wants/" : ".requires/", automount_name, NULL); if (!lnk) { log_error("Out of memory"); r = -ENOMEM; diff --git a/src/getty-generator/getty-generator.c b/src/getty-generator/getty-generator.c index bb7c225e02..b2e3eb6393 100644 --- a/src/getty-generator/getty-generator.c +++ b/src/getty-generator/getty-generator.c @@ -39,7 +39,7 @@ static int add_symlink(const char *fservice, const char *tservice) { assert(tservice); from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice); - to = join(arg_dest,"/getty.target.wants/", tservice, NULL); + to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL); if (!from || !to) { log_error("Out of memory"); diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 300677bb92..fcd0d1e625 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -213,14 +213,14 @@ int main(int argc, char* argv[]) { IOVEC_SET_STRING(iovec[j++], core_cmdline); } - core_timestamp = join("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL); + core_timestamp = strjoin("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL); if (core_timestamp) IOVEC_SET_STRING(iovec[j++], core_timestamp); IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); IOVEC_SET_STRING(iovec[j++], "PRIORITY=2"); - core_message = join("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL); + core_message = strjoin("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL); if (core_message) IOVEC_SET_STRING(iovec[j++], core_message); diff --git a/src/journal/journald.c b/src/journal/journald.c index 2402f7f6d0..fd292f019e 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -1976,7 +1976,7 @@ static int system_journal_open(Server *s) { (void) mkdir(fn, 0755); free(fn); - fn = join("/var/log/journal/", ids, "/system.journal", NULL); + fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL); if (!fn) return -ENOMEM; @@ -2002,7 +2002,7 @@ static int system_journal_open(Server *s) { if (!s->runtime_journal && (s->storage != STORAGE_NONE)) { - fn = join("/run/log/journal/", ids, "/system.journal", NULL); + fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL); if (!fn) return -ENOMEM; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 4bcc65c5c7..57572d4f01 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -313,7 +313,7 @@ static char *match_make_string(Match *m) { } if (p) { - k = join(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL); + k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL); free(p); free(t); @@ -330,7 +330,7 @@ static char *match_make_string(Match *m) { } if (enclose) { - r = join("(", p, ")", NULL); + r = strjoin("(", p, ")", NULL); free(p); return r; } @@ -1101,7 +1101,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { (startswith(filename, "system@") && endswith(filename, ".journal")))) return 0; - path = join(prefix, "/", filename, NULL); + path = strjoin(prefix, "/", filename, NULL); if (!path) return -ENOMEM; @@ -1149,7 +1149,7 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) assert(prefix); assert(filename); - path = join(prefix, "/", filename, NULL); + path = strjoin(prefix, "/", filename, NULL); if (!path) return -ENOMEM; @@ -1184,7 +1184,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) !sd_id128_equal(id, mid))) return 0; - path = join(prefix, "/", dirname, NULL); + path = strjoin(prefix, "/", dirname, NULL); if (!path) return -ENOMEM; diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 6740d3b885..b0d378de5a 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -522,16 +522,16 @@ static int join_path(const char *controller, const char *path, const char *suffi if (controller) { if (path && suffix) - t = join("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); else if (path) - t = join("/sys/fs/cgroup/", controller, "/", path, NULL); + t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL); else if (suffix) - t = join("/sys/fs/cgroup/", controller, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL); else - t = join("/sys/fs/cgroup/", controller, NULL); + t = strjoin("/sys/fs/cgroup/", controller, NULL); } else { if (path && suffix) - t = join(path, "/", suffix, NULL); + t = strjoin(path, "/", suffix, NULL); else if (path) t = strdup(path); } diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 8c62fb959b..1eccec5989 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -90,7 +90,7 @@ int config_item_perf_lookup( else { char *key; - key = join(section, ".", lvalue, NULL); + key = strjoin(section, ".", lvalue, NULL); if (!key) return -ENOMEM; diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index d40bb2653f..9f8ab08e2b 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -74,7 +74,7 @@ static int rtc_open(int flags) { if (ignore_file(de->d_name)) continue; - p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL); + p = strjoin("/sys/class/rtc/", de->d_name, "/hctosys", NULL); if (!p) { closedir(d); return -ENOMEM; diff --git a/src/shared/path-util.c b/src/shared/path-util.c index ccd7667608..8bc7955020 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -120,7 +120,7 @@ char *path_make_absolute(const char *p, const char *prefix) { if (path_is_absolute(p) || !prefix) return strdup(p); - return join(prefix, "/", p, NULL); + return strjoin(prefix, "/", p, NULL); } char *path_make_absolute_cwd(const char *p) { diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c index 3e437b77a1..fcf5902c78 100644 --- a/src/shared/unit-name.c +++ b/src/shared/unit-name.c @@ -208,7 +208,7 @@ char *unit_name_build(const char *prefix, const char *instance, const char *suff if (!instance) return strappend(prefix, suffix); - return join(prefix, "@", instance, suffix, NULL); + return strjoin(prefix, "@", instance, suffix, NULL); } static char *do_escape_char(char c, char *t) { @@ -425,7 +425,7 @@ char *unit_name_from_path_instance(const char *prefix, const char *path, const c if (!p) return NULL; - r = join(prefix, "@", p, suffix, NULL); + r = strjoin(prefix, "@", p, suffix, NULL); free(p); return r; diff --git a/src/shared/util.c b/src/shared/util.c index 63471899fd..2aabd8d634 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1083,7 +1083,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * if (h < 0) return h; - r = join("[", t, "]", NULL); + r = strjoin("[", t, "]", NULL); free(t); if (!r) @@ -5145,7 +5145,7 @@ finish: return r; } -char *join(const char *x, ...) { +char *strjoin(const char *x, ...) { va_list ap; size_t l; char *r, *p; diff --git a/src/shared/util.h b/src/shared/util.h index c8d048f9b2..d9b656d2ca 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -451,7 +451,7 @@ int dirent_ensure_type(DIR *d, struct dirent *de); int in_search_path(const char *path, char **search); int get_files_in_directory(const char *path, char ***list); -char *join(const char *x, ...) _sentinel_; +char *strjoin(const char *x, ...) _sentinel_; bool is_main_thread(void); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 2d5d90d265..3b52b9889c 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1297,7 +1297,7 @@ static char *resolve_fragment(const char *fragment, const char **search_paths) { return strdup(fragment); STRV_FOREACH(p, search_paths) { - resolved_path = join(*p, "/", fragment, NULL); + resolved_path = strjoin(*p, "/", fragment, NULL); if (resolved_path == NULL) { log_error("Out of memory"); return NULL; -- cgit v1.2.3-54-g00ecf From 72edcff5db936e54cfc322d9392ec46e2428fd9b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 17 Sep 2012 16:41:13 +0200 Subject: hwclock: always set the kernel's timezone Properly tell the kernel at bootup, and any later time zone changes, the actual system time zone. Things like the kernel's FAT filesystem driver needs the actual time zone to calculate the proper local time to use for the on-disk time stamps. https://bugzilla.redhat.com/show_bug.cgi?id=802198 --- src/core/main.c | 15 ++++++++++++--- src/shared/hwclock.c | 9 +++++++-- src/shared/hwclock.h | 4 ++-- src/timedate/timedated.c | 13 +++++-------- 4 files changed, 26 insertions(+), 15 deletions(-) (limited to 'src/shared/hwclock.c') diff --git a/src/core/main.c b/src/core/main.c index 44c010cfbf..199383e636 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1319,17 +1319,26 @@ int main(int argc, char *argv[]) { if (label_init(NULL) < 0) goto finish; - if (!skip_setup) + if (!skip_setup) { if (hwclock_is_localtime() > 0) { int min; - r = hwclock_apply_localtime_delta(&min); + /* The first-time call to settimeofday() does a time warp in the kernel */ + r = hwclock_set_timezone(&min); if (r < 0) log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); else log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); - } + } else { + /* Do dummy first-time call to seal the kernel's time warp magic */ + hwclock_reset_timezone(); + /* Tell the kernel our time zone */ + r = hwclock_set_timezone(NULL); + if (r < 0) + log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r)); + } + } } else { arg_running_as = MANAGER_USER; log_set_target(LOG_TARGET_AUTO); diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index 9f8ab08e2b..d9d5600ff3 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -188,7 +188,7 @@ int hwclock_is_localtime(void) { return local; } -int hwclock_apply_localtime_delta(int *min) { +int hwclock_set_timezone(int *min) { const struct timeval *tv_null = NULL; struct timespec ts; struct tm *tm; @@ -214,13 +214,18 @@ int hwclock_apply_localtime_delta(int *min) { return 0; } -int hwclock_reset_localtime_delta(void) { +int hwclock_reset_timezone(void) { const struct timeval *tv_null = NULL; struct timezone tz; tz.tz_minuteswest = 0; tz.tz_dsttime = 0; /* DST_NONE*/ + /* + * The very first time we set the kernel's timezone, it will warp + * the clock. Do a dummy call here, so the time warping is sealed + * and we set only the time zone with next call. + */ if (settimeofday(tv_null, &tz) < 0) return -errno; diff --git a/src/shared/hwclock.h b/src/shared/hwclock.h index 26d1b444e7..b2bdc78f0c 100644 --- a/src/shared/hwclock.h +++ b/src/shared/hwclock.h @@ -23,8 +23,8 @@ ***/ int hwclock_is_localtime(void); -int hwclock_apply_localtime_delta(int *min); -int hwclock_reset_localtime_delta(void); +int hwclock_set_timezone(int *min); +int hwclock_reset_timezone(void); int hwclock_get_time(struct tm *tm); int hwclock_set_time(const struct tm *tm); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 7eed31c477..0ebece893f 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -696,13 +696,13 @@ static DBusHandlerResult timedate_message_handler( return bus_send_error_reply(connection, message, NULL, r); } + /* 2. Tell the kernel our time zone */ + hwclock_set_timezone(NULL); + if (tz.local_rtc) { struct timespec ts; struct tm *tm; - /* 2. Teach kernel new timezone */ - hwclock_apply_localtime_delta(NULL); - /* 3. Sync RTC from system clock, with the new delta */ assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); assert_se(tm = localtime(&ts.tv_sec)); @@ -753,11 +753,8 @@ static DBusHandlerResult timedate_message_handler( return bus_send_error_reply(connection, message, NULL, r); } - /* 2. Teach kernel new timezone */ - if (tz.local_rtc) - hwclock_apply_localtime_delta(NULL); - else - hwclock_reset_localtime_delta(); + /* 2. Tell the kernel our time zone */ + hwclock_set_timezone(NULL); /* 3. Synchronize clocks */ assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); -- cgit v1.2.3-54-g00ecf From a866073d35dea05e6f3e56328d3eb6436943e7e6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2012 17:42:13 +0200 Subject: main: when transitioning from initrd to the main system log to kmsg When the new PID is invoked the journal socket from the initrd might still be around. Due to the default log target being journal we'd log to that initially when the new main systemd initializes even if the kernel command line included a directive to redirect systemd's logging elsewhere. With this fix we initially always log to kmsg now, if we are PID1, and only after parsing the kernel cmdline try to open the journal if that's desired. (The effective benefit of this is that SELinux performance data is now logged again to kmsg like it used to be.) --- TODO | 2 -- src/core/main.c | 39 +++++++++++++++++++++++++++++---------- src/shared/hwclock.c | 1 + 3 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src/shared/hwclock.c') diff --git a/TODO b/TODO index 10f43d7d25..ec31f1d466 100644 --- a/TODO +++ b/TODO @@ -28,8 +28,6 @@ F18: * refuse automount triggers when automount is queued for stop, much like we refuse socket triggers when sockets are queued for stop -* perfomance messages for selinux are gone from debug log? - * There's something wrong with escaping unit names: http://lists.freedesktop.org/archives/systemd-devel/2012-August/006292.html * logind: different policy actions for idle, suspend, shutdown blockers: allow idle blockers by default, don't allow suspend blockers by default diff --git a/src/core/main.c b/src/core/main.c index 199383e636..9d2d55154c 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1285,10 +1285,15 @@ int main(int argc, char *argv[]) { saved_argc = argc; log_show_color(isatty(STDERR_FILENO) > 0); - log_show_location(false); - log_set_max_level(LOG_INFO); - if (getpid() == 1) { + if (getpid() == 1 && detect_container(NULL) <= 0) { + + /* Running outside of a container as PID 1 */ + arg_running_as = MANAGER_SYSTEM; + make_null_stdio(); + log_set_target(LOG_TARGET_KMSG); + log_open(); + if (in_initrd()) { char *rd_timestamp = NULL; @@ -1302,11 +1307,6 @@ int main(int argc, char *argv[]) { } } - arg_running_as = MANAGER_SYSTEM; - - make_null_stdio(); - log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG); - if (!skip_setup) { if (selinux_setup(&loaded_policy) < 0) goto finish; @@ -1314,8 +1314,6 @@ int main(int argc, char *argv[]) { goto finish; } - log_open(); - if (label_init(NULL) < 0) goto finish; @@ -1339,7 +1337,28 @@ int main(int argc, char *argv[]) { log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r)); } } + + /* Set the default for later on, but don't actually + * open the logs like this for now. Note that if we + * are transitioning from the initrd there might still + * be journal fd open, and we shouldn't attempt + * opening that before we parsed /proc/cmdline which + * might redirect output elsewhere. */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + + } else if (getpid() == 1) { + + /* Running inside a container, as PID 1 */ + arg_running_as = MANAGER_SYSTEM; + log_set_target(LOG_TARGET_CONSOLE); + log_open(); + + /* For the later on, see above... */ + log_set_target(LOG_TARGET_JOURNAL); + } else { + + /* Running as user instance */ arg_running_as = MANAGER_USER; log_set_target(LOG_TARGET_AUTO); log_open(); diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index d9d5600ff3..67eb2eff8b 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -154,6 +154,7 @@ int hwclock_set_time(const struct tm *tm) { return err; } + int hwclock_is_localtime(void) { FILE *f; bool local = false; -- cgit v1.2.3-54-g00ecf From 7d5e9c0f60cddf01ec803012cbdc02d2f55b78c1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2012 22:21:09 +0200 Subject: util: define union dirent_storage and make use of it everywhere Make sure to allocate enough space for readdir_r(). https://bugzilla.redhat.com/show_bug.cgi?id=858754 --- src/delta/delta.c | 5 +++-- src/journal/journal-vacuum.c | 5 +++-- src/journal/journald.c | 5 +++-- src/journal/sd-journal.c | 10 ++++++---- src/login/sd-login.c | 5 +++-- src/shared/conf-files.c | 5 +++-- src/shared/hwclock.c | 5 +++-- src/shared/install.c | 15 +++++++++------ src/shared/util.c | 15 +++++++++------ src/shared/util.h | 7 +++++++ src/tmpfiles/tmpfiles.c | 5 +++-- 11 files changed, 52 insertions(+), 30 deletions(-) (limited to 'src/shared/hwclock.c') diff --git a/src/delta/delta.c b/src/delta/delta.c index eef6536b01..803d2a7fc7 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -176,11 +176,12 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) { } for (;;) { - struct dirent *de, buf; + struct dirent *de; + union dirent_storage buf; int k; char *p; - k = readdir_r(d, &buf, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -k; goto finish; diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c index c890146537..ac16bdfcfd 100644 --- a/src/journal/journal-vacuum.c +++ b/src/journal/journal-vacuum.c @@ -86,7 +86,8 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m for (;;) { int k; - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; size_t q; struct stat st; char *p; @@ -94,7 +95,7 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m sd_id128_t seqnum_id; bool have_seqnum; - k = readdir_r(d, &buf, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -k; goto finish; diff --git a/src/journal/journald.c b/src/journal/journald.c index 74c80f5a08..164e1087d1 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -141,9 +141,10 @@ static uint64_t available_space(Server *s) { for (;;) { struct stat st; - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0) break; diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 2fa81727e0..acde84fe2d 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1256,9 +1256,10 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 || !de) break; @@ -1334,10 +1335,11 @@ static int add_root_directory(sd_journal *j, const char *p) { } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; sd_id128_t id; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 || !de) break; diff --git a/src/login/sd-login.c b/src/login/sd-login.c index 82fe2ce3e3..45e3bb8dcd 100644 --- a/src/login/sd-login.c +++ b/src/login/sd-login.c @@ -651,11 +651,12 @@ _public_ int sd_get_uids(uid_t **users) { return -errno; for (;;) { - struct dirent buffer, *de; + struct dirent *de; + union dirent_storage buf; int k; uid_t uid; - k = readdir_r(d, &buffer, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -k; goto finish; diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c index 83e4cce156..34b86293d3 100644 --- a/src/shared/conf-files.c +++ b/src/shared/conf-files.c @@ -39,7 +39,6 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) { DIR *dir; - struct dirent buffer, *de; int r = 0; dir = opendir(path); @@ -50,10 +49,12 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) { } for (;;) { + struct dirent *de; + union dirent_storage buf; int k; char *p; - k = readdir_r(dir, &buffer, &de); + k = readdir_r(dir, &buf.de, &de); if (k != 0) { r = -k; goto finish; diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index 67eb2eff8b..b93855d957 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -61,10 +61,11 @@ static int rtc_open(int flags) { for (;;) { char *p, *v; - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; int r; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0) goto fallback; diff --git a/src/shared/install.c b/src/shared/install.c index f30bf8317b..a99c757ea8 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -201,7 +201,6 @@ static int remove_marked_symlinks_fd( int r = 0; DIR *d; - struct dirent buffer, *de; assert(remove_symlinks_to); assert(fd >= 0); @@ -218,9 +217,11 @@ static int remove_marked_symlinks_fd( rewinddir(d); for (;;) { + struct dirent *de; + union dirent_storage buf; int k; - k = readdir_r(d, &buffer, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -errno; break; @@ -375,7 +376,6 @@ static int find_symlinks_fd( int r = 0; DIR *d; - struct dirent buffer, *de; assert(name); assert(fd >= 0); @@ -391,8 +391,10 @@ static int find_symlinks_fd( for (;;) { int k; + struct dirent *de; + union dirent_storage buf; - k = readdir_r(d, &buffer, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -errno; break; @@ -1906,7 +1908,6 @@ int unit_file_get_list( return r; STRV_FOREACH(i, paths.unit_path) { - struct dirent buffer, *de; const char *units_dir; free(buf); @@ -1934,9 +1935,11 @@ int unit_file_get_list( } for (;;) { + struct dirent *de; + union dirent_storage buffer; UnitFileList *f; - r = readdir_r(d, &buffer, &de); + r = readdir_r(d, &buffer.de, &de); if (r != 0) { r = -r; goto finish; diff --git a/src/shared/util.c b/src/shared/util.c index 69c9437db8..b48bad4c46 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2956,9 +2956,10 @@ int dir_is_empty(const char *path) { return -errno; for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r > 0) return -r; @@ -3260,12 +3261,13 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; bool is_dir, keep_around; struct stat st; int r; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 && ret == 0) { ret = -r; break; @@ -4942,10 +4944,11 @@ int get_files_in_directory(const char *path, char ***list) { return -errno; for (;;) { - struct dirent buffer, *de; + struct dirent *de; + union dirent_storage buf; int k; - k = readdir_r(d, &buffer, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -k; goto finish; diff --git a/src/shared/util.h b/src/shared/util.h index 2429339f5b..e5728bd87e 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "macro.h" @@ -46,6 +47,12 @@ typedef struct dual_timestamp { usec_t monotonic; } dual_timestamp; +union dirent_storage { + struct dirent de; + uint8_t storage[offsetof(struct dirent, d_name) + + ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))]; +}; + #define MSEC_PER_SEC 1000ULL #define USEC_PER_SEC 1000000ULL #define USEC_PER_MSEC 1000ULL diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 5d0f571bea..f10f90845e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -551,12 +551,13 @@ static int recursive_relabel_children(Item *i, const char *path) { return errno == ENOENT ? 0 : -errno; for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; bool is_dir; int r; char *entry_path; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0) { if (ret == 0) ret = -r; -- cgit v1.2.3-54-g00ecf From 4eeebf70aa5ac9825899f5a063431329904d37e5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Sep 2012 16:29:09 +0200 Subject: hwclock: add missing OOM check --- src/shared/hwclock.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/shared/hwclock.c') diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index b93855d957..0e8fa45971 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -94,6 +94,11 @@ static int rtc_open(int flags) { continue; p = strappend("/dev/", de->d_name); + if (!p) { + closedir(d); + return -ENOMEM; + } + fd = open(p, flags); free(p); -- cgit v1.2.3-54-g00ecf From 19e65613563dd9c14cf1ce58aa6e151de8fb90c2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Oct 2012 16:23:32 +0200 Subject: hwclock: do not seal the kernel's time-warp call from inside the initrd --- src/core/main.c | 11 +++++++++-- src/shared/hwclock.c | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src/shared/hwclock.c') diff --git a/src/core/main.c b/src/core/main.c index e094efeb3c..4da8ecb864 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1350,8 +1350,15 @@ int main(int argc, char *argv[]) { log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); else log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); - } else { - /* Do dummy first-time call to seal the kernel's time warp magic */ + } else if (!in_initrd()) { + /* + * Do dummy first-time call to seal the kernel's time warp magic + * + * Do not call this this from inside the initrd. The initrd might not + * carry /etc/adjtime with LOCAL, but the real system could be set up + * that way. In such case, we need to delay the time-warp or the sealing + * until we reach the real system. + */ hwclock_reset_timezone(); /* Tell the kernel our time zone */ diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c index 0e8fa45971..f9adf0369e 100644 --- a/src/shared/hwclock.c +++ b/src/shared/hwclock.c @@ -199,14 +199,14 @@ int hwclock_set_timezone(int *min) { const struct timeval *tv_null = NULL; struct timespec ts; struct tm *tm; - int minuteswest; + int minutesdelta; struct timezone tz; assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); assert_se(tm = localtime(&ts.tv_sec)); - minuteswest = tm->tm_gmtoff / 60; + minutesdelta = tm->tm_gmtoff / 60; - tz.tz_minuteswest = -minuteswest; + tz.tz_minuteswest = -minutesdelta; tz.tz_dsttime = 0; /* DST_NONE*/ /* @@ -217,7 +217,7 @@ int hwclock_set_timezone(int *min) { if (settimeofday(tv_null, &tz) < 0) return -errno; if (min) - *min = minuteswest; + *min = minutesdelta; return 0; } -- cgit v1.2.3-54-g00ecf