[systemd-devel] [PATCH] Add support for supplying an exit status code to "systemctl exit"

Lennart Poettering lennart at poettering.net
Thu Nov 6 18:14:47 PST 2014


On Thu, 06.11.14 18:09, Vito Caputo (vito.caputo at coreos.com) wrote:

> The capability of directly propagating a return code out to the caller of
> systemd --user from within something like an OnFailure unit has utility.
> 
> This also contains a minor fixup to the documentation adding "exit" to the
> --force section.

Patch is borked, is line-broken. Please resend non-line-broken
version! It's so hard to review otherwise.

> 
> Cheers,
> Vito Caputo
> 
> ---
>  man/systemctl.xml         | 11 ++++++-----
>  src/core/dbus-manager.c   |  6 +++++-
>  src/core/main.c           |  2 +-
>  src/core/manager.c        |  1 +
>  src/core/manager.h        |  1 +
>  src/systemctl/systemctl.c | 20 ++++++++++++++++++--
>  6 files changed, 32 insertions(+), 9 deletions(-)
> 
> diff --git a/man/systemctl.xml b/man/systemctl.xml
> index 7cbaa6c..25ad2f7 100644
> --- a/man/systemctl.xml
> +++ b/man/systemctl.xml
> @@ -432,9 +432,9 @@ along with systemd; If not, see <
> http://www.gnu.org/licenses/>.
>            <para>When used with <command>enable</command>, overwrite
>            any existing conflicting symlinks.</para>
> 
> -          <para>When used with <command>halt</command>,
> -          <command>poweroff</command>, <command>reboot</command> or
> -          <command>kexec</command>, execute the selected operation
> +         <para>When used with <command>exit</command>,
> <command>halt</command>,
> +         <command>poweroff</command>, <command>reboot</command> or
> +         <command>kexec</command>, execute the selected operation
>            without shutting down all units. However, all processes will
>            be killed forcibly and all file systems are unmounted or
>            remounted read-only. This is hence a drastic but relatively
> @@ -1485,13 +1485,14 @@ kobject-uevent 1 systemd-udevd-kernel.socket
> systemd-udevd.service
>            </listitem>
>          </varlistentry>
>          <varlistentry>
> -          <term><command>exit</command></term>
> +          <term><command>exit
> <optional><replaceable>STATUS</replaceable></optional></command></term>
> 
>            <listitem>
>              <para>Ask the systemd manager to quit. This is only
>              supported for user service managers (i.e. in conjunction
>              with the <option>--user</option> option) and will fail
> -            otherwise.</para>
> +            otherwise.  Used in conjunction with --force a status code may
> be
> +           propagated into the sytemd manager's exit code.</para>
>            </listitem>
> 
>          </varlistentry>
> diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
> index c54abd3..78f7f6d 100644
> --- a/src/core/dbus-manager.c
> +++ b/src/core/dbus-manager.c
> @@ -1140,6 +1140,10 @@ static int method_exit(sd_bus *bus, sd_bus_message
> *message, void *userdata, sd_
>          if (m->running_as == SYSTEMD_SYSTEM)
>                  return sd_bus_error_setf(error,
> SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service
> managers.");
> 
> +        r = sd_bus_message_read(message, "i", &m->exit_retval);
> +        if (r < 0)
> +                return r;
> +
>          m->exit_code = MANAGER_EXIT;
> 
>          return sd_bus_reply_method_return(message, NULL);
> @@ -1918,7 +1922,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
>          SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot,
> 0),
>          SD_BUS_METHOD("Reload", NULL, NULL, method_reload,
> SD_BUS_VTABLE_UNPRIVILEGED),
>          SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute,
> SD_BUS_VTABLE_UNPRIVILEGED),
> -        SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
> +        SD_BUS_METHOD("Exit", "i", NULL, method_exit, 0),
>          SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot,
> SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
>          SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff,
> SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
>          SD_BUS_METHOD("Halt", NULL, NULL, method_halt,
> SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
> diff --git a/src/core/main.c b/src/core/main.c
> index d48604e..2481f5c 100644
> --- a/src/core/main.c
> +++ b/src/core/main.c
> @@ -1737,7 +1737,7 @@ int main(int argc, char *argv[]) {
>                  switch (m->exit_code) {
> 
>                  case MANAGER_EXIT:
> -                        retval = EXIT_SUCCESS;
> +                        retval = m->exit_retval;
>                          log_debug("Exit.");
>                          goto finish;
> 
> diff --git a/src/core/manager.c b/src/core/manager.c
> index 129f6dd..e417514 100644
> --- a/src/core/manager.c
> +++ b/src/core/manager.c
> @@ -550,6 +550,7 @@ int manager_new(SystemdRunningAs running_as, bool
> test_run, Manager **_m) {
> 
>          m->running_as = running_as;
>          m->exit_code = _MANAGER_EXIT_CODE_INVALID;
> +        m->exit_retval = EXIT_SUCCESS;
>          m->default_timer_accuracy_usec = USEC_PER_MINUTE;
> 
>          m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] =
> m->idle_pipe[3] = -1;
> diff --git a/src/core/manager.h b/src/core/manager.h
> index ab72548..ef96e03 100644
> --- a/src/core/manager.h
> +++ b/src/core/manager.h
> @@ -232,6 +232,7 @@ struct Manager {
>          /* Flags */
>          SystemdRunningAs running_as;
>          ManagerExitCode exit_code:5;
> +        int exit_retval;
> 
>          bool dispatching_load_queue:1;
>          bool dispatching_dbus_queue:1;
> diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
> index d9e9c2a..11c7e55 100644
> --- a/src/systemctl/systemctl.c
> +++ b/src/systemctl/systemctl.c
> @@ -4875,6 +4875,22 @@ static int daemon_reload(sd_bus *bus, char **args) {
>          if (r < 0)
>                  return bus_log_create_error(r);
> 
> +        if (streq(method, "Exit")) {
> +                int retval = EXIT_SUCCESS;
> +
> +                if (strv_length(args) > 1) {
> +                        r = safe_atoi(args[1], &retval);
> +                        if (r < 0) {
> +                                log_error("Invalid exit status: %s",
> strerror(-r));
> +                                return -EINVAL;
> +                        }
> +                }
> +
> +                r = sd_bus_message_append(m, "i", retval);
> +                if (r < 0)
> +                        return bus_log_create_error(r);
> +        }
> +
>          r = sd_bus_message_set_allow_interactive_authorization(m,
> arg_ask_password);
>          if (r < 0)
>                  return bus_log_create_error(r);
> @@ -5849,7 +5865,7 @@ static void systemctl_help(void) {
>                 "  poweroff                        Shut down and power-off
> the system\n"
>                 "  reboot [ARG]                    Shut down and reboot the
> system\n"
>                 "  kexec                           Shut down and reboot the
> system with kexec\n"
> -               "  exit                            Request user instance
> exit\n"
> +               "  exit [STATUS]                   Request user instance
> exit\n"
>                 "  switch-root ROOT [INIT]         Change to a different
> root file system\n"
>                 "  suspend                         Suspend the system\n"
>                 "  hibernate                       Hibernate the system\n"
> @@ -6815,7 +6831,7 @@ static int systemctl_main(sd_bus *bus, int argc, char
> *argv[], int bus_error) {
>                  { "default",               EQUAL, 1, start_special     },
>                  { "rescue",                EQUAL, 1, start_special     },
>                  { "emergency",             EQUAL, 1, start_special     },
> -                { "exit",                  EQUAL, 1, start_special     },
> +                { "exit",                  LESS,  2, start_special     },
>                  { "reset-failed",          MORE,  1, reset_failed      },
>                  { "enable",                MORE,  2, enable_unit,
> NOBUS },
>                  { "disable",               MORE,  2, enable_unit,
> NOBUS },
> --
> 2.1.1

> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel



Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list