8e5ffbf5da4829f44e83115b3fe26abeb758cb6c
[platform/core/system/swap-manager.git] / daemon / main.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
32 #include <stdio.h>                      // for fopen, fprintf
33 #include <stdlib.h>                     // for atexit
34 #include <sys/types.h>          // for open
35 #include <sys/file.h>
36 #include <sys/stat.h>           // for open
37 #include <sys/socket.h>         // for socket
38 #include <sys/un.h>                     // for sockaddr_un
39 #include <arpa/inet.h>          // for sockaddr_in, socklen_t
40 #include <linux/netlink.h>
41 #include <linux/connector.h>
42
43 #include <signal.h>                     // for signal
44 #include <unistd.h>                     // for unlink
45 #include <fcntl.h>                      // for open, fcntl
46 #include <errno.h>
47 #include <stdbool.h>
48 #include "daemon.h"
49 #include "da_protocol.h"
50 #include "sys_stat.h"
51 #include "buffer.h"
52 #include "debug.h"
53 #include "utils.h"
54 #include "smack.h"
55 #include "us_interaction_msg.h"
56 #include "freezing.h"
57
58 #define SINGLETON_LOCKFILE                      "/tmp/da_manager.lock"
59 #define PORTFILE                                        "/tmp/port.da"
60 #define UDS_NAME                                        "/tmp/da.socket"
61
62 #define INIT_PORT                               8001
63 #define LIMIT_PORT                              8100
64
65
66 // initialize global variable
67 __da_manager manager =
68 {
69         .host_server_socket = -1,
70         .target_server_socket = -1,
71         .kernel_socket = -1,
72         .target_count = 0,
73         .apps_to_run = 0,
74         .config_flag = 0,
75         .app_launch_timerfd = -1,
76         .connect_timeout_timerfd = -1,
77         .sampling_thread = -1,
78         .replay_thread = -1,
79         .transfer_thread = -1,
80         .buf_fd = -1,
81         .user_ev_fd = -1,
82         .efd = -1,
83
84         .host = {
85                 .control_socket = -1,
86                 .data_socket = -1,
87                 .data_socket_mutex = PTHREAD_MUTEX_INITIALIZER
88         },
89
90         .target = {
91                 {0L, },
92         },
93         .fd = {
94                 .brightness = -1,
95                 .voltage = -1,
96                 .procmeminfo = -1,
97                 .video = NULL,
98                 .procstat = NULL,
99                 .networkstat = NULL,
100                 .diskstats = NULL
101         },
102         .appPath = {0, }
103
104         };
105 // =============================================================================
106 // util functions
107 // =============================================================================
108
109 static void write_int(FILE *fp, int code)
110 {
111         fprintf(fp, "%d", code);
112 }
113
114 // =============================================================================
115 // atexit functions
116 // =============================================================================
117
118 static void _close_server_socket(void)
119 {
120         LOGI("close_server_socket\n");
121         // close server socket
122         if(manager.host_server_socket != -1)
123                 close(manager.host_server_socket);
124         if(manager.target_server_socket != -1)
125                 close(manager.target_server_socket);
126         if (manager.kernel_socket != -1)
127                 close(manager.kernel_socket);
128 }
129
130 static void _unlink_files(void)
131 {
132         LOGI("unlink files start\n");
133         unlink(PORTFILE);
134         unlink(SINGLETON_LOCKFILE);
135         LOGI("unlink files done\n");
136 }
137
138 void unlink_portfile(void)
139 {
140         unlink(PORTFILE);
141 }
142
143 // =============================================================================
144 // making sockets
145 // =============================================================================
146
147 // return 0 for normal case
148 static int makeTargetServerSocket()
149 {
150         struct sockaddr_un serverAddrUn;
151
152         if(manager.target_server_socket != -1)
153                 return -1;      // should be never happend
154
155         // remove existed unix domain socket file
156         unlink(UDS_NAME);
157
158         if ((manager.target_server_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
159         {
160                 LOGE("Target server socket creation failed\n");
161                 return -1;
162         }
163
164         fd_setup_attributes(manager.target_server_socket);
165
166         memset(&serverAddrUn, '\0', sizeof(serverAddrUn));
167         serverAddrUn.sun_family = AF_UNIX;
168         sprintf(serverAddrUn.sun_path, "%s", UDS_NAME);
169
170         if (-1 == bind(manager.target_server_socket, (struct sockaddr*) &serverAddrUn,
171                                         sizeof(serverAddrUn)))
172         {
173                 LOGE("Target server socket binding failed\n");
174                 return -1;
175         }
176
177         if(chmod(serverAddrUn.sun_path, 0777) < 0)
178         {
179                 LOGE("Failed to change mode for socket file : errno(%d)\n", errno);
180         }
181
182
183         if (-1 == listen(manager.target_server_socket, 5))
184         {
185                 LOGE("Target server socket listening failed\n");
186                 return -1;
187         }
188
189         LOGI("Created TargetSock %d\n", manager.target_server_socket);
190         return 0;
191 }
192
193 // return port number for normal case
194 // return negative value for error case
195 static int makeHostServerSocket()
196 {
197         struct sockaddr_in serverAddrIn;
198         int opt = 1;
199         int port;
200
201         if(manager.host_server_socket != -1)
202                 return -1;      // should be never happened
203
204         if ((manager.host_server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
205         {
206                 LOGE("Host server socket creation failed\n");
207                 return -1;
208         }
209
210         if(setsockopt(manager.host_server_socket,
211            SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
212         {
213                 LOGE("Failed to set socket option : errno(%d)\n", errno);
214         }
215
216         memset(&serverAddrIn, 0, sizeof(serverAddrIn));
217         serverAddrIn.sin_family = AF_INET;
218         serverAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
219
220         // bind address to server socket
221         for(port = INIT_PORT; port < LIMIT_PORT; port++)
222         {
223                 serverAddrIn.sin_port = htons(port);
224                 if (0 == bind(manager.host_server_socket,
225                                         (struct sockaddr*) &serverAddrIn, sizeof(serverAddrIn)))
226                         break;
227         }
228
229         if(port == LIMIT_PORT)
230         {
231                 LOGE("Host server socket binding failed\n");
232                 return -1;
233         }
234
235         // enter listen state from client
236         if (-1 == listen(manager.host_server_socket, 5))
237         {
238                 LOGE("Host server socket listening failed\n");
239                 return -1;
240         }
241
242         LOGI("Created HostSock %d\n", manager.host_server_socket);
243         return port;
244 }
245
246 // return 0 for normal case
247 static int makeKernelSocket(void)
248 {
249         struct sockaddr_nl nlAddr;
250         int ret;
251
252         if (manager.kernel_socket != -1)
253                 return -1;      // should be never happend
254
255         manager.kernel_socket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
256         if (manager.kernel_socket < 0) {
257                 LOGE("Kernel socket creation failed\n");
258                 return -1;
259         }
260
261         nlAddr.nl_family = AF_NETLINK;
262         nlAddr.nl_groups = CN_DAEMON_GROUP;
263         nlAddr.nl_pid = 0;
264
265         if (-1 == bind(manager.kernel_socket, (struct sockaddr*) &nlAddr,
266                    sizeof(nlAddr))) {
267                 LOGE("Kernel socket binding failed\n");
268                 return -1;
269         }
270
271         LOGI("Created KernelSock %d\n", manager.kernel_socket);
272         return 0;
273 }
274
275 // =============================================================================
276 // initializing / finalizing functions
277 // =============================================================================
278
279 static bool ensure_singleton(const char *lockfile)
280 {
281         if (access(lockfile, F_OK) == 0)        /* File exists */
282                 return false;
283
284         int lockfd = open(lockfile, O_WRONLY | O_CREAT, 0600);
285         if (lockfd < 0) {
286                 LOGE("singleton lock file creation failed");
287                 return false;
288         }
289         /* To prevent race condition, also check for lock availiability. */
290         bool locked = flock(lockfd, LOCK_EX | LOCK_NB) == 0;
291
292         if (!locked) {
293                 LOGE("another instance of daemon is already running");
294         }
295         close(lockfd);
296         return locked;
297 }
298
299 static void inititialize_manager_targets(__da_manager * mng)
300 {
301         int index;
302         __da_target_info target_init_value = {
303                 .pid = -1,
304                 .socket = -1,
305                 .event_fd = -1,
306                 .recv_thread = -1,
307                 .initial_log = 0,
308                 .allocmem = 0
309         };
310
311         for (index = 0; index < MAX_TARGET_COUNT; index++)
312                 mng->target[index] = target_init_value;
313
314         manager.target_count = 0;
315 }
316
317 static bool initialize_pthread_sigmask()
318 {
319         sigset_t newsigmask;
320
321         sigemptyset(&newsigmask);
322         sigaddset(&newsigmask, SIGALRM);
323         sigaddset(&newsigmask, SIGUSR1);
324         return pthread_sigmask(SIG_BLOCK, &newsigmask, NULL) == 0;
325 }
326
327 // return 0 for normal case
328 static int initializeManager(FILE *portfile)
329 {
330         if (init_buf() != 0) {
331                 LOGE("Cannot init buffer\n");
332                 return -1;
333         }
334
335         if (initialize_system_info() < 0) {
336                 write_int(portfile, ERR_INITIALIZE_SYSTEM_INFO_FAILED);
337                 return -1;
338         }
339         // make server socket
340         if (makeTargetServerSocket() != 0) {
341                 write_int(portfile, ERR_TARGET_SERVER_SOCKET_CREATE_FAILED);
342                 return -1;
343         }
344         if (!initialize_pthread_sigmask()) {
345                 write_int(portfile, ERR_SIGNAL_MASK_SETTING_FAILED);
346                 return -1;
347         }
348
349         if (makeKernelSocket() != 0)
350                 return -1;
351
352         int port = makeHostServerSocket();
353         if (port < 0) {
354                 write_int(portfile, ERR_HOST_SERVER_SOCKET_CREATE_FAILED);
355                 return -1;
356         } else {
357                 write_int(portfile, port);
358         }
359
360         LOGI("SUCCESS to write port\n");
361
362         inititialize_manager_targets(&manager);
363
364         // initialize sendMutex
365         pthread_mutex_init(&(manager.host.data_socket_mutex), NULL);
366
367         return 0;
368 }
369
370
371 static int finalizeManager()
372 {
373         LOGI("Finalize daemon\n");
374         LOGI("finalize system info\n");
375         finalize_system_info();
376
377         // close host client socket
378         if(manager.host.control_socket != -1){
379                 LOGI("close host control socket (%d)\n", manager.host.control_socket);
380                 close(manager.host.control_socket);
381         }
382         if(manager.host.data_socket != -1){
383                 LOGI("close host data socket (%d)\n", manager.host.data_socket);
384                 close(manager.host.data_socket);
385         }
386
387         LOGI("return\n");
388         return 0;
389 }
390
391 static void remove_buf_modules(void)
392 {
393         LOGI("rmmod buffer start\n");
394         if (system("cd /opt/swap/sdk && ./stop.sh")) {
395                 LOGW("Cannot remove swap modules\n");
396         }
397         LOGI("rmmod buffer done\n");
398 }
399
400 static void terminate(int sig)
401 {
402         LOGI("terminate! sig = %d\n", sig);
403         if (!stop_all_in_process()) {
404                 // we are up there if signal accept and stop_all func was not
405                 // called yet.
406
407                 // so we need stop_all firstly (if profiling was
408                 // not started it will be dummy call) and release other sources
409                 stop_all_no_lock();
410                 _unlink_files();
411                 _close_server_socket();
412                 exit_buf();
413                 remove_buf_modules();
414                 if (sig != 0) {
415                         LOGW("Terminating due signal %s\n", strsignal(sig));
416                         signal(sig, SIG_DFL);
417                         raise(sig);
418                 }
419                 stop_all_done();
420         } else {
421                 // we are there if stop_all function was called by some reasons
422
423                 // if stop_all called we cannot call remove_buf_modules and
424                 // other funcs because of threads are not stopped yet
425                 LOGW("Stop in progress\n");
426                 if (sig != 0) {
427                         LOGW("ignore signal %s\n", strsignal(sig));
428                         signal(sig, SIG_IGN);
429                 }
430         }
431 }
432
433 static void terminate0()
434 {
435         terminate(0);
436 }
437
438
439 static void setup_signals()
440 {
441         struct sigaction sigact = {
442                 .sa_handler = terminate,
443                 .sa_flags = 0
444         };
445         sigemptyset(&sigact.sa_mask);
446         sigaction(SIGTERM, &sigact, 0);
447         sigaction(SIGINT, &sigact, 0);
448
449         signal(SIGHUP, SIG_IGN);
450         signal(SIGPIPE,SIG_IGN);
451 }
452
453 // main function
454 int main()
455 {
456         if (!ensure_singleton(SINGLETON_LOCKFILE))
457                 return 1;
458
459         initialize_log();
460
461         LOGI("da_started\n");
462         atexit(terminate0);
463
464
465         //for terminal exit
466         setup_signals();
467         daemon(0, 1);
468         LOGI("--- daemonized (pid %d) ---\n", getpid());
469
470         FILE *portfile = fopen(PORTFILE, "w");
471         if (!portfile) {
472                 LOGE("cannot create portfile");
473                 return 1;
474         }
475
476         int err = initializeManager(portfile);
477         fclose(portfile);
478         if (err)
479                 return 1;
480
481         err = create_freezer_subgroup();
482         if (err) {
483                 LOGE("cannot create freezer subgroup");
484                 return 1;
485         }
486
487         //init all file descriptors
488         init_system_file_descriptors();
489         //daemon work
490         //FIX ME remove samplingThread it is only for debug
491         //samplingThread(NULL);
492         daemonLoop();
493         LOGI("daemon loop finished\n");
494         stop_all();
495         destroy_freezer_subgroup();
496         finalizeManager();
497
498         close_system_file_descriptors();
499
500         LOGI("main finished\n");
501         return 0;
502 }