1 /* vi:set et ai sw=2 sts=2 ts=2: */
3 * Copyright (c) 2012 GENIVI.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 #include <glib-object.h>
16 #include <glib-unix.h>
18 #include <systemd/sd-daemon.h>
22 #include <common/watchdog-client.h>
24 #include <boot-manager/boot-manager-application.h>
25 #include <boot-manager/boot-manager-service.h>
26 #include <boot-manager/job-manager.h>
27 #include <boot-manager/la-handler-service.h>
28 #include <boot-manager/luc-starter.h>
33 DLT_IMPORT_CONTEXT (boot_manager_context);
37 /* property identifiers */
43 PROP_BOOT_MANAGER_SERVICE,
51 static void boot_manager_application_finalize (GObject *object);
52 static void boot_manager_application_constructed (GObject *object);
53 static void boot_manager_application_get_property (GObject *object,
57 static void boot_manager_application_set_property (GObject *object,
61 static gboolean boot_manager_application_sigint_handler (BootManagerApplication *application);
65 struct _BootManagerApplicationClass
67 GObjectClass __parent__;
70 struct _BootManagerApplication
74 /* the connection to D-Bus */
75 GDBusConnection *connection;
77 /* systemd watchdog client that repeatedly asks systemd to update
78 * the watchdog timestamp */
79 WatchdogClient *watchdog_client;
81 /* internal handler of Start() and Stop() jobs */
82 JobManager *job_manager;
84 /* boot manager service */
85 BootManagerService *boot_manager_service;
87 /* LUC starter to restore the LUC */
88 LUCStarter *luc_starter;
90 /* signal handler IDs */
93 /* Legacy App Handler to register apps with the Node State Manager */
94 LAHandlerService *la_handler;
96 /* the application's main loop */
99 /* Identifier for the registered bus name */
105 G_DEFINE_TYPE (BootManagerApplication, boot_manager_application, G_TYPE_OBJECT);
110 boot_manager_application_class_init (BootManagerApplicationClass *klass)
112 GObjectClass *gobject_class;
114 gobject_class = G_OBJECT_CLASS (klass);
115 gobject_class->finalize = boot_manager_application_finalize;
116 gobject_class->constructed = boot_manager_application_constructed;
117 gobject_class->get_property = boot_manager_application_get_property;
118 gobject_class->set_property = boot_manager_application_set_property;
120 g_object_class_install_property (gobject_class,
122 g_param_spec_object ("connection",
124 "The connection to D-Bus",
125 G_TYPE_DBUS_CONNECTION,
127 G_PARAM_CONSTRUCT_ONLY |
128 G_PARAM_STATIC_STRINGS));
130 g_object_class_install_property (gobject_class,
132 g_param_spec_object ("job-manager",
134 "The internal handler of Start()"
138 G_PARAM_CONSTRUCT_ONLY |
139 G_PARAM_STATIC_STRINGS));
141 g_object_class_install_property (gobject_class,
143 g_param_spec_object ("la-handler",
145 "Legacy Application Handler",
146 LA_HANDLER_TYPE_SERVICE,
148 G_PARAM_CONSTRUCT_ONLY |
149 G_PARAM_STATIC_STRINGS));
151 g_object_class_install_property (gobject_class,
152 PROP_BOOT_MANAGER_SERVICE,
153 g_param_spec_object ("boot-manager-service",
154 "boot-manager-service",
155 "boot-manager-service",
156 BOOT_MANAGER_TYPE_SERVICE,
158 G_PARAM_CONSTRUCT_ONLY |
159 G_PARAM_STATIC_STRINGS));
161 g_object_class_install_property (gobject_class,
163 g_param_spec_object ("luc-starter",
168 G_PARAM_STATIC_STRINGS));
170 g_object_class_install_property (gobject_class,
172 g_param_spec_boxed ("main-loop",
177 G_PARAM_CONSTRUCT_ONLY |
178 G_PARAM_STATIC_STRINGS));
184 boot_manager_application_init (BootManagerApplication *application)
186 /* update systemd's watchdog timestamp every 120 seconds */
187 application->watchdog_client = watchdog_client_new (120);
189 /* install the signal handler */
190 application->sigint_id =
191 g_unix_signal_add (SIGINT, (GSourceFunc) boot_manager_application_sigint_handler,
198 boot_manager_application_finalize (GObject *object)
200 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
202 /* release the bus name */
203 g_bus_unown_name (application->bus_name_id);
205 /* release the D-Bus connection object */
206 if (application->connection != NULL)
207 g_object_unref (application->connection);
209 /* release the signal handler */
210 g_source_remove (application->sigint_id);
212 /* release the watchdog client */
213 g_object_unref (application->watchdog_client);
215 /* release the boot manager */
216 g_object_unref (application->boot_manager_service);
218 /* release the LUC starter */
219 g_object_unref (application->luc_starter);
221 /* release the legacy app handler */
222 g_object_unref (application->la_handler);
224 /* release the job manager */
225 g_object_unref (application->job_manager);
227 /* release the main loop */
228 g_main_loop_unref (application->main_loop);
230 (*G_OBJECT_CLASS (boot_manager_application_parent_class)->finalize) (object);
236 boot_manager_application_constructed (GObject *object)
238 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
239 GError *error = NULL;
242 /* get a bus name on the given connection */
243 application->bus_name_id =
244 g_bus_own_name_on_connection (application->connection, "org.genivi.BootManager1",
245 G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
247 /* instantiate the LUC starter */
248 application->luc_starter = luc_starter_new (application->job_manager,
249 application->boot_manager_service);
251 /* attempt to start the boot manager service */
252 if (!boot_manager_service_start_up (application->boot_manager_service, &error))
254 log_text = g_strdup_printf ("Failed to start the boot manager service: %s",
256 DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
260 /* restore the LUC if desired */
261 luc_starter_start_groups (application->luc_starter);
263 /* start the legacy app handler */
264 if (!la_handler_service_start (application->la_handler, &error))
266 log_text = g_strdup_printf ("Failed to start the legacy app handler service: %s",
268 DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
272 /* inform systemd that this process has started */
273 sd_notify (0, "READY=1");
279 boot_manager_application_get_property (GObject *object,
284 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
288 case PROP_CONNECTION:
289 g_value_set_object (value, application->connection);
291 case PROP_JOB_MANAGER:
292 g_value_set_object (value, application->job_manager);
294 case PROP_BOOT_MANAGER_SERVICE:
295 g_value_set_object (value, application->boot_manager_service);
296 case PROP_LA_HANDLER:
297 g_value_set_object (value, application->la_handler);
299 case PROP_LUC_STARTER:
300 g_value_set_object (value, application->luc_starter);
303 g_value_set_boxed (value, application->main_loop);
306 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
314 boot_manager_application_set_property (GObject *object,
319 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
323 case PROP_CONNECTION:
324 application->connection = g_value_dup_object (value);
326 case PROP_JOB_MANAGER:
327 application->job_manager = g_value_dup_object (value);
329 case PROP_BOOT_MANAGER_SERVICE:
330 application->boot_manager_service = g_value_dup_object (value);
332 case PROP_LA_HANDLER:
333 application->la_handler = g_value_dup_object (value);
336 application->main_loop = g_main_loop_ref (g_value_get_boxed (value));
339 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
347 boot_manager_application_sigint_handler (BootManagerApplication *application)
349 /* cancel the LUC startup */
350 luc_starter_cancel (application->luc_starter);
352 /* quit the application */
353 g_main_loop_quit (application->main_loop);
360 BootManagerApplication *
361 boot_manager_application_new (GMainLoop *main_loop,
362 GDBusConnection *connection,
363 JobManager *job_manager,
364 LAHandlerService *la_handler,
365 BootManagerService *boot_manager_service)
367 g_return_val_if_fail (main_loop != NULL, NULL);
368 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
369 g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL);
370 g_return_val_if_fail (LA_HANDLER_IS_SERVICE (la_handler), NULL);
371 g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager_service), NULL);
373 return g_object_new (BOOT_MANAGER_TYPE_APPLICATION,
374 "connection", connection,
375 "boot-manager-service", boot_manager_service,
376 "job-manager", job_manager,
377 "la-handler", la_handler,
378 "main-loop", main_loop,