diff options
author | Jannis Pohlmann <jannis.pohlmann@codethink.co.uk> | 2012-08-06 13:06:43 +0100 |
---|---|---|
committer | Jannis Pohlmann <jannis.pohlmann@codethink.co.uk> | 2012-08-06 14:11:59 +0100 |
commit | 39dcfd5d9381c4494fad324b50588f9df1bc946e (patch) | |
tree | 2686371bdf2d15b81d709231e437e46ba330ace6 | |
parent | 53d25fc8ddba4de1340cad4885ba9fce880bc3fe (diff) | |
download | node-startup-controller-39dcfd5d9381c4494fad324b50588f9df1bc946e.tar.gz |
Unregister all shutdown consumers when receiving SIGTERM
systemd uses SIGTERM to stop its units. We want to cleanly shut down
the NSC when receiving this signal. Part of that is to unregister all
shutdown consumers. If we don't do this, the NSM will later during its
shutdown phase call all shutdown consumers registered by the NSC. And
if the NSC was no longer running, this would cause the NSM to wait for a
timeout for every single one of these shutdown consumers. Obviously,
that is not desirable.
-rw-r--r-- | node-startup-controller/node-startup-controller-application.c | 125 |
1 files changed, 88 insertions, 37 deletions
diff --git a/node-startup-controller/node-startup-controller-application.c b/node-startup-controller/node-startup-controller-application.c index b2edc1b..e3684fa 100644 --- a/node-startup-controller/node-startup-controller-application.c +++ b/node-startup-controller/node-startup-controller-application.c @@ -52,29 +52,31 @@ enum -static void node_startup_controller_application_finalize (GObject *object); -static void node_startup_controller_application_constructed (GObject *object); -static void node_startup_controller_application_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static gboolean node_startup_controller_application_handle_lifecycle_request (ShutdownConsumer *interface, - GDBusMethodInvocation *invocation, - NSMShutdownType request, - guint request_id, - NodeStartupControllerApplication *application); -static void node_startup_controller_application_handle_register_finish (GObject *object, - GAsyncResult *res, - gpointer user_data); -static void node_startup_controller_application_handle_unregister_finish (GObject *object, - GAsyncResult *res, - gpointer user_data); -static void node_startup_controller_application_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void node_startup_controller_application_luc_groups_started (LUCStarter *starter, - NodeStartupControllerApplication *application); +static void node_startup_controller_application_finalize (GObject *object); +static void node_startup_controller_application_constructed (GObject *object); +static void node_startup_controller_application_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static gboolean node_startup_controller_application_handle_lifecycle_request (ShutdownConsumer *interface, + GDBusMethodInvocation *invocation, + NSMShutdownType request, + guint request_id, + NodeStartupControllerApplication *application); +static void node_startup_controller_application_handle_register_finish (GObject *object, + GAsyncResult *res, + gpointer user_data); +static void node_startup_controller_application_handle_unregister_finish (GObject *object, + GAsyncResult *res, + gpointer user_data); +static void node_startup_controller_application_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void node_startup_controller_application_luc_groups_started (LUCStarter *starter, + NodeStartupControllerApplication *application); +static gboolean node_startup_controller_application_handle_sigterm (gpointer user_data); +static void node_startup_controller_application_unregister_shutdown_consumer (NodeStartupControllerApplication *application); @@ -114,6 +116,9 @@ struct _NodeStartupControllerApplication /* shutdown client for the node startup controller itself */ ShutdownClient *client; + + /* source ID for the SIGTERM handler */ + guint sigterm_id; }; @@ -226,6 +231,12 @@ node_startup_controller_application_init (NodeStartupControllerApplication *appl DLT_STRING ("Updating the systemd watchdog timestamp every"), DLT_UINT (watchdog_sec), DLT_STRING ("seconds")); } + + /* release all registered shutdown consumers upon receiving SIGTERM */ + application->sigterm_id = + g_unix_signal_add (SIGTERM, + node_startup_controller_application_handle_sigterm, + application); } @@ -270,6 +281,10 @@ node_startup_controller_application_finalize (GObject *object) /* release the main loop */ g_main_loop_unref (application->main_loop); + /* remove the SIGTERM handler source */ + if (application->sigterm_id > 0) + g_source_remove (application->sigterm_id); + (*G_OBJECT_CLASS (node_startup_controller_application_parent_class)->finalize) (object); } @@ -430,11 +445,6 @@ node_startup_controller_application_handle_lifecycle_request (ShutdownConsumer guint request_id, NodeStartupControllerApplication *application) { - NSMConsumer *nsm_consumer; - const gchar *bus_name; - const gchar *object_path; - gint shutdown_mode; - g_return_val_if_fail (IS_SHUTDOWN_CONSUMER (consumer), FALSE); g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE); g_return_val_if_fail (IS_NODE_STARTUP_CONTROLLER_APPLICATION (application), FALSE); @@ -445,19 +455,13 @@ node_startup_controller_application_handle_lifecycle_request (ShutdownConsumer /* deregister the shutdown consumers */ la_handler_service_deregister_consumers (application->la_handler); + /* deregister the shutdown consumer of the application itself */ + node_startup_controller_application_unregister_shutdown_consumer (application); + /* let the NSM know that we have handled the lifecycle request */ shutdown_consumer_complete_lifecycle_request (consumer, invocation, NSM_ERROR_STATUS_OK); - /* deregister the node startup controller as a shutdown client itself */ - nsm_consumer = la_handler_service_get_nsm_consumer (application->la_handler); - bus_name = shutdown_client_get_bus_name (application->client); - object_path = shutdown_client_get_object_path (application->client); - shutdown_mode = shutdown_client_get_shutdown_mode (application->client); - nsm_consumer_call_un_register_shutdown_client (nsm_consumer, bus_name, - object_path, shutdown_mode, NULL, - node_startup_controller_application_handle_unregister_finish, - application); return TRUE; } @@ -546,6 +550,53 @@ node_startup_controller_application_luc_groups_started (LUCStarter +static gboolean +node_startup_controller_application_handle_sigterm (gpointer user_data) +{ + NodeStartupControllerApplication *application = NODE_STARTUP_CONTROLLER_APPLICATION (user_data); + + g_return_val_if_fail (IS_NODE_STARTUP_CONTROLLER_APPLICATION (application), FALSE); + + /* deregister the shutdown consumers of legacy applications */ + la_handler_service_deregister_consumers (application->la_handler); + + /* unregister the shutdown client for the app itself */ + node_startup_controller_application_unregister_shutdown_consumer (application); + + /* quit the application */ + g_main_loop_quit (application->main_loop); + + /* reset the source ID */ + application->sigterm_id = 0; + + return FALSE; +} + + + +static void +node_startup_controller_application_unregister_shutdown_consumer (NodeStartupControllerApplication *application) +{ + NSMConsumer *nsm_consumer; + const gchar *bus_name; + const gchar *object_path; + gint shutdown_mode; + + g_return_if_fail (IS_NODE_STARTUP_CONTROLLER_APPLICATION (application)); + + /* deregister the node startup controller as a shutdown client itself */ + nsm_consumer = la_handler_service_get_nsm_consumer (application->la_handler); + bus_name = shutdown_client_get_bus_name (application->client); + object_path = shutdown_client_get_object_path (application->client); + shutdown_mode = shutdown_client_get_shutdown_mode (application->client); + nsm_consumer_call_un_register_shutdown_client (nsm_consumer, bus_name, + object_path, shutdown_mode, NULL, + node_startup_controller_application_handle_unregister_finish, + application); +} + + + NodeStartupControllerApplication * node_startup_controller_application_new (GMainLoop *main_loop, GDBusConnection *connection, |