[systemd-commits] 5 commits - fixme man/daemon.xml man/systemd.socket.xml src/load-fragment.c src/mount.c src/readahead-collect.c src/service.c src/service.h src/socket.c src/unit.c src/unit.h
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Oct 5 10:50:21 PDT 2010
fixme | 13 +++---
man/daemon.xml | 6 ++-
man/systemd.socket.xml | 12 ++++++
src/load-fragment.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++-
src/mount.c | 13 +++++-
src/readahead-collect.c | 2 -
src/service.c | 52 ++++++++++++++++-----------
src/service.h | 3 +
src/socket.c | 40 +++++++++++++++++---
src/unit.c | 17 ++++++++
src/unit.h | 1
11 files changed, 209 insertions(+), 42 deletions(-)
New commits:
commit a55da3cd5ea9d8cb6d7f1490516734fd43d016cb
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 5 19:49:38 2010 +0200
mount: sort network mounts after network.target by default
diff --git a/src/mount.c b/src/mount.c
index 3c08baf..fd77516 100644
--- a/src/mount.c
+++ b/src/mount.c
@@ -260,7 +260,7 @@ static char* mount_test_option(const char *haystack, const char *needle) {
}
static int mount_add_target_links(Mount *m) {
- const char *target;
+ const char *target, *after = NULL;
MountParameters *p;
Unit *tu;
int r;
@@ -282,14 +282,21 @@ static int mount_add_target_links(Mount *m) {
automount = !!mount_test_option(p->options, "comment=systemd.automount");
if (mount_test_option(p->options, "_netdev") ||
- fstype_is_network(p->fstype))
+ fstype_is_network(p->fstype)) {
target = SPECIAL_REMOTE_FS_TARGET;
- else
+
+ if (m->meta.manager->running_as == MANAGER_SYSTEM)
+ after = SPECIAL_NETWORK_TARGET;
+ } else
target = SPECIAL_LOCAL_FS_TARGET;
if ((r = manager_load_unit(m->meta.manager, target, NULL, NULL, &tu)) < 0)
return r;
+ if (after)
+ if ((r = unit_add_dependency_by_name(tu, UNIT_AFTER, after, NULL, true)) < 0)
+ return r;
+
if (automount && m->meta.manager->running_as == MANAGER_SYSTEM) {
Unit *am;
commit f976f3f67ce5140dc0ba48e0c21a91a553905c57
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 5 19:49:15 2010 +0200
socket: make sockets to pass to a service configurable
diff --git a/fixme b/fixme
index 0ba02a2..24fb169 100644
--- a/fixme
+++ b/fixme
@@ -1,12 +1,5 @@
v11:
-* have a simple syslog bridge providing /dev/log and forward messages
- to /dev/kmsg. at the moment the real syslog can be started, the bridge
- is stopped and the open /dev/log fd to the real syslog. that way we
- don't lose any early log message, and simple systems have full syslog
- support in the kernel ringbuffer, without any syslog service or disk
- access
-
* emergency.service should start default.target after C-d. synchronize from fedora's initscripts package
* verify ordering of random-seed-load and base.target!
@@ -108,6 +101,12 @@ later:
* beefed up tmpwatch that reads tmpfiles.d
+* /lib/systemd/system/systemd-readahead-replay.service
+
+* use /sbin/swapon
+
+* enable syslog.socket by default, activating our kmsg bridge
+
External:
* place /etc/inittab with explaining blurb.
diff --git a/src/load-fragment.c b/src/load-fragment.c
index eba3fdb..1685c4a 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1246,8 +1246,8 @@ static int config_parse_socket_service(
dbus_error_init(&error);
- if (endswith(rvalue, ".service")) {
- log_error("[%s:%u] Unit must be of type serivce, ignoring: %s", filename, line, rvalue);
+ if (!endswith(rvalue, ".service")) {
+ log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue);
return 0;
}
@@ -1260,6 +1260,60 @@ static int config_parse_socket_service(
return 0;
}
+static int config_parse_service_sockets(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Service *s = data;
+ int r;
+ DBusError error;
+ char *state, *w;
+ size_t l;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ dbus_error_init(&error);
+
+ FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+ char *t;
+ Unit *sock;
+
+ if (!(t = strndup(w, l)))
+ return -ENOMEM;
+
+ if (!endswith(t, ".socket")) {
+ log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue);
+ free(t);
+ continue;
+ }
+
+ r = manager_load_unit(s->meta.manager, t, NULL, &error, &sock);
+ free(t);
+
+ if (r < 0) {
+ log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+ dbus_error_free(&error);
+ continue;
+ }
+
+ if ((r = set_ensure_allocated(&s->configured_sockets, trivial_hash_func, trivial_compare_func)) < 0)
+ return r;
+
+ if ((r = set_put(s->configured_sockets, sock)) < 0)
+ return r;
+ }
+
+ return 0;
+}
+
static int config_parse_env_file(
const char *filename,
unsigned line,
@@ -1655,11 +1709,12 @@ static int load_from_path(Unit *u, const char *path) {
#ifdef HAVE_SYSV_COMPAT
{ "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" },
#else
- { "SysVStartPriority", config_parse_warn_compat, NULL, "Service" },
+ { "SysVStartPriority", config_parse_warn_compat, NULL, "Service" },
#endif
{ "NonBlocking", config_parse_bool, &u->service.exec_context.non_blocking, "Service" },
{ "BusName", config_parse_string_printf, &u->service.bus_name, "Service" },
{ "NotifyAccess", config_parse_notify_access, &u->service.notify_access, "Service" },
+ { "Sockets", config_parse_service_sockets, &u->service, "Service" },
EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"),
{ "ListenStream", config_parse_listen, &u->socket, "Socket" },
diff --git a/src/service.c b/src/service.c
index b18c950..301633e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -178,11 +178,11 @@ static void service_close_socket_fd(Service *s) {
static void service_connection_unref(Service *s) {
assert(s);
- if (!s->socket)
+ if (!s->accept_socket)
return;
- socket_connection_unref(s->socket);
- s->socket = NULL;
+ socket_connection_unref(s->accept_socket);
+ s->accept_socket = NULL;
}
static void service_done(Unit *u) {
@@ -222,6 +222,8 @@ static void service_done(Unit *u) {
service_close_socket_fd(s);
service_connection_unref(s);
+ set_free(s->configured_sockets);
+
unit_unwatch_timer(u, &s->timer_watch);
}
@@ -1177,6 +1179,9 @@ static int service_get_sockets(Service *s, Set **_set) {
if (s->socket_fd >= 0)
return 0;
+ if (!set_isempty(s->configured_sockets))
+ return 0;
+
/* Collects all Socket objects that belong to this
* service. Note that a service might have multiple sockets
* via multiple names. */
@@ -1216,23 +1221,30 @@ fail:
static int service_notify_sockets_dead(Service *s) {
Iterator i;
- Set *set;
+ Set *set, *free_set = NULL;
Socket *sock;
int r;
assert(s);
+ /* Notifies all our sockets when we die */
+
if (s->socket_fd >= 0)
return 0;
- /* Notifies all our sockets when we die */
- if ((r = service_get_sockets(s, &set)) < 0)
- return r;
+ if (!set_isempty(s->configured_sockets))
+ set = s->configured_sockets;
+ else {
+ if ((r = service_get_sockets(s, &free_set)) < 0)
+ return r;
+
+ set = free_set;
+ }
SET_FOREACH(sock, set, i)
socket_notify_service_dead(sock);
- set_free(set);
+ set_free(free_set);
return 0;
}
@@ -1390,7 +1402,7 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
int r;
int *rfds = NULL;
unsigned rn_fds = 0;
- Set *set;
+ Set *set, *free_set = NULL;
Socket *sock;
assert(s);
@@ -1400,8 +1412,14 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
if (s->socket_fd >= 0)
return 0;
- if ((r = service_get_sockets(s, &set)) < 0)
- return r;
+ if (!set_isempty(s->configured_sockets))
+ set = s->configured_sockets;
+ else {
+ if ((r = service_get_sockets(s, &free_set)) < 0)
+ return r;
+
+ set = free_set;
+ }
SET_FOREACH(sock, set, i) {
int *cfds;
@@ -1438,7 +1456,7 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
*fds = rfds;
*n_fds = rn_fds;
- set_free(set);
+ set_free(free_set);
return 0;
@@ -2084,14 +2102,6 @@ static int service_start(Unit *u) {
return -ECANCELED;
}
- if ((s->exec_context.std_input == EXEC_INPUT_SOCKET ||
- s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
- s->exec_context.std_error == EXEC_OUTPUT_SOCKET) &&
- s->socket_fd < 0) {
- log_warning("%s can only be started with a per-connection socket.", u->meta.id);
- return -EINVAL;
- }
-
s->failure = false;
s->main_pid_known = false;
s->forbid_restart = false;
@@ -3062,7 +3072,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock) {
s->socket_fd = fd;
s->got_socket_fd = true;
- s->socket = sock;
+ s->accept_socket = sock;
return 0;
}
diff --git a/src/service.h b/src/service.h
index 39bd1b3..e2b11db 100644
--- a/src/service.h
+++ b/src/service.h
@@ -133,7 +133,8 @@ struct Service {
RateLimit ratelimit;
- struct Socket *socket;
+ struct Socket *accept_socket;
+ Set *configured_sockets;
Watch timer_watch;
diff --git a/src/socket.c b/src/socket.c
index bbb54f6..2567d0f 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -129,8 +129,10 @@ static void socket_done(Unit *u) {
LIST_FOREACH(units_per_type, i, u->meta.manager->units_per_type[UNIT_SERVICE]) {
Service *service = (Service *) i;
- if (service->socket == s)
- service->socket = NULL;
+ if (service->accept_socket == s)
+ service->accept_socket = NULL;
+
+ set_remove(service->configured_sockets, s);
}
}
@@ -1197,8 +1199,27 @@ static void socket_enter_running(Socket *s, int cfd) {
}
if (cfd < 0) {
- if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, &error, NULL)) < 0)
- goto fail;
+ bool pending = false;
+ Meta *i;
+
+ /* If there's already a start pending don't bother to
+ * do anything */
+ LIST_FOREACH(units_per_type, i, s->meta.manager->units_per_type[UNIT_SERVICE]) {
+ Service *service = (Service *) i;
+
+ if (!set_get(service->configured_sockets, s))
+ continue;
+
+ if (!unit_pending_active(UNIT(service)))
+ continue;
+
+ pending = true;
+ break;
+ }
+
+ if (!pending)
+ if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, &error, NULL)) < 0)
+ goto fail;
socket_set_state(s, SOCKET_RUNNING);
} else {
diff --git a/src/unit.c b/src/unit.c
index 0a8ee61..fefa0eb 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -2190,6 +2190,23 @@ bool unit_pending_inactive(Unit *u) {
return false;
}
+bool unit_pending_active(Unit *u) {
+ assert(u);
+
+ /* Returns true if the unit is inactive or going down */
+
+ if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
+ return true;
+
+ if (u->meta.job &&
+ (u->meta.job->type == JOB_START ||
+ u->meta.job->type == JOB_RELOAD_OR_START ||
+ u->meta.job->type == JOB_RESTART))
+ return true;
+
+ return false;
+}
+
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
[UNIT_STUB] = "stub",
[UNIT_LOADED] = "loaded",
diff --git a/src/unit.h b/src/unit.h
index 20bb6a2..47a1eb6 100644
--- a/src/unit.h
+++ b/src/unit.h
@@ -500,6 +500,7 @@ void unit_reset_failed(Unit *u);
Unit *unit_following(Unit *u);
bool unit_pending_inactive(Unit *u);
+bool unit_pending_active(Unit *u);
int unit_add_default_target_dependency(Unit *u, Unit *target);
commit d9ff321ad9477664c34b81a9dd4fce616e44124e
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Sep 30 02:19:12 2010 +0200
socket: make service to start on incoming traffic configurable
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index a7b8228..78d379d 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -518,6 +518,18 @@
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>Service=</varname></term>
+ <listitem><para>Specifies the service
+ unit name to activate on incoming
+ traffic. This defaults to the service
+ that bears the same name as the socket
+ (ignoring the different suffixes). In
+ most cases it should not be necessary
+ to use this option.</para></listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 4395fb2..eba3fdb 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1226,6 +1226,40 @@ static int config_parse_path_unit(
return 0;
}
+static int config_parse_socket_service(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Socket *s = data;
+ int r;
+ DBusError error;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ dbus_error_init(&error);
+
+ if (endswith(rvalue, ".service")) {
+ log_error("[%s:%u] Unit must be of type serivce, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if ((r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, (Unit**) &s->service)) < 0) {
+ log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+ dbus_error_free(&error);
+ return 0;
+ }
+
+ return 0;
+}
+
static int config_parse_env_file(
const char *filename,
unsigned line,
@@ -1654,6 +1688,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "PipeSize", config_parse_size, &u->socket.pipe_size, "Socket" },
{ "FreeBind", config_parse_bool, &u->socket.free_bind, "Socket" },
{ "TCPCongestion", config_parse_string, &u->socket.tcp_congestion, "Socket" },
+ { "Service", config_parse_socket_service, &u->socket, "Socket" },
EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
{ "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" },
diff --git a/src/socket.c b/src/socket.c
index aacf9be..bbb54f6 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -212,6 +212,11 @@ static int socket_verify(Socket *s) {
return -EINVAL;
}
+ if (s->accept && s->service) {
+ log_error("Explicit service configuration for accepting sockets not supported on %s. Refusing.", s->meta.id);
+ return -EINVAL;
+ }
+
if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", s->meta.id);
return -EINVAL;
@@ -315,8 +320,10 @@ static int socket_load(Unit *u) {
if (u->meta.load_state == UNIT_LOADED) {
if (have_non_accept_socket(s)) {
- if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
- return r;
+
+ if (!s->service)
+ if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
+ return r;
if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0)
return r;
commit 20ed3656786a36f58a27901356e67d03cdd6de5e
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Sep 30 02:18:55 2010 +0200
man: fix suggested autoconf snippet
diff --git a/man/daemon.xml b/man/daemon.xml
index dac244c..46988ef 100644
--- a/man/daemon.xml
+++ b/man/daemon.xml
@@ -785,8 +785,10 @@
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
[], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
-AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
-AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"])</programlisting>
+if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])</programlisting>
<para>This snippet allows automatic
installation of the unit files on systemd
commit 0840ce2d4944bf1b14ed92f10db220991c1e94c9
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Sep 30 00:52:48 2010 +0200
readahead: ignore deleted files
diff --git a/src/readahead-collect.c b/src/readahead-collect.c
index 75e7a28..a9f544d 100644
--- a/src/readahead-collect.c
+++ b/src/readahead-collect.c
@@ -398,8 +398,8 @@ static int collect(const char *root) {
char_array_0(fn);
if ((k = readlink_malloc(fn, &p)) >= 0) {
-
if (startswith(p, "/tmp") ||
+ endswith(p, " (deleted)") ||
hashmap_get(files, p))
/* Not interesting, or
* already read */
More information about the systemd-commits
mailing list