[systemd-commits] 4 commits - Makefile.am TODO man/journalctl.xml man/journald.conf.xml src/core src/journal src/login src/timedate units/systemd-timedated-ntp.target

Lennart Poettering lennart at kemper.freedesktop.org
Mon Jul 2 01:44:18 PDT 2012


 Makefile.am                        |    8 
 TODO                               |   26 +-
 man/journalctl.xml                 |    8 
 man/journald.conf.xml              |   40 ++++
 src/core/manager.c                 |   33 +--
 src/journal/journalctl.c           |   32 +++
 src/journal/journald-gperf.gperf   |    1 
 src/journal/journald.c             |   37 +++-
 src/journal/journald.h             |   16 +
 src/login/logind.conf              |    1 
 src/timedate/ntp-units             |    4 
 src/timedate/timedated.c           |  321 ++++++++++++++++++++++++-------------
 units/systemd-timedated-ntp.target |   18 --
 13 files changed, 367 insertions(+), 178 deletions(-)

New commits:
commit e156d769c3ee756cdb20f8522ace9ea459a82655
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jul 1 20:17:48 2012 +0200

    journald: add Storage= setting to control where the journal is stored

diff --git a/TODO b/TODO
index 37c048c..6790088 100644
--- a/TODO
+++ b/TODO
@@ -22,6 +22,14 @@ Bugfixes:
 
 Features:
 
+* reexec journald across initrd transition
+
+* nspawn: bind mount /var/log/journal from the host
+
+* The current Storage=auto logic is borked, since people cannot mount
+  /var/log/journal via NFS since the mount point has to exist and we
+  already take that as signal to store our stuff there.
+
 * rename systemd-udev.service to systemd-udevd.service
 
 * document that journal data is primarily ASCII, UTF-8 where necessary and binary only where nothing else makes sense.
@@ -110,8 +118,6 @@ Features:
 
 * don't delete /tmp/systemd-namespace-* before a process is gone down
 
-* don't delete /run/users/lennart if lennart is still logged in even if aging is used
-
 * vconsole: implement setterm -store -foreground xxx --background zzz
 
 * ExecOnFailure=/usr/bin/foo
@@ -170,8 +176,6 @@ Features:
 
 * journal: store euid in journal if it differs from uid
 
-* support chrony in addition to ntpd in timedated
-
 * There's currently no way to cancel fsck (used to be possible via C-c or c on the console)
 
 * journal: sanely deal with entries which are larger than the individual file size, but where the componets would fit
@@ -236,8 +240,6 @@ Features:
 
 * when an instanced service exits, remove its parent cgroup too if possible.
 
-* automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service at serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary.
-
 * if we can not get user quota for tmpfs, mount a separate tmpfs instance
   for every user in /run/user/$USER with a configured maximum size
 
@@ -417,3 +419,5 @@ Regularly:
 Scheduled for removal (or fixing):
 
 * xxxOverridable dependencies
+
+* journald.conf: ImportKernel=
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index deb2344..72d81fb 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -286,6 +286,46 @@
                                 traditional syslog service.
                                 </para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Storage=</varname></term>
+
+                                <listitem><para>Controls where to
+                                store journal data. One of
+                                <literal>volatile</literal>,
+                                <literal>permanent</literal>,
+                                <literal>auto</literal> and
+                                <literal>none</literal>. If
+                                <literal>volatile</literal> journal
+                                log data will be stored only in
+                                memory, i.e. below the
+                                <filename>/run/log/journal</filename>
+                                hierarchy (which is created if
+                                needed). If
+                                <literal>permanent</literal> data will
+                                be stored preferably on disk,
+                                i.e. below the
+                                <filename>/var/log/journal</filename>
+                                hierarchy (which is created if
+                                needed), with a fallback to
+                                <filename>/run/log/journal</filename>
+                                (which is created if needed), during
+                                early boot and if the disk is not
+                                writable. <literal>auto</literal> is
+                                similar to
+                                <literal>permanent</literal> but the
+                                directory
+                                <filename>/var/log/journal</filename>
+                                is not created if needed, so that its
+                                existance controls where log data
+                                goes. <literal>none</literal> turns
+                                off all storage, all log data received
+                                will be dropped. Forwarding to other
+                                targets, such as the console, the
+                                kernel log buffer or a syslog daemon
+                                will still work however.  Defaults to
+                                <literal>auto</literal>.</para></listitem>
+                        </varlistentry>
                 </variablelist>
 
         </refsect1>
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index c9b0fbb..4fe2ea0 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -34,3 +34,4 @@ Journal.MaxLevelStore,      config_parse_level,     0, offsetof(Server, max_leve
 Journal.MaxLevelSyslog,     config_parse_level,     0, offsetof(Server, max_level_syslog)
 Journal.MaxLevelKMsg,       config_parse_level,     0, offsetof(Server, max_level_kmsg)
 Journal.MaxLevelConsole,    config_parse_level,     0, offsetof(Server, max_level_console)
+Journal.Storage,            config_parse_storage,   0, offsetof(Server, storage)
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 7ea68aa..08597ae 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -111,6 +111,16 @@ struct StdoutStream {
         LIST_FIELDS(StdoutStream, stdout_stream);
 };
 
+static const char* const storage_table[] = {
+        [STORAGE_AUTO] = "auto",
+        [STORAGE_VOLATILE] = "volatile",
+        [STORAGE_PERMANENT] = "permanent",
+        [STORAGE_NONE] = "none"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(storage, Storage);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
+
 static int server_flush_to_var(Server *s);
 
 static uint64_t available_space(Server *s) {
@@ -397,7 +407,6 @@ static void server_vacuum(Server *s) {
                 free(p);
         }
 
-
         if (s->runtime_journal) {
                 if (asprintf(&p, "/run/log/journal/%s", ids) < 0) {
                         log_error("Out of memory.");
@@ -625,9 +634,7 @@ static void dispatch_message_real(
 
 retry:
         f = find_journal(s, realuid == 0 ? 0 : loginuid);
-        if (!f)
-                log_warning("Dropping message, as we can't find a place to store the data.");
-        else {
+        if (f) {
                 r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
 
                 if ((r == -E2BIG || /* hit limit */
@@ -1955,12 +1962,23 @@ static int system_journal_open(Server *s) {
 
         sd_id128_to_string(machine, ids);
 
-        if (!s->system_journal) {
+        if (!s->system_journal &&
+            (s->storage == STORAGE_PERMANENT ||
+             s->storage == STORAGE_AUTO)) {
+
+                /* If in auto mode: first try to create the machine
+                 * path, but not the prefix.
+                 *
+                 * If in permanent mode: create /var/log/journal and
+                 * the machine path */
+
+                if (s->storage & STORAGE_PERMANENT)
+                        (void) mkdir("/var/log/journal/", 0755);
 
-                /* First try to create the machine path, but not the prefix */
                 fn = strappend("/var/log/journal/", ids);
                 if (!fn)
                         return -ENOMEM;
+
                 (void) mkdir(fn, 0755);
                 free(fn);
 
@@ -1988,7 +2006,8 @@ static int system_journal_open(Server *s) {
                 }
         }
 
-        if (!s->runtime_journal) {
+        if (!s->runtime_journal &&
+            (s->storage != STORAGE_NONE)) {
 
                 fn = join("/run/log/journal/", ids, "/system.journal", NULL);
                 if (!fn)
@@ -2048,6 +2067,10 @@ static int server_flush_to_var(Server *s) {
 
         assert(s);
 
+        if (s->storage != STORAGE_AUTO &&
+            s->storage != STORAGE_PERMANENT)
+                return 0;
+
         if (!s->runtime_journal)
                 return 0;
 
diff --git a/src/journal/journald.h b/src/journal/journald.h
index 159364d..34deb85 100644
--- a/src/journal/journald.h
+++ b/src/journal/journald.h
@@ -33,6 +33,15 @@
 #include "journal-rate-limit.h"
 #include "list.h"
 
+typedef enum Storage {
+        STORAGE_AUTO,
+        STORAGE_VOLATILE,
+        STORAGE_PERMANENT,
+        STORAGE_NONE,
+        _STORAGE_MAX,
+        _STORAGE_INVALID = -1
+} Storage;
+
 typedef struct StdoutStream StdoutStream;
 
 typedef struct Server {
@@ -86,9 +95,16 @@ typedef struct Server {
         int max_level_syslog;
         int max_level_kmsg;
         int max_level_console;
+
+        Storage storage;
 } Server;
 
 /* gperf lookup function */
 const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length);
 
+int config_parse_storage(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+const char *storage_to_string(Storage s);
+Storage storage_from_string(const char *s);
+
 #endif
diff --git a/src/login/logind.conf b/src/login/logind.conf
index 78496a0..c3798f7 100644
--- a/src/login/logind.conf
+++ b/src/login/logind.conf
@@ -18,3 +18,4 @@
 #HandlePowerKey=no-session
 #HandleSleepKey=tty-session
 #HandleLidSwitch=off
+#Storage=auto

commit 29252e9e5bad3b0bcfc45d9bc761aee4b0ece1da
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jul 1 18:59:55 2012 +0200

    manager: turn notify socket into abstract namespace socket again
    
    sd_notify() should work for daemons that chroot() as part of their
    initilization, hence it's a good idea to use an abstract namespace
    socket which is not affected by chroot.

diff --git a/TODO b/TODO
index b3aac5a..37c048c 100644
--- a/TODO
+++ b/TODO
@@ -51,9 +51,6 @@ Features:
 
 * change Requires=basic.target to RequisiteOverride=basic.target
 
-* turn $NOTIFY_SOCKET back into an abstract namespace socket for
-  compatibility with services which chroot()
-
 * exclude processes marked with argv[0][0]=@ from the normal service killing too
 
 * support rd.luks.allow-discards= kernel cmdline params in cryptsetup generator
diff --git a/src/core/manager.c b/src/core/manager.c
index c0cc1b3..5958ade 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -74,8 +74,7 @@
 #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
 
 /* Where clients shall send notification messages to */
-#define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify"
-#define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify"
+#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
 
 static int manager_setup_notify(Manager *m) {
         union {
@@ -83,13 +82,13 @@ static int manager_setup_notify(Manager *m) {
                 struct sockaddr_un un;
         } sa;
         struct epoll_event ev;
-        int one = 1, r;
-        mode_t u;
+        int one = 1;
 
         assert(m);
 
         m->notify_watch.type = WATCH_NOTIFY;
-        if ((m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+        m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->notify_watch.fd < 0) {
                 log_error("Failed to allocate notification socket: %m");
                 return -errno;
         }
@@ -98,20 +97,13 @@ static int manager_setup_notify(Manager *m) {
         sa.sa.sa_family = AF_UNIX;
 
         if (getpid() != 1)
-                snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull());
-        else {
-                unlink(NOTIFY_SOCKET_SYSTEM);
-                strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path));
-        }
+                snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull());
+        else
+                strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path));
 
-        if (sa.un.sun_path[0] == '@')
-                sa.un.sun_path[0] = 0;
+        sa.un.sun_path[0] = 0;
 
-        u = umask(0111);
-        r = bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
-        umask(u);
-
-        if (r < 0) {
+        if (bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
                 log_error("bind() failed: %m");
                 return -errno;
         }
@@ -128,10 +120,9 @@ static int manager_setup_notify(Manager *m) {
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
                 return -errno;
 
-        if (sa.un.sun_path[0] == 0)
-                sa.un.sun_path[0] = '@';
-
-        if (!(m->notify_socket = strdup(sa.un.sun_path)))
+        sa.un.sun_path[0] = '@';
+        m->notify_socket = strdup(sa.un.sun_path);
+        if (!m->notify_socket)
                 return -ENOMEM;
 
         log_debug("Using notification socket %s", m->notify_socket);

commit 59cea26a349cfa8db906b520dac72563dd773ff2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jul 1 18:47:40 2012 +0200

    journalctl: add new switch -b to show data from current boot only

diff --git a/TODO b/TODO
index 1a7b60e..b3aac5a 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,3 @@
-Fedora 18:
-* chrony/ntp target?
-
 Bugfixes:
 * remove MS_SHARED from src/core/execute.c and src/test/test-ns.c. They are always combined
   with MS_REMOUNT, which currently does nothing in the kernel, but might which fail in the
@@ -52,9 +49,7 @@ Features:
 
 * new dependency type to "group" services in a target
 
-* add switch to journalctl to only show data from current boot
-
-* change REquires=basic.target to RequisiteOverride=basic.target
+* change Requires=basic.target to RequisiteOverride=basic.target
 
 * turn $NOTIFY_SOCKET back into an abstract namespace socket for
   compatibility with services which chroot()
diff --git a/man/journalctl.xml b/man/journalctl.xml
index d46a164..6254c5c 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -210,6 +210,14 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><option>--this-boot</option></term>
+                                <term><option>-b</option></term>
+
+                                <listitem><para>Show data only from
+                                local boot.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><option>--new-id128</option></term>
 
                                 <listitem><para>Instead of showing
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index e9d918a..6929b76 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -49,6 +49,7 @@ static bool arg_no_tail = false;
 static bool arg_new_id128 = false;
 static bool arg_quiet = false;
 static bool arg_local = false;
+static bool arg_this_boot = false;
 
 static int help(void) {
 
@@ -64,8 +65,9 @@ static int help(void) {
                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
                "                      verbose, export, json, cat)\n"
                "  -q --quiet          Don't show privilege warning\n"
-               "     --new-id128      Generate a new 128 Bit id\n"
-               "  -l --local          Only local entries\n",
+               "  -l --local          Only local entries\n"
+               "  -b --this-boot      Show data only from current boot\n"
+               "     --new-id128      Generate a new 128 Bit id\n",
                program_invocation_short_name);
 
         return 0;
@@ -92,6 +94,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "new-id128", no_argument,       NULL, ARG_NEW_ID128 },
                 { "quiet",     no_argument,       NULL, 'q'           },
                 { "local",     no_argument,       NULL, 'l'           },
+                { "this-boot", no_argument,       NULL, 'b'           },
                 { NULL,        0,                 NULL, 0             }
         };
 
@@ -100,7 +103,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hfo:an:ql", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hfo:an:qlb", options, NULL)) >= 0) {
 
                 switch (c) {
 
@@ -159,6 +162,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_local = true;
                         break;
 
+                case 'b':
+                        arg_this_boot = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -232,6 +239,25 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
+        if (arg_this_boot) {
+                char match[9+32+1] = "_BOOT_ID=";
+                sd_id128_t boot_id;
+
+                r = sd_id128_get_boot(&boot_id);
+                if (r < 0) {
+                        log_error("Failed to get boot id: %s", strerror(-r));
+                        goto finish;
+                }
+
+                sd_id128_to_string(boot_id, match + 9);
+
+                r = sd_journal_add_match(j, match, strlen(match));
+                if (r < 0) {
+                        log_error("Failed to add match: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
         for (i = optind; i < argc; i++) {
                 if (path_is_absolute(argv[i])) {
                         char *p = NULL;

commit ac7019f33f1618f5b69ed44a8623e2596f1e3856
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Jul 1 17:37:21 2012 +0200

    timedated: replace systemd-timedated-ntp.target logic with simpler scheme
    
    The previous systemd-timedated-ntp.target was suffering by the problem
    that NTP implementations enabled via the machanism could not be disabled
    the obvious way on the "systemctl disable" command line. Replace
    systemd-timedated-ntp.target by a list of implementations we try in
    turn. The list is encoded in $pkgdatadir/ntp-units.

diff --git a/Makefile.am b/Makefile.am
index 5789a13..616f998 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,7 @@ dist_udevrules_DATA =
 nodist_udevrules_DATA =
 dist_man_MANS =
 dist_pkgsysconf_DATA =
+dist_pkgdata_DATA =
 dist_dbuspolicy_DATA =
 dbusinterface_DATA =
 dist_dbussystemservice_DATA =
@@ -132,6 +133,7 @@ AM_CPPFLAGS = \
 	-DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
 	-DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
 	-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
+	-DSYSTEMD_NTP_UNITS=\"$(pkgdatadir)/ntp-units\" \
 	-DX_SERVER=\"$(bindir)/X\" \
 	-DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \
 	-DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
@@ -309,7 +311,6 @@ dist_systemunit_DATA = \
 	units/syslog.target \
 	units/systemd-udev-control.socket \
 	units/systemd-udev-kernel.socket \
-	units/systemd-timedated-ntp.target  \
 	units/system-update.target
 
 nodist_systemunit_DATA = \
@@ -2745,7 +2746,7 @@ man/systemd-localed.8: man/systemd-localed.service.8
 EXTRA_DIST += \
 	units/systemd-localed.service.in
 
-dist_pkgdata_DATA = \
+dist_pkgdata_DATA += \
 	src/locale/kbd-model-map
 
 dist_noinst_SCRIPT = \
@@ -2801,6 +2802,9 @@ timedated-install-data-hook:
 INSTALL_DATA_HOOKS += \
 	timedated-install-data-hook
 
+dist_pkgdata_DATA += \
+	src/timedate/ntp-units
+
 MANPAGES += \
 	man/systemd-timedated.service.8
 
diff --git a/src/timedate/ntp-units b/src/timedate/ntp-units
new file mode 100644
index 0000000..6fdef44
--- /dev/null
+++ b/src/timedate/ntp-units
@@ -0,0 +1,4 @@
+# NTP ervice implementations, in order for preference
+
+chronyd.service
+ntpd.service
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 8316bc3..4be7c3a 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -303,62 +303,112 @@ static int write_data_local_rtc(void) {
         return r;
 }
 
+static char** get_ntp_services(void) {
+        char **r = NULL;
+        FILE *f;
+
+        f = fopen(SYSTEMD_NTP_UNITS, "re");
+        if (!f)
+                return NULL;
+
+        for (;;) {
+                char line[PATH_MAX], *l, **q;
+
+                if (!fgets(line, sizeof(line), f)) {
+
+                        if (ferror(f))
+                                log_error("Failed to read NTP units file: %m");
+
+                        break;
+                }
+
+                l = strstrip(line);
+                if (l[0] == 0 || l[0] == '#')
+                        continue;
+
+
+                q = strv_append(r, l);
+                if (!q) {
+                        log_error("Out of memory");
+                        break;
+                }
+
+                strv_free(r);
+                r = q;
+        }
+
+        fclose(f);
+
+        return r;
+}
+
 static int read_ntp(DBusConnection *bus) {
         DBusMessage *m = NULL, *reply = NULL;
-        const char *name = "systemd-timedated-ntp.target", *s;
         DBusError error;
         int r;
+        char **i, **l;
 
         assert(bus);
 
         dbus_error_init(&error);
 
-        m = dbus_message_new_method_call(
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "GetUnitFileState");
-
-        if (!m) {
-                log_error("Out of memory");
-                r = -ENOMEM;
-                goto finish;
-        }
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                const char *s;
+
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "GetUnitFileState");
+                if (!m) {
+                        log_error("Out of memory");
+                        r = -ENOMEM;
+                        goto finish;
+                }
 
-        if (!dbus_message_append_args(m,
-                                      DBUS_TYPE_STRING, &name,
-                                      DBUS_TYPE_INVALID)) {
-                log_error("Could not append arguments to message.");
-                r = -ENOMEM;
-                goto finish;
-        }
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, i,
+                                              DBUS_TYPE_INVALID)) {
+                        log_error("Could not append arguments to message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
 
-        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
-        if (!reply) {
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+                if (!reply) {
+                        if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(&error);
+                                continue;
+                        }
 
-                if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
-                        /* NTP is not installed. */
-                        tz.use_ntp = false;
-                        r = 0;
+                        log_error("Failed to issue method call: %s", bus_error_message(&error));
+                        r = -EIO;
                         goto finish;
                 }
 
-                log_error("Failed to issue method call: %s", bus_error_message(&error));
-                r = -EIO;
-                goto finish;
-        }
+                if (!dbus_message_get_args(reply, &error,
+                                           DBUS_TYPE_STRING, &s,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse reply: %s", bus_error_message(&error));
+                        r = -EIO;
+                        goto finish;
+                }
 
-        if (!dbus_message_get_args(reply, &error,
-                                   DBUS_TYPE_STRING, &s,
-                                   DBUS_TYPE_INVALID)) {
-                log_error("Failed to parse reply: %s", bus_error_message(&error));
-                r = -EIO;
+                tz.use_ntp =
+                        streq(s, "enabled") ||
+                        streq(s, "enabled-runtime");
+                r = 0;
                 goto finish;
         }
 
-        tz.use_ntp =
-                streq(s, "enabled") ||
-                streq(s, "enabled-runtime");
+        /* NTP is not installed. */
+        tz.use_ntp = 0;
         r = 0;
 
 finish:
@@ -368,6 +418,8 @@ finish:
         if (reply)
                 dbus_message_unref(reply);
 
+        strv_free(l);
+
         dbus_error_free(&error);
 
         return r;
@@ -375,40 +427,60 @@ finish:
 
 static int start_ntp(DBusConnection *bus, DBusError *error) {
         DBusMessage *m = NULL, *reply = NULL;
-        const char *name = "systemd-timedated-ntp.target", *mode = "replace";
+        const char *mode = "replace";
+        char **i, **l;
         int r;
 
         assert(bus);
         assert(error);
 
-        m = dbus_message_new_method_call(
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        tz.use_ntp ? "StartUnit" : "StopUnit");
-        if (!m) {
-                log_error("Could not allocate message.");
-                r = -ENOMEM;
-                goto finish;
-        }
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                tz.use_ntp ? "StartUnit" : "StopUnit");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
 
-        if (!dbus_message_append_args(m,
-                                      DBUS_TYPE_STRING, &name,
-                                      DBUS_TYPE_STRING, &mode,
-                                      DBUS_TYPE_INVALID)) {
-                log_error("Could not append arguments to message.");
-                r = -ENOMEM;
-                goto finish;
-        }
+                if (!dbus_message_append_args(m,
+                                              DBUS_TYPE_STRING, i,
+                                              DBUS_TYPE_STRING, &mode,
+                                              DBUS_TYPE_INVALID)) {
+                        log_error("Could not append arguments to message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
+                            streq(error->name, "org.freedesktop.systemd1.LoadFailed") ||
+                            streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(error);
+                                continue;
+                        }
+
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
 
-        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
-        if (!reply) {
-                log_error("Failed to issue method call: %s", bus_error_message(error));
-                r = -EIO;
+                r = 0;
                 goto finish;
         }
 
-        r = 0;
+        /* No implementaiton available... */
+        r = -ENOENT;
 
 finish:
         if (m)
@@ -417,82 +489,105 @@ finish:
         if (reply)
                 dbus_message_unref(reply);
 
+        strv_free(l);
+
         return r;
 }
 
 static int enable_ntp(DBusConnection *bus, DBusError *error) {
         DBusMessage *m = NULL, *reply = NULL;
-        const char * const names[] = { "systemd-timedated-ntp.target", NULL };
         int r;
         DBusMessageIter iter;
         dbus_bool_t f = FALSE, t = TRUE;
+        char **i, **l;
 
         assert(bus);
         assert(error);
 
-        m = dbus_message_new_method_call(
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+        l = get_ntp_services();
+        STRV_FOREACH(i, l) {
+                char* k[2];
+
+                if (m)
+                        dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
 
-        if (!m) {
-                log_error("Could not allocate message.");
-                r = -ENOMEM;
-                goto finish;
-        }
+                dbus_message_iter_init_append(m, &iter);
 
-        dbus_message_iter_init_append(m, &iter);
+                k[0] = *i;
+                k[1] = NULL;
 
-        r = bus_append_strv_iter(&iter, (char**) names);
-        if (r < 0) {
-                log_error("Failed to append unit files.");
-                goto finish;
-        }
-        /* send runtime bool */
-        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
-                log_error("Failed to append runtime boolean.");
-                r = -ENOMEM;
-                goto finish;
-        }
+                r = bus_append_strv_iter(&iter, k);
+                if (r < 0) {
+                        log_error("Failed to append unit files.");
+                        goto finish;
+                }
 
-        if (tz.use_ntp) {
-                /* send force bool */
-                if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
-                        log_error("Failed to append force boolean.");
+                /* send runtime bool */
+                if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
+                        log_error("Failed to append runtime boolean.");
                         r = -ENOMEM;
                         goto finish;
                 }
-        }
 
-        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
-        if (!reply) {
-                log_error("Failed to issue method call: %s", bus_error_message(error));
-                r = -EIO;
-                goto finish;
-        }
+                if (tz.use_ntp) {
+                        /* send force bool */
+                        if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
+                                log_error("Failed to append force boolean.");
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                }
 
-        dbus_message_unref(m);
-        m = dbus_message_new_method_call(
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "Reload");
-        if (!m) {
-                log_error("Could not allocate message.");
-                r = -ENOMEM;
-                goto finish;
-        }
+                if (reply)
+                        dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
+                                /* This implementation does not exist, try next one */
+                                dbus_error_free(error);
+                                continue;
+                        }
 
-        dbus_message_unref(reply);
-        reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
-        if (!reply) {
-                log_error("Failed to issue method call: %s", bus_error_message(error));
-                r = -EIO;
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                dbus_message_unref(m);
+                m = dbus_message_new_method_call(
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "Reload");
+                if (!m) {
+                        log_error("Could not allocate message.");
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                dbus_message_unref(reply);
+                reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+                if (!reply) {
+                        log_error("Failed to issue method call: %s", bus_error_message(error));
+                        r = -EIO;
+                        goto finish;
+                }
+
+                r = 0;
                 goto finish;
         }
 
-        r = 0;
+        r = -ENOENT;
 
 finish:
         if (m)
@@ -501,6 +596,8 @@ finish:
         if (reply)
                 dbus_message_unref(reply);
 
+        strv_free(l);
+
         return r;
 }
 
diff --git a/units/systemd-timedated-ntp.target b/units/systemd-timedated-ntp.target
deleted file mode 100644
index 0837004..0000000
--- a/units/systemd-timedated-ntp.target
+++ /dev/null
@@ -1,18 +0,0 @@
-#  This file is part of systemd.
-#
-#  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.
-
-# This target is enabled/disabled via the timedated mechanism when the
-# user asks for it via the UI. NTP implementations should hook
-# themselves into this target via .wants/ symlinks, and then add
-# BindTo= on this target so that they are stopped when it goes away.
-
-[Unit]
-Description=Network Time Protocol
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
-
-[Install]
-WantedBy=multi-user.target



More information about the systemd-commits mailing list