diff options
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | fixme | 2 | ||||
-rw-r--r-- | man/systemd.special.xml.in | 30 | ||||
-rw-r--r-- | src/manager.c | 21 | ||||
-rw-r--r-- | src/manager.h | 1 | ||||
-rw-r--r-- | units/session/.gitignore | 1 | ||||
-rw-r--r-- | units/session/exit.service.in | 8 |
7 files changed, 60 insertions, 10 deletions
diff --git a/Makefile.am b/Makefile.am index a96b89d618..bd2523923e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -128,7 +128,8 @@ dist_sessionunit_DATA = \ units/session/default.target sessionunit_DATA = \ - units/session/remote-fs.target + units/session/remote-fs.target \ + units/session/exit.service EXTRA_DIST = \ units/basic.target.m4 \ @@ -139,6 +140,7 @@ EXTRA_DIST = \ units/systemd-initctl.service.in \ units/systemd-logger.service.in \ units/syslog.target.in \ + units/session/exit.service.in \ LICENSE \ README \ DISTRO_PORTING @@ -359,6 +361,8 @@ SED_PROCESS = \ $(SED) -e 's,@libexecdir\@,$(libexecdir),g' \ -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \ -e 's,@SPECIAL_SYSLOG_SERVICE\@,$(SPECIAL_SYSLOG_SERVICE),g' \ + -e 's,@SPECIAL_DBUS_SERVICE\@,$(SPECIAL_DBUS_SERVICE),g' \ + -e 's,@SYSTEMCTL\@,$(bindir)/systemctl,g' \ < $< > $@ units/%: units/%.in Makefile @@ -391,6 +395,7 @@ CLEANFILES = \ units/multi-user.target \ units/remote-fs.target \ units/session/remote-fs.target \ + units/session/exit.service \ man/systemd.special.7 \ man/systemd.special.html @@ -64,8 +64,6 @@ * tcpwrap -* introduce exit.target for session instances - Regularly: * look for close() vs. close_nointr() vs. close_nointr_nofail() diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index 0af9c6e7bb..1c9e88c612 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -53,6 +53,7 @@ <filename>default.target</filename>, <filename>display-manager.service</filename>, <filename>emergency.service</filename>, + <filename>exit.service</filename>, <filename>graphical.target</filename>, <filename>halt.target</filename>, <filename>kbrequest.target</filename>, @@ -635,6 +636,35 @@ <filename>shutdown.target</filename>, <filename>sockets.target</filename>, <filename>swap.target</filename>.</para> + + <para>In addition the following special unit is + understood only when systemd runs as service instance:</para> + + <variablelist> + <varlistentry> + <term><filename>exit.service</filename></term> + <listitem> + <para>A special service unit + for shutting down the + session.</para> + + <para>Applications wanting to + terminate the session should + start this unit. If systemd + receives SIGTERM or SIGINT + when running as session daemon + it will start this + unit.</para> + + <para>Normally, this pulls in + <filename>shutdown.target</filename> + which in turn should be + conflicted by all units that + want to be shut down on + session exit.</para> + </listitem> + </varlistentry> + </variablelist> </refsect1> <refsect1> diff --git a/src/manager.c b/src/manager.c index 2a773c6dbb..933dd5064f 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1791,11 +1791,13 @@ static int manager_dispatch_sigchld(Manager *m) { return 0; } -static void manager_start_target(Manager *m, const char *name) { +static int manager_start_target(Manager *m, const char *name) { int r; if ((r = manager_add_job_by_name(m, JOB_START, name, JOB_REPLACE, true, NULL)) < 0) log_error("Failed to enqueue %s job: %s", name, strerror(-r)); + + return r; } static int manager_process_signal_fd(Manager *m) { @@ -1824,14 +1826,14 @@ static int manager_process_signal_fd(Manager *m) { break; case SIGTERM: - if (m->running_as == MANAGER_INIT) + if (m->running_as == MANAGER_INIT) { /* This is for compatibility with the * original sysvinit */ m->exit_code = MANAGER_REEXECUTE; - else - m->exit_code = MANAGER_EXIT; + break; + } - return 0; + /* Fall through */ case SIGINT: if (m->running_as == MANAGER_INIT) { @@ -1839,8 +1841,13 @@ static int manager_process_signal_fd(Manager *m) { break; } - m->exit_code = MANAGER_EXIT; - return 0; + /* Run the exit target if there is one, if not, just exit. */ + if (manager_start_target(m, SPECIAL_EXIT_SERVICE) < 0) { + m->exit_code = MANAGER_EXIT; + return 0; + } + + break; case SIGWINCH: if (m->running_as == MANAGER_INIT) diff --git a/src/manager.h b/src/manager.h index 22ba04f799..210e66053c 100644 --- a/src/manager.h +++ b/src/manager.h @@ -109,6 +109,7 @@ struct Watch { #define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ #define SPECIAL_BASIC_TARGET "basic.target" #define SPECIAL_RESCUE_TARGET "rescue.target" +#define SPECIAL_EXIT_SERVICE "exit.service" #ifndef SPECIAL_DBUS_SERVICE #define SPECIAL_DBUS_SERVICE "dbus.service" diff --git a/units/session/.gitignore b/units/session/.gitignore new file mode 100644 index 0000000000..eeb62b32ba --- /dev/null +++ b/units/session/.gitignore @@ -0,0 +1 @@ +exit.service diff --git a/units/session/exit.service.in b/units/session/exit.service.in new file mode 100644 index 0000000000..86c8bbc672 --- /dev/null +++ b/units/session/exit.service.in @@ -0,0 +1,8 @@ +[Unit] +Description=Exit +Requires=shutdown.target +After=shutdown.target + +[Service] +Type=finish +ExecStart=@SYSTEMCTL@ --session daemon-exit |