static list initial_proto_list;
static list flush_proto_list;
+static int proto_shutdown_counter;
+
static event *proto_flush_event;
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
static void
proto_set_goal(struct proto *p, unsigned goal)
{
- if (p->disabled)
+ if (p->disabled || shutting_down)
goal = FS_HUNGRY;
p->core_goal = goal;
proto_rethink_goal(p);
proto_set_goal(p, FS_HAPPY);
}
+void
+protos_shutdown(void)
+{
+ struct proto *p, *n;
+
+ debug("Protocol shutdown\n");
+ WALK_LIST_DELSAFE(p, n, inactive_proto_list)
+ if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN)
+ {
+ proto_shutdown_counter++;
+ proto_set_goal(p, FS_HUNGRY);
+ }
+ WALK_LIST_DELSAFE(p, n, proto_list)
+ {
+ proto_shutdown_counter++;
+ proto_set_goal(p, FS_HUNGRY);
+ }
+}
+
void
protos_dump_all(void)
{
proto_fell_down(struct proto *p)
{
DBG("Protocol %s down\n", p->name);
+ if (!--proto_shutdown_counter)
+ protos_shutdown_notify();
proto_rethink_goal(p);
}
cs = FS_FLUSHING;
ev_schedule(proto_flush_event);
}
+ break;
default:
error:
bug("Invalid state transition for %s from %s/%s to */%s", p->name, c_states[cs], p_states[ops], p_states[ps]);
p->pool = NULL;
p->core_state = FS_HUNGRY;
proto_relink(p);
- proto_rethink_goal(p);
+ proto_fell_down(p);
}
}
void protos_commit(struct config *);
void protos_start(void);
void protos_dump_all(void);
+void protos_shutdown(void);
extern list protocol_list;
extern struct proto_config *cf_dev_proto;
+/*
+ * Callback to sysdep code when shutdown is finished
+ */
+
+void protos_shutdown_notify(void);
+
#endif
#include "unix.h"
#include "krt.h"
+int shutting_down;
+
/*
* Debugging
*/
debug("Asynchronous reconfigurations are not supported in demo version\n");
}
+/*
+ * Shutdown
+ */
+
+void
+async_shutdown(void)
+{
+ debug("Shutting down...\n");
+ shutting_down = 1;
+ protos_shutdown();
+}
+
+void
+protos_shutdown_notify(void)
+{
+ die("System shutdown completed");
+}
+
/*
* Signals
*/
async_dump_flag = 1;
}
+static void
+handle_sigterm(int sig)
+{
+ debug("Caught SIGTERM...\n");
+ async_shutdown_flag = 1;
+}
+
static void
signal_init(void)
{
sa.sa_handler = handle_sighup;
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, NULL);
+ sa.sa_handler = handle_sigterm;
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGTERM, &sa, NULL);
signal(SIGPIPE, SIG_IGN);
}