2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
23 #include <sys/signalfd.h>
26 #include <systemd/sd-daemon.h>
30 #include <glib-object.h>
37 #if defined(HAVE_LIVEBOX)
39 #include <dynamicbox_service.h>
40 #include <dynamicbox_conf.h>
42 #include "slave_life.h"
43 #include "slave_rpc.h"
44 #include "client_life.h"
46 #include "buffer_handler.h"
47 #include "script_handler.h"
50 #include "dead_monitor.h"
55 #include "file_service.h"
56 #include "utility_service.h"
63 #include "critical_log.h"
64 #include "shortcut_service.h"
65 #include "notification_service.h"
66 #include "badge_service.h"
69 #define TMP_LOG_FILE "/tmp/live.log"
73 static inline int app_create(void)
77 if (access(DYNAMICBOX_CONF_LOG_PATH, R_OK | W_OK) != 0) {
78 if (mkdir(DYNAMICBOX_CONF_LOG_PATH, 0755) < 0) {
79 ErrPrint("Failed to create %s (%s)\n", DYNAMICBOX_CONF_LOG_PATH, strerror(errno));
85 * Dead signal handler has to be initialized before
86 * initate package or client (slave and client).
88 * Because while creating slaves for packages.
89 * It could be crashed before complete the initation stage.
91 * Then the dead callback should be invoked to handle it properly.
93 * To enable the dead signal handler,
94 * dead_init should be done before other components are initiated.
98 DbgPrint("Setting initialized: %d\n", ret);
101 #if defined(HAVE_LIVEBOX)
104 DbgPrint("Client initialized: %d\n", ret);
109 DbgPrint("Dead callback is registered: %d\n", ret);
114 DbgPrint("group init: %d\n", ret);
119 DbgPrint("Init I/O: %d\n", ret);
122 ret = package_init();
124 DbgPrint("pkgmgr initialized: %d\n", ret);
129 ret = xmonitor_init();
131 DbgPrint("XMonitor init is done: %d\n", ret);
134 ret = buffer_handler_init();
136 DbgPrint("Buffer handler init is done: %d\n", ret);
141 * After initiate all other sub-systtems,
142 * Enable the server socket.
146 DbgPrint("Server initialized: %d\n", ret);
153 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_FILE)) {
157 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_UTILITY)) {
158 utility_service_init();
162 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_SHORTCUT)) {
163 shortcut_service_init();
166 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_NOTIFICATION)) {
167 notification_service_init();
170 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_BADGE)) {
171 badge_service_init();
177 static inline int app_terminate(void)
181 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_BADGE)) {
182 ret = badge_service_fini();
184 DbgPrint("badge: %d\n", ret);
188 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_NOTIFICATION)) {
189 ret = notification_service_fini();
191 DbgPrint("noti: %d\n", ret);
195 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_SHORTCUT)) {
196 ret = shortcut_service_fini();
198 DbgPrint("shortcut: %d\n", ret);
202 #if defined(HAVE_LIVEBOX)
203 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_FILE)) {
204 ret = file_service_fini();
206 DbgPrint("Finalize the file service: %d\n", ret);
212 DbgPrint("Finalize server: %d\n", ret);
217 DbgPrint("dead signal handler finalized: %d\n", ret);
220 if (util_service_is_enabled(DYNAMICBOX_CONF_SERVICE_UTILITY)) {
221 ret = utility_service_fini();
223 DbgPrint("utility: %d\n", ret);
229 DbgPrint("event: %d\n", ret);
232 ret = setting_fini();
234 DbgPrint("Finalize setting : %d\n", ret);
237 ret = instance_fini();
239 DbgPrint("Finalizing instances: %d\n", ret);
242 ret = package_fini();
244 DbgPrint("Finalize package info: %d\n", ret);
249 DbgPrint("script: %d\n", ret);
252 ret = buffer_handler_fini();
254 DbgPrint("buffer handler: %d\n", ret);
263 DbgPrint("IO finalized: %d\n", ret);
268 DbgPrint("Group finalized: %d\n", ret);
272 DbgPrint("Terminated\n");
276 static Eina_Bool signal_cb(void *data, Ecore_Fd_Handler *handler)
278 struct signalfd_siginfo fdsi;
282 fd = ecore_main_fd_handler_fd_get(handler);
284 ErrPrint("Unable to get FD\n");
285 ecore_main_fd_handler_del(handler);
286 return ECORE_CALLBACK_CANCEL;
289 size = read(fd, &fdsi, sizeof(fdsi));
290 if (size != sizeof(fdsi)) {
291 ErrPrint("Unable to get siginfo: %s\n", strerror(errno));
292 ecore_main_fd_handler_del(handler);
293 return ECORE_CALLBACK_CANCEL;
296 if (fdsi.ssi_signo == SIGTERM) {
299 CRITICAL_LOG("Terminated(SIGTERM)\n");
301 cfd = creat("/tmp/.stop.provider", 0644);
302 if (cfd < 0 || close(cfd) < 0) {
303 ErrPrint("stop.provider: %s\n", strerror(errno));
306 vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
308 ecore_main_loop_quit();
309 } else if (fdsi.ssi_signo == SIGUSR1) {
311 * Turn off auto-reactivation
312 * Terminate all slaves
314 #if defined(HAVE_LIVEBOX)
315 CRITICAL_LOG("USRS1, Deactivate ALL\n");
316 slave_deactivate_all(0, 1, 1);
318 } else if (fdsi.ssi_signo == SIGUSR2) {
320 * Turn on auto-reactivation
321 * Launch all slaves again
323 #if defined(HAVE_LIVEBOX)
324 CRITICAL_LOG("USR2, Activate ALL\n");
325 slave_activate_all();
328 CRITICAL_LOG("Unknown SIG[%d] received\n", fdsi.ssi_signo);
331 return ECORE_CALLBACK_RENEW;
334 int main(int argc, char *argv[])
337 int restart_count = 0;
339 Ecore_Fd_Handler *signal_handler = NULL;
342 __file_log_fp = fopen(TMP_LOG_FILE, "w+t");
343 if (!__file_log_fp) {
344 __file_log_fp = fdopen(1, "w+t");
348 /* appcore_agent_terminate */
349 if (ecore_init() <= 0) {
353 if (util_screen_init() <= 0) {
358 dynamicbox_conf_init();
359 dynamicbox_conf_load();
362 * How could we care this return values?
363 * Is there any way to print something on the screen?
365 ret = critical_log_init(util_basename(argv[0]));
367 ErrPrint("Failed to init the critical log\n");
372 * Clear old contents files before start the master provider.
374 (void)util_unlink_files(DYNAMICBOX_CONF_ALWAYS_PATH);
375 (void)util_unlink_files(DYNAMICBOX_CONF_READER_PATH);
376 (void)util_unlink_files(DYNAMICBOX_CONF_IMAGE_PATH);
377 (void)util_unlink_files(DYNAMICBOX_CONF_LOG_PATH);
379 if (util_free_space(DYNAMICBOX_CONF_IMAGE_PATH) < DYNAMICBOX_CONF_MINIMUM_SPACE) {
380 util_remove_emergency_disk();
381 util_prepare_emergency_disk();
384 util_setup_log_disk();
388 ret = sigaddset(&mask, SIGTERM);
390 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
393 ret = sigaddset(&mask, SIGUSR1);
395 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
398 ret = sigaddset(&mask, SIGUSR2);
400 CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
403 ret = sigprocmask(SIG_BLOCK, &mask, NULL);
405 CRITICAL_LOG("Failed to mask the SIGTERM: %s\n", strerror(errno));
408 ret = signalfd(-1, &mask, 0);
410 CRITICAL_LOG("Failed to initiate the signalfd: %s\n", strerror(errno));
412 signal_handler = ecore_main_fd_handler_add(ret, ECORE_FD_READ, signal_cb, NULL, NULL, NULL);
413 CRITICAL_LOG("Signal handler initiated: %d\n", ret);
416 ecore_app_args_set(argc, (const char **)argv);
418 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
423 sd_notify(0, "READY=1");
425 vconf_get_int(VCONFKEY_MASTER_RESTART_COUNT, &restart_count);
427 vconf_set_int(VCONFKEY_MASTER_RESTART_COUNT, restart_count);
429 vconf_set_bool(VCONFKEY_MASTER_STARTED, 1);
430 ecore_main_loop_begin();
431 vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
437 if (signal_handler) {
438 ecore_main_fd_handler_del(signal_handler);
446 fclose(__file_log_fp);
450 dynamicbox_conf_reset();