[systemd-commits] 5 commits - TODO man/systemd.service.xml src/core src/shared src/systemctl

Lennart Poettering lennart at kemper.freedesktop.org
Thu Aug 21 10:12:11 PDT 2014


 TODO                      |    2 -
 man/systemd.service.xml   |   44 ++++++++++++++++++++------------
 src/core/service.c        |   62 +++++++++++++++++++++++++++++-----------------
 src/shared/install.c      |   27 +++++++++-----------
 src/shared/path-lookup.h  |    4 +-
 src/systemctl/systemctl.c |   14 +++-------
 6 files changed, 87 insertions(+), 66 deletions(-)

New commits:
commit 4fe1be9ce2e0cca6354a4167f0a1a7e1f943c91c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Aug 21 19:10:26 2014 +0200

    systemctl: in list-unit-files, always show legend, even if we know about no unit files

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 072f615..d9b8bee 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1351,11 +1351,8 @@ static int list_unit_files(sd_bus *bus, char **args) {
 
                 n_units = hashmap_size(h);
 
-                if (n_units == 0)
-                        return 0;
-
                 units = new(UnitFileList, n_units);
-                if (!units) {
+                if (!units && n_units > 0) {
                         unit_file_list_free(h);
                         return log_oom();
                 }
@@ -1411,14 +1408,13 @@ static int list_unit_files(sd_bus *bus, char **args) {
                         return bus_log_parse_error(r);
         }
 
-        if (c > 0) {
-                qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
-                output_unit_file_list(units, c);
-        }
+        qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
+        output_unit_file_list(units, c);
 
-        if (avoid_bus())
+        if (avoid_bus()) {
                 for (unit = units; unit < units + c; unit++)
                         free(unit->path);
+        }
 
         return 0;
 }

commit 59ccf93d97f0a37522e5f4fbf5cc0288dbedf495
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Aug 21 19:08:30 2014 +0200

    install: simplify usage of _cleanup_ macros

diff --git a/src/shared/install.c b/src/shared/install.c
index 03c7a9d..4b09a69 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -45,8 +45,6 @@ typedef struct {
         Hashmap *have_installed;
 } InstallContext;
 
-#define _cleanup_install_context_done_ _cleanup_(install_context_done)
-
 static int in_search_path(const char *path, char **search) {
         _cleanup_free_ char *parent = NULL;
         int r;
@@ -1161,7 +1159,7 @@ static int unit_file_can_install(
                 const char *name,
                 bool allow_symlink) {
 
-        _cleanup_install_context_done_ InstallContext c = {};
+        _cleanup_(install_context_done) InstallContext c = {};
         InstallInfo *i;
         int r;
 
@@ -1498,7 +1496,7 @@ int unit_file_enable(
                 unsigned *n_changes) {
 
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
-        _cleanup_install_context_done_ InstallContext c = {};
+        _cleanup_(install_context_done) InstallContext c = {};
         char **i;
         _cleanup_free_ char *config_path = NULL;
         int r;
@@ -1537,7 +1535,7 @@ int unit_file_disable(
                 unsigned *n_changes) {
 
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
-        _cleanup_install_context_done_ InstallContext c = {};
+        _cleanup_(install_context_done) InstallContext c = {};
         char **i;
         _cleanup_free_ char *config_path = NULL;
         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
@@ -1597,7 +1595,7 @@ int unit_file_set_default(
                 unsigned *n_changes) {
 
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
-        _cleanup_install_context_done_ InstallContext c = {};
+        _cleanup_(install_context_done) InstallContext c = {};
         _cleanup_free_ char *config_path = NULL;
         char *path;
         int r;
@@ -1859,7 +1857,7 @@ int unit_file_preset(
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
-        _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
+        _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
         _cleanup_free_ char *config_path = NULL;
         char **i;
@@ -1927,7 +1925,7 @@ int unit_file_preset_all(
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
-        _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
+        _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
         _cleanup_free_ char *config_path = NULL;
         char **i;
@@ -2019,14 +2017,15 @@ int unit_file_preset_all(
         return r;
 }
 
-static void unitfilelist_free(UnitFileList **f) {
-        if (!*f)
+static void unit_file_list_free_one(UnitFileList *f) {
+        if (!f)
                 return;
 
-        free((*f)->path);
-        free(*f);
+        free(f->path);
+        free(f);
 }
-#define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
 
 int unit_file_get_list(
                 UnitFileScope scope,
@@ -2071,7 +2070,7 @@ int unit_file_get_list(
                 }
 
                 for (;;) {
-                        _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
+                        _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
                         struct dirent *de;
 
                         errno = 0;
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
index 2fe8173..4bbd47e 100644
--- a/src/shared/path-lookup.h
+++ b/src/shared/path-lookup.h
@@ -38,8 +38,6 @@ typedef enum SystemdRunningAs {
         _SYSTEMD_RUNNING_AS_INVALID = -1
 } SystemdRunningAs;
 
-#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
-
 int user_config_home(char **config_home);
 
 int lookup_paths_init(LookupPaths *p,
@@ -50,3 +48,5 @@ int lookup_paths_init(LookupPaths *p,
                       const char *generator_early,
                       const char *generator_late);
 void lookup_paths_free(LookupPaths *p);
+
+#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)

commit 96fb8242cc1ef6b0e28f6c86a4f57950095dd7f1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Aug 21 18:50:42 2014 +0200

    service: allow services of Type=oneshot that specify no ExecStart= commands
    
    This is useful for services that simply want to run something on
    shutdown, but not at bootup. They should only set ExecStop= but leave
    ExecStart= unset.

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 5c4bd65..e584a1f 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -139,9 +139,10 @@
 
                                 <para>If set to
                                 <option>simple</option> (the default
-                                value if neither
+                                if neither
                                 <varname>Type=</varname> nor
-                                <varname>BusName=</varname> are
+                                <varname>BusName=</varname>, but
+                                <varname>ExecStart=</varname> are
                                 specified), it is expected that the
                                 process configured with
                                 <varname>ExecStart=</varname> is the
@@ -177,13 +178,17 @@
                                 exits.</para>
 
                                 <para>Behavior of
-                                <option>oneshot</option> is similar
-                                to <option>simple</option>; however,
-                                it is expected that the process has to
+                                <option>oneshot</option> is similar to
+                                <option>simple</option>; however, it
+                                is expected that the process has to
                                 exit before systemd starts follow-up
                                 units. <varname>RemainAfterExit=</varname>
                                 is particularly useful for this type
-                                of service.</para>
+                                of service. This is the implied
+                                default if neither
+                                <varname>Type=</varname> or
+                                <varname>ExecStart=</varname> are
+                                specified.</para>
 
                                 <para>Behavior of
                                 <option>dbus</option> is similar to
@@ -313,22 +318,27 @@
 
                                 <para>When <varname>Type</varname> is
                                 not <option>oneshot</option>, only one
-                                command may be given. When
+                                command may and must be given. When
                                 <varname>Type=oneshot</varname> is
-                                used, more than one command may be
-                                specified. Multiple command lines may
-                                be concatenated in a single directive
-                                by separating them with semicolons
-                                (these semicolons must be passed as
-                                separate words). Alternatively, this
-                                directive may be specified more than
-                                once with the same effect.
-                                Lone semicolons may be escaped as
+                                used, none or more than one command
+                                may be specified. Multiple command
+                                lines may be concatenated in a single
+                                directive by separating them with
+                                semicolons (these semicolons must be
+                                passed as separate
+                                words). Alternatively, this directive
+                                may be specified more than once with
+                                the same effect.  Lone semicolons may
+                                be escaped as
                                 <literal>\;</literal>. If the empty
                                 string is assigned to this option, the
                                 list of commands to start is reset,
                                 prior assignments of this option will
-                                have no effect.</para>
+                                have no effect. If no
+                                <varname>ExecStart=</varname> is
+                                specified, then the service must have
+                                <varname>RemainAfterExit=yes</varname>
+                                set.</para>
 
                                 <para>Each command line is split on
                                 whitespace, with the first item being
diff --git a/src/core/service.c b/src/core/service.c
index 7d6ea73..1b864c4 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -313,14 +313,23 @@ static int service_verify(Service *s) {
         if (UNIT(s)->load_state != UNIT_LOADED)
                 return 0;
 
-        if (!s->exec_command[SERVICE_EXEC_START]) {
-                log_error_unit(UNIT(s)->id, "%s lacks ExecStart setting. Refusing.", UNIT(s)->id);
+        if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) {
+                log_error_unit(UNIT(s)->id, "%s lacks both ExecStart= and ExecStop= setting. Refusing.", UNIT(s)->id);
                 return -EINVAL;
         }
 
-        if (s->type != SERVICE_ONESHOT &&
-            s->exec_command[SERVICE_EXEC_START]->command_next) {
-                log_error_unit(UNIT(s)->id, "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+        if (s->type != SERVICE_ONESHOT && !s->exec_command[SERVICE_EXEC_START]) {
+                log_error_unit(UNIT(s)->id, "%s has no ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START]) {
+                log_error_unit(UNIT(s)->id, "%s has no ExecStart= setting, which is only allowed for RemainAfterExit=yes services. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->type != SERVICE_ONESHOT && s->exec_command[SERVICE_EXEC_START]->command_next) {
+                log_error_unit(UNIT(s)->id, "%s has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
                 return -EINVAL;
         }
 
@@ -410,8 +419,15 @@ static int service_load(Unit *u) {
                 if (r < 0)
                         return r;
 
-                if (s->type == _SERVICE_TYPE_INVALID)
-                        s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE;
+                if (s->type == _SERVICE_TYPE_INVALID) {
+                        /* Figure out a type automatically */
+                        if (s->bus_name)
+                                s->type = SERVICE_DBUS;
+                        else if (s->exec_command[SERVICE_EXEC_START])
+                                s->type = SERVICE_SIMPLE;
+                        else
+                                s->type = SERVICE_ONESHOT;
+                }
 
                 /* Oneshot services have disabled start timeout by default */
                 if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
@@ -1309,9 +1325,6 @@ static void service_enter_start(Service *s) {
 
         assert(s);
 
-        assert(s->exec_command[SERVICE_EXEC_START]);
-        assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT);
-
         service_unwatch_control_pid(s);
         service_unwatch_main_pid(s);
 
@@ -1332,6 +1345,12 @@ static void service_enter_start(Service *s) {
                 c = s->main_command = s->exec_command[SERVICE_EXEC_START];
         }
 
+        if (!c) {
+                assert(s->type == SERVICE_ONESHOT);
+                service_enter_start_post(s);
+                return;
+        }
+
         r = service_spawn(s,
                           c,
                           IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_ONESHOT) ? s->timeout_start_usec : 0,

commit 1954ea346dc28226c0fffde848d49a297165b0a9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Aug 21 18:01:47 2014 +0200

    update TODO

diff --git a/TODO b/TODO
index 868518a..16b61d0 100644
--- a/TODO
+++ b/TODO
@@ -40,8 +40,6 @@ Features:
 
 * merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share....
 
-* make "systemctl suspend" block until we are back from suspend
-
 * remove readahead in 217
 
 * journald: allows specification of UID range for splitting up journal files

commit 21b2ce39d4038cd6176394836fdcfb7fba63f424
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Aug 21 18:01:22 2014 +0200

    service: use the right timeout for stop processes we fork

diff --git a/src/core/service.c b/src/core/service.c
index 3221938..7d6ea73 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -862,7 +862,7 @@ fail:
 static int service_spawn(
                 Service *s,
                 ExecCommand *c,
-                bool timeout,
+                usec_t timeout,
                 bool pass_fds,
                 bool apply_permissions,
                 bool apply_chroot,
@@ -907,8 +907,8 @@ static int service_spawn(
                 }
         }
 
-        if (timeout && s->timeout_start_usec > 0) {
-                r = service_arm_timer(s, s->timeout_start_usec);
+        if (timeout > 0) {
+                r = service_arm_timer(s, timeout);
                 if (r < 0)
                         goto fail;
         } else
@@ -1108,7 +1108,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
 
                 r = service_spawn(s,
                                   s->control_command,
-                                  true,
+                                  s->timeout_stop_usec,
                                   false,
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
@@ -1207,7 +1207,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
 
                 r = service_spawn(s,
                                   s->control_command,
-                                  true,
+                                  s->timeout_stop_usec,
                                   false,
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
@@ -1270,7 +1270,7 @@ static void service_enter_start_post(Service *s) {
 
                 r = service_spawn(s,
                                   s->control_command,
-                                  true,
+                                  s->timeout_start_usec,
                                   false,
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
@@ -1334,8 +1334,7 @@ static void service_enter_start(Service *s) {
 
         r = service_spawn(s,
                           c,
-                          s->type == SERVICE_FORKING || s->type == SERVICE_DBUS ||
-                            s->type == SERVICE_NOTIFY || s->type == SERVICE_ONESHOT,
+                          IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_ONESHOT) ? s->timeout_start_usec : 0,
                           true,
                           true,
                           true,
@@ -1401,7 +1400,7 @@ static void service_enter_start_pre(Service *s) {
 
                 r = service_spawn(s,
                                   s->control_command,
-                                  true,
+                                  s->timeout_start_usec,
                                   false,
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
@@ -1482,7 +1481,7 @@ static void service_enter_reload(Service *s) {
 
                 r = service_spawn(s,
                                   s->control_command,
-                                  true,
+                                  s->timeout_start_usec,
                                   false,
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
@@ -1519,7 +1518,7 @@ static void service_run_next_control(Service *s) {
 
         r = service_spawn(s,
                           s->control_command,
-                          true,
+                          IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD) ? s->timeout_start_usec : s->timeout_stop_usec,
                           false,
                           !s->permissions_start_only,
                           !s->root_directory_start_only,
@@ -1563,7 +1562,7 @@ static void service_run_next_main(Service *s) {
 
         r = service_spawn(s,
                           s->main_command,
-                          true,
+                          s->timeout_start_usec,
                           true,
                           true,
                           true,



More information about the systemd-commits mailing list