Drop GApplication, fix D-Bus activation, further NSM integration work
authorJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Fri, 20 Jul 2012 16:06:42 +0000 (17:06 +0100)
committerJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Mon, 23 Jul 2012 14:02:28 +0000 (15:02 +0100)
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.

16 files changed:
.gitignore
boot-manager/boot-manager-application.c
boot-manager/boot-manager-application.h
boot-manager/boot-manager.service.in
boot-manager/la-handler-service.c
boot-manager/main.c
nsm-dummy/dbus/Makefile.am
nsm-dummy/dbus/com.contiautomotive.NodeStateManager.Consumer.service.in [moved from nsm-dummy/dbus/com.contiautomotive.NodeStateManager.service.in with 65% similarity]
nsm-dummy/dbus/com.contiautomotive.NodeStateManager.LifecycleControl.service.in [new file with mode: 0644]
nsm-dummy/main.c
nsm-dummy/nsm-consumer-service.c
nsm-dummy/nsm-consumer-service.h
nsm-dummy/nsm-dummy-application.c
nsm-dummy/nsm-dummy-application.h
nsm-dummy/systemd/Makefile.am
nsm-dummy/systemd/nsm-dummy.service.in [moved from nsm-dummy/systemd/com.contiautomotive.NodeStateManager.service.in with 53% similarity]

index 75124d5..b736c72 100644 (file)
@@ -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
index 5124dfc..f7398da 100644 (file)
@@ -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);
 }
index 1733a4f..d42ddc1 100644 (file)
@@ -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;
index 09fb441..f46af51 100644 (file)
@@ -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
index 70a0a20..d857331 100644 (file)
@@ -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);
-}
index a467e2d..e822313 100644 (file)
@@ -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;
 }
index 39f663d..224ab50 100644 (file)
@@ -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)
@@ -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 (file)
index 0000000..6aac825
--- /dev/null
@@ -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
index 1580a87..ae33116 100644 (file)
@@ -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;
 }
index bdd7ce9..32020c7 100644 (file)
@@ -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;
index e2907ae..dabab0b 100644 (file)
@@ -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
 
index 2bca474..031f148 100644 (file)
@@ -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,
index ead61d4..e6bfed2 100644 (file)
@@ -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;
 
index 30971e5..6e5dc43 100644 (file)
@@ -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)
 
@@ -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