[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