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