From: Jannis Pohlmann Date: Fri, 20 Jul 2012 16:06:42 +0000 (+0100) Subject: Drop GApplication, fix D-Bus activation, further NSM integration work X-Git-Tag: node-startup-controller-0.9.1~112 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6dbde884617a6f5a8e4ab98229092969b2e64823;p=profile%2Fivi%2Fnode-startup-controller.git Drop GApplication, fix D-Bus activation, further NSM integration work We no longer want GApplication because (a) D-Bus already guarantees that there is only one unique instance that provides a certain service, (b) we no longer use the GApplication command-line forwarding anyway and (c) there might be no session bus anyway. We want to own the bus names on the system bus and GApplication doesn't help with that. The D-Bus activation did not work for various reasons: (a) the systemd .service files had the type set to "notify" instead of "dbus" and also had BusName set to "foo.bar.baz.service" where it should be just "foo.bar.baz", (b) the NSM dummy .service files for D-Bus were pointing to the wrong systemd .service files and were installed under the wrong name (I think there needs to be one .service file per interface, but this may not be 100% true). The rest of this commit is changes necessary for the integration of the Node State Manager. --- diff --git a/.gitignore b/.gitignore index 75124d5..b736c72 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,32 @@ -*~ +*~ +*.o +*.la +*.so +*.service +*-dbus.[ch] +*.lo +*.swo +*.swp +Makefile +Makefile.in +.libs +.deps +missing +aclocal.m4 +INSTALL +autom4te.cache +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +gtk-doc.make +install-sh +libtool +ltmain.sh +m4 +stamp-h1 diff --git a/boot-manager/boot-manager-application.c b/boot-manager/boot-manager-application.c index 5124dfc..f7398da 100644 --- a/boot-manager/boot-manager-application.c +++ b/boot-manager/boot-manager-application.c @@ -43,33 +43,33 @@ enum PROP_BOOT_MANAGER_SERVICE, PROP_LUC_STARTER, PROP_LA_HANDLER, + PROP_MAIN_LOOP, }; -static void boot_manager_application_finalize (GObject *object); -static void boot_manager_application_constructed (GObject *object); -static void boot_manager_application_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void boot_manager_application_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void boot_manager_application_startup (GApplication *application); -static gboolean boot_manager_application_sigint_handler (GApplication *application); +static void boot_manager_application_finalize (GObject *object); +static void boot_manager_application_constructed (GObject *object); +static void boot_manager_application_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void boot_manager_application_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean boot_manager_application_sigint_handler (BootManagerApplication *application); struct _BootManagerApplicationClass { - GApplicationClass __parent__; + GObjectClass __parent__; }; struct _BootManagerApplication { - GApplication __parent__; + GObject __parent__; /* the connection to D-Bus */ GDBusConnection *connection; @@ -93,20 +93,22 @@ struct _BootManagerApplication /* Legacy App Handler to register apps with the Node State Manager */ LAHandlerService *la_handler; + /* the application's main loop */ + GMainLoop *main_loop; + /* Identifier for the registered bus name */ guint bus_name_id; }; -G_DEFINE_TYPE (BootManagerApplication, boot_manager_application, G_TYPE_APPLICATION); +G_DEFINE_TYPE (BootManagerApplication, boot_manager_application, G_TYPE_OBJECT); static void boot_manager_application_class_init (BootManagerApplicationClass *klass) { - GApplicationClass *gapplication_class; GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (klass); @@ -115,9 +117,6 @@ boot_manager_application_class_init (BootManagerApplicationClass *klass) gobject_class->get_property = boot_manager_application_get_property; gobject_class->set_property = boot_manager_application_set_property; - gapplication_class = G_APPLICATION_CLASS (klass); - gapplication_class->startup = boot_manager_application_startup; - g_object_class_install_property (gobject_class, PROP_CONNECTION, g_param_spec_object ("connection", @@ -167,6 +166,16 @@ boot_manager_application_class_init (BootManagerApplicationClass *klass) TYPE_LUC_STARTER, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_MAIN_LOOP, + g_param_spec_boxed ("main-loop", + "main-loop", + "main-loop", + G_TYPE_MAIN_LOOP, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } @@ -215,6 +224,9 @@ boot_manager_application_finalize (GObject *object) /* release the job manager */ g_object_unref (application->job_manager); + /* release the main loop */ + g_main_loop_unref (application->main_loop); + (*G_OBJECT_CLASS (boot_manager_application_parent_class)->finalize) (object); } @@ -224,6 +236,8 @@ static void boot_manager_application_constructed (GObject *object) { BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object); + GError *error = NULL; + gchar *log_text; /* get a bus name on the given connection */ application->bus_name_id = @@ -233,6 +247,30 @@ boot_manager_application_constructed (GObject *object) /* instantiate the LUC starter */ application->luc_starter = luc_starter_new (application->job_manager, application->boot_manager_service); + + /* attempt to start the boot manager service */ + if (!boot_manager_service_start_up (application->boot_manager_service, &error)) + { + log_text = g_strdup_printf ("Failed to start the boot manager service: %s", + error->message); + DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text)); + g_free (log_text); + } + + /* restore the LUC if desired */ + luc_starter_start_groups (application->luc_starter); + + /* start the legacy app handler */ + if (!la_handler_service_start (application->la_handler, &error)) + { + log_text = g_strdup_printf ("Failed to start the legacy app handler service: %s", + error->message); + DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text)); + g_free (log_text); + } + + /* inform systemd that this process has started */ + sd_notify (0, "READY=1"); } @@ -261,6 +299,9 @@ boot_manager_application_get_property (GObject *object, case PROP_LUC_STARTER: g_value_set_object (value, application->luc_starter); break; + case PROP_MAIN_LOOP: + g_value_set_boxed (value, application->main_loop); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -291,6 +332,9 @@ boot_manager_application_set_property (GObject *object, case PROP_LA_HANDLER: application->la_handler = g_value_dup_object (value); break; + case PROP_MAIN_LOOP: + application->main_loop = g_main_loop_ref (g_value_get_boxed (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -299,78 +343,38 @@ boot_manager_application_set_property (GObject *object, -static void -boot_manager_application_startup (GApplication *app) -{ - BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app); - GError *error = NULL; - gchar *log_text; - - /* chain up to the parent class */ - (*G_APPLICATION_CLASS (boot_manager_application_parent_class)->startup) (app); - - /* start the boot manager service */ - boot_manager_service_start_up (application->boot_manager_service, &error); - - if (error != NULL) - { - log_text = g_strdup_printf ("Error starting boot manager service: %s", - error->message); - DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text)); - g_free (log_text); - } - - /* restore the LUC if desired */ - luc_starter_start_groups (application->luc_starter); - - /* start the legacy app handler */ - la_handler_service_start (application->la_handler, &error); - - if (error != NULL) - { - log_text = - g_strdup_printf ("Boot Manager Application failed to start the legacy app " - "handler: %s", error->message); - DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text)); - g_free (log_text); - } - - /* inform systemd that this process has started */ - sd_notify (0, "READY=1"); - - /* hold the application so that it persists */ - g_application_hold (app); -} - - - static gboolean -boot_manager_application_sigint_handler (GApplication *app) +boot_manager_application_sigint_handler (BootManagerApplication *application) { - BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app); - + /* cancel the LUC startup */ luc_starter_cancel (application->luc_starter); - return TRUE; + /* quit the application */ + g_main_loop_quit (application->main_loop); + + return FALSE; } BootManagerApplication * -boot_manager_application_new (GDBusConnection *connection, +boot_manager_application_new (GMainLoop *main_loop, + GDBusConnection *connection, JobManager *job_manager, LAHandlerService *la_handler, BootManagerService *boot_manager_service) { + g_return_val_if_fail (main_loop != NULL, NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL); + g_return_val_if_fail (LA_HANDLER_IS_SERVICE (la_handler), NULL); g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager_service), NULL); return g_object_new (BOOT_MANAGER_TYPE_APPLICATION, - "application-id", "org.genivi.BootManager1", - "flags", G_APPLICATION_IS_SERVICE, "connection", connection, - "job-manager", job_manager, "boot-manager-service", boot_manager_service, + "job-manager", job_manager, "la-handler", la_handler, + "main-loop", main_loop, NULL); } diff --git a/boot-manager/boot-manager-application.h b/boot-manager/boot-manager-application.h index 1733a4f..d42ddc1 100644 --- a/boot-manager/boot-manager-application.h +++ b/boot-manager/boot-manager-application.h @@ -30,7 +30,8 @@ typedef struct _BootManagerApplication BootManagerApplication; GType boot_manager_application_get_type (void) G_GNUC_CONST; -BootManagerApplication *boot_manager_application_new (GDBusConnection *connection, +BootManagerApplication *boot_manager_application_new (GMainLoop *main_loop, + GDBusConnection *connection, JobManager *job_manager, LAHandlerService *la_handler, BootManagerService *boot_manager_service) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; diff --git a/boot-manager/boot-manager.service.in b/boot-manager/boot-manager.service.in index 09fb441..f46af51 100644 --- a/boot-manager/boot-manager.service.in +++ b/boot-manager/boot-manager.service.in @@ -1,4 +1,4 @@ [Service] -Type = notify -BusName = org.genivi.BootManager1.service +Type = dbus +BusName = org.genivi.BootManager1 ExecStart = @libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager diff --git a/boot-manager/la-handler-service.c b/boot-manager/la-handler-service.c index 70a0a20..d857331 100644 --- a/boot-manager/la-handler-service.c +++ b/boot-manager/la-handler-service.c @@ -28,7 +28,7 @@ DLT_IMPORT_CONTEXT (la_handler_context); - + /* property identifiers */ enum { @@ -39,44 +39,45 @@ enum -typedef struct _LAHandlerServiceConsumerBundle LAHandlerServiceConsumerBundle; -typedef struct _LAHandlerServiceShutdownConsumer LAHandlerServiceShutdownConsumer; - - - -static void la_handler_service_constructed (GObject *object); -static void la_handler_service_finalize (GObject *object); -static void la_handler_service_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void la_handler_service_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gboolean la_handler_service_handle_register (LAHandler *interface, - GDBusMethodInvocation *invocation, - const gchar *unit, - const gchar *mode, - guint timeout, - LAHandlerService *service); -static void la_handler_service_handle_register_finish (NSMConsumer *nsm_consumer, - GAsyncResult *res, - GDBusMethodInvocation *invocation); -static gboolean la_handler_service_handle_deregister (LAHandler *interface, - GDBusMethodInvocation *invocation, - const gchar *unit, - LAHandlerService *service); -static void la_handler_service_handle_consumer_lifecycle_request (ShutdownConsumer *interface, - GDBusMethodInvocation *invocation, - guint request, - guint request_id, - LAHandlerService *service); -static void la_handler_service_handle_consumer_lifecycle_request_finish (JobManager *manager, - const gchar *unit, - const gchar *result, - GError *error, - gpointer user_data); +typedef struct _LAHandlerServiceData LAHandlerServiceData; + + + +static void la_handler_service_constructed (GObject *object); +static void la_handler_service_finalize (GObject *object); +static void la_handler_service_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void la_handler_service_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean la_handler_service_handle_register (LAHandler *interface, + GDBusMethodInvocation *invocation, + const gchar *unit, + const gchar *mode, + guint timeout, + LAHandlerService *service); +static void la_handler_service_handle_register_finish (GObject *object, + GAsyncResult *res, + gpointer user_data); +static void la_handler_service_handle_consumer_lifecycle_request (ShutdownConsumer *interface, + GDBusMethodInvocation *invocation, + guint request, + guint request_id, + LAHandlerService *service); +static void la_handler_service_handle_consumer_lifecycle_request_finish (JobManager *manager, + const gchar *unit, + const gchar *result, + GError *error, + gpointer user_data); +static LAHandlerServiceData *la_handler_service_data_new (LAHandlerService *service, + GDBusMethodInvocation *invocation, + guint request_id); +static void la_handler_service_data_unref (LAHandlerServiceData *data); + + struct _LAHandlerServiceClass { @@ -103,6 +104,13 @@ struct _LAHandlerService NSMConsumer *nsm_consumer; }; +struct _LAHandlerServiceData +{ + GDBusMethodInvocation *invocation; + LAHandlerService *service; + guint request_id; +}; + G_DEFINE_TYPE (LAHandlerService, la_handler_service, G_TYPE_OBJECT); @@ -181,22 +189,17 @@ la_handler_service_init (LAHandlerService *service) service->prefix = "/org/genivi/BootManager1/ShutdownConsumer"; /* initialize the association of shutdown consumers to units */ - service->units_to_consumers = - g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); - service->consumers_to_units = - g_hash_table_new_full (g_direct_hash, g_direct_equal, - (GDestroyNotify) g_object_unref, (GDestroyNotify) g_free); + service->units_to_consumers = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + service->consumers_to_units = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) g_free); /* implement the Register() handler */ g_signal_connect (service->interface, "handle-register", G_CALLBACK (la_handler_service_handle_register), service); - - /* implement the Deregister() handler */ - g_signal_connect (service->interface, "handle-deregister", - G_CALLBACK (la_handler_service_handle_deregister), - service); } @@ -223,8 +226,8 @@ la_handler_service_finalize (GObject *object) g_object_unref (service->job_manager); /* release the shutdown consumers */ - g_hash_table_destroy (service->units_to_consumers); - g_hash_table_destroy (service->consumers_to_units); + g_hash_table_unref (service->units_to_consumers); + g_hash_table_unref (service->consumers_to_units); (*G_OBJECT_CLASS (la_handler_service_parent_class)->finalize) (object); } @@ -287,9 +290,66 @@ la_handler_service_handle_register (LAHandler *interface, guint timeout, LAHandlerService *service) { - /* delegate registration of the legacy app to a more generalised function */ - la_handler_service_register (service, unit, mode, timeout, - (GAsyncReadyCallback) la_handler_service_handle_register_finish, invocation); + ShutdownConsumer *consumer; + GError *error = NULL; + gchar *log_text; + gchar *object_path; + + g_return_val_if_fail (IS_LA_HANDLER (interface), FALSE); + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE); + g_return_val_if_fail (unit != NULL && *unit != '\0', FALSE); + g_return_val_if_fail (mode != NULL && *mode != '\0', FALSE); + g_return_val_if_fail (LA_HANDLER_IS_SERVICE (service), FALSE); + + /* find out if this unit is already registered with a shutdown consumer */ + if (g_hash_table_lookup (service->units_to_consumers, unit)) + { + /* there already is a shutdown consumer for the unit, so ignore this request */ + la_handler_complete_register (interface, invocation); + return TRUE; + } + + /* create a new ShutdownConsumer and implement its LifecycleRequest method */ + consumer = shutdown_consumer_skeleton_new (); + g_signal_connect (consumer, "handle-lifecycle-request", + G_CALLBACK (la_handler_service_handle_consumer_lifecycle_request), + service); + + /* associate the shutdown consumer with the unit name */ + g_hash_table_insert (service->units_to_consumers, g_strdup (unit), + g_object_ref (consumer)); + g_hash_table_insert (service->consumers_to_units, g_object_ref (consumer), + g_strdup (unit)); + + /* export the shutdown consumer on the bus */ + object_path = g_strdup_printf ("%s/%u", service->prefix, service->index); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (consumer), + service->connection, object_path, &error); + if (error != NULL) + { + log_text = + g_strdup_printf ("Failed to export shutdown consumer on the bus: %s", + error->message); + DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text)); + g_free (log_text); + g_error_free (error); + } + + /* temporarily store a reference to the LAHandlerService in the invocation object */ + g_object_set_data_full (G_OBJECT (invocation), "la-handler-service", + g_object_ref (service), (GDestroyNotify) g_object_unref); + + /* register the shutdown consumer with the NSM Consumer */ + nsm_consumer_call_register_shutdown_client (service->nsm_consumer, + "org.genivi.BootManager1", object_path, 0, + timeout, NULL, + la_handler_service_handle_register_finish, + invocation); + + g_free (object_path); + + /* increment the counter for our shutdown consumer object paths */ + service->index++; return TRUE; } @@ -297,63 +357,77 @@ la_handler_service_handle_register (LAHandler *interface, static void -la_handler_service_handle_register_finish (NSMConsumer *nsm_consumer, - GAsyncResult *res, - GDBusMethodInvocation *invocation) +la_handler_service_handle_register_finish (GObject *object, + GAsyncResult *res, + gpointer user_data) { - GError *error = NULL; - gchar *log_text; - gint error_code; - + GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data); + LAHandlerService *service; + NSMConsumer *nsm_consumer = NSM_CONSUMER (object); + GError *error = NULL; + gchar *log_text; + gint error_code; + + g_return_if_fail (IS_NSM_CONSUMER (nsm_consumer)); + g_return_if_fail (G_IS_ASYNC_RESULT (res)); + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + + /* finish registering the shutdown client */ nsm_consumer_call_register_shutdown_client_finish (nsm_consumer, &error_code, res, &error); if (error != NULL) { - log_text = g_strdup_printf ("Error occurred registering legacy app: %s", + log_text = g_strdup_printf ("Failed to register a shutdown consumer: %s", error->message); DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text)); g_free (log_text); g_error_free (error); } - /* notify the caller that we have handled the registration request */ - g_dbus_method_invocation_return_value (invocation, NULL); -} + /* retrieve the LAHandlerService from the invocation object */ + service = g_object_get_data (G_OBJECT (invocation), "la-handler-service"); - - -static gboolean -la_handler_service_handle_deregister (LAHandler *object, - GDBusMethodInvocation *invocation, - const gchar *unit, - LAHandlerService *service) -{ /* notify the caller that we have handled the registration request */ - g_dbus_method_invocation_return_value (invocation, NULL); - return TRUE; + la_handler_complete_register (service->interface, invocation); } static void -la_handler_service_handle_consumer_lifecycle_request (ShutdownConsumer *interface, +la_handler_service_handle_consumer_lifecycle_request (ShutdownConsumer *consumer, GDBusMethodInvocation *invocation, guint request, guint request_id, LAHandlerService *service) { - GVariant *return_type; - gchar *unit_name = g_hash_table_lookup (service->consumers_to_units, interface); - - /* call job_manager_stop */ - job_manager_stop (service->job_manager, unit_name, NULL, - la_handler_service_handle_consumer_lifecycle_request_finish, - GUINT_TO_POINTER (request_id)); - - /* returns for the invocation (with error code) */ - return_type = g_variant_new_int32 (1); /* bare number because enum comes later */ - g_dbus_method_invocation_return_value (invocation, return_type); - g_variant_unref (return_type); + LAHandlerServiceData *data; + gchar *unit_name; + + g_return_if_fail (IS_SHUTDOWN_CONSUMER (consumer)); + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (LA_HANDLER_IS_SERVICE (service)); + + /* look up the unit name associated with this shutdown consumer */ + unit_name = g_hash_table_lookup (service->consumers_to_units, consumer); + + if (unit_name != NULL) + { + data = la_handler_service_data_new (service, NULL, request_id); + + /* stop this unit now */ + job_manager_stop (service->job_manager, unit_name, NULL, + la_handler_service_handle_consumer_lifecycle_request_finish, + data); + + /* let the NSM know that we are working on this request */ + shutdown_consumer_complete_lifecycle_request (consumer, invocation, 7); + } + else + { + /* NSM asked us to shutdown a shutdown consumer we did not register; + * make it aware by returning an error */ + shutdown_consumer_complete_lifecycle_request (consumer, invocation, 2); + } } @@ -365,23 +439,85 @@ la_handler_service_handle_consumer_lifecycle_request_finish (JobManager *manage GError *error, gpointer user_data) { - gchar *log_text; + LAHandlerServiceData *data = (LAHandlerServiceData *)user_data; + GError *err = NULL; + gchar *log_text; + gint status = 1; + + g_return_if_fail (IS_JOB_MANAGER (manager)); + g_return_if_fail (unit != NULL && *unit != '\0'); + g_return_if_fail (result != NULL && *result != '\0'); + g_return_if_fail (data != NULL); - /* log any errors */ + /* log an error if shutting down the consumer has failed */ if (error != NULL) { - log_text = g_strdup_printf ("Error occurred handling lifecycle request: %s", + log_text = g_strdup_printf ("Failed to shutdown a shutdown consumer: %s", error->message); DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text)); g_free (log_text); + + /* send an error back to the NSM */ + status = 2; } + /* log an error if systemd failed to stop the consumer */ if (g_strcmp0 (result, "failed") == 0) { DLT_LOG (la_handler_context, DLT_LOG_ERROR, - DLT_STRING ("Error occurred handling lifecycle request")); + DLT_STRING ("Failed to shutdown a shutdown consumer")); + + /* send an error back to the NSM */ + status = 2; } + /* let the NSM know that we have handled the lifecycle request */ + if (!nsm_consumer_call_lifecycle_request_complete_sync (data->service->nsm_consumer, + data->request_id, status, + NULL, NULL, &err)) + { + log_text = g_strdup_printf ("Failed to notify Node State Manager about completed " + "lifecycle request: %s", err->message); + DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text)); + g_free (log_text); + g_error_free (err); + } + + la_handler_service_data_unref (data); +} + + + +static LAHandlerServiceData * +la_handler_service_data_new (LAHandlerService *service, + GDBusMethodInvocation *invocation, + guint request_id) +{ + LAHandlerServiceData *data; + + data = g_slice_new0 (LAHandlerServiceData); + if (service != NULL) + data->service = g_object_ref (service); + if (invocation != NULL) + data->invocation = g_object_ref (invocation); + data->request_id = request_id; + + return data; +} + + + +static void +la_handler_service_data_unref (LAHandlerServiceData *data) +{ + if (data == NULL) + return; + + if (data->invocation != NULL) + g_object_unref (data->invocation); + if (data->service != NULL) + g_object_unref (data->service); + g_slice_free (LAHandlerServiceData, data); } @@ -413,59 +549,3 @@ la_handler_service_start (LAHandlerService *service, "/org/genivi/BootManager1/LegacyAppHandler", error); } - - - -void -la_handler_service_register (LAHandlerService *service, - const gchar *unit, - const gchar *mode, - guint timeout, - GAsyncReadyCallback callback, - gpointer user_data) -{ - ShutdownConsumer *consumer; - GError *error = NULL; - gchar *log_text; - gchar *object_path; - - g_return_if_fail (LA_HANDLER_IS_SERVICE (service)); - g_return_if_fail (unit != NULL && *unit != '\0'); - g_return_if_fail (mode != NULL && *mode != '\0'); - - /* find out if this unit is already registered with a shutdown consumer */ - if (g_hash_table_lookup (service->units_to_consumers, unit)) - return; - - /* create a new ShutdownConsumer and store it in service */ - consumer = shutdown_consumer_skeleton_new (); - g_hash_table_insert (service->units_to_consumers, g_strdup (unit), - g_object_ref (consumer)); - g_hash_table_insert (service->consumers_to_units, g_object_ref (consumer), - g_strdup (unit)); - service->index++; - - /* set up signal handling and skeleton exporting */ - object_path = g_strdup_printf ("%s/%u", service->prefix, service->index); - g_signal_connect (consumer, "handle-lifecycle-request", - G_CALLBACK (la_handler_service_handle_consumer_lifecycle_request), - service); - g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (consumer), - service->connection, object_path, &error); - if (error != NULL) - { - log_text = - g_strdup_printf ("Error exporting shutdown consumer interface skeleton: %s", - error->message); - DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text)); - g_free (log_text); - g_error_free (error); - } - - /* register the shutdown consumer with the NSM Consumer */ - nsm_consumer_call_register_shutdown_client (service->nsm_consumer, - "org.genivi.BootManager1", object_path, 0, - timeout, NULL, callback, user_data); - - g_free (object_path); -} diff --git a/boot-manager/main.c b/boot-manager/main.c index a467e2d..e822313 100644 --- a/boot-manager/main.c +++ b/boot-manager/main.c @@ -56,6 +56,7 @@ main (int argc, GDBusConnection *connection; SystemdManager *systemd_manager; JobManager *job_manager; + GMainLoop *main_loop; GError *error = NULL; gint exit_status; @@ -91,9 +92,7 @@ main (int argc, if (argc > 1) { exit_status = boot_manager_handle_command_line (argc, argv, connection); - g_object_unref (connection); - return exit_status; } @@ -139,18 +138,24 @@ main (int argc, /* instantiate the legacy app handler */ la_handler_service = la_handler_service_new (connection, job_manager); + /* create the main loop */ + main_loop = g_main_loop_new (NULL, FALSE); + /* create and run the main application */ - application = boot_manager_application_new (connection, job_manager, + application = boot_manager_application_new (main_loop, connection, job_manager, la_handler_service, boot_manager_service); - exit_status = g_application_run (G_APPLICATION (application), 0, NULL); - g_object_unref (application); + + /* run the main loop */ + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); /* release allocated objects */ + g_object_unref (application); g_object_unref (target_startup_monitor); g_object_unref (systemd_manager); g_object_unref (job_manager); g_object_unref (boot_manager_service); g_object_unref (connection); - return exit_status; + return EXIT_SUCCESS; } diff --git a/nsm-dummy/dbus/Makefile.am b/nsm-dummy/dbus/Makefile.am index 39f663d..224ab50 100644 --- a/nsm-dummy/dbus/Makefile.am +++ b/nsm-dummy/dbus/Makefile.am @@ -1,18 +1,19 @@ # vi:set ts=8 sw=8 noet ai nocindent: -bus_servicedir = $(datadir)/dbus-1/system-services +servicedir = $(datadir)/dbus-1/system-services -bus_service_in_files = \ - com.contiautomotive.NodeStateManager.service.in +service_in_files = \ + com.contiautomotive.NodeStateManager.Consumer.service.in \ + com.contiautomotive.NodeStateManager.LifecycleControl.service.in -bus_service_DATA = $(bus_service_in_files:.service.in=.service) +service_DATA = $(service_in_files:.service.in=.service) %.service: %.service.in sed -e "s,\@libdir\@,$(libdir),g" \ -e "s,\@BOOT_MANAGER_VERSION_API\@,$(BOOT_MANAGER_VERSION_API),g" < $< > $@ CLEANFILES = \ - $(bus_service_DATA) + $(service_DATA) EXTRA_DIST = \ - $(bus_service_in_files) + $(service_in_files) diff --git a/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.service.in b/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.Consumer.service.in similarity index 65% rename from nsm-dummy/dbus/com.contiautomotive.NodeStateManager.service.in rename to nsm-dummy/dbus/com.contiautomotive.NodeStateManager.Consumer.service.in index b2035a4..6aac825 100644 --- a/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.service.in +++ b/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.Consumer.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=com.contiautomotive.NodeStateManager -SystemdService = com.contiautomotive.NodeStateManager.service +SystemdService = nsm-dummy.service Exec=@libdir@/nsm-dummy-@BOOT_MANAGER_VERSION_API@/nsm-dummy diff --git a/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.LifecycleControl.service.in b/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.LifecycleControl.service.in new file mode 100644 index 0000000..6aac825 --- /dev/null +++ b/nsm-dummy/dbus/com.contiautomotive.NodeStateManager.LifecycleControl.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=com.contiautomotive.NodeStateManager +SystemdService = nsm-dummy.service +Exec=@libdir@/nsm-dummy-@BOOT_MANAGER_VERSION_API@/nsm-dummy diff --git a/nsm-dummy/main.c b/nsm-dummy/main.c index 1580a87..ae33116 100644 --- a/nsm-dummy/main.c +++ b/nsm-dummy/main.c @@ -38,8 +38,8 @@ main (int argc, NSMDummyApplication *application; NSMConsumerService *consumer_service; GDBusConnection *connection; + GMainLoop *main_loop; GError *error = NULL; - int exit_status; /* register the application and context in DLT */ DLT_REGISTER_APP ("NSMD", "GENIVI Node State Manager Dummy"); @@ -89,11 +89,16 @@ main (int argc, return EXIT_FAILURE; } - /* create and run the main application */ - application = nsm_dummy_application_new (connection, - consumer_service, + /* create the main loop */ + main_loop = g_main_loop_new (NULL, FALSE); + + /* create the main application */ + application = nsm_dummy_application_new (main_loop, connection, consumer_service, lifecycle_control_service); - exit_status = g_application_run (G_APPLICATION (application), 0, NULL); + + /* run the main loop */ + g_main_loop_run (main_loop); + g_main_loop_unref (main_loop); /* release allocated objects */ g_object_unref (application); @@ -105,5 +110,5 @@ main (int argc, DLT_UNREGISTER_CONTEXT (nsm_dummy_context); DLT_UNREGISTER_APP (); - return exit_status; + return EXIT_SUCCESS; } diff --git a/nsm-dummy/nsm-consumer-service.c b/nsm-dummy/nsm-consumer-service.c index bdd7ce9..32020c7 100644 --- a/nsm-dummy/nsm-consumer-service.c +++ b/nsm-dummy/nsm-consumer-service.c @@ -35,7 +35,7 @@ enum -typedef struct _NSMShutdownClient NSMShutdownClient; +typedef struct _NSMShutdownClient NSMShutdownClient; @@ -354,10 +354,10 @@ nsm_shutdown_client_release (NSMShutdownClient *shutdown_client) void -nsm_shutdown_consumers (NSMConsumerService *service) +nsm_consumer_service_shutdown_consumers (NSMConsumerService *service) { - ShutdownConsumer *proxy = NULL; - GError *error = NULL; + ShutdownConsumer *proxy = NULL; + GError *error = NULL; gchar *message; GList *clients; GList *shutdown_consumers; diff --git a/nsm-dummy/nsm-consumer-service.h b/nsm-dummy/nsm-consumer-service.h index e2907ae..dabab0b 100644 --- a/nsm-dummy/nsm-consumer-service.h +++ b/nsm-dummy/nsm-consumer-service.h @@ -24,12 +24,12 @@ G_BEGIN_DECLS typedef struct _NSMConsumerServiceClass NSMConsumerServiceClass; typedef struct _NSMConsumerService NSMConsumerService; -GType nsm_consumer_service_get_type (void) G_GNUC_CONST; +GType nsm_consumer_service_get_type (void) G_GNUC_CONST; -NSMConsumerService *nsm_consumer_service_new (GDBusConnection *connection) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean nsm_consumer_service_start (NSMConsumerService *service, - GError **error); -void nsm_shutdown_consumers (NSMConsumerService *service); +NSMConsumerService *nsm_consumer_service_new (GDBusConnection *connection) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; +gboolean nsm_consumer_service_start (NSMConsumerService *service, + GError **error); +void nsm_consumer_service_shutdown_consumers (NSMConsumerService *service); G_END_DECLS diff --git a/nsm-dummy/nsm-dummy-application.c b/nsm-dummy/nsm-dummy-application.c index 2bca474..031f148 100644 --- a/nsm-dummy/nsm-dummy-application.c +++ b/nsm-dummy/nsm-dummy-application.c @@ -33,33 +33,33 @@ enum PROP_0, PROP_CONNECTION, PROP_CONSUMER_SERVICE, - PROP_LIFECYCLE_CONTROL_SERVICE + PROP_LIFECYCLE_CONTROL_SERVICE, + PROP_MAIN_LOOP, }; -static void nsm_dummy_application_constructed (GObject *object); -static void nsm_dummy_application_finalize (GObject *object); -static void nsm_dummy_application_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void nsm_dummy_application_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void nsm_dummy_application_startup (GApplication *application); -static gboolean nsm_dummy_application_int_handler (GApplication *application); +static void nsm_dummy_application_constructed (GObject *object); +static void nsm_dummy_application_finalize (GObject *object); +static void nsm_dummy_application_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void nsm_dummy_application_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean nsm_dummy_application_int_handler (NSMDummyApplication *application); struct _NSMDummyApplicationClass { - GApplicationClass __parent__; + GObjectClass __parent__; }; struct _NSMDummyApplication { - GApplication __parent__; + GObject __parent__; /* the connection to D-Bus */ GDBusConnection *connection; @@ -72,6 +72,9 @@ struct _NSMDummyApplication NSMLifecycleControlService *lifecycle_control_service; NSMConsumerService *consumer_service; + /* the main loop of the application */ + GMainLoop *main_loop; + /* signal handler IDs */ guint sigint_id; @@ -81,15 +84,14 @@ struct _NSMDummyApplication -G_DEFINE_TYPE (NSMDummyApplication, nsm_dummy_application, G_TYPE_APPLICATION); +G_DEFINE_TYPE (NSMDummyApplication, nsm_dummy_application, G_TYPE_OBJECT); static void nsm_dummy_application_class_init (NSMDummyApplicationClass *klass) { - GApplicationClass *gapplication_class; - GObjectClass *gobject_class; + GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = nsm_dummy_application_finalize; @@ -97,9 +99,6 @@ nsm_dummy_application_class_init (NSMDummyApplicationClass *klass) gobject_class->get_property = nsm_dummy_application_get_property; gobject_class->set_property = nsm_dummy_application_set_property; - gapplication_class = G_APPLICATION_CLASS (klass); - gapplication_class->startup = nsm_dummy_application_startup; - g_object_class_install_property (gobject_class, PROP_CONNECTION, g_param_spec_object ("connection", @@ -129,8 +128,15 @@ nsm_dummy_application_class_init (NSMDummyApplicationClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - /* inform systemd that this process has started */ - sd_notify (0, "READY=1"); + g_object_class_install_property (gobject_class, + PROP_MAIN_LOOP, + g_param_spec_boxed ("main-loop", + "main-loop", + "main-loop", + G_TYPE_MAIN_LOOP, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } @@ -167,6 +173,9 @@ nsm_dummy_application_finalize (GObject *object) /* release the watchdog client */ g_object_unref (application->watchdog_client); + /* release the main loop */ + g_main_loop_unref (application->main_loop); + /* release the NSM Dummy service implementations */ if (application->consumer_service != NULL) g_object_unref (application->consumer_service); @@ -189,6 +198,9 @@ nsm_dummy_application_constructed (GObject *object) g_bus_own_name_on_connection (application->connection, "com.contiautomotive.NodeStateManager", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); + + /* inform systemd that this process has started */ + sd_notify (0, "READY=1"); } @@ -212,6 +224,9 @@ nsm_dummy_application_get_property (GObject *object, case PROP_LIFECYCLE_CONTROL_SERVICE: g_value_set_object (value, application->lifecycle_control_service); break; + case PROP_MAIN_LOOP: + g_value_set_boxed (value, application->main_loop); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -239,6 +254,9 @@ nsm_dummy_application_set_property (GObject *object, case PROP_LIFECYCLE_CONTROL_SERVICE: application->lifecycle_control_service = g_value_dup_object (value); break; + case PROP_MAIN_LOOP: + application->main_loop = g_main_loop_ref (g_value_get_boxed (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -248,46 +266,32 @@ nsm_dummy_application_set_property (GObject *object, static gboolean -nsm_dummy_application_int_handler (GApplication *app) +nsm_dummy_application_int_handler (NSMDummyApplication *application) { - NSMDummyApplication *application = NSM_DUMMY_APPLICATION (app); - /* call the shutdown consumer method */ - nsm_shutdown_consumers (application->consumer_service); - - return TRUE; -} + nsm_consumer_service_shutdown_consumers (application->consumer_service); + /* quit the application */ + g_main_loop_quit (application->main_loop); - -static void -nsm_dummy_application_startup (GApplication *app) -{ - NSMDummyApplication *application = NSM_DUMMY_APPLICATION (app); - - /* chain up to the parent class */ - (*G_APPLICATION_CLASS (nsm_dummy_application_parent_class)->startup) (app); - - /* update systemd's watchdog timestamp every 120 seconds */ - application->watchdog_client = watchdog_client_new (120); - - /* increment the reference count holding the application running to test the services */ - g_application_hold (app); + return FALSE; } NSMDummyApplication * -nsm_dummy_application_new (GDBusConnection *connection, +nsm_dummy_application_new (GMainLoop *main_loop, + GDBusConnection *connection, NSMConsumerService *consumer_service, NSMLifecycleControlService *lifecycle_control_service) { + g_return_val_if_fail (main_loop != NULL, NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); g_return_val_if_fail (NSM_CONSUMER_IS_SERVICE (consumer_service), NULL); g_return_val_if_fail (NSM_LIFECYCLE_CONTROL_IS_SERVICE (lifecycle_control_service), NULL); return g_object_new (NSM_DUMMY_TYPE_APPLICATION, - "application-id", "com.contiautomotive.NodeStateManager", - "flags", G_APPLICATION_IS_SERVICE, + "main-loop", main_loop, "connection", connection, "nsm-consumer-service", consumer_service, "nsm-lifecycle-control-service", lifecycle_control_service, diff --git a/nsm-dummy/nsm-dummy-application.h b/nsm-dummy/nsm-dummy-application.h index ead61d4..e6bfed2 100644 --- a/nsm-dummy/nsm-dummy-application.h +++ b/nsm-dummy/nsm-dummy-application.h @@ -27,7 +27,8 @@ typedef struct _NSMDummyApplication NSMDummyApplication; GType nsm_dummy_application_get_type (void) G_GNUC_CONST; -NSMDummyApplication *nsm_dummy_application_new (GDBusConnection *connection, +NSMDummyApplication *nsm_dummy_application_new (GMainLoop *main_loop, + GDBusConnection *connection, NSMConsumerService *consumer_service, NSMLifecycleControlService *lifecycle_control_service) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; diff --git a/nsm-dummy/systemd/Makefile.am b/nsm-dummy/systemd/Makefile.am index 30971e5..6e5dc43 100644 --- a/nsm-dummy/systemd/Makefile.am +++ b/nsm-dummy/systemd/Makefile.am @@ -3,7 +3,7 @@ systemd_servicedir = /lib/systemd/system systemd_service_in_files = \ - com.contiautomotive.NodeStateManager.service.in + nsm-dummy.service.in systemd_service_DATA = $(systemd_service_in_files:.service.in=.service) diff --git a/nsm-dummy/systemd/com.contiautomotive.NodeStateManager.service.in b/nsm-dummy/systemd/nsm-dummy.service.in similarity index 53% rename from nsm-dummy/systemd/com.contiautomotive.NodeStateManager.service.in rename to nsm-dummy/systemd/nsm-dummy.service.in index 718dc44..206dae5 100644 --- a/nsm-dummy/systemd/com.contiautomotive.NodeStateManager.service.in +++ b/nsm-dummy/systemd/nsm-dummy.service.in @@ -1,4 +1,4 @@ [Service] -Type = notify -BusName = com.contiautomotive.NodeStateManager.service +Type = dbus +BusName = com.contiautomotive.NodeStateManager ExecStart = @libdir@/nsm-dummy-@BOOT_MANAGER_VERSION_API@/nsm-dummy