summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/pies.h5
-rw-r--r--src/progman.c74
-rw-r--r--tests/Makefile.am3
-rwxr-xr-xtests/aux/touchfile (renamed from tests/aux/startup)0
-rw-r--r--tests/shutdown.at58
-rw-r--r--tests/startup.at4
-rw-r--r--tests/testsuite.at1
7 files changed, 125 insertions, 20 deletions
diff --git a/src/pies.h b/src/pies.h
index bdc406b..74cb346 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -142,7 +142,10 @@ enum pies_comp_mode
components is delayed until the last startup component finishes. */
pies_comp_startup,
- /* FIXME: Runs before program termination */
+ /* Components of this type are run right before program termination.
+ They have shutdown_timeout seconds to finish their job and terminate
+ gracefully, othervise they will be terminated forcefully via SIGTERM
+ (and SIGKILL, for persisting ones). */
pies_comp_shutdown,
/*
diff --git a/src/progman.c b/src/progman.c
index a625885..bae82ba 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -287,7 +287,9 @@ register_prog0 (struct component *comp)
else
newp->v.p.status = status_stopped;
- if ((comp->flags & CF_DISABLED) || comp->mode == pies_comp_ondemand)
+ if ((comp->flags & CF_DISABLED)
+ || comp->mode == pies_comp_ondemand
+ || comp->mode == pies_comp_shutdown)
newp->active = 0;
else
newp->active = 1;
@@ -1795,21 +1797,6 @@ prog_stop (struct prog *prog, int sig)
kill (prog->pid, sig);
}
-static int
-mark_for_stopping (struct prog *prog, void *data)
-{
- if (IS_COMPONENT (prog))
- prog->stop = 1;
- return 0;
-}
-
-void
-progman_stop (void)
-{
- progman_foreach (mark_for_stopping, NULL);
- progman_gc ();
-}
-
static void
print_status (const char *tag, pid_t pid, int status, int expect_term)
{
@@ -2582,4 +2569,59 @@ progman_gc (void)
}
+static int
+start_shutdown (struct prog *prog, void *data)
+{
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_shutdown)
+ {
+ int *p = data;
+ if (!*p)
+ {
+ diagmsg (DIAG_CON, LOG_INFO, "Starting shutdown components");
+ *p = 1;
+ }
+ prog->active = 1;
+ prog_start (prog);
+ prog->stop = 1;
+ }
+ return 0;
+}
+
+void
+program_shutdown (void)
+{
+ time_t start = time (NULL);
+ int sd = 0;
+
+ /* Activate shutdown components. */
+ progman_foreach (start_shutdown, &sd);
+ while (prog_to_stop (proghead))
+ {
+ progman_cleanup (1);
+ if (time (NULL) - start < shutdown_timeout)
+ sleep (1);
+ else
+ {
+ progman_gc ();
+ break;
+ }
+ }
+}
+
+static int
+mark_for_stopping (struct prog *prog, void *data)
+{
+ if (IS_COMPONENT (prog))
+ prog->stop = 1;
+ return 0;
+}
+
+void
+progman_stop (void)
+{
+ progman_foreach (mark_for_stopping, NULL);
+ progman_gc ();
+ program_shutdown ();
+}
+
/* EOF */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b2f2719..b404ed4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -18,7 +18,7 @@ AUXTOOLS = \
aux/respawn\
aux/retcode\
aux/mailer\
- aux/startup
+ aux/touchfile
EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS)
DISTCLEANFILES = atconfig $(check_SCRIPTS)
@@ -53,6 +53,7 @@ TESTSUITE_AT = \
ret-exec.at\
ret-notify.at\
startup.at\
+ shutdown.at\
version.at
TESTSUITE = $(srcdir)/testsuite
diff --git a/tests/aux/startup b/tests/aux/touchfile
index b9d92a3..b9d92a3 100755
--- a/tests/aux/startup
+++ b/tests/aux/touchfile
diff --git a/tests/shutdown.at b/tests/shutdown.at
new file mode 100644
index 0000000..79bec37
--- a/dev/null
+++ b/tests/shutdown.at
@@ -0,0 +1,58 @@
+# This file is part of GNU pies testsuite. -*- Autotest -*-
+# Copyright (C) 2019 Sergey Poznyakoff
+#
+# GNU pies is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU pies is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU pies. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([Shutdown components])
+
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+comp_pid_file=$PWD/comp.pid
+
+cat > pies.conf <<_EOT
+component s {
+ mode shutdown;
+ command "$auxdir/touchfile $PWD 0 shutdown";
+}
+
+component test {
+ mode respawn;
+ command "$auxdir/respawn -append -pid $comp_pid_file";
+}
+_EOT
+
+pies --config-file control.conf --config-file pies.conf
+
+n=0
+while :
+do
+ if test -f $comp_pid_file; then
+ break
+ fi
+ sleep 1
+ n=$(($n + 1))
+ if test $n -gt 10; then
+ echo >&2 "timed out"
+ break
+ fi
+done
+
+PIES_STOP
+
+test -f shutdown
+])
+
+AT_CLEANUP
+
diff --git a/tests/startup.at b/tests/startup.at
index 72017ce..440c249 100644
--- a/tests/startup.at
+++ b/tests/startup.at
@@ -24,12 +24,12 @@ comp_pid_file=$PWD/comp.pid
cat > pies.conf <<_EOT
component b1 {
mode startup;
- command "$auxdir/startup $PWD 1 b1";
+ command "$auxdir/touchfile $PWD 1 b1";
}
component b2 {
mode startup;
- command "$auxdir/startup $PWD 2 b2";
+ command "$auxdir/touchfile $PWD 2 b2";
}
component test {
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2a1167d..6775ee7 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -66,3 +66,4 @@ m4_include([redirect.at])
m4_include([ret-exec.at])
m4_include([ret-notify.at])
m4_include([startup.at])
+m4_include([shutdown.at])

Return to:

Send suggestions and report system problems to the System administrator.