7f439d68c177cebee8b96c4362c574a66a630ffd
[platform/core/multimedia/mmsvc-core.git] / server / src / muse_server_private.c
1 /*
2  * muse-server
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: YoungHun Kim <yh8004.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include "muse_server_private.h"
23 #include <sys/file.h>
24 #include <gst/gst.h>
25 #include <syslog.h>
26 #include <malloc.h>
27 #include <tzplatform_config.h>
28
29 #if !GLIB_CHECK_VERSION(2, 58, 0)
30 #define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
31 #endif
32
33 #if defined (__aarch64__) || defined (__x86_64__)
34 #define MUSE_DEFAULT_MMAP_THRESHOLD_MAX (512 * 1024)
35 #endif
36
37
38 #ifdef MUSE_REGISTER_VIP
39 #include <proc_stat.h>
40 #endif
41
42 #ifdef MUSE_USE_LWIPC
43 #include <lwipc.h>
44 #define MUSE_LWIPC_WAIT_TIME                    1000
45 #endif
46
47
48 static const char *channel_name[MUSE_CHANNEL_MAX] = {
49         "msg",
50         "data"
51 };
52
53 static const char *UDS_files[MUSE_CHANNEL_MAX] = {MUSE_MSG_SOCK, MUSE_DATA_SOCK};
54
55 static muse_server_h muse_server;
56
57 static const char *module_cmd[MUSE_MODULE_COMMAND_MAX] = {
58         "initialize",
59         "shutdown",
60         "debug_info_dump",
61         "create_server_ack",
62         "resource_not_available",
63         "external_storage_state_changed",
64         "create_caution",
65         "resource_manager_shutdown"
66 };
67
68 static bool _ms_attach(int fd, muse_module_callback connection_handler, gpointer module_idx);
69 static void _ms_create_new_server_from_fd(int fd[], int type);
70 static int _ms_new(muse_channel_e channel);
71 static int _ms_get_pid(int fd);
72 static void _ms_get_module_addr(int fd, intptr_t *module_addr);
73 static void _ms_check_idle_state(void);
74 static gpointer _ms_diag_check_idle_state_thread(gpointer data);
75 static gpointer _ms_diag_check_connection_event_thread(gpointer data);
76 static void _ms_lock_state(void);
77 static void _ms_unlock_state(void);
78 static gboolean _ms_connection_handler(GIOChannel *source, GIOCondition condition, gpointer data);
79 #ifdef MUSE_USE_LWIPC
80 static void _ms_wait_event(void);
81 static void _ms_diag_init(void);
82 static void _ms_diag_deinit(void);
83 static gboolean _ms_idle_cb(gpointer data);
84 static int _ms_open_lockfile(void);
85
86 static void _ms_wait_event(void)
87 {
88         const char *lw_event_list[] = { "/run/.wm_ready", "/tmp/avoc_ready" };
89         unsigned int count = sizeof(lw_event_list) / sizeof(char *);
90
91         if (LwipcWaitMultiEvents(lw_event_list, count, true, MUSE_LWIPC_WAIT_TIME, NULL, 0) != 0)
92                 LOGE("Fail to receive Multiple Events");
93 }
94 #endif
95
96 static bool _ms_attach(int fd, muse_module_callback connection_handler, gpointer module_idx)
97 {
98         GIOChannel *channel = NULL;
99         GSource *src = NULL;
100
101         LOGI("Enter");
102
103         muse_return_val_if_fail(muse_server, false);
104         muse_return_val_if_fail(muse_core_fd_is_valid(fd), false);
105
106         channel = g_io_channel_unix_new(fd);
107         muse_return_val_if_fail(channel, false);
108
109         src = g_io_create_watch(channel, G_IO_IN);
110         if (!src) {
111                 LOGE("g_io_create_watch() is failed");
112                 g_io_channel_unref(channel);
113                 return false;
114         }
115
116         g_source_set_callback(src, G_SOURCE_FUNC(connection_handler), module_idx, NULL);
117
118         if (g_source_attach(src, g_main_loop_get_context(muse_server->main_loop)) == 0) {
119                 LOGE("g_source_attach() is failed");
120                 g_io_channel_unref(channel);
121                 return false;
122         }
123
124         g_source_unref(src);
125
126         g_io_channel_unref(channel);
127
128         LOGI("Leave");
129
130         return true;
131 }
132
133 static void _ms_create_new_server_from_fd(int fd[], int type)
134 {
135         int i;
136         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
137
138         LOGD("Enter");
139
140         muse_return_if_fail(muse_server);
141
142         muse_server->msg_fd = fd[MUSE_CHANNEL_MSG];
143         muse_server->data_fd = fd[MUSE_CHANNEL_DATA];
144         muse_server->type = type;
145
146         for (i = 0; i < MUSE_CHANNEL_MAX; i++) {
147                 if (!_ms_attach(fd[i], _ms_connection_handler, GINT_TO_POINTER(i))) {
148                         snprintf(err_msg, sizeof(err_msg), "Fail to attach server fd %d", fd[i]);
149
150                         LOGE("%s", err_msg);
151                         ms_terminate(SIGABRT);
152                 }
153         }
154
155         LOGD("Leave");
156 }
157
158 static int _ms_new(muse_channel_e channel)
159 {
160         int fd, errsv;
161         struct sockaddr_un addr_un;
162         socklen_t address_len;
163         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
164
165         muse_return_val_if_fail(channel < MUSE_CHANNEL_MAX, MM_ERROR_INVALID_ARGUMENT);
166
167         unlink(UDS_files[channel]);
168
169         /* Create Socket */
170         fd = socket(AF_UNIX, SOCK_STREAM, 0); /* Unix Domain Socket */
171         if (!muse_core_fd_is_valid(fd)) {
172                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
173                 LOGE("socket failed sock (%d) : %s", errno, err_msg);
174                 return MUSE_ERR;
175         }
176
177         LOGD("muse server fd : %d", fd);
178
179         memset(&addr_un, 0, sizeof(addr_un));
180         addr_un.sun_family = AF_UNIX;
181         strncpy(addr_un.sun_path, UDS_files[channel], sizeof(addr_un.sun_path) - 1);
182         address_len = (socklen_t)sizeof(addr_un);
183
184         /* Bind to filename */
185         if (bind(fd, (struct sockaddr *)&addr_un, address_len) < 0) {
186                 errsv = errno;
187                 strerror_r(errsv, err_msg, MUSE_MSG_LEN_MAX);
188                 LOGE("[%d] socket bind failed (%d) %s", fd, errsv, err_msg);
189                 muse_core_log_file_list(UDS_files[channel]);
190                 ms_log_user_group_info();
191                 if (errsv == EADDRINUSE)
192                         unlink(addr_un.sun_path);
193                 close(fd);
194                 return MUSE_ERR;
195         }
196
197         /* Setup listen queue */
198         if (listen(fd, 5) == MUSE_ERR) {
199                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
200                 LOGE("[%d] listen() failed (%d) %s", fd, errno, err_msg);
201                 muse_core_log_file_list(UDS_files[channel]);
202                 ms_log_user_group_info();
203                 close(fd);
204                 return MUSE_ERR;
205         }
206
207         if (muse_core_set_nonblocking(fd, false) < 0) /* blocking */
208                 LOGE("failed to set server socket to blocking");
209
210         return fd;
211 }
212
213 static int _ms_get_pid(int fd)
214 {
215         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
216         struct ucred credentials;
217         socklen_t length;
218
219         length = (socklen_t)sizeof(struct ucred);
220         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &length) < 0) {
221                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
222                 LOGE("failed to get the value of credential type %s", err_msg);
223                 return MUSE_ERR;
224         }
225
226         muse_core_update_fd_state(fd);
227
228         return credentials.pid;
229 }
230
231 static void _ms_get_module_addr(int fd, intptr_t *module_addr)
232 {
233         void *jobj;
234         int try_count = 0;
235         bool ret = true;
236         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
237         char recv_buf[MUSE_MSG_LEN_MAX] = {'\0',};
238
239         do {
240                 if (muse_core_msg_recv_fd(fd, recv_buf, MUSE_MSG_LEN_MAX, NULL) <= 0) {
241                         strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
242                         LOGE("failed to receive message for module %s", err_msg);
243                         return;
244                 }
245
246                 jobj = muse_core_msg_object_new(recv_buf, NULL, NULL);
247                 if (jobj) {
248                         ret = muse_core_msg_object_get_value(MSG_KEY_MODULE_ADDR, jobj, MUSE_TYPE_POINTER, module_addr);
249                         muse_core_msg_object_free(jobj);
250                         if (!ret)
251                                 LOGE("[%d] Error - module_addr %s", try_count, recv_buf);
252                         else
253                                 break;
254                 }
255         } while (++try_count < MS_RECV_TRY_COUNT_MAX);
256 }
257
258 static gboolean _ms_connection_handler(GIOChannel *source, GIOCondition condition, gpointer data)
259 {
260         int server_sockfd, client_sockfd, pid, idx, len;
261         socklen_t client_len;
262         struct sockaddr_un client_address;
263         muse_channel_e channel = GPOINTER_TO_INT(data);
264         muse_module_h m = NULL;
265         muse_module_h peeked_m = NULL;
266         muse_module_h candidate_m = NULL;
267         intptr_t module_addr = 0;
268         GQueue *instance_queue = NULL;
269         ms_system_t *system = NULL;
270         ms_connection_t *connection = NULL;
271         char time_buf[MUSE_MSG_TIME_LEN];
272
273         muse_return_val_if_fail(channel == MUSE_CHANNEL_MSG || channel == MUSE_CHANNEL_DATA, FALSE);
274
275         LOGI("Enter [%s channel]", channel_name[channel]);
276
277         muse_return_val_if_fail(muse_server, FALSE);
278
279         system = muse_server->system;
280         muse_return_val_if_fail(system, FALSE);
281
282         ms_system_stat_detach(system);
283
284         connection = muse_server->connection;
285         muse_return_val_if_fail(connection, FALSE);
286
287         _ms_lock_state();
288
289         if (!ms_is_server_ready()) {
290                 LOGW("Now mused state is not ready...");
291                 _ms_unlock_state();
292                 ms_terminate(SIGABRT);
293         }
294
295         server_sockfd = g_io_channel_unix_get_fd(source);
296         if (!muse_core_fd_is_valid(server_sockfd)) {
297                 LOGE("Critical Error : server %d is invalid", server_sockfd);
298                 _ms_unlock_state();
299                 muse_core_dump_fd_state(server_sockfd);
300                 ms_terminate(SIGABRT);
301         }
302
303         client_len = (socklen_t)sizeof(client_address);
304
305         LOGI("[%d] Try to accept...", server_sockfd);
306         client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
307         if (!muse_core_fd_is_valid(client_sockfd)) {
308                 LOGE("Critical Error : accept %d is invalid", client_sockfd);
309                 muse_core_dump_fd_state(client_sockfd);
310                 close(server_sockfd);
311                 _ms_unlock_state();
312                 ms_terminate(SIGABRT);
313         }
314
315         LOGI("server : %d client [%s channel] : %d", server_sockfd, channel_name[channel], client_sockfd);
316
317         pid = _ms_get_pid(client_sockfd);
318         if (pid == -1) {
319                 close(client_sockfd);
320                 _ms_unlock_state();
321                 return FALSE;
322         }
323
324
325         if (channel == MUSE_CHANNEL_MSG) {
326                 m = g_new0(muse_module_t, 1);
327                 SECURE_LOGI("module [%p]", m);
328                 m->ch[MUSE_CHANNEL_MSG].sock_fd = client_sockfd;
329                 m->pid = pid;
330                 g_mutex_init(&m->dispatch_lock);
331
332                 ms_ipc_create_msg_dispatch_worker(m);
333
334         } else {
335                 _ms_get_module_addr(client_sockfd, &module_addr);
336
337                 ms_connection_lock(connection);
338
339                 instance_queue = connection->instance_q;
340                 len = g_queue_get_length(instance_queue);
341
342                 m = (muse_module_h)module_addr;
343
344                 for (idx = 0; idx < len; idx++) {
345                         peeked_m = (muse_module_h)g_queue_peek_nth(instance_queue, idx);
346                         if (!peeked_m) {
347                                 LOGW("[%d] Make sure if the queue length is changed (%d = %d), which means that it was destroyed somewhere",
348                                         idx, len, g_queue_get_length(instance_queue));
349                                 continue;
350                         }
351
352                         if (peeked_m->pid != pid)
353                                 continue;
354
355                         if (!m) {
356                                 if (candidate_m) {
357                                         LOGE("muse-server can't support the error case which there are several modules now");
358                                         ms_connection_unlock(connection);
359                                         goto out;
360                                 }
361
362                                 if (!muse_core_fd_is_valid(peeked_m->ch[MUSE_CHANNEL_DATA].sock_fd))
363                                         candidate_m = peeked_m;
364                                 else
365                                         SECURE_LOGW("already paired module %p", peeked_m);
366
367                                 continue;
368                         }
369
370                         if (m != peeked_m)
371                                 continue;
372
373                         if (muse_core_fd_is_valid(m->ch[MUSE_CHANNEL_DATA].sock_fd)) {
374                                 SECURE_LOGE("[%d] %s pid %d %p you had better check if instance destroy completed properly",
375                                         client_sockfd, ms_config_get_host_name(m->idx), pid, m);
376                                 ms_connection_unlock(connection);
377                                 goto out;
378                         }
379
380                         m->ch[MUSE_CHANNEL_DATA].sock_fd = client_sockfd;
381                         SECURE_LOGI("%s (pid %d) module : %p module addr from client : %p",
382                                 ms_config_get_host_name(m->idx), pid, m, (void *)module_addr);
383                         break;
384                 }
385
386                 if (candidate_m) {
387                         m = candidate_m;
388                         m->ch[MUSE_CHANNEL_DATA].sock_fd = client_sockfd;
389                         SECURE_LOGW("[%d] %s pid %d %p restore module address at the only one null data channel",
390                                 client_sockfd, ms_config_get_host_name(m->idx), pid, m);
391                 }
392
393                 ms_connection_unlock(connection);
394
395                 ms_ipc_create_data_dispatch_worker(m);
396         }
397
398         muse_core_get_cur_time(&muse_server->tv, NULL);
399         muse_core_change_time_format((int)muse_server->tv.tv_sec, time_buf);
400         LOGW("connected time (%s)", time_buf);
401
402         _ms_unlock_state();
403
404         LOGI("Leave");
405
406         return TRUE;
407 out:
408         close(server_sockfd);
409         close(client_sockfd);
410
411         if (m)
412                 muse_core_connection_close(m->ch[MUSE_CHANNEL_MSG].sock_fd);
413
414         _ms_unlock_state();
415
416         LOGE("FALSE");
417
418         return FALSE;
419 }
420
421 static void _ms_check_idle_state(void)
422 {
423         ms_connection_t *connection = NULL;
424         ms_config_t *conf = NULL;
425         int instance_number, period;
426         uint32_t elapsed_time;
427         struct timespec tv;
428         static int period_idx = 1;
429         char time_buf[MUSE_MSG_TIME_LEN];
430
431         muse_return_if_fail(muse_server);
432         muse_return_if_fail(muse_server->state == MUSE_SERVER_STATE_READY);
433
434         connection = muse_server->connection;
435         muse_return_if_fail(connection);
436
437         conf = muse_server->conf;
438         muse_return_if_fail(conf);
439
440         period = ms_config_get_log_period();
441
442         if (muse_server->tv.tv_sec == 0)
443                 return;
444
445         muse_core_get_cur_time(&tv, NULL);
446
447         elapsed_time = (uint32_t)(tv.tv_sec - muse_server->tv.tv_sec);
448
449         ms_connection_lock(connection);
450
451         instance_number = g_queue_get_length(connection->instance_q);
452
453         if (elapsed_time >= (uint32_t)(period * period_idx)) {
454                 muse_core_change_time_format((int)muse_server->tv.tv_sec, time_buf);
455                 LOGW("[#%d] %us [period %ds] [%s] total number of modules = %d ( %s)", period_idx,
456                         elapsed_time, period, time_buf, instance_number, muse_server->instance_pid_info);
457                 period_idx++;
458         }
459
460         ms_connection_unlock(connection);
461
462         if (conf->is_on_demand) {
463                 if (instance_number == 0 && elapsed_time >= (uint32_t)ms_config_get_max_idle_time()) {
464                         LOGE("Timeout exit !!! [Idle time] %u sec", elapsed_time);
465                         ms_remove_ready_file();
466                         exit(EXIT_SUCCESS);
467                 }
468         }
469 }
470
471 static gpointer _ms_diag_check_idle_state_thread(gpointer data)
472 {
473         int idle_state_wait_time = ms_config_get_idle_state_wait_time();
474
475         muse_return_val_if_fail(muse_server, NULL);
476         muse_return_val_if_fail(idle_state_wait_time > 0, NULL);
477
478         while (ms_is_server_ready()) {
479                 _ms_check_idle_state();
480                 sleep(idle_state_wait_time);
481         }
482
483         return NULL;
484 }
485
486 static gpointer _ms_diag_check_connection_event_thread(gpointer data)
487 {
488         ms_diag_t *d;
489         ms_diag_msg_t *dm = NULL;
490         muse_return_val_if_fail(muse_server, NULL);
491
492         d = &muse_server->diag;
493
494         while (ms_is_server_ready()) {
495                 dm = (ms_diag_msg_t *)g_async_queue_pop(d->msg_aq);
496
497                 LOGD("[%p] POP message (thread stop ? %d [%s])", dm, dm->thread_stop, ms_get_command_string(dm->cmd));
498
499                 if (dm->thread_stop) {
500                         g_free(dm);
501                         break;
502                 }
503
504                 if (dm->cmd == API_CREATE) {
505                         /* can be updated if connection at the next patch */
506                 } else if (dm->cmd == API_DESTROY) {
507                         if (ms_config_is_check_cpu_memory())
508                                 ms_check_cpu_memory();
509                 }
510
511                 g_free(dm);
512         }
513
514         return NULL;
515 }
516
517 static void _ms_lock_state(void)
518 {
519         muse_return_if_fail(muse_server);
520         g_mutex_lock(&muse_server->state_lock);
521 }
522
523 static void _ms_unlock_state(void)
524 {
525         muse_return_if_fail(muse_server);
526         g_mutex_unlock(&muse_server->state_lock);
527 }
528
529 static void _ms_diag_init(void)
530 {
531         ms_diag_t *d;
532         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
533         GError *error = NULL;
534
535         muse_return_if_fail(muse_server);
536
537         d = &muse_server->diag;
538
539         d->idle_state_thread = g_thread_try_new("diag_idle_state",
540                 _ms_diag_check_idle_state_thread, muse_server->main_loop, &error);
541         if (!d->idle_state_thread) {
542                 snprintf(err_msg, sizeof(err_msg), "diag_idle_state_thread creation failed : %s", error->message);
543                 LOGE("%s", err_msg);
544                 g_error_free(error);
545                 ms_log_process_info(muse_server->pid);
546         }
547
548         d->msg_aq = g_async_queue_new_full(g_free);
549
550         d->conn_event_thread = g_thread_try_new("diag_connection",
551                 _ms_diag_check_connection_event_thread, muse_server->main_loop, &error);
552         if (!d->conn_event_thread) {
553                 snprintf(err_msg, sizeof(err_msg), "diag_connection_event_thread creation failed : %s", error->message);
554                 LOGE("%s", err_msg);
555                 g_error_free(error);
556                 ms_log_process_info(muse_server->pid);
557         }
558 }
559
560 static void _ms_diag_deinit(void)
561 {
562         ms_diag_t *d;
563         ms_diag_msg_t *dm;
564
565         LOGD("Enter");
566
567         muse_return_if_fail(muse_server);
568
569         d = &muse_server->diag;
570
571         dm = g_new0(ms_diag_msg_t, 1);
572
573         dm->thread_stop = TRUE;
574         LOGI("[%p] g_async_queue_push", dm);
575         g_async_queue_push_front(d->msg_aq, (gpointer)dm);
576
577         if (d->idle_state_thread) {
578                 g_thread_join(d->idle_state_thread);
579                 d->idle_state_thread = NULL;
580         }
581
582         if (d->conn_event_thread) {
583                 g_thread_join(d->conn_event_thread);
584                 d->conn_event_thread = NULL;
585         }
586
587         g_async_queue_unref(d->msg_aq);
588         d->msg_aq = NULL;
589 }
590
591 static gboolean _ms_idle_cb(gpointer data)
592 {
593         struct timespec tv;
594         char time_buf[MUSE_MSG_TIME_LEN];
595
596         if (!ms_create_ready_file())
597                 LOGE("%s file creation is failed", MUSE_SERVER_READY);
598
599         _ms_diag_init();
600
601         muse_core_get_cur_time(&tv, NULL);
602
603         muse_core_change_time_format((int)tv.tv_sec, time_buf);
604
605         LOGW("muse server is completed to ready (%s)", time_buf);
606
607         return G_SOURCE_REMOVE;
608 }
609
610 static void _ms_init(void)
611 {
612         int idx;
613
614         LOGD("Enter");
615
616 #if defined (__aarch64__) || defined (__x86_64__)
617         mallopt(M_MMAP_THRESHOLD, MUSE_DEFAULT_MMAP_THRESHOLD_MAX);
618         mallopt(M_TRIM_THRESHOLD, 2 * MUSE_DEFAULT_MMAP_THRESHOLD_MAX);
619 #endif
620
621         muse_server->system = g_new0(ms_system_t, 1);
622         ms_system_init(muse_server->system);
623
624         muse_server->conf = g_new0(ms_config_t, 1);
625         ms_config_init(muse_server->conf);
626
627         muse_server->log = g_new0(ms_log_t, 1);
628         ms_log_init(muse_server->log);
629
630         muse_server->security = g_new0(ms_security_t, 1);
631         ms_security_init(muse_server->security);
632
633         for (idx = 0; idx < muse_server->conf->host_cnt; idx++) {
634                 muse_server->module[idx] = g_new0(ms_module_t, 1);
635                 muse_server->module[idx]->idx = idx;
636                 ms_module_init(muse_server->module[idx]);
637         }
638
639 #ifdef MUSE_USE_WATCHDOG
640         muse_server->watchdog = g_new0(ms_watchdog_t, 1);
641         if (ms_watchdog_init(muse_server->watchdog) != MM_ERROR_NONE)
642                 LOGE("Fail to initialize server watchdog");
643 #endif
644
645         muse_server->connection = g_new0(ms_connection_t, 1);
646         ms_connection_init(muse_server->connection);
647
648         ms_signal_init();
649
650         g_mutex_init(&muse_server->state_lock);
651
652         muse_core_create_fd_table();
653
654         muse_server->main_loop = g_main_loop_new(NULL, FALSE);
655         muse_return_if_fail(muse_server->main_loop);
656
657         LOGD("Leave");
658 }
659
660 static int _ms_open_lockfile(void)
661 {
662         int fd, already_running;
663         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
664         char *lockfile = NULL;
665
666         muse_return_val_if_fail(muse_server, MUSE_ERR);
667
668         lockfile = ms_config_get_lockfile();
669         muse_return_val_if_fail(lockfile, MUSE_ERR);
670
671         muse_core_remove_symlink((const char *)lockfile);
672         fd = open(lockfile, O_RDONLY);
673         if (fd == -1 && errno != ENOENT) {
674                 /* Cannot open file even though file exists. */
675                 snprintf(err_msg, sizeof(err_msg), "Cannot open lock file %s", lockfile);
676                 LOGE("open failed : %s", err_msg);
677                 return MUSE_ERR;
678         } else if (fd != -1) {
679                 already_running = flock(fd, LOCK_EX | LOCK_NB) == -1;
680                 close(fd);
681                 if (already_running) {
682                         LOGE("File already locked. There's already a server running");
683                         return MUSE_ERR;
684                 }
685         }
686
687         /* Lock file does not exist, or is not locked. Create a new lockfile and lock it. */
688         fd = open(lockfile, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
689         if (fd == -1) {
690                 LOGE("dataserver: Cannot create lock file");
691                 return MUSE_ERR;
692         }
693
694         if (flock(fd, LOCK_EX | LOCK_NB) != 0) {
695                 LOGE("Can't lock the lock file \"%s\". " "Is another instance running?", lockfile);
696                 close(fd);
697                 return MUSE_ERR;
698         }
699
700         close(fd);
701
702         return MM_ERROR_NONE;
703 }
704
705 void ms_setup_syslog(void)
706 {
707         int flags = LOG_CONS|LOG_NDELAY|LOG_PID;
708         if (isatty(STDOUT_FILENO))
709                 flags |= LOG_PERROR;
710
711         openlog("mused", flags, LOG_DAEMON);
712         LOGD("openlog - mused");
713 }
714
715 void ms_fork(int *notify_fd)
716 {
717         pid_t pid;
718         int fds[2];
719         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
720         char msg[MUSE_MSG_LEN_MAX] = {'\0',};
721
722         if (pipe(fds) == MUSE_ERR) {
723                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
724                 LOGE("Failed to create pipe to get child status: %s", err_msg);
725                 exit(EXIT_FAILURE);
726         }
727
728         if ((pid = fork()) < 0) {
729                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
730                 LOGE("Error: fork() failed: %s", err_msg);
731                 exit(EXIT_FAILURE);
732         } else if (pid != 0) {
733                 close(fds[1]);
734                 /* Read in a string from the pipe */
735                 if (read(fds[0], msg, sizeof(msg)) <= 0) {
736                         LOGE("Failed to read from a file descriptor [%d]", fds[0]);
737                         close(fds[0]);
738                         return;
739                 }
740                 close(fds[0]);
741
742                 /* Parent process closes up output side of pipe */
743                 if (!strncmp(msg, MSG_DONE, strlen(MSG_DONE))) {
744                         LOGI("Successfully daemonized");
745                         exit(EXIT_SUCCESS);
746                 } else {
747                         LOGE("Daemonizing failed after fork");
748                         exit(EXIT_FAILURE);
749                 }
750         } else if (pid == 0) {
751                 /* Child process closes up input side of pipe */
752                 close(fds[0]);
753                 *notify_fd = fds[1];
754         }
755 }
756
757 pid_t ms_daemonize(int *notify_fd)
758 {
759         pid_t pid;
760         int fd, result;
761
762         muse_return_val_if_fail(notify_fd, MUSE_ERR);
763
764         ms_fork(notify_fd);
765
766         if ((pid = setsid()) < 0) {
767                 LOGE("create new session");
768                 exit(EXIT_FAILURE);
769         }
770
771         /* change the file mode mask */
772         umask(0);
773
774         result = chdir("/");
775         LOGD("result = %d sid: %d pgid: %d pid: %d ppid: %d", result, (int)getsid(0), (int)getpgid(0), (int)pid, (int)getppid());
776
777         /* redirect fds to /dev/null */
778         fd = open("/dev/null", O_RDWR);
779         if (!muse_core_fd_is_valid(fd)) {
780                 LOGE("Critical Error : %d is invalid", fd);
781                 exit(EXIT_SUCCESS);
782         }
783
784         close(STDIN_FILENO);
785         close(STDOUT_FILENO);
786         close(STDERR_FILENO);
787
788         dup2(fd, STDIN_FILENO);
789         dup2(fd, STDOUT_FILENO);
790         dup2(fd, STDERR_FILENO);
791
792         close(fd);
793
794         return pid;
795 }
796
797 void ms_daemonize_complete(int notify_fd)
798 {
799         LOGD("Enter");
800
801         muse_return_if_fail(muse_core_fd_is_valid(notify_fd));
802
803 #ifdef MUSE_REGISTER_VIP
804         proc_stat_set_vip_process();
805 #endif
806
807         write(notify_fd, MSG_DONE, strlen(MSG_DONE) + 1);
808         LOGW("[%d] Notify parent process that child initialization is done", notify_fd);
809         close(notify_fd);
810
811         LOGD("Leave");
812 }
813
814 void ms_gst_init(char **cmd)
815 {
816         gint argc = 0;
817         gchar **argv = NULL;
818         GError *err = NULL;
819         gboolean ret = FALSE;
820         int gst_param_cnt;
821
822 #ifdef MUSE_TTRACE_LOG
823         trace_begin("MUSE:gst_init");
824 #endif
825
826         gst_param_cnt = ms_config_get_gst_param_cnt();
827
828         /* add gst_param */
829         argv = g_malloc0(sizeof(gchar *) * (gst_param_cnt + 1));
830
831         argv[argc++] = (gchar *)cmd[0];
832         for (; argc <= gst_param_cnt; argc++) {
833                 argv[argc] = ms_config_get_gst_param_str(argc - 1);
834                 LOGI("%d %s", argc, argv[argc]);
835         }
836
837         /* initializing gstreamer */
838         ret = gst_init_check(&argc, &argv, &err);
839         if (!ret) {
840                 LOGE("Could not initialize GStreamer: %s ", err ? err->message : "unknown error occurred");
841                 if (err)
842                         g_error_free(err);
843         }
844
845         LOGI("gst_init_check is completed");
846
847         /* release */
848         g_free(argv);
849
850         LOGI("complete to initialize gstreamer");
851
852 #ifdef MUSE_TTRACE_LOG
853         trace_end();
854 #endif
855 }
856
857 void ms_gst_preload_plugin(void)
858 {
859         char *token = NULL;
860         char *saveptr = NULL;
861         char plugin_path[128];
862         const char *delimeters = " ,";
863         gchar *gst_preload_plugins = g_strdup(ms_config_get_gst_preload_plugins());
864         GstPlugin *plugin = NULL;
865
866         muse_return_if_fail(gst_preload_plugins);
867
868         LOGI("preload plugins [%s]", gst_preload_plugins);
869
870         token = strtok_r(gst_preload_plugins, delimeters, &saveptr);
871         while (token) {
872                 snprintf(plugin_path, sizeof(plugin_path), "%s/gstreamer-1.0/libgst%s.so", LIBDIR, token);
873
874                 LOGI("    plugin path : %s", plugin_path);
875
876                 plugin = gst_plugin_load_file(plugin_path, NULL);
877                 if (plugin)
878                         gst_object_unref(plugin);
879                 else
880                         LOGW("failed to load plugin [%s]", plugin_path);
881
882                 token = strtok_r(NULL, delimeters, &saveptr);
883         }
884
885         g_free(gst_preload_plugins);
886
887         LOGI("Leave");
888 }
889
890 int ms_pidfile_create(const char *path, pid_t pid)
891 {
892         int fd;
893         struct flock lock;
894         char pid_buf[MUSE_MSG_LEN] = {'\0',};
895         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
896
897         muse_return_val_if_fail(path, MM_ERROR_INVALID_ARGUMENT);
898         muse_core_remove_symlink(path);
899         fd = open(path, O_WRONLY | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
900
901         if (!muse_core_fd_is_valid(fd)) {
902                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
903                 LOGE("Fail to open pidfile [%s] : %s", path, err_msg);
904                 return MM_ERROR_FILE_NOT_FOUND;
905         }
906
907         lock.l_type = F_WRLCK;
908         lock.l_start = 0;
909         lock.l_whence = SEEK_SET;
910         lock.l_len = 0;
911
912         if (fcntl(fd, F_SETLK, &lock) < 0) {
913                 if (errno != EACCES && errno != EAGAIN) {
914                         strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
915                         LOGE("Fail to lock pidfile [%s] : %s", path, err_msg);
916                 } else {
917                         LOGE("process is already running");
918                 }
919                 close(fd);
920                 return MM_ERROR_FILE_INTERNAL;
921         }
922
923         if (ftruncate(fd, 0) < 0) {
924                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
925                 LOGE("Fail to truncate pidfile [%s] : %s", path, err_msg);
926                 close(fd);
927                 return MM_ERROR_FILE_INTERNAL;
928         }
929
930         memset(pid_buf, 0, sizeof(pid_buf));
931         snprintf(pid_buf, sizeof(pid_buf), "%u", pid);
932
933         if (write(fd, pid_buf, strlen(pid_buf)) != (int)strlen(pid_buf)) {
934                 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
935                 LOGE("Fail to write pid to pidfile [%s] : %s", path, err_msg);
936                 close(fd);
937                 return MM_ERROR_FILE_WRITE;
938         }
939
940         close(fd);
941         return MM_ERROR_NONE;
942 }
943
944 void ms_init(char **argv)
945 {
946         int idx;
947         int notify_fd;
948         muse_module_cmd_dispatchfunc *cmd_dispatcher = NULL;
949
950         LOGW("Enter");
951
952         muse_server = g_new0(muse_server_t, 1);
953
954         ms_setup_syslog();
955
956         muse_server->pid = ms_daemonize(&notify_fd);
957
958         if (g_mkdir_with_parents(tzplatform_mkpath(TZ_SYS_RUN, "mused"), S_IRWXU | S_IRWXG | S_IRWXO) != 0)
959                 exit(EXIT_FAILURE);
960
961         if (ms_pidfile_create(MUSE_DEFAULT_PIDFILE, muse_server->pid) != MM_ERROR_NONE)
962                 exit(EXIT_FAILURE);
963         else
964                 LOGW("MUSE_DEFAULT_PIDFILE(%s) file was created", MUSE_DEFAULT_PIDFILE);
965
966         _ms_init();
967
968         muse_return_if_fail(_ms_open_lockfile() == MM_ERROR_NONE);
969
970         ms_new();
971
972         ms_daemonize_complete(notify_fd);
973
974 #ifdef MUSE_TTRACE_LOG
975         trace_end();
976 #endif
977
978         ms_system_subscribe_external_event(muse_server->system);
979
980 #ifdef MUSE_USE_WATCHDOG
981         if (!ms_watchdog_attach(muse_server->watchdog)) {
982                 LOGE("watchdog thread failed");
983                 ms_log_process_info(muse_server->pid);
984                 return;
985         }
986 #endif
987
988         ms_gst_init(argv);
989
990         ms_init_bufmgr();
991
992 #ifdef MUSE_TTRACE_LOG
993         trace_begin("MUSE:preloading module");
994 #endif
995         for (idx = 0; idx < ms_config_get_host_cnt(); idx++) {
996                 if (0 == strncmp(ms_config_get_preloaded_value(idx), "yes", strlen("yes"))) {
997                         g_module_symbol(ms_module_open(idx), CMD_DISPATCHER, (gpointer *)&cmd_dispatcher);
998                         if (cmd_dispatcher && cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE])
999                                 cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE](NULL);
1000                 }
1001         }
1002 #ifdef MUSE_TTRACE_LOG
1003         trace_end();
1004 #endif
1005
1006 #ifdef MUSE_TTRACE_LOG
1007         trace_begin("MUSE:preloading GST module");
1008 #endif
1009         ms_gst_preload_plugin();
1010 #ifdef MUSE_TTRACE_LOG
1011         trace_end();
1012 #endif
1013
1014 #ifdef MUSE_GCOV_TEST
1015         muse_core_setenv("GCOV_PREFIX", "/tmp", 1);
1016 #endif
1017
1018         LOGW("Leave");
1019 }
1020
1021 muse_server_h ms_get_instance(void)
1022 {
1023         return muse_server;
1024 }
1025
1026 gboolean ms_check_module_idx(int idx)
1027 {
1028         int module_cnt = ms_config_get_host_cnt();
1029
1030         if (idx < 0 || idx >= module_cnt) {
1031                 LOGE("%d error - the number of modules is %d", idx, module_cnt);
1032                 return FALSE;
1033         }
1034
1035         return TRUE;
1036 }
1037
1038 ms_module_t *ms_get_module_instance(int idx)
1039 {
1040         muse_return_val_if_fail(ms_check_module_idx(idx), NULL);
1041
1042         return muse_server->module[idx];
1043 }
1044
1045 int ms_deinit(void)
1046 {
1047         int retval = MUSE_ERR;
1048         int idx;
1049
1050         LOGD("Enter");
1051
1052         muse_return_val_if_fail(muse_server, retval);
1053         muse_return_val_if_fail(muse_server->conf, retval);
1054         muse_return_val_if_fail(muse_server->connection, retval);
1055         muse_return_val_if_fail(muse_server->log, retval);
1056         muse_return_val_if_fail(muse_server->security, retval);
1057         muse_return_val_if_fail(muse_server->watchdog, retval);
1058
1059         ms_recursive_rmdir(MUSE_DATA_ROOT_PATH);
1060
1061         ms_set_state(MUSE_SERVER_STATE_IDLE);
1062
1063         _ms_diag_deinit();
1064
1065 #ifdef MUSE_USE_WATCHDOG
1066         ms_watchdog_detach(muse_server->watchdog);
1067
1068         if (ms_watchdog_deinit(muse_server->watchdog) == MM_ERROR_NONE)
1069                 free(muse_server->watchdog);
1070         else
1071                 LOGE("Fail to deinitialize server watchdog");
1072 #endif
1073
1074         ms_remove_ready_file();
1075
1076         retval = muse_server->retval;
1077         muse_core_fd_close(muse_server->msg_fd);
1078         muse_core_fd_close(muse_server->data_fd);
1079         for (idx = 0; idx < MUSE_CHANNEL_MAX; idx++) {
1080                 if (remove(UDS_files[idx]) == MUSE_ERR)
1081                         LOGE("remove %s failed", UDS_files[idx]);
1082         }
1083
1084         if (remove(MUSE_DEFAULT_PIDFILE) == -1)
1085                 LOGE("remove %s failed [errno : %d]", MUSE_DEFAULT_PIDFILE, errno);
1086
1087         for (idx = 0; idx < muse_server->conf->host_cnt; idx++)
1088                 ms_module_deinit(muse_server->module[idx]);
1089
1090         ms_security_deinit(muse_server->security);
1091         muse_server->security = NULL;
1092
1093         ms_system_deinit(muse_server->system);
1094         muse_server->system = NULL;
1095
1096         ms_log_deinit(muse_server->log);
1097         muse_server->log = NULL;
1098
1099         ms_config_deinit(muse_server->conf);
1100         muse_server->conf = NULL;
1101
1102         ms_connection_deinit(muse_server->connection);
1103         muse_server->connection = NULL;
1104
1105         muse_core_destroy_fd_table();
1106
1107         ms_deinit_bufmgr();
1108
1109         g_mutex_clear(&muse_server->state_lock);
1110
1111         g_free(muse_server);
1112         muse_server = NULL;
1113
1114         LOGD("Leave");
1115         return retval;
1116 }
1117
1118 void ms_check_cpu_memory(void)
1119 {
1120         int used_pss, memory_threshold, cpu_usage, cpu_threshold;
1121         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
1122         ms_connection_t *connection = NULL;
1123         ms_system_t *system = NULL;
1124
1125         muse_return_if_fail(muse_server);
1126
1127         connection = muse_server->connection;
1128         muse_return_if_fail(connection);
1129
1130         system = muse_server->system;
1131         muse_return_if_fail(system);
1132
1133         ms_connection_lock(connection);
1134
1135         if (g_queue_is_empty(connection->instance_q) && ms_is_server_ready()) {
1136                 used_pss = ms_system_get_memory_usage(muse_server->pid);
1137                 cpu_usage = muse_core_get_process_cpu_usage(muse_server->pid);
1138
1139                 LOGW("[%d] Proportional set size %d (KByte) (CPU %d %%)", muse_server->pid, used_pss, cpu_usage);
1140
1141                 memory_threshold = ms_config_get_memory_threshold();
1142                 cpu_threshold = ms_config_get_cpu_threshold();
1143
1144                 if (used_pss >= memory_threshold) {
1145                         ms_log_process_info(muse_server->pid);
1146
1147                         snprintf(err_msg, sizeof(err_msg), "[Memory Leak] %d >= %d (KByte)", used_pss, memory_threshold);
1148
1149                         LOGE("%s", err_msg);
1150                         ms_connection_unlock(connection);
1151                         ms_terminate(SIGTERM);
1152                 }
1153
1154                 if (cpu_usage > cpu_threshold)
1155                         ms_system_stat_attach(system);
1156
1157                 muse_core_remove_all_fd_table();
1158         } else {
1159                 LOGI("skip cpu memory check due to instance queue length : %d", g_queue_get_length(connection->instance_q));
1160         }
1161
1162         ms_connection_unlock(connection);
1163 }
1164
1165 void ms_new(void)
1166 {
1167         int fd[MUSE_CHANNEL_MAX];
1168         int i, j;
1169
1170         for (i = 0; i < MUSE_CHANNEL_MAX; i++) {
1171                 if (ms_config_is_on_demand() && i == MUSE_CHANNEL_MSG)
1172                         fd[i] = SD_LISTEN_FDS_START;
1173                 else
1174                         fd[i] = _ms_new(i);
1175
1176                 if (!muse_core_fd_is_valid(fd[i])) {
1177                         LOGE("Failed to create socket server %d", i);
1178                         for (j = 0; j < i; j++)
1179                                 close(fd[j]);
1180                         return;
1181                 }
1182         }
1183
1184         _ms_create_new_server_from_fd(fd, READ | PERSIST);
1185 }
1186
1187 void ms_run(void)
1188 {
1189         LOGW("Enter");
1190
1191         muse_return_if_fail(muse_server->main_loop);
1192
1193         muse_return_if_fail(g_idle_add_full(G_PRIORITY_HIGH, _ms_idle_cb, NULL, NULL) > 0);
1194
1195         LOGI("g_main_loop_run");
1196         g_main_loop_run(muse_server->main_loop);
1197
1198         LOGW("Leave");
1199 }
1200
1201 void ms_cmd_dispatch(muse_module_h m, muse_module_command_e cmd)
1202 {
1203         muse_module_cmd_dispatchfunc *cmd_dispatcher = NULL;
1204
1205         if (m->ch[MUSE_CHANNEL_MSG].dll_handle &&
1206                 g_module_symbol(m->ch[MUSE_CHANNEL_MSG].dll_handle, CMD_DISPATCHER, (gpointer *)&cmd_dispatcher)) {
1207                 if (cmd_dispatcher && cmd_dispatcher[cmd])
1208                         cmd_dispatcher[cmd](m);
1209         }
1210 }
1211
1212 void ms_terminate(int signo)
1213 {
1214         muse_return_if_fail(muse_server);
1215
1216         ms_set_state(MUSE_SERVER_STATE_IDLE);
1217
1218         LOGE("send signal %d to process %d", signo, muse_server->pid);
1219         raise(signo);
1220 }
1221
1222 int ms_get_pid(muse_module_h m)
1223 {
1224         muse_return_val_if_fail(m, MUSE_ERR);
1225         return m->pid;
1226 }
1227
1228 void ms_log_process_info(int pid)
1229 {
1230         muse_core_log_process_thread_info(pid);
1231
1232         muse_core_log_process_opened_fds(pid);
1233
1234         muse_core_log_process_cpu_memory(pid);
1235 }
1236
1237 void ms_log_user_group_info(void)
1238 {
1239         uid_t uid;
1240         gid_t gid;
1241         char buffer[MUSE_MSG_MAX_LENGTH];
1242         struct passwd pwbuf;
1243         struct passwd *pwbufp;
1244         struct group gbuf;
1245         struct group *gbufp;
1246
1247         uid = getuid();
1248         gid = getgid();
1249
1250         getpwuid_r(uid, &pwbuf, buffer, sizeof(buffer), &pwbufp);
1251         muse_return_if_fail(pwbufp);
1252
1253         getgrgid_r(gid, &gbuf, buffer, sizeof(buffer), &gbufp);
1254         muse_return_if_fail(gbufp);
1255
1256         LOGE("user [%s : %lu] group [%s : %lu]", pwbufp->pw_name, (unsigned long)uid, gbufp->gr_name, (unsigned long)gid);
1257 }
1258
1259 gboolean ms_is_log_enabled(void)
1260 {
1261         return ms_config_is_log_enabled();
1262 }
1263
1264 gboolean ms_init_bufmgr(void)
1265 {
1266         LOGD("Enter");
1267
1268         muse_return_val_if_fail(muse_server, FALSE);
1269
1270         muse_server->bufmgr = tbm_bufmgr_init(-1);
1271         if (!muse_server->bufmgr) {
1272                 LOGE("Error - tbm_bufmgr_init");
1273                 ms_log_user_group_info();
1274                 return FALSE;
1275         }
1276
1277         LOGD("Leave bufmgr: %p", muse_server->bufmgr);
1278
1279         return TRUE;
1280 }
1281
1282 void ms_deinit_bufmgr(void)
1283 {
1284         LOGD("Enter");
1285
1286         muse_return_if_fail(muse_server);
1287         muse_return_if_fail(muse_server->bufmgr);
1288
1289         tbm_bufmgr_deinit(muse_server->bufmgr);
1290
1291         LOGD("Leave");
1292 }
1293
1294 void ms_cmd_dispatch_foreach_func(gpointer data, gpointer user_data)
1295 {
1296         muse_module_h m = (muse_module_h)data;
1297         ms_cmd_dispatcher_info_t *dispatch = (ms_cmd_dispatcher_info_t *)user_data;
1298         muse_module_command_e cmd;
1299         muse_external_storage_info_t *storage;
1300
1301         muse_return_if_fail(muse_server);
1302         muse_return_if_fail(m);
1303         muse_return_if_fail(dispatch);
1304
1305         cmd = dispatch->cmd;
1306
1307         if (cmd == MUSE_MODULE_COMMAND_EXTERNAL_STORAGE_STATE_CHANGED) {
1308                 storage = &dispatch->storage;
1309                 LOGD("external storage id %d state %d path %s", storage->id, storage->state, storage->path);
1310                 muse_server_set_user_data(m, (void *)storage);
1311         }
1312
1313         ms_cmd_dispatch(m, cmd);
1314         SECURE_LOGI("[%s] module %p (%s)", module_cmd[cmd], m, muse_server->conf->host[m->idx]);
1315
1316         if (cmd == MUSE_MODULE_COMMAND_EXTERNAL_STORAGE_STATE_CHANGED)
1317                 muse_server_set_user_data(m, NULL);
1318 }
1319
1320 void ms_set_state(ms_state_e state)
1321 {
1322         muse_return_if_fail(muse_server);
1323
1324         g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&muse_server->state_lock);
1325
1326         muse_server->state = state;
1327 }
1328
1329 gboolean ms_is_server_ready(void)
1330 {
1331         muse_return_val_if_fail(muse_server, FALSE);
1332
1333         return muse_server->state == MUSE_SERVER_STATE_READY;
1334 }
1335
1336 gboolean ms_create_ready_file(void)
1337 {
1338         LOGD("Enter");
1339 #ifndef MUSE_USE_LWIPC
1340         int ready_fd;
1341 #endif
1342
1343 #ifdef MUSE_USE_LWIPC
1344         _ms_wait_event();
1345
1346         ms_set_state(MUSE_SERVER_STATE_READY);
1347
1348         if (LwipcEventDone(MUSE_SERVER_READY) < 0) {
1349                 LOGE("Fail to send server ready done event");
1350                 return FALSE;
1351         }
1352 #else
1353         ready_fd = creat(MUSE_SERVER_READY, 0644);
1354         if (muse_core_fd_is_valid(ready_fd)) {
1355                 LOGD("MUSE_SERVER_READY(%s) file was created", MUSE_SERVER_READY);
1356
1357                 close(ready_fd);
1358                 ms_set_state(MUSE_SERVER_STATE_READY);
1359         } else {
1360                 LOGE("[%d] Fail to create MUSE_SERVER_READY(%s)", ready_fd, MUSE_SERVER_READY);
1361                 return FALSE;
1362         }
1363 #endif
1364         LOGD("Leave");
1365
1366         return TRUE;
1367
1368 }
1369
1370 void ms_remove_ready_file(void)
1371 {
1372 #ifdef MUSE_USE_LWIPC
1373         LwipcResetEvent(MUSE_SERVER_READY);
1374 #else
1375         unlink(MUSE_SERVER_READY);
1376         unlink(MUSE_DEFAULT_PIDFILE);
1377 #endif
1378 }
1379
1380 const char *ms_get_command_string(int cmd)
1381 {
1382         if (cmd == API_CREATE)
1383                 return "connect";
1384         else if (cmd == API_DESTROY)
1385                 return "disconnect";
1386         else
1387                 LOGE("Invalid value of cmd (%d)", cmd);
1388
1389         return "Invalid value of cmd";
1390 }
1391
1392 gboolean ms_module_idx_is_valid(muse_module_h m)
1393 {
1394         return (m->idx >= 0 && m->idx < ms_config_get_host_cnt());
1395 }