[Title] apply runtime config and new protocol
[platform/core/system/swap-manager.git] / daemon / daemon.c
1 /*
2 *  DA manager
3 *
4 * Copyright (c) 2000 - 2011 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
12  * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 * Contributors:
25 * - S-Core Co., Ltd
26 *
27 */ 
28
29 #include <stdio.h>
30 #include <stdlib.h>                     // for realpath
31 #include <string.h>                     // for strtok, strcpy, strncpy
32 #include <limits.h>                     // for realpath
33
34 #include <errno.h>                      // for errno
35 #include <sys/types.h>          // for accept, mkdir, opendir, readdir
36 #include <sys/socket.h>         // for accept
37 #include <sys/stat.h>           // for mkdir
38 #include <sys/eventfd.h>        // for eventfd
39 #include <sys/epoll.h>          // for epoll apis
40 #include <unistd.h>                     // for access, sleep
41 #include <attr/xattr.h>         // for fsetxattr
42
43 #include "daemon.h"
44 #include "sys_stat.h"
45 #include "utils.h"
46
47 #define DA_WORK_DIR                             "/home/developer/sdk_tools/da/"
48 #define DA_READELF_PATH                 "/home/developer/sdk_tools/da/readelf"
49 #define SCREENSHOT_DIR                  "/tmp/da"
50
51 #define EPOLL_SIZE 10
52 #define MAX_CONNECT_SIZE 12
53
54 static void terminate_error(char* errstr, int sendtohost);
55
56 long long get_total_alloc_size()
57 {
58         int i;
59         long long allocsize = 0;
60
61         for(i = 0; i < MAX_TARGET_COUNT; i++)
62         {
63                 if(manager.target[i].socket != -1 && manager.target[i].allocmem > 0)
64                         allocsize += manager.target[i].allocmem;
65         }
66         return allocsize;
67 }
68
69 static int getEmptyTargetSlot()
70 {
71         int i;
72         for(i = 0; i < MAX_TARGET_COUNT; i++)
73         {
74                 if(manager.target[i].socket == -1)
75                         break;
76         }
77
78         return i;
79 }
80
81 static void setEmptyTargetSlot(int index)
82 {
83         if(index >= 0 && index < MAX_TARGET_COUNT)
84         {
85                 manager.target[index].pid = -1;
86                 manager.target[index].recv_thread = -1;
87                 manager.target[index].allocmem = 0;
88                 manager.target[index].starttime = 0;
89                 if(manager.target[index].event_fd != -1)
90                         close(manager.target[index].event_fd);
91                 manager.target[index].event_fd = -1;
92                 if(manager.target[index].socket != -1)
93                         close(manager.target[index].socket);
94                 manager.target[index].socket = -1;
95         }
96 }
97
98 // ======================================================================================
99 // send functions to host
100 // ======================================================================================
101
102 int sendDataToHost(msg_t* log)
103 {
104         if (manager.host.data_socket != -1)
105         {
106                 char logstr[DA_MSG_MAX];
107                 int loglen;
108
109                 if(log->length != 0)
110                         loglen = sprintf(logstr, "%d|%d|%s\n", log->type, log->length + 1, log->data);
111                 else
112                         loglen = sprintf(logstr, "%d|%d|\n", log->type, log->length + 1);
113
114 //              loglen = sprintf(logstr, "%d|%s\n", log->type, log->data);
115
116                 pthread_mutex_lock(&(manager.host.data_socket_mutex));
117                 send(manager.host.data_socket, logstr, loglen, MSG_NOSIGNAL);
118                 pthread_mutex_unlock(&(manager.host.data_socket_mutex));
119                 return 0;
120         }
121         else
122                 return 1;
123 }
124
125 // msgstr can be NULL
126 static int sendACKStrToHost(enum HostMessageType resp, char* msgstr)
127 {
128         if (manager.host.control_socket != -1)
129         {
130                 char logstr[DA_MSG_MAX];
131                 int loglen;
132
133                 if(msgstr != NULL)
134                         loglen = sprintf(logstr, "%d|%d|%s", (int)resp, strlen(msgstr), msgstr);
135                 else
136                         loglen = sprintf(logstr, "%d|0|", (int)resp);
137
138                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
139                 return 0;
140         }
141         else
142                 return 1;
143 }
144
145 static int sendACKCodeToHost(enum HostMessageType resp, int msgcode)
146 {
147         if (manager.host.control_socket != -1)
148         {
149                 char codestr[16];
150                 char logstr[DA_MSG_MAX];
151                 int loglen, codelen;
152
153                 codelen = sprintf(codestr, "%d", msgcode);
154                 loglen = sprintf(logstr, "%d|%d|%s", (int)resp, codelen, codestr);
155
156                 send(manager.host.control_socket, logstr, loglen, MSG_NOSIGNAL);
157                 return 0;
158         }
159         else
160                 return 1;
161 }
162
163 // ========================================================================================
164 // start and terminate control functions
165 // ========================================================================================
166
167 static int startProfiling(long launchflag)
168 {
169         char execPath[PATH_MAX];
170
171         // remove previous screen capture files
172         remove_indir(SCREENSHOT_DIR);
173         mkdir(SCREENSHOT_DIR, 0777);
174
175         manager.config_flag = launchflag;
176
177 #ifdef RUN_APP_LOADER
178         strcpy(execPath, manager.appPath);
179 #else
180         get_executable(manager.appPath, execPath, PATH_MAX);
181 #endif
182         if(exec_app(execPath, get_app_type(manager.appPath)))
183         {
184                 if(samplingStart() < 0)
185                 {
186                         return -1;
187                 }
188                 LOGI("Timer Started\n");
189         }
190         else
191                 return -1;
192
193         return 0;
194 }
195
196 // terminate single target
197 // just send stop message to target process
198 static void terminate_target(int index)
199 {
200         ssize_t sendlen;
201         msg_t sendlog;
202         sendlog.type = MSG_STOP;
203         sendlog.length = 0;
204
205         if(manager.target[index].socket != -1)
206         {
207                 // result of sending to disconnected socket is not expected
208                 sendlen = send(manager.target[index].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
209                 if(sendlen != -1)
210                 {
211                         LOGI("TERMINATE send exit msg (socket %d) by terminate_target()\n", manager.target[index].socket);
212                 }
213         }
214 }
215
216 // just send stop message to all target process
217 static void terminate_all_target()
218 {
219         int i;
220         ssize_t sendlen;
221         msg_t sendlog;
222
223         sendlog.type = MSG_STOP;
224         sendlog.length = 0;
225
226         for (i = 0; i < MAX_TARGET_COUNT; i++)
227         {
228                 if(manager.target[i].socket != -1)
229                 {
230                         sendlen = send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length), MSG_NOSIGNAL);
231                         if(sendlen != -1)
232                         {
233                                 LOGI("TERMINATE send exit msg (socket %d) by terminate_all_target()\n", manager.target[i].socket);
234                         }
235                 }
236         }
237 }
238
239 // terminate all target and wait for threads
240 static void terminate_all()
241 {
242         int i;
243         terminate_all_target();
244         samplingStop();
245
246         // wait for all other thread exit
247         for(i = 0; i < MAX_TARGET_COUNT; i++)
248         {
249                 if(manager.target[i].recv_thread != -1)
250                 {
251                         pthread_join(manager.target[i].recv_thread, NULL);
252                 }
253         }
254 }
255
256 // terminate all profiling by critical error
257 static void terminate_error(char* errstr, int sendtohost)
258 {
259         msg_t log;
260
261         LOGE("TERMINATE ERROR: %s\n", errstr);
262         if(sendtohost)
263         {
264                 log.type = MSG_ERROR;
265                 log.length = sprintf(log.data, "%s", errstr);
266                 sendDataToHost(&log);
267         }
268
269         terminate_all();
270 }
271
272 // ===========================================================================================
273 // message parsing and handling functions
274 // ===========================================================================================
275
276 // return 0 for normal case
277 // return negative value for error case
278 static int parseHostMessage(msg_t* log, char* msg)
279 {
280         int i;
281         int bfind = 0;
282         int ret = 0;    // parsing success
283
284         if(log == NULL || msg == NULL)
285                 return -1;
286
287         // Host message looks like this
288         // MSG_TYPE|MSG_LENGTH|MSG_STRING
289         // MSG_TYPE is always 3 digits number
290         if(msg[3] == '|')
291         {
292                 msg[3] = '\0';
293                 log->type = atoi(msg);
294
295                 msg = msg + 4;
296                 for(i = 0; msg[i] != '\0'; i++)
297                 {
298                         if(msg[i] == '|')
299                         {
300                                 bfind = 1;
301                                 msg[i] = '\0';
302                                 break;
303                         }
304                 }
305                 log->length = atoi(msg);
306
307                 if(log->length == 0)
308                 {
309                         log->data[0] = '\0';
310                 }
311                 else
312                 {
313                         if(bfind != 0)
314                         {
315                                 int msglen;
316                                 msg = msg + i + 1;
317                                 msglen = strlen(msg);
318
319                                 if(msglen == log->length)
320                                 {
321                                         strcpy(log->data, msg);
322                                         log->data[log->length] = '\0';
323                                 }
324 //                              else if(msglen > log->length)
325 //                              {
326 //                                      strncpy(log->data, msg, log->length);
327 //                                      log->data[log->length] = '\0';
328 //                              }
329                                 else
330                                 {
331                                         ret = -1;       // parsing error
332                                 }
333                         }
334                         else
335                         {
336                                 ret = -1;       // parsing error
337                         }
338                 }
339         }
340         else
341         {
342                 ret = -1;       // parsing error
343         }
344
345         return ret;
346 }
347
348 // return 0 if normal case
349 // return plus value if non critical error occur
350 // return minus value if critical error occur
351 static int hostMessageHandler(msg_t* log)
352 {
353         int ret = 0;
354         long flag = 0;
355         char *barloc, *tmploc;
356         char execPath[PATH_MAX];
357
358         if (log == NULL)
359                 return 1;
360
361         switch (log->type)
362         {
363         case MSG_VERSION:
364                 if(strcmp(PROTOCOL_VERSION, log->data) != 0)
365                 {
366                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_PROTOCOL_VERSION);
367                 }
368                 else
369                 {
370                         sendACKStrToHost(MSG_OK, NULL);
371                 }
372                 break;
373         case MSG_START:
374                 LOGI("MSG_START handling : %s\n", log->data);
375                 if(log->length == 0)
376                 {
377                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
378                         return -1;              // wrong message format
379                 }
380
381                 // parsing for host start status
382                 tmploc  = log->data;
383                 barloc = strchr(tmploc, '|');
384                 if(barloc == NULL)
385                 {
386                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
387                         return -1;              // wrong message format
388                 }
389
390                 // parsing for target launch option flag
391                 tmploc = barloc + 1;
392                 barloc = strchr(tmploc, '|');
393                 if(barloc != NULL)
394                 {
395                         while(tmploc < barloc)
396                         {
397                                 flag = (flag * 10) + (*tmploc - '0');
398                                 tmploc++;
399                         }
400                 }
401                 else
402                 {
403                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
404                         return -1;      // wrong message format
405                 }
406                 LOGI("launch flag : %lx\n", flag);
407
408                 // parsing for application package name
409                 tmploc = barloc + 1;
410                 strcpy(manager.appPath, tmploc);
411
412                 get_executable(manager.appPath, execPath, PATH_MAX); // get exact app executable file name
413                 LOGI("executable app path %s\n", manager.appPath);
414
415 #ifdef RUN_APP_LOADER
416                 kill_app(manager.appPath);
417 #else
418                 kill_app(execPath);
419 #endif
420
421                 {
422                         char command[PATH_MAX];
423
424                         //save app install path
425                         mkdir(DA_WORK_DIR, 0775);
426                         sprintf(command,
427                                         "%s -Wwi %s | grep DW_AT_comp_dir > %s", DA_READELF_PATH,
428                                         execPath, DA_INSTALL_PATH);
429                         LOGI("appInstallCommand %s\n", command);
430                         system(command);
431
432                         sprintf(command,
433                                         "%s -h %s | grep Type | cut -d\" \" -f33 > %s", DA_READELF_PATH,
434                                         execPath, DA_BUILD_OPTION);
435                         LOGI("appInstallCommand %s\n", command);
436                         system(command);
437
438                         if(startProfiling(flag) < 0)
439                         {
440                                 sendACKCodeToHost(MSG_NOTOK, ERR_CANNOT_START_PROFILING);
441                                 return -1;
442                         }
443                 }
444                 sendACKStrToHost(MSG_OK, NULL);
445                 break;
446         case MSG_STOP:
447                 LOGI("MSG_STOP handling\n");
448                 sendACKStrToHost(MSG_OK, NULL);
449                 terminate_all();
450                 break;
451         case MSG_OPTION:
452                 if(log->length > 0)
453                 {
454                         int i;
455                         msg_t sendlog;
456                         manager.config_flag = atoi(log->data);
457                         sendACKStrToHost(MSG_OK, NULL);
458
459                         LOGI("MSG_OPTION : str(%s), flag(%x)\n", log->data, manager.config_flag);
460
461                         sendlog.type = MSG_OPTION;
462                         sendlog.length = sprintf(sendlog.data, "%u", manager.config_flag);
463
464                         for(i = 0; i < MAX_TARGET_COUNT; i++)
465                         {
466                                 if(manager.target[i].socket != -1)
467                                 {
468                                         send(manager.target[i].socket, &sendlog, sizeof(sendlog.type) + sizeof(sendlog.length) + sendlog.length, MSG_NOSIGNAL);
469                                 }
470                         }
471                 }
472                 else
473                 {
474                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_DATA);
475                         ret = 1;
476                 }
477                 break;
478         case MSG_ISALIVE:
479                 sendACKStrToHost(MSG_OK, NULL);
480                 break;
481         default:
482                 LOGW("Unknown msg\n");
483                 sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_TYPE);
484                 ret = 1;
485                 break;
486         }
487
488         return ret;
489 }
490
491 // ========================================================================================
492 // socket and event_fd handling functions
493 // ========================================================================================
494
495 // return 0 if normal case
496 // return plus value if non critical error occur
497 // return minus value if critical error occur
498 // return -11 if all target process closed
499 static int targetEventHandler(int epollfd, int index, uint64_t msg)
500 {
501         msg_t log;
502
503         if(msg & EVENT_PID)
504         {
505                 if(index == 0)          // assume index 0 is main application process
506                 {
507                         int base_address;
508                         char tempBuff[DA_MSG_MAX];
509                         char tempBuff2[DA_MSG_MAX];
510                         char tempPath[PATH_MAX];
511
512                         get_executable(manager.appPath, tempPath, PATH_MAX);
513                         if(realpath(tempPath, tempBuff) == NULL)
514                         {
515                                 LOGW("Failed to get realpath of app\n");
516                                 strcpy(tempBuff, tempPath);
517                         }
518
519                         sprintf(tempPath, "/proc/%d/maps", manager.target[index].pid);
520                         sprintf(tempBuff2, "cat %s | grep %s | cut -d\"-\" -f1 > %s",
521                                         tempPath, tempBuff, DA_BASE_ADDRESS);
522                         LOGI("base address command is %s\n", tempBuff2);
523
524                         do {
525                                 if(access(tempPath, F_OK) != 0)
526                                         return -1;
527                                 if(is_same_app_process(manager.appPath, manager.target[index].pid) == 0)
528                                         return -1;
529
530                                 system(tempBuff2);
531                                 if(get_app_base_address(&base_address) == 1)
532                                         break;
533                                 sleep(0);
534                         } while(1);
535
536                         tempPath[0] = '\0';
537                         get_app_install_path(tempPath, PATH_MAX);
538                         get_device_info(tempBuff, DA_MSG_MAX);
539                         log.type = MSG_DEVICE;
540                         if (strlen(tempPath) > 0)
541                         {
542                                 get_executable(manager.appPath, tempBuff2, DA_MSG_MAX);
543                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,%s/%s", tempBuff,
544                                                 manager.target[index].pid, manager.target[index].starttime,
545                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath),
546                                                 tempPath, get_app_name(tempBuff2));
547                         }
548                         else
549                         {
550                                 log.length = sprintf(log.data, "%s`,%d`,%Lu`,%d`,%u`,%d`,", tempBuff,
551                                                 manager.target[index].pid, manager.target[index].starttime,
552                                                 is_app_built_pie(), base_address, get_app_type(manager.appPath));
553                         }
554
555                         LOGI("%s\n", log.data);
556                 }
557                 else
558                 {
559                         log.type = MSG_PID;
560                         log.length = sprintf(log.data, "%d`,%Lu", manager.target[index].pid, manager.target[index].starttime);
561                 }
562
563                 sendDataToHost(&log);
564         }
565
566         if(msg & EVENT_STOP || msg & EVENT_ERROR)
567         {
568                 LOGI("target close, socket(%d), pid(%d) : (remaining %d target)\n",
569                                 manager.target[index].socket, manager.target[index].pid, manager.target_count - 1);
570
571                 terminate_target(index);
572                 epoll_ctl(epollfd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
573                 setEmptyTargetSlot(index);
574                 if (0 == __sync_sub_and_fetch(&manager.target_count, 1))        // all target client are closed
575                 {
576                         log.type = MSG_TERMINATE;
577                         log.length = 0;
578                         log.data[0] = '\0';
579                         sendDataToHost(&log);
580                         return -11;
581                 }
582         }
583
584         return 0;
585 }
586
587 // return 0 if normal case
588 // return plus value if non critical error occur
589 // return minus value if critical error occur
590 static int targetServerHandler(int efd)
591 {
592         msg_t log;
593         struct epoll_event ev;
594
595         int index = getEmptyTargetSlot();
596         if(index == MAX_TARGET_COUNT)
597         {
598                 LOGW("Max target number(8) reached, no more target can connected\n");
599                 return 1;
600         }
601
602         manager.target[index].socket = accept(manager.target_server_socket, NULL, NULL);
603
604         if(manager.target[index].socket >= 0)   // accept succeed
605         {
606                 // set smack attribute for certification
607                 fsetxattr(manager.target[index].socket, "security.SMACK64IPIN", "*", 1, 0);
608                 fsetxattr(manager.target[index].socket, "security.SMACK64IPOUT", "*", 1, 0);
609
610                 // send config message to target process
611                 log.type = MSG_OPTION;
612                 log.length = sprintf(log.data, "%u", manager.config_flag);
613                 send(manager.target[index].socket, &log, sizeof(log.type) + sizeof(log.length) + log.length, MSG_NOSIGNAL);
614
615                 // make event fd
616                 manager.target[index].event_fd = eventfd(0, EFD_NONBLOCK);
617                 if(manager.target[index].event_fd == -1)
618                 {
619                         // fail to make event fd
620                         LOGE("fail to make event fd for socket (%d)\n", manager.target[index].socket);
621                         goto TARGET_CONNECT_FAIL;
622                 }
623
624                 // add event fd to epoll list
625                 ev.events = EPOLLIN;
626                 ev.data.fd = manager.target[index].event_fd;
627                 if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target[index].event_fd, &ev) < 0)
628                 {
629                         // fail to add event fd
630                         LOGE("fail to add event fd to epoll list for socket (%d)\n", manager.target[index].socket);
631                         goto TARGET_CONNECT_FAIL;
632                 }
633
634                 // make recv thread for target
635                 if(makeRecvThread(index) != 0)
636                 {
637                         // fail to make recv thread
638                         LOGE("fail to make recv thread for socket (%d)\n", manager.target[index].socket);
639                         epoll_ctl(efd, EPOLL_CTL_DEL, manager.target[index].event_fd, NULL);
640                         goto TARGET_CONNECT_FAIL;
641                 }
642
643                 LOGI("target connected = %d(running %d target)\n",
644                                 manager.target[index].socket, manager.target_count + 1);
645
646                 manager.target_count++;
647                 return 0;
648         }
649         else    // accept error
650         {
651                 LOGE("Failed to accept at target server socket\n");
652         }
653
654 TARGET_CONNECT_FAIL:
655         if(manager.target_count == 0)   // if this connection is main connection
656         {
657                 return -1;
658         }
659         else    // if this connection is not main connection then ignore process by error
660         {
661                 setEmptyTargetSlot(index);
662                 return 1;
663         }
664 }
665
666 // return 0 if normal case
667 // return plus value if non critical error occur
668 // return minus value if critical error occur
669 static int hostServerHandler(int efd)
670 {
671         static int hostserverorder = 0;
672         int csocket;
673         struct epoll_event ev;
674
675         if(hostserverorder > 1) // control and data socket connected already
676                 return 1;                       // ignore
677
678         csocket = accept(manager.host_server_socket, NULL, NULL);
679
680         if(csocket >= 0)                // accept succeed
681         {
682                 ev.events = EPOLLIN;
683                 ev.data.fd = csocket;
684                 if(epoll_ctl(efd, EPOLL_CTL_ADD, csocket, &ev) < 0)
685                 {
686                         // consider as accept fail
687                         LOGE("Failed to add socket fd to epoll list\n");
688                         close(csocket);
689                         return -1;
690                 }
691
692                 if(hostserverorder == 0)
693                 {
694                         manager.host.control_socket = csocket;
695                         LOGI("host control socket connected = %d\n", csocket);
696                 }
697                 else
698                 {
699                         manager.host.data_socket = csocket;
700                         LOGI("host data socket connected = %d\n", csocket);
701                 }
702
703                 hostserverorder++;
704                 return 0;
705         }
706         else    // accept error
707         {
708                 LOGE("Failed to accept from host server socket\n");
709                 return -1;
710         }
711 }
712
713 // return 0 if normal case
714 // return plus value if non critical error occur
715 // return minus value if critical error occur
716 // return -11 if socket closed
717 static int controlSocketHandler()
718 {
719         ssize_t recvLen;
720         char recvBuf[DA_MSG_MAX];
721         msg_t log;
722
723         // host log format xxx|length|str
724         recvLen = recv(manager.host.control_socket, recvBuf, RECV_BUF_MAX, 0);
725
726         if (recvLen > 0)
727         {
728                 recvBuf[recvLen] = '\0';
729                 LOGI("host sent control msg str(%s)\n", recvBuf);
730
731                 if(parseHostMessage(&log, recvBuf) < 0)
732                 {
733                         // error to parse host message
734                         sendACKCodeToHost(MSG_NOTOK, ERR_WRONG_MESSAGE_FORMAT);
735                         return 1;
736                 }
737
738                 // host msg command handling
739                 return hostMessageHandler(&log);
740         }
741         else    // close request from HOST
742         {
743                 return -11;
744         }
745 }
746
747 // return 0 for normal case
748 int daemonLoop()
749 {
750         int                     ret = 0;                                // return value
751         int                     i, k;
752         ssize_t         recvLen;
753
754         struct epoll_event ev, *events;
755         int efd;                // epoll fd
756         int numevent;   // number of occured events
757
758         // initialize epoll event pool
759         events = (struct epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
760         if(events == NULL)
761         {
762                 LOGE("Out of memory when allocate epoll event pool\n");
763                 ret = -1;
764                 goto END_RETURN;
765         }
766         if((efd = epoll_create(MAX_CONNECT_SIZE)) < 0)
767         {
768                 LOGE("epoll creation error\n");
769                 ret = -1;
770                 goto END_EVENT;
771         }
772
773         // add server sockets to epoll event pool
774         ev.events = EPOLLIN;
775         ev.data.fd = manager.host_server_socket;
776         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.host_server_socket, &ev) < 0)
777         {
778                 LOGE("Host server socket epoll_ctl error\n");
779                 ret = -1;
780                 goto END_EFD;
781         }
782         ev.events = EPOLLIN;
783         ev.data.fd = manager.target_server_socket;
784         if(epoll_ctl(efd, EPOLL_CTL_ADD, manager.target_server_socket, &ev) < 0)
785         {
786                 LOGE("Target server socket epoll_ctl error\n");
787                 ret = -1;
788                 goto END_EFD;
789         }
790
791         // handler loop
792         while (1)
793         {
794                 numevent = epoll_wait(efd, events, EPOLL_SIZE, -1);
795                 if(numevent <= 0)
796                 {
797                         LOGE("Failed to epoll_wait : num of event(%d), errno(%d)\n", numevent, errno);
798                         continue;
799                 }
800
801                 for(i = 0; i < numevent; i++)
802                 {
803                         // check for request from event fd
804                         for(k = 0; k < MAX_TARGET_COUNT; k++)
805                         {
806                                 if(manager.target[k].socket != -1 &&
807                                                 events[i].data.fd == manager.target[k].event_fd)
808                                 {
809                                         uint64_t u;
810                                         recvLen = read(manager.target[k].event_fd, &u, sizeof(uint64_t));
811                                         if(recvLen != sizeof(uint64_t))
812                                         {
813                                                 // maybe closed, but ignoring is more safe then removing fd from epoll list
814                                         }
815                                         else
816                                         {
817                                                 if(-11 == targetEventHandler(efd, k, u))
818                                                 {
819                                                         LOGI("all target process is closed\n");
820                                                         terminate_all();
821                                                         ret = 0;
822                                                         goto END_EFD;
823                                                 }
824                                         }
825                                         break;
826                                 }
827                         }
828
829                         if(k != MAX_TARGET_COUNT)
830                                 continue;
831
832                         // connect request from target
833                         if(events[i].data.fd == manager.target_server_socket)
834                         {
835                                 if(targetServerHandler(efd) < 0)        // critical error
836                                 {
837                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
838                                         ret = -1;
839                                         goto END_EFD;
840                                 }
841                         }
842                         // connect request from host
843                         else if(events[i].data.fd == manager.host_server_socket)
844                         {
845                                 int result = hostServerHandler(efd);
846                                 if(result < 0)
847                                 {
848                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
849                                         ret = -1;
850                                         goto END_EFD;
851                                 }
852                         }
853                         // control message from host
854                         else if(events[i].data.fd == manager.host.control_socket)
855                         {
856                                 int result = controlSocketHandler();
857                                 if(result == -11)       // socket close
858                                 {
859                                         // close target and host socket and quit
860                                         LOGI("host close = %d\n", manager.host.control_socket);
861                                         terminate_all();
862                                         ret = 0;
863                                         goto END_EFD;
864                                 }
865                                 else if(result < 0)
866                                 {
867                                         terminate_error("Internal DA framework error, Please re-run the profiling.", 1);
868                                         ret = -1;
869                                         goto END_EFD;
870                                 }
871                         }
872                         else if(events[i].data.fd == manager.host.data_socket)
873                         {
874                                 LOGW("host message from data socket\n");
875                         }
876                         // unknown socket
877                         else
878                         {
879                                 // never happened
880                                 LOGW("Unknown socket fd (%d)\n", events[i].data.fd);
881                         }
882                 }
883         }
884
885 END_EFD:
886         close(efd);
887 END_EVENT:
888         free(events);
889 END_RETURN:
890         return ret;
891 }