[systemd-commits] 4 commits - man/systemd.service.xml src/core src/machine src/nspawn src/shared units/systemd-nspawn at .service.in

Lennart Poettering lennart at kemper.freedesktop.org
Thu Jul 3 03:52:06 PDT 2014


 man/systemd.service.xml               |   19 +++++++++++++----
 src/core/load-fragment-gperf.gperf.m4 |    3 +-
 src/core/service.c                    |   38 +++++++++++++++-------------------
 src/core/service.h                    |    3 +-
 src/machine/machine.c                 |   10 +++++---
 src/machine/machine.h                 |    1 
 src/machine/machined-dbus.c           |    1 
 src/nspawn/nspawn.c                   |   15 +++++++++++++
 src/shared/architecture.c             |    1 
 src/shared/exit-status.c              |    8 +++++++
 src/shared/exit-status.h              |    2 +
 units/systemd-nspawn at .service.in      |    2 +
 12 files changed, 72 insertions(+), 31 deletions(-)

New commits:
commit 9b3a0ba3e9e28382a1072bf0e2c07a3661432743
Author: Umut Tezduyar Lindskog <umut.tezduyar at axis.com>
Date:   Thu Jul 3 09:54:45 2014 +0200

    arch: add crisv32 to uname check

diff --git a/src/shared/architecture.c b/src/shared/architecture.c
index 9e0c3ef..7dd049a 100644
--- a/src/shared/architecture.c
+++ b/src/shared/architecture.c
@@ -116,6 +116,7 @@ Architecture uname_architecture(void) {
                 { "tilegx",     ARCHITECTURE_TILEGX   },
 #elif defined(__cris__)
                 { "cris",       ARCHITECTURE_CRIS     },
+                { "crisv32",    ARCHITECTURE_CRIS     },
 #else
 #error "Please register your architecture here!"
 #endif

commit ce38dbc84b40148026801dd29fd0ad1f1b25d3fb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 3 12:50:11 2014 +0200

    nspawn: when running in a service unit, use systemd for restarts
    
    THis way we can remove cgroup priviliges after setup, but get them back
    for the next restart, as we need it.

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 656c1bf..0d538c2 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3342,6 +3342,21 @@ int main(int argc, char *argv[]) {
                         break;
 
                 /* CONTAINER_REBOOTED, loop again */
+
+                if (arg_keep_unit) {
+                        /* Special handling if we are running as a
+                         * service: instead of simply restarting the
+                         * machine we want to restart the entire
+                         * service, so let's inform systemd about this
+                         * with the special exit code 133. The service
+                         * file uses RestartForceExitStatus=133 so
+                         * that this results in a full nspawn
+                         * restart. This is necessary since we might
+                         * have cgroup parameters set we want to have
+                         * flushed out. */
+                        r = 133;
+                        break;
+                }
         }
 
 finish:
diff --git a/units/systemd-nspawn at .service.in b/units/systemd-nspawn at .service.in
index e373628..574d0de 100644
--- a/units/systemd-nspawn at .service.in
+++ b/units/systemd-nspawn at .service.in
@@ -13,6 +13,8 @@ Documentation=man:systemd-nspawn(1)
 ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=guest --directory=/var/lib/container/%i
 KillMode=mixed
 Type=notify
+RestartForceExitStatus=133
+SuccessExitStatus=133
 
 [Install]
 WantedBy=multi-user.target

commit 206e7a5f7b55ac61188efd895e65ab26e478cbb2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 3 12:48:51 2014 +0200

    machined: don't force terminate registered machines
    
    When a machine is registered in machined with CreateMachine it is OK to
    kill the machine when it is terminated, but when an existing unit is
    simply registered via RegisterMachine we shouldn't do that, as the unit
    is controlled by somebody else.

diff --git a/src/machine/machine.c b/src/machine/machine.c
index 0b0d45b..c0fa1b2 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -360,10 +360,12 @@ static int machine_stop_scope(Machine *m) {
         if (!m->unit)
                 return 0;
 
-        r = manager_stop_unit(m->manager, m->unit, &error, &job);
-        if (r < 0) {
-                log_error("Failed to stop machine scope: %s", bus_error_message(&error, r));
-                return r;
+        if (!m->registered) {
+                r = manager_stop_unit(m->manager, m->unit, &error, &job);
+                if (r < 0) {
+                        log_error("Failed to stop machine scope: %s", bus_error_message(&error, r));
+                        return r;
+                }
         }
 
         free(m->scope_job);
diff --git a/src/machine/machine.h b/src/machine/machine.h
index a894a46..ed1c81c 100644
--- a/src/machine/machine.h
+++ b/src/machine/machine.h
@@ -72,6 +72,7 @@ struct Machine {
 
         bool in_gc_queue:1;
         bool started:1;
+        bool registered:1;
 
         sd_bus_message *create_message;
 
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 6f8ba47..7c1802c 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -223,6 +223,7 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
         m->leader = leader;
         m->class = c;
         m->id = id;
+        m->registered = true;
 
         if (!isempty(service)) {
                 m->service = strdup(service);

commit 37520c1bec9a92adbe02fceaece588a7aa2fea2b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 3 12:47:40 2014 +0200

    core: introduce new RestartForceExitStatus= service setting
    
    This does the inverse of RestartPreventExitStatus=: it forces a restart
    of a service when a certain exit status is returned by a service
    process.

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 1d80480..7f7d49e 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -857,7 +857,7 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 definitions can either be numeric exit
                                 codes or termination signal names,
                                 separated by spaces. For example:
-                                <programlisting>SuccessExitStatus=1 2 8 <constant>SIGKILL</constant></programlisting>
+                                <programlisting>SuccessExitStatus=1 2 8 SIGKILL</programlisting>
                                 ensures that exit codes 1, 2, 8 and
                                 the termination signal
                                 <constant>SIGKILL</constant> are
@@ -897,9 +897,8 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 spaces. Defaults to the empty list, so
                                 that, by default, no exit status is
                                 excluded from the configured restart
-                                logic. Example:
-                                <literal>RestartPreventExitStatus=1 6
-                                SIGABRT</literal>, ensures that exit
+                                logic. For example:
+                                <programlisting>RestartPreventExitStatus=1 6 SIGABRT</programlisting> ensures that exit
                                 codes 1 and 6 and the termination
                                 signal <constant>SIGABRT</constant> will
                                 not result in automatic service
@@ -914,6 +913,18 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>RestartForceExitStatus=</varname></term>
+                                <listitem><para>Takes a list of exit
+                                status definitions that when returned
+                                by the main service process will force
+                                automatic service restarts, regardless
+                                of the restart setting configured with
+                                <varname>Restart=</varname>. The
+                                argument format is similar to
+                                <varname>RestartPreventExitStatus=</varname>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>PermissionsStartOnly=</varname></term>
                                 <listitem><para>Takes a boolean
                                 argument. If true, the permission-related
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 4f3731b..a7c4469 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -194,7 +194,8 @@ Service.PermissionsStartOnly,    config_parse_bool,                  0,
 Service.RootDirectoryStartOnly,  config_parse_bool,                  0,                             offsetof(Service, root_directory_start_only)
 Service.RemainAfterExit,         config_parse_bool,                  0,                             offsetof(Service, remain_after_exit)
 Service.GuessMainPID,            config_parse_bool,                  0,                             offsetof(Service, guess_main_pid)
-Service.RestartPreventExitStatus, config_parse_set_status,           0,                             offsetof(Service, restart_ignore_status)
+Service.RestartPreventExitStatus, config_parse_set_status,           0,                             offsetof(Service, restart_prevent_status)
+Service.RestartForceExitStatus,  config_parse_set_status,            0,                             offsetof(Service, restart_force_status)
 Service.SuccessExitStatus,       config_parse_set_status,            0,                             offsetof(Service, success_status)
 m4_ifdef(`HAVE_SYSV_COMPAT',
 `Service.SysVStartPriority,      config_parse_sysv_priority,         0,                             offsetof(Service, sysv_start_priority)',
diff --git a/src/core/service.c b/src/core/service.c
index 10dc79c..e221899 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -266,15 +266,9 @@ static void service_done(Unit *u) {
         s->control_command = NULL;
         s->main_command = NULL;
 
-        set_free(s->restart_ignore_status.code);
-        s->restart_ignore_status.code = NULL;
-        set_free(s->restart_ignore_status.signal);
-        s->restart_ignore_status.signal = NULL;
-
-        set_free(s->success_status.code);
-        s->success_status.code = NULL;
-        set_free(s->success_status.signal);
-        s->success_status.signal = NULL;
+        exit_status_set_free(&s->restart_prevent_status);
+        exit_status_set_free(&s->restart_force_status);
+        exit_status_set_free(&s->success_status);
 
         /* This will leak a process, but at least no memory or any of
          * our resources */
@@ -337,7 +331,12 @@ static int service_verify(Service *s) {
         }
 
         if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) {
-                log_error_unit(UNIT(s)->id, "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                log_error_unit(UNIT(s)->id, "%s has Restart= setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->type == SERVICE_ONESHOT && !(set_isempty(s->restart_force_status.signal) && set_isempty(s->restart_force_status.code))) {
+                log_error_unit(UNIT(s)->id, "%s has RestartForceStatus= set, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
                 return -EINVAL;
         }
 
@@ -1071,11 +1070,11 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
              (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) ||
              (s->restart == SERVICE_RESTART_ON_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) ||
              (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) ||
-             (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP))) &&
-            (s->result != SERVICE_FAILURE_EXIT_CODE ||
-             !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) &&
-            (s->result != SERVICE_FAILURE_SIGNAL ||
-             !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
+             (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) ||
+             (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.code, INT_TO_PTR(s->main_exec_status.status))) ||
+             (IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) && set_contains(s->restart_force_status.signal, INT_TO_PTR(s->main_exec_status.status)))) &&
+            (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.code, INT_TO_PTR(s->main_exec_status.status))) &&
+            (!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
 
                 r = service_arm_timer(s, s->restart_usec);
                 if (r < 0)
@@ -1421,8 +1420,7 @@ static void service_enter_start_pre(Service *s) {
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id,
-                         "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
+        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
         service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
 }
 
@@ -1434,8 +1432,7 @@ static void service_enter_restart(Service *s) {
 
         if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) {
                 /* Don't restart things if we are going down anyway */
-                log_info_unit(UNIT(s)->id,
-                              "Stop job pending for unit, delaying automatic restart.");
+                log_info_unit(UNIT(s)->id, "Stop job pending for unit, delaying automatic restart.");
 
                 r = service_arm_timer(s, s->restart_usec);
                 if (r < 0)
@@ -1456,8 +1453,7 @@ static void service_enter_restart(Service *s) {
          * it will be canceled as part of the service_stop() call that
          * is executed as part of JOB_RESTART. */
 
-        log_debug_unit(UNIT(s)->id,
-                       "%s scheduled restart job.", UNIT(s)->id);
+        log_debug_unit(UNIT(s)->id, "%s scheduled restart job.", UNIT(s)->id);
         return;
 
 fail:
diff --git a/src/core/service.h b/src/core/service.h
index b8f0e0c..7406d90 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -118,7 +118,8 @@ struct Service {
 
         ServiceType type;
         ServiceRestart restart;
-        ExitStatusSet restart_ignore_status;
+        ExitStatusSet restart_prevent_status;
+        ExitStatusSet restart_force_status;
         ExitStatusSet success_status;
 
         /* If set we'll read the main daemon PID from this file */
diff --git a/src/shared/exit-status.c b/src/shared/exit-status.c
index ce1f1bd..38d71e1 100644
--- a/src/shared/exit-status.c
+++ b/src/shared/exit-status.c
@@ -208,3 +208,11 @@ bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
                 code == CLD_EXITED &&
                 (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
 }
+
+void exit_status_set_free(ExitStatusSet *x) {
+        assert(x);
+
+        set_free(x->code);
+        set_free(x->signal);
+        x->code = x->signal = NULL;
+}
diff --git a/src/shared/exit-status.h b/src/shared/exit-status.h
index 57d066f..93abf7f 100644
--- a/src/shared/exit-status.h
+++ b/src/shared/exit-status.h
@@ -95,3 +95,5 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) _con
 
 bool is_clean_exit(int code, int status, ExitStatusSet *success_status);
 bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status);
+
+void exit_status_set_free(ExitStatusSet *x);



More information about the systemd-commits mailing list