[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