[REFACTOR] encapsulate target struct (part 1)
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Jaewon Lim <jaewon81.lim@samsung.com>
9  * Woojin Jung <woojin2.jung@samsung.com>
10  * Juyoung Kim <j0.kim@samsung.com>
11  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12  * Nikita Kalyazin    <n.kalyazin@samsung.com>
13  *
14  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  * http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  * - Samsung RnD Institute Russia
29  *
30  */
31 #define __STDC_FORMAT_MACROS
32 #include <stdio.h>
33 #include <stdlib.h>             // for realpath
34 #include <string.h>             // for strtok, strcpy, strncpy
35 #include <limits.h>             // for realpath
36 #include <inttypes.h>
37
38 #include <errno.h>              // for errno
39 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
40 #include <sys/socket.h>         // for accept
41 #include <sys/stat.h>           // for mkdir
42 #include <sys/eventfd.h>        // for eventfd
43 #include <sys/timerfd.h>        // for timerfd
44 #include <unistd.h>             // for access, sleep
45 #include <stdbool.h>
46
47 #include <ctype.h>
48
49 #include <fcntl.h>
50
51 #include <assert.h>
52
53 #include <Ecore.h>
54
55 #include "daemon.h"
56 #include "sys_stat.h"
57 #include "utils.h"
58 #include "da_protocol.h"
59 #include "da_inst.h"
60 #include "da_data.h"
61 #include "input_events.h"
62 #include "smack.h"
63 #include "debug.h"
64
65 #define DA_WORK_DIR                     "/home/developer/sdk_tools/da/"
66 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
67 #define SCREENSHOT_DIR                  "/tmp/da"
68
69 #define MAX_APP_LAUNCH_TIME             60
70 #define MAX_CONNECT_TIMEOUT_TIME        5*60
71
72
73 // =============================================================================
74 // start and terminate control functions
75 // =============================================================================
76
77 static Ecore_Fd_Handler *launch_timer_handler;
78
79 //stop application launch timer
80 static int stop_app_launch_timer()
81 {
82         close(manager.app_launch_timerfd);
83         manager.app_launch_timerfd = -1;
84
85         return 0;
86 }
87
88 static Eina_Bool launch_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
89 {
90         LOGE("Failed to launch application\n");
91         if (stop_app_launch_timer() < 0)
92                 LOGE("cannot stop app launch timer\n");
93
94         return ECORE_CALLBACK_CANCEL;
95 }
96
97 //start application launch timer function
98 static int start_app_launch_timer(int apps_count)
99 {
100         int res = 0;
101
102         assert(apps_count >= 0 && "negative apps count");
103
104         if (apps_count == 0)
105                 return res;
106
107         manager.app_launch_timerfd =
108             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
109         if (manager.app_launch_timerfd > 0) {
110                 struct itimerspec ctime;
111                 ctime.it_value.tv_sec = MAX_APP_LAUNCH_TIME * apps_count;
112                 ctime.it_value.tv_nsec = 0;
113                 ctime.it_interval.tv_sec = 0;
114                 ctime.it_interval.tv_nsec = 0;
115                 if (timerfd_settime(manager.app_launch_timerfd, 0, &ctime, NULL) < 0) {
116                         LOGE("fail to set app launch timer\n");
117                         stop_app_launch_timer();
118                         res = -1;
119                 } else {
120                         launch_timer_handler =
121                                 ecore_main_fd_handler_add(manager.app_launch_timerfd,
122                                                           ECORE_FD_READ,
123                                                           launch_timer_cb,
124                                                           NULL,
125                                                           NULL, NULL);
126                         if (!launch_timer_handler) {
127                                 LOGE("fail to add app launch timer fd to \n");
128                                 stop_app_launch_timer();
129                                 res = -2;
130                         } else {
131                                 LOGI("application launch time started\n");
132                         }
133                 }
134         } else {
135                 LOGE("cannot create launch timer\n");
136                 res = -3;
137         }
138
139         return res;
140 }
141
142 static inline void inc_apps_to_run()
143 {
144         manager.apps_to_run++;
145 }
146
147 static inline void dec_apps_to_run()
148 {
149         if (manager.apps_to_run > 0)
150                 manager.apps_to_run--;
151 }
152
153 static inline int get_apps_to_run()
154 {
155         return manager.apps_to_run;
156 }
157
158 static int kill_app_by_info(const struct app_info_t *app_info)
159 {
160         int res = 0;
161
162         if (app_info == NULL) {
163                 LOGE("Cannot exec app. app_info is NULL");
164                 return -1;
165         }
166
167         switch (app_info->app_type) {
168         case APP_TYPE_TIZEN:
169                 res = kill_app(app_info->exe_path);
170                 break;
171         case APP_TYPE_RUNNING:
172                 // TODO: nothing, it's running
173                 LOGI("already started\n");
174                 break;
175         case APP_TYPE_COMMON:
176                 res = kill_app(app_info->exe_path);
177                 break;
178         case APP_TYPE_WEB:
179                 /* do nothing (it is restarted by itself) */
180                 break;
181         default:
182                 LOGE("Unknown app type %d\n", app_info->app_type);
183                 res = -1;
184                 break;
185         }
186
187         return res;
188 }
189
190 static int exec_app(const struct app_info_t *app_info)
191 {
192         int res = 0;
193
194         if (app_info == NULL) {
195                 LOGE("Cannot exec app. app_info is NULL");
196                 return -1;
197         }
198
199         switch (app_info->app_type) {
200         case APP_TYPE_TIZEN:
201                 if (exec_app_tizen(app_info->app_id, app_info->exe_path)) {
202                         LOGE("Cannot exec tizen app %s\n", app_info->app_id);
203                         res = -1;
204                 } else {
205                         inc_apps_to_run();
206                 }
207                 break;
208         case APP_TYPE_RUNNING:
209                 // TODO: nothing, it's running
210                 LOGI("already started\n");
211                 break;
212         case APP_TYPE_COMMON:
213                 if (exec_app_common(app_info->exe_path)) {
214                         LOGE("Cannot exec common app %s\n", app_info->exe_path);
215                         res = -1;
216                 } else {
217                         inc_apps_to_run();
218                 }
219                 break;
220         case APP_TYPE_WEB:
221                 if (exec_app_web(app_info->app_id)) {
222                         LOGE("Cannot exec web app %s\n", app_info->app_id);
223                         res = -1;
224                 }
225                 break;
226         default:
227                 LOGE("Unknown app type %d\n", app_info->app_type);
228                 res = -1;
229                 break;
230         }
231
232         LOGI("ret=%d\n", res);
233         return res;
234 }
235
236 // just send stop message to all target process
237 static void terminate_all_target()
238 {
239         struct msg_target_t msg = {
240                 .type = MSG_STOP,
241                 .length = 0
242         };
243
244         target_send_msg_to_all(&msg);
245 }
246
247 // terminate all target and wait for threads
248 void terminate_all()
249 {
250         terminate_all_target();
251
252         // wait for all other thread exit
253         target_wait_all();
254 }
255
256 // terminate all profiling by critical error
257 // TODO: don't send data to host
258 static void terminate_error(char *errstr, int send_to_host)
259 {
260         LOGE("termination all with err '%s'\n", errstr);
261         struct msg_data_t *msg = NULL;
262         if (send_to_host != 0) {
263                 msg = gen_message_error(errstr);
264                 if (msg) {
265                         if (write_to_buf(msg) != 0)
266                                 LOGE("write to buf fail\n");
267                         free_msg_data(msg);
268                 } else {
269                         LOGI("cannot generate error message\n");
270                 }
271         }
272         terminate_all();
273 }
274
275 static Ecore_Fd_Handler *connect_timer_handler;
276
277 static Eina_Bool connect_timer_cb(void *data, Ecore_Fd_Handler *fd_handler)
278 {
279         terminate_error("no incoming connections", 1);
280         close(manager.connect_timeout_timerfd);
281         manager.connect_timeout_timerfd = -1;
282         LOGE("No connection in %d sec. shutdown.\n",
283              MAX_CONNECT_TIMEOUT_TIME);
284         ecore_main_loop_quit();
285
286         return ECORE_CALLBACK_CANCEL;
287 }
288
289 static int launch_timer_start(void)
290 {
291         int res = 0;
292
293         manager.connect_timeout_timerfd =
294             timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
295         if (manager.connect_timeout_timerfd > 0) {
296                 struct itimerspec ctime;
297                 ctime.it_value.tv_sec = MAX_CONNECT_TIMEOUT_TIME;
298                 ctime.it_value.tv_nsec = 0;
299                 ctime.it_interval.tv_sec = 0;
300                 ctime.it_interval.tv_nsec = 0;
301                 if (timerfd_settime(manager.connect_timeout_timerfd, 0, &ctime, NULL) < 0) {
302                         LOGE("fail to set connect timeout timer\n");
303                         close(manager.connect_timeout_timerfd);
304                         manager.connect_timeout_timerfd = -1;
305                 } else {
306                         connect_timer_handler =
307                                 ecore_main_fd_handler_add(manager.connect_timeout_timerfd,
308                                                           ECORE_FD_READ,
309                                                           connect_timer_cb,
310                                                           NULL,
311                                                           NULL, NULL);
312                         if (!connect_timer_handler) {
313                                 LOGE("fail to add app connection timeout timer fd\n");
314                                 close(manager.connect_timeout_timerfd);
315                                 manager.connect_timeout_timerfd = -1;
316                         } else {
317                                 LOGI("connection timeout timer started\n");
318                         }
319                 }
320         } else {
321                 LOGE("cannot create connection timeout timer\n");
322         }
323
324         LOGI("ret=%d\n", res);
325         return res;
326 }
327
328 int prepare_profiling(void)
329 {
330         struct app_list_t *app = NULL;
331         const struct app_info_t *app_info = NULL;
332
333         app_info = app_info_get_first(&app);
334         if (app_info == NULL) {
335                 LOGE("No app info found\n");
336                 return -1;
337         }
338
339         //all apps
340         while (app_info != NULL) {
341                 if (kill_app_by_info(app_info) != 0) {
342                         LOGE("kill app failed\n");
343                         return -1;
344                 }
345                 app_info = app_info_get_next(&app);
346         }
347         //init rw for systeminfo
348         //init recv send network systeminfo
349         sys_stat_prepare();
350         return 0;
351
352 }
353
354 int start_profiling(void)
355 {
356         struct app_list_t *app = NULL;
357         const struct app_info_t *app_info = NULL;
358         int res = 0;
359
360         app_info = app_info_get_first(&app);
361         if (app_info == NULL) {
362                 LOGE("No app info found\n");
363                 return -1;
364         }
365         // remove previous screen capture files
366         remove_indir(SCREENSHOT_DIR);
367         if (mkdir(SCREENSHOT_DIR, 0777) == -1 && errno != EEXIST)
368                 LOGW("Failed to create directory for screenshot : %s\n",
369                      strerror(errno));
370
371         set_label_for_all(SCREENSHOT_DIR);
372
373         if (samplingStart() < 0) {
374                 LOGE("Cannot start sampling\n");
375                 res = -1;
376                 goto exit;
377         }
378
379         if (IS_OPT_SET(FL_RECORDING))
380                 add_input_events();
381
382         while (app_info != NULL) {
383                 if (exec_app(app_info)) {
384                         LOGE("Cannot exec app\n");
385                         res = -1;
386                         goto recording_stop;
387                 }
388                 app_info = app_info_get_next(&app);
389         }
390
391         if (start_app_launch_timer(get_apps_to_run()) < 0) {
392                 res = -1;
393                 goto recording_stop;
394         }
395
396         goto exit;
397
398  recording_stop:
399         if (IS_OPT_SET(FL_RECORDING))
400                 del_input_events();
401         samplingStop();
402
403  exit:
404         LOGI("return %d\n", res);
405         return res;
406 }
407
408 void stop_profiling(void)
409 {
410         if (IS_OPT_SET(FL_RECORDING))
411                 del_input_events();
412         samplingStop();
413 }
414
415 static void reconfigure_recording(struct conf_t conf)
416 {
417         uint64_t old_features = prof_session.conf.use_features0;
418         uint64_t new_features = conf.use_features0;
419         uint64_t to_enable = (new_features ^ old_features) & new_features;
420         uint64_t to_disable = (new_features ^ old_features) & old_features;
421
422         if (IS_OPT_SET_IN(FL_RECORDING, to_disable)) {
423                 del_input_events();
424                 prof_session.conf.use_features0 &= ~FL_RECORDING;
425         }
426
427         if (IS_OPT_SET_IN(FL_RECORDING, to_enable)) {
428                 add_input_events();
429                 prof_session.conf.use_features0 |= FL_RECORDING;
430         }
431
432 }
433
434 int reconfigure(struct conf_t conf)
435 {
436         reconfigure_recording(conf);
437
438         samplingStop();
439         memcpy(&prof_session.conf, &conf, sizeof(conf));
440         if (samplingStart() < 0) {
441                 LOGE("Cannot start sampling\n");
442                 return -1;
443         }
444
445         return 0;
446 }
447
448
449 static int file2str(const char *filename, char *buf, int len)
450 {
451         int fd, num_read;
452
453         fd = open(filename, O_RDONLY, 0);
454         if (fd == -1)
455                 return -1;
456
457         num_read = read(fd, buf, len - 1);
458
459         close(fd);
460
461         if (num_read <= 0)
462                 return -1;
463
464         buf[num_read] = '\0';
465
466         return num_read;
467 }
468
469 static pid_t get_lpad_pid(pid_t pid)
470 {
471         static pid_t lpad_pid = UNKNOWN_PID;
472         static const char lpad_path[] = DEBUG_LAUNCH_PRELOAD_PATH;
473         enum { lpad_path_len = sizeof(lpad_path) };
474
475         if (lpad_pid == UNKNOWN_PID) {
476                 char fname[64];
477                 char buf[lpad_path_len];
478
479                 sprintf(fname, "/proc/%d/cmdline", pid);
480                 if (-1 == file2str(fname, buf, lpad_path_len))
481                         return lpad_pid;
482
483                 buf[lpad_path_len - 1] = '\0';
484
485                 if (strncmp(buf, lpad_path, lpad_path_len - 1) == 0)
486                         lpad_pid = pid;
487         }
488
489         return lpad_pid;
490 }
491
492 static pid_t get_current_pid(void)
493 {
494         static pid_t pid = UNKNOWN_PID;
495
496         if (pid == UNKNOWN_PID)
497                 pid = getpid();
498
499         return pid;
500 }
501
502 static void target_set_type(struct target *t)
503 {
504         pid_t ppid = target_get_ppid(t);
505
506         if (get_current_pid() == ppid) {
507                 t->app_type = APP_TYPE_COMMON;
508         } else if (get_lpad_pid(ppid) == ppid) {
509                 t->app_type = APP_TYPE_TIZEN;
510         }
511 }
512
513
514 static int target_event_pid_handler(struct target *target)
515 {
516         struct app_list_t *app = NULL;
517         struct app_info_t *app_info = NULL;
518
519         target_set_type(target);
520
521         if (0) {        // main application (index == 0)
522                 app_info = app_info_get_first(&app);
523                 if (app_info == NULL) {
524                         LOGE("No app info found\n");
525                         return -1;
526                 }
527
528                 while (app_info != NULL) {
529                         if (is_same_app_process(app_info->exe_path,
530                                                 target_get_pid(target)))
531                                 break;
532                         app_info = app_info_get_next(&app);
533                 }
534
535                 if (app_info == NULL) {
536                         LOGE("pid %d not found in app list\n",
537                              target_get_pid(target));
538                         return -1;
539                 }
540
541                 if (start_replay() != 0) {
542                         LOGE("Cannot start replay thread\n");
543                         return -1;
544                 }
545         }
546
547         target->initial_log = 1;
548
549         return 0;
550 }
551
552 static int target_event_stop_handler(struct target *target)
553 {
554         int cnt;
555         enum app_type_t app_type = target->app_type;
556
557         LOGI("target[%p] close, pid(%d) : (remaining %d target)\n",
558              target, target_get_pid(target), target_cnt_get() - 1);
559
560         if (0)          // main application (index == 0)
561                 stop_replay();
562
563         ecore_main_fd_handler_del(target->handler);
564
565         target_dtor(target);
566         // all target client are closed
567         cnt = target_cnt_sub_and_fetch();
568         if (0 == cnt) {
569                 switch (app_type) {
570                 case APP_TYPE_TIZEN:
571                 case APP_TYPE_COMMON:
572                         LOGI("all targets are stopped\n");
573                         if (stop_all() != ERR_NO)
574                                 LOGE("Stop failed\n");
575                         return -11;
576                 }
577         }
578
579         return 0;
580 }
581
582 // return 0 if normal case
583 // return plus value if non critical error occur
584 // return minus value if critical error occur
585 // return -11 if all target process closed
586 static int target_event_handler(struct target *t, uint64_t msg)
587 {
588         int err = 0;
589         if (msg & EVENT_PID)
590                 err = target_event_pid_handler(t);
591         if (err)
592                 return err;
593
594         if (msg & EVENT_STOP || msg & EVENT_ERROR)
595                 err = target_event_stop_handler(t);
596
597         return err;
598 }
599
600 static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
601 {
602         uint64_t u;
603         ssize_t recvLen;
604         struct target *target = (struct target *)data;
605
606         recvLen = read(target->event_fd, &u, sizeof(uint64_t));
607         if (recvLen != sizeof(uint64_t)) {
608                 // maybe closed, but ignoring is more safe then
609                 // removing fd from event loop
610         } else {
611                 if (-11 == target_event_handler(target, u)) {
612                         LOGI("all target process is closed\n");
613                 }
614         }
615
616         return ECORE_CALLBACK_RENEW;
617 }
618
619 /**
620  * return 0 if normal case
621  * return plus value if non critical error occur
622  * return minus value if critical error occur
623  */
624 static int targetServerHandler(void)
625 {
626         int err;
627         struct msg_target_t log;
628         struct target *target;
629
630         target = target_ctor();
631         if (target == NULL) {
632                 LOGW("(target == NULL) no more target can connected\n");
633                 return 1;
634         }
635
636         err = target_accept(target, manager.target_server_socket);
637         if (err == 0) {
638                 /* send config message to target process */
639                 log.type = MSG_OPTION;
640                 log.length = sprintf(log.data, "%llu\0",
641                                      prof_session.conf.use_features0) + 1;
642                 if (target_send_msg(target, &log) != 0)
643                         LOGE("fail to send data to target %p\n", target);
644
645                 /* send current instrument maps */
646                 send_maps_inst_msg_to(target);
647
648                 // make event fd
649                 target->event_fd = eventfd(EFD_CLOEXEC, EFD_NONBLOCK);
650                 if (target->event_fd == -1) {
651                         // fail to make event fd
652                         LOGE("fail to make event fd for target[%p]\n", target);
653                         goto TARGET_CONNECT_FAIL;
654                 }
655
656                 target->handler =
657                         ecore_main_fd_handler_add(target->event_fd,
658                                                   ECORE_FD_READ,
659                                                   target_event_cb,
660                                                   (void *)target,
661                                                   NULL, NULL);
662                 if (!target->handler) {
663                         LOGE("fail to add event fd for target[%p]\n", target);
664                         goto TARGET_CONNECT_FAIL;
665                 }
666
667                 // make recv thread for target
668                 if (makeRecvThread(target) != 0) {
669                         // fail to make recv thread
670                         LOGE("fail to make recv thread for target[%p]\n",
671                              target);
672                         ecore_main_fd_handler_del(target->handler);
673                         goto TARGET_CONNECT_FAIL;
674                 }
675
676                 dec_apps_to_run();
677
678                 if ((manager.app_launch_timerfd > 0) && (get_apps_to_run() == 0)) {
679                         if (stop_app_launch_timer() < 0)
680                                 LOGE("cannot stop app launch timer\n");
681                 }
682
683                 LOGI("target connected target[%p](running %d target)\n",
684                      target, target_cnt_get() + 1);
685
686                 target_cnt_set(target_cnt_get() + 1);
687                 return 0;
688         } else {
689                 // accept error
690                 LOGE("Failed to accept at target server socket\n");
691         }
692
693  TARGET_CONNECT_FAIL:
694         if (target_cnt_get() == 0) {
695                 // if this connection is main connection
696                 return -1;
697         } else {
698                 // if this connection is not main connection then ignore process by error
699                 target_dtor(target);
700                 return 1;
701         }
702 }
703
704 static Ecore_Fd_Handler *host_ctrl_handler;
705 static Ecore_Fd_Handler *host_data_handler;
706
707 // return plus value if non critical error occur
708 // return minus value if critical error occur
709 // return -11 if socket closed
710 static int controlSocketHandler(int efd)
711 {
712         ssize_t recv_len;
713         struct msg_t msg_head;
714         struct msg_t *msg;
715         int res = 0;
716
717         if (manager.connect_timeout_timerfd >= 0) {
718                 LOGI("release connect timeout timer\n");
719                 close(manager.connect_timeout_timerfd);
720                 manager.connect_timeout_timerfd = -1;
721         }
722         // Receive header
723         recv_len = recv(manager.host.control_socket,
724                         &msg_head, MSG_CMD_HDR_LEN, 0);
725         // error or close request from host
726         if (recv_len == -1 || recv_len == 0)
727                 return -11;
728         else {
729                 if (msg_head.len > RECV_BUF_MAX)
730                         return -1;
731                 msg = malloc(MSG_CMD_HDR_LEN + msg_head.len);
732                 if (!msg) {
733                         LOGE("Cannot alloc msg\n");
734                         sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
735                         return -1;
736                 }
737                 msg->id = msg_head.id;
738                 msg->len = msg_head.len;
739                 if (msg->len > 0) {
740                         // Receive payload (if exists)
741                         recv_len = recv(manager.host.control_socket,
742                                         msg->payload, msg->len, MSG_WAITALL);
743                         if (recv_len == -1) {
744                                 free(msg);
745                                 return -11;
746                         }
747                 }
748                 printBuf((char *)msg, MSG_CMD_HDR_LEN + msg->len);
749                 res = host_message_handler(msg);
750                 free(msg);
751         }
752
753         return res;
754 }
755
756 static Eina_Bool host_ctrl_cb(void *data, Ecore_Fd_Handler *fd_handler)
757 {
758         int result = controlSocketHandler(manager.efd);
759         if (result == -11) {
760                 // socket close
761                 //if the host disconnected.
762                 //In all other cases daemon must report an error and continue the loop
763                 //close connect_timeoutt and host socket and quit
764                 LOGI("Connection closed. Termination. (%d)\n",
765                      manager.host.control_socket);
766                 manager.host.data_socket = -1; //splice will fail without that
767                 ecore_main_loop_quit();
768         } else if (result < 0) {
769                 LOGE("Control socket handler.\n");
770         }
771
772         return ECORE_CALLBACK_RENEW;
773 }
774
775 static Eina_Bool host_data_cb(void *data, Ecore_Fd_Handler *fd_handler)
776 {
777         ssize_t recvLen;
778         char recvBuf[32];
779
780         recvLen = recv(manager.host.data_socket, recvBuf, 32, MSG_DONTWAIT);
781         if (recvLen == 0) {
782                 // close data socket
783                 ecore_main_fd_handler_del(host_data_handler);
784                 close(manager.host.data_socket);
785                 manager.host.data_socket = -1;
786                 // TODO: finish transfer thread
787         }
788
789         LOGI("host message from data socket %d\n", recvLen);
790
791         return ECORE_CALLBACK_RENEW;
792 }
793
794 // return 0 if normal case
795 // return plus value if non critical error occur
796 // return minus value if critical error occur
797 static int hostServerHandler(void)
798 {
799         static int hostserverorder = 0;
800         int csocket;
801
802         if (hostserverorder > 1)        // control and data socket connected already
803                 return 1;               // ignore
804
805         csocket = accept4(manager.host_server_socket, NULL, NULL, SOCK_CLOEXEC);
806
807         if (csocket >= 0) {
808                 // accept succeed
809
810                 if (hostserverorder == 0) {
811                         manager.host.control_socket = csocket;
812                         unlink_portfile();
813                         LOGI("host control socket connected = %d\n", csocket);
814                         host_ctrl_handler =
815                                 ecore_main_fd_handler_add(manager.host.control_socket,
816                                                           ECORE_FD_READ,
817                                                           host_ctrl_cb,
818                                                           NULL,
819                                                           NULL, NULL);
820                         if (!host_ctrl_handler) {
821                                 LOGE("Failed to add host control socket fd\n");
822                                 close(csocket);
823                                 return -1;
824                         }
825                 } else {
826                         manager.host.data_socket = csocket;
827                         LOGI("host data socket connected = %d\n", csocket);
828
829                         host_data_handler =
830                                 ecore_main_fd_handler_add(manager.host.data_socket,
831                                                           ECORE_FD_READ,
832                                                           host_data_cb,
833                                                           NULL,
834                                                           NULL, NULL);
835                         if (!host_data_handler) {
836                                 LOGE("Failed to add host data socket fd\n");
837                                 close(csocket);
838                                 return -1;
839                         }
840                 }
841
842                 hostserverorder++;
843                 return 0;
844         } else {
845                 // accept error
846                 LOGE("Failed to accept from host server socket\n");
847                 return -1;
848         }
849 }
850
851 static Ecore_Fd_Handler *host_connect_handler;
852 static Ecore_Fd_Handler *target_connect_handler;
853
854 static Eina_Bool host_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
855 {
856         // connect request from host
857         int result = hostServerHandler();
858         if (result < 0) {
859                 LOGE("Internal DA framework error (hostServerHandler)\n");
860         }
861
862         return ECORE_CALLBACK_RENEW;
863 }
864
865 static Eina_Bool target_connect_cb(void *data, Ecore_Fd_Handler *fd_handler)
866 {
867         if (targetServerHandler() < 0) {
868                 // critical error
869                 terminate_error("Internal DA framework error, "
870                                 "Please re-run the profiling "
871                                 "(targetServerHandler)\n", 1);
872         }
873
874         return ECORE_CALLBACK_RENEW;
875 }
876
877 static bool initialize_events(void)
878 {
879         host_connect_handler =
880                 ecore_main_fd_handler_add(manager.host_server_socket,
881                                           ECORE_FD_READ,
882                                           host_connect_cb,
883                                           NULL,
884                                           NULL, NULL);
885         if (!host_connect_handler) {
886                 LOGE("Host server socket add error\n");
887                 return false;
888         }
889
890         target_connect_handler =
891                 ecore_main_fd_handler_add(manager.target_server_socket,
892                                           ECORE_FD_READ,
893                                           target_connect_cb,
894                                           NULL,
895                                           NULL, NULL);
896         if (!target_connect_handler) {
897                 LOGE("Target server socket add error\n");
898                 return false;
899         }
900
901         return true;
902 }
903
904 // return 0 for normal case
905 int daemonLoop(void)
906 {
907         int return_value = 0;
908
909         ecore_init();
910
911         if (init_input_events() == -1) {
912                 return_value = -1;
913                 goto END_EVENT;
914         }
915
916         if (!initialize_events()) {
917                 return_value = -1;
918                 goto END_EFD;
919         }
920
921         if (launch_timer_start() < 0) {
922                 LOGE("Launch timer start failed\n");
923                 return_value = -1;
924                 goto END_EFD;
925         }
926
927         init_prof_session(&prof_session);
928
929         ecore_main_loop_begin();
930         ecore_shutdown();
931
932  END_EFD:
933         LOGI("close efd\n");
934         close(manager.efd);
935  END_EVENT:
936         return return_value;
937 }