Create the diag thread after daemonizing 01/210201/18 accepted/tizen/unified/20190828.011014 submit/tizen/20190827.081232
authorYoungHun Kim <yh8004.kim@samsung.com>
Wed, 17 Jul 2019 01:14:47 +0000 (10:14 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Tue, 27 Aug 2019 06:02:01 +0000 (15:02 +0900)
 - remove pid file before entering idle at on-demand
 - update gst parameter log
 - update ms_init and ms_run part
 - move ms prefix function of server.c to server_private.c
 - set server ready after daemonizing

Change-Id: I90c4358ee8f9373f896070d2709df237e7ab03e5

packaging/mused.spec
server/include/muse_server_private.h
server/src/muse_server.c
server/src/muse_server_config.c
server/src/muse_server_ipc.c
server/src/muse_server_private.c
server/src/muse_server_signal.c

index 21d1de8506ec85d6292dc53bc888cc36fcf2dd66..f0a8f67dfc17234a841f72cf739a0f24b50c4e95 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mused
 Summary:    A multimedia daemon
-Version:    0.3.85
+Version:    0.3.86
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause
index 8afed6c67c921e93f6d442a83159b153bb13e0b9..1e4c2fa3936b0b6d67f490edabdf2dc4f7c834ed 100644 (file)
@@ -92,15 +92,21 @@ typedef struct ms_cmd_dispatch_info {
        muse_external_storage_info_t storage;
 } ms_cmd_dispatcher_info_t;
 
-void ms_init(void);
+void ms_setup_syslog(void);
+void ms_fork(int *notify_fd);
+pid_t ms_daemonize(int *notify_fd);
+void ms_daemonize_complete(int notify_fd);
+void ms_gst_init(char **cmd);
+int ms_pidfile_create(const char *path, pid_t pid);
+void ms_init(char **argv);
 muse_server_h ms_get_instance(void);
 gboolean ms_check_module_idx(int idx);
 ms_module_t *ms_get_module_instance(int idx);
 int ms_deinit(void);
 void ms_check_memory(int pid);
 void ms_new(void);
-void ms_gst_init(char **cmd);
-int ms_run(char **cmd, int notify_fd);
+int ms_open_lockfile(void);
+void ms_run(void);
 void ms_cmd_dispatch(muse_module_h m, muse_module_command_e cmd);
 void ms_respawn(int signo);
 int ms_get_pid(muse_module_h m);
@@ -113,6 +119,10 @@ void ms_deinit_bufmgr(void);
 void ms_cmd_dispatch_foreach_func(gpointer data, gpointer user_data);
 void ms_set_state(ms_state_e state);
 gboolean ms_is_server_ready(void);
+void ms_diag_thread_create(void);
+void ms_diag_thread_destroy(void);
+gboolean ms_create_ready_file(void);
+void ms_remove_ready_file(void);
 
 #ifdef __cplusplus
 }
index d795731977b933e631ae64af154fc632b9fe69c4..b6f2b080bd59430e9b84d62c57ee81d5c14d4a8c 100644 (file)
  */
 
 #include "muse_server_private.h"
-#include <gst/gst.h>
-#include <syslog.h>
-
-static void _ms_setup_syslog(void);
-static void _ms_fork(int *notify_fd);
-static pid_t _ms_daemonize(int *notify_fd);
-static int _ms_pidfile_create(const char *path, pid_t pid);
-
-static void _ms_setup_syslog(void)
-{
-       int flags = LOG_CONS|LOG_NDELAY|LOG_PID;
-       if (isatty(STDOUT_FILENO))
-               flags |= LOG_PERROR;
-
-       openlog("mused", flags, LOG_DAEMON);
-       LOGD("openlog - mused");
-}
-
-static void _ms_fork(int *notify_fd)
-{
-       pid_t pid;
-       int fds[2];
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
-       char msg[MUSE_MSG_LEN_MAX] = {'\0',};
-
-       if (pipe(fds) == MUSE_ERR) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("Failed to create pipe to get child status: %s", err_msg);
-               exit(EXIT_FAILURE);
-       }
-
-       if ((pid = fork()) < 0) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("Error: fork() failed: %s", err_msg);
-               exit(EXIT_FAILURE);
-       } else if (pid != 0) {
-               close(fds[1]);
-               /* Read in a string from the pipe */
-               if (read(fds[0], msg, sizeof(msg)) <= 0) {
-                       LOGE("Failed to read from a file descriptor [%d]", fds[0]);
-                       close(fds[0]);
-                       return;
-               }
-               close(fds[0]);
-
-               /* Parent process closes up output side of pipe */
-               if (!strcmp(msg, MSG_DONE)) {
-                       LOGI("Successfully daemonized");
-                       exit(EXIT_SUCCESS);
-               } else {
-                       LOGE("Daemonizing failed after fork");
-                       exit(EXIT_FAILURE);
-               }
-       } else if (pid == 0) {
-               /* Child process closes up input side of pipe */
-               close(fds[0]);
-               *notify_fd = fds[1];
-       }
-}
-
-static pid_t _ms_daemonize(int *notify_fd)
-{
-       pid_t pid;
-       int fd, result;
-
-       muse_return_val_if_fail(notify_fd, MUSE_ERR);
-
-       _ms_fork(notify_fd);
-
-       if ((pid = setsid()) < 0) {
-               LOGE("create new session");
-               exit(EXIT_FAILURE);
-       }
-
-       /* change the file mode mask */
-       umask(0);
-
-       result = chdir("/");
-       LOGD("result = %d sid: %d pgid: %d pid: %d ppid: %d", result, (int)getsid(0), (int)getpgid(0), (int)pid, (int)getppid());
-
-       /* redirect fds to /dev/null */
-       fd = open("/dev/null", O_RDWR);
-       if (!muse_core_fd_is_valid(fd)) {
-               LOGE("Critical Error : %d is invalid", fd);
-               exit(EXIT_SUCCESS);
-       }
-
-       close(STDIN_FILENO);
-       close(STDOUT_FILENO);
-       close(STDERR_FILENO);
-
-       dup2(fd, STDIN_FILENO);
-       dup2(fd, STDOUT_FILENO);
-       dup2(fd, STDERR_FILENO);
-
-       close(fd);
-
-       return pid;
-}
-
-void ms_gst_init(char **cmd)
-{
-       gint *argc = NULL;
-       gchar **argv = NULL;
-       GError *err = NULL;
-       gboolean ret = FALSE;
-       int gst_param_cnt;
-
-#ifdef MUSE_TTRACE_LOG
-       trace_begin("MUSE:gst_init");
-#endif
-
-       gst_param_cnt = ms_config_get_gst_param_cnt();
-
-       argc = malloc(sizeof(gint));
-       muse_return_if_fail(argc);
-
-       /* add gst_param */
-       argv = malloc(sizeof(gchar *) * (gst_param_cnt + 1));
-       if (!argv) {
-               LOGE("argv memory leak allocatoin failed");
-               free(argc);
-               return;
-       }
-
-       memset(argv, 0, sizeof(gchar *) * (gst_param_cnt + 1));
-
-       *argc = 0;
-       argv[*argc] = (gchar *)cmd[0];
-       (*argc)++;
-       for (; (*argc) <= gst_param_cnt; (*argc)++)
-               argv[*argc] = ms_config_get_gst_param_str((*argc) - 1);
-
-       /* initializing gstreamer */
-       ret = gst_init_check(argc, &argv, &err);
-       if (!ret) {
-               LOGE("Could not initialize GStreamer: %s ", err ? err->message : "unknown error occurred");
-               if (err)
-                       g_error_free(err);
-       }
-
-       /* release */
-       free(argv);
-       free(argc);
-
-       LOGI("complete to initialize gstreamer");
-
-#ifdef MUSE_TTRACE_LOG
-       trace_end();
-#endif
-}
-
-static int _ms_pidfile_create(const char *path, pid_t pid)
-{
-       int fd;
-       struct flock lock;
-       char pid_buf[MUSE_MSG_LEN] = {'\0',};
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
-
-       muse_return_val_if_fail(path, MM_ERROR_INVALID_ARGUMENT);
-       muse_core_remove_symlink(path);
-       fd = open(path, O_WRONLY | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
-
-       if (!muse_core_fd_is_valid(fd)) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("Fail to open pidfile [%s] : %s", path, err_msg);
-               return MM_ERROR_FILE_NOT_FOUND;
-       }
-
-       lock.l_type = F_WRLCK;
-       lock.l_start = 0;
-       lock.l_whence = SEEK_SET;
-       lock.l_len = 0;
-
-       if (fcntl(fd, F_SETLK, &lock) < 0) {
-               if (errno != EACCES && errno != EAGAIN) {
-                       strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-                       LOGE("Fail to lock pidfile [%s] : %s", path, err_msg);
-               } else {
-                       LOGE("process is already running");
-               }
-               close(fd);
-               return MM_ERROR_FILE_INTERNAL;
-       }
-
-       if (ftruncate(fd, 0) < 0) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("Fail to truncate pidfile [%s] : %s", path, err_msg);
-               close(fd);
-               return MM_ERROR_FILE_INTERNAL;
-       }
-
-       memset(pid_buf, 0, sizeof(pid_buf));
-       snprintf(pid_buf, sizeof(pid_buf), "%u", pid);
-
-       if (write(fd, pid_buf, strlen(pid_buf)) != (int)strlen(pid_buf)) {
-               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
-               LOGE("Fail to write pid to pidfile [%s] : %s", path, err_msg);
-               close(fd);
-               return MM_ERROR_FILE_WRITE;
-       }
-
-       close(fd);
-       return MM_ERROR_NONE;
-}
 
 void muse_server_set_dispatch_timeout(muse_module_h m, int api, int timeout)
 {
@@ -493,48 +288,17 @@ bool muse_server_is_on_demand(void)
 
 int main(int argc, char **argv)
 {
-       pid_t pid;
-       int idx;
-       int notify_fd = -1;
-       muse_module_cmd_dispatchfunc *cmd_dispatcher = NULL;
 
 #ifdef MUSE_TTRACE_LOG
        trace_begin("MUSE:START");
 #endif
 
-       _ms_setup_syslog();
-
-       pid = _ms_daemonize(&notify_fd);
-
-       if (_ms_pidfile_create(MUSE_DEFAULT_PIDFILE, pid) != MM_ERROR_NONE)
-               exit(EXIT_FAILURE);
-       else
-               LOGD("MUSE_DEFAULT_PIDFILE(%s) file was created", MUSE_DEFAULT_PIDFILE);
-
-       ms_init();
-
        if (argc > 1)
                ms_parse_params(argc, argv);
 
-#ifdef MUSE_TTRACE_LOG
-       trace_begin("MUSE:preloading module");
-#endif
-       for (idx = 0; idx < ms_config_get_host_cnt(); idx++) {
-               if (0 == strncmp(ms_config_get_preloaded_value(idx), "yes", strlen("yes") + 1)) {
-                       g_module_symbol(ms_module_open(idx), CMD_DISPATCHER, (gpointer *)&cmd_dispatcher);
-                       if (cmd_dispatcher && cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE])
-                               cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE](NULL);
-               }
-       }
-#ifdef MUSE_TTRACE_LOG
-       trace_end();
-#endif
+       ms_init(argv);
 
-       muse_return_val_if_fail(ms_get_instance(), 0);
-       ms_get_instance()->pid = pid;
+       ms_run();
 
-#ifdef MUSE_TTRACE_LOG
-       trace_end();
-#endif
-       return ms_run(argv, notify_fd);
+       return ms_deinit();
 }
index a935eb9f97c107e9f9d60f4eed49db0d2b69d6b4..706cf1e482f0d2cdba00642327e92042670a2555 100644 (file)
@@ -109,8 +109,8 @@ static int _ms_config_parser(ms_config_t *conf)
 
                conf->gst_param_str[conf->gst_param_cnt] = _ms_config_get_str(conf->muse_dict, gst_param_key, NULL);
 
-               if (!conf->gst_param_str[conf->gst_param_cnt]) {
-                       LOGD("updated gst_param #: %d", conf->gst_param_cnt);
+               if (!conf->gst_param_str[conf->gst_param_cnt] || strlen(conf->gst_param_str[conf->gst_param_cnt]) == 0) {
+                       LOGD("completed to update gst_param #: %d", conf->gst_param_cnt);
                        break;
                }
                LOGD("gstparam%d: %s", conf->gst_param_cnt + 1, conf->gst_param_str[conf->gst_param_cnt]);
index f2be07b20878cd0de81d738ac6ce0a5d6e8d2f83..95acba81c97e06783b7ad80448f17639f8587db3 100644 (file)
@@ -37,7 +37,7 @@ static gboolean _ms_ipc_module_instance_creation_is_allowed(int module_idx);
 static gboolean _ms_ipc_get_module_idx(muse_module_h m, void *jobj);
 static gboolean _ms_ipc_dispatch_create(muse_module_h m, void *jobj);
 static gboolean _ms_ipc_dispatch_destroy(muse_module_h m);
-static void _ms_ipc_dispatch_no_instance(muse_module_h m, void *jobj);
+static gboolean _ms_ipc_dispatch_no_instance(muse_module_h m, void *jobj);
 static gpointer _ms_ipc_dispatch_worker(gpointer data);
 static gboolean _ms_ipc_data_processing(int fd, muse_recv_data_head_t *header, muse_channel_info_t *ch);
 static gpointer _ms_ipc_data_worker(gpointer data);
@@ -134,7 +134,6 @@ static gboolean _ms_ipc_get_module_idx(muse_module_h m, void *jobj)
 
        if (!muse_core_msg_object_get_value(MSG_KEY_MODULE_INDEX, jobj, MUSE_TYPE_INT, &m->idx)) {
                LOGE("Failed to get the value of module index");
-               ms_cmd_dispatch(m, MUSE_MODULE_COMMAND_DEBUG_INFO_DUMP);
                return FALSE;
        }
 
@@ -150,8 +149,10 @@ static gboolean _ms_ipc_dispatch_create(muse_module_h m, void *jobj)
 
        ms_module_dispatch_lock(m);
 
-       if (!_ms_ipc_get_module_idx(m, jobj))
+       if (!_ms_ipc_get_module_idx(m, jobj)) {
+               ms_cmd_dispatch(m, MUSE_MODULE_COMMAND_DEBUG_INFO_DUMP);
                goto out;
+       }
 
        m->ch[MUSE_CHANNEL_MSG].dll_handle = ms_module_open(m->idx);
 
@@ -207,15 +208,17 @@ static gboolean _ms_ipc_dispatch_destroy(muse_module_h m)
        return FALSE;
 }
 
-static void _ms_ipc_dispatch_no_instance(muse_module_h m, void *jobj)
+static gboolean _ms_ipc_dispatch_no_instance(muse_module_h m, void *jobj)
 {
-       muse_return_if_fail(m);
-       muse_return_if_fail(jobj);
+       muse_return_val_if_fail(m, FALSE);
+       muse_return_val_if_fail(jobj, FALSE);
 
        ms_module_dispatch_lock(m);
 
-       if (!_ms_ipc_get_module_idx(m, jobj))
+       if (!_ms_ipc_get_module_idx(m, jobj)) {
+               ms_cmd_dispatch(m, MUSE_MODULE_COMMAND_DEBUG_INFO_DUMP);
                goto out;
+       }
 
        m->ch[MUSE_CHANNEL_MSG].dll_handle = ms_module_open(m->idx);
 
@@ -232,11 +235,13 @@ static void _ms_ipc_dispatch_no_instance(muse_module_h m, void *jobj)
 
 out:
        ms_module_dispatch_unlock(m);
+
+       return FALSE;
 }
 
 static gpointer _ms_ipc_dispatch_worker(gpointer data)
 {
-       int len, api, fd, i;
+       int len, fd, i;
        int parse_len = 0;
        muse_module_h m = NULL;
        gboolean attempt_to_dispatch = TRUE;
@@ -276,9 +281,8 @@ static gpointer _ms_ipc_dispatch_worker(gpointer data)
                                break;
                        }
 
-                       if (muse_core_msg_object_get_value(MSG_KEY_API, jobj, MUSE_TYPE_INT, &api)) {
-                               m->api = api;
-                               switch (api) {
+                       if (muse_core_msg_object_get_value(MSG_KEY_API, jobj, MUSE_TYPE_INT, &m->api)) {
+                               switch (m->api) {
                                case API_CREATE:
                                        SECURE_LOGI("CREATE %p %d", m, fd);
                                        attempt_to_dispatch = _ms_ipc_dispatch_create(m, jobj);
@@ -291,7 +295,7 @@ static gpointer _ms_ipc_dispatch_worker(gpointer data)
                                        if (m->is_created) /* handle based */
                                                ms_module_dispatch(m);
                                        else
-                                               _ms_ipc_dispatch_no_instance(m, jobj);
+                                               attempt_to_dispatch = _ms_ipc_dispatch_no_instance(m, jobj);
                                        break;
                                }
                        }
index aaa2fea51b535455d750b4b372aa326c1b38df77..be058051decc04a89f8e8e4c4cef625b77a79ffb 100644 (file)
@@ -22,6 +22,8 @@
 #include "muse_server_private.h"
 #include <sys/file.h>
 #include <sys/syscall.h>
+#include <gst/gst.h>
+#include <syslog.h>
 
 #ifdef MUSE_REGISTER_VIP
 #include <proc_stat.h>
@@ -58,7 +60,6 @@ static const char *module_cmd[MUSE_MODULE_COMMAND_MAX] = {
        "resource_manager_shutdown"
 };
 
-static int _ms_run(void);
 static bool _ms_attach(int fd, muse_module_callback connection_handler, gpointer module_idx);
 static void _ms_create_new_server_from_fd(int fd[], int type);
 static int _ms_new(muse_channel_e channel);
@@ -70,51 +71,18 @@ gpointer _ms_diag_thread(gpointer data);
 static void _ms_lock_state(void);
 static void _ms_unlock_state(void);
 static gboolean _ms_connection_handler(GIOChannel *source, GIOCondition condition, gpointer data);
+#ifdef MUSE_USE_LWIPC
+static void _ms_wait_event(void);
 
-static int _ms_run(void)
+static void _ms_wait_event(void)
 {
-       int fd, already_running;
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
-       char *lockfile = NULL;
-
-       muse_return_val_if_fail(muse_server, MUSE_ERR);
-
-       lockfile = ms_config_get_lockfile();
-       muse_return_val_if_fail(lockfile, MUSE_ERR);
-
-       muse_core_remove_symlink((const char *)lockfile);
-       fd = open(lockfile, O_RDONLY);
-       if (fd == -1 && errno != ENOENT) {
-               /* Cannot open file even though file exists. */
-               snprintf(err_msg, sizeof(err_msg), "datserver: Cannot open lock file %s", lockfile);
-               LOGE("open failed : %s", err_msg);
-               return MUSE_ERR;
-       } else if (fd != -1) {
-               already_running = flock(fd, LOCK_EX | LOCK_NB) == -1;
-               close(fd);
-               if (already_running) {
-                       LOGE("File already locked. There's already a server running");
-                       return MUSE_ERR;
-               }
-       }
-
-       /* Lock file does not exist, or is not locked. Create a new lockfile and lock it. */
-       fd = open(lockfile, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-       if (fd == -1) {
-               LOGE("dataserver: Cannot create lock file");
-               return MUSE_ERR;
-       }
-
-       if (flock(fd, LOCK_EX | LOCK_NB) != 0) {
-               LOGE("Can't lock the lock file \"%s\". " "Is another instance running?", lockfile);
-               close(fd);
-               return MUSE_ERR;
-       }
-
-       close(fd);
+       const char *lw_event_list[] = { "/run/.wm_ready", "/tmp/avoc_ready" };
+       unsigned int count = sizeof(lw_event_list) / sizeof(char *);
 
-       return MM_ERROR_NONE;
+       if (LwipcWaitMultiEvents(lw_event_list, count, true, MUSE_LWIPC_WAIT_TIME, NULL, 0) != 0)
+               LOGE("Fail to receive Multiple Events");
 }
+#endif
 
 static bool _ms_attach(int fd, muse_module_callback connection_handler, gpointer module_idx)
 {
@@ -124,7 +92,6 @@ static bool _ms_attach(int fd, muse_module_callback connection_handler, gpointer
        LOGI("Enter");
 
        muse_return_val_if_fail(muse_server, false);
-       muse_return_val_if_fail(muse_server->main_loop, false);
        muse_return_val_if_fail(muse_core_fd_is_valid(fd), false);
 
        channel = g_io_channel_unix_new(fd);
@@ -448,23 +415,13 @@ out:
        return FALSE;
 }
 
-#ifdef MUSE_USE_LWIPC
-static void _ms_wait_event(void)
-{
-       const char *lw_event_list[] = { "/run/.wm_ready", "/tmp/avoc_ready" };
-       unsigned int count = sizeof(lw_event_list) / sizeof(char *);
-
-       if (LwipcWaitMultiEvents(lw_event_list, count, true, MUSE_LWIPC_WAIT_TIME, NULL, 0) != 0)
-               LOGE("Fail to receive Multiple Events");
-}
-#endif
-
 static void _ms_check_idle_state(void)
 {
        struct timeval tv_c, tv_r;
        int instance_number, timeout;
 
        muse_return_if_fail(muse_server);
+       muse_return_if_fail(muse_server->state == MUSE_SERVER_STATE_READY);
 
        gettimeofday(&tv_c, NULL);
        timersub(&tv_c, &muse_server->tv_s, &tv_r);
@@ -472,8 +429,11 @@ static void _ms_check_idle_state(void)
        instance_number = g_queue_get_length(muse_server->connection->instance_queue);
        timeout = (int)tv_r.tv_sec;
 
+       LOGD("timeout %d", timeout);
+
        if (instance_number == 0 && timeout >= ms_config_get_max_idle_time()) {
                LOGE("Timeout exit !!! [Idle time] %d sec", timeout);
+               ms_remove_ready_file();
                exit(EXIT_SUCCESS);
        }
 }
@@ -500,7 +460,7 @@ gpointer _ms_diag_thread(gpointer data)
        muse_return_val_if_fail(muse_server, NULL);
 
        while (1) {
-               if (muse_server->conf->is_on_demand == TRUE)
+               if (muse_server->conf->is_on_demand)
                        _ms_check_idle_state();
 
                _ms_check_connection_event();
@@ -521,7 +481,7 @@ static void _ms_unlock_state(void)
        g_mutex_unlock(&muse_server->state_lock);
 }
 
-void ms_init(void)
+static void _ms_init(void)
 {
        int idx;
 
@@ -574,6 +534,362 @@ void ms_init(void)
 
        muse_core_create_fd_table();
 
+       muse_server->main_loop = g_main_loop_new(NULL, FALSE);
+       muse_return_if_fail(muse_server->main_loop);
+
+       LOGD("Leave");
+}
+
+int ms_open_lockfile(void)
+{
+       int fd, already_running;
+       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
+       char *lockfile = NULL;
+
+       muse_return_val_if_fail(muse_server, MUSE_ERR);
+
+       lockfile = ms_config_get_lockfile();
+       muse_return_val_if_fail(lockfile, MUSE_ERR);
+
+       muse_core_remove_symlink((const char *)lockfile);
+       fd = open(lockfile, O_RDONLY);
+       if (fd == -1 && errno != ENOENT) {
+               /* Cannot open file even though file exists. */
+               snprintf(err_msg, sizeof(err_msg), "datserver: Cannot open lock file %s", lockfile);
+               LOGE("open failed : %s", err_msg);
+               return MUSE_ERR;
+       } else if (fd != -1) {
+               already_running = flock(fd, LOCK_EX | LOCK_NB) == -1;
+               close(fd);
+               if (already_running) {
+                       LOGE("File already locked. There's already a server running");
+                       return MUSE_ERR;
+               }
+       }
+
+       /* Lock file does not exist, or is not locked. Create a new lockfile and lock it. */
+       fd = open(lockfile, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+       if (fd == -1) {
+               LOGE("dataserver: Cannot create lock file");
+               return MUSE_ERR;
+       }
+
+       if (flock(fd, LOCK_EX | LOCK_NB) != 0) {
+               LOGE("Can't lock the lock file \"%s\". " "Is another instance running?", lockfile);
+               close(fd);
+               return MUSE_ERR;
+       }
+
+       close(fd);
+
+       return MM_ERROR_NONE;
+}
+
+void ms_diag_thread_create(void)
+{
+       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
+       GError *error = NULL;
+
+       muse_return_if_fail(muse_server);
+
+       muse_server->diag_thread = g_thread_try_new("muse_server_diag_thread", _ms_diag_thread, muse_server->main_loop, &error);
+       if (!muse_server->diag_thread && error) {
+               snprintf(err_msg, sizeof(err_msg), "diag_thread creation failed : %s", error->message);
+               LOGE("%s", err_msg);
+               g_error_free(error);
+               ms_log_process_info(muse_server->pid);
+       }
+}
+
+void ms_diag_thread_destroy(void)
+{
+       muse_return_if_fail(muse_server);
+       muse_return_if_fail(muse_server->diag_thread);
+
+       LOGD("Enter");
+
+       g_thread_join(muse_server->diag_thread);
+       muse_server->diag_thread = NULL;
+
+       LOGD("Leave");
+}
+
+void ms_setup_syslog(void)
+{
+       int flags = LOG_CONS|LOG_NDELAY|LOG_PID;
+       if (isatty(STDOUT_FILENO))
+               flags |= LOG_PERROR;
+
+       openlog("mused", flags, LOG_DAEMON);
+       LOGD("openlog - mused");
+}
+
+void ms_fork(int *notify_fd)
+{
+       pid_t pid;
+       int fds[2];
+       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
+       char msg[MUSE_MSG_LEN_MAX] = {'\0',};
+
+       if (pipe(fds) == MUSE_ERR) {
+               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+               LOGE("Failed to create pipe to get child status: %s", err_msg);
+               exit(EXIT_FAILURE);
+       }
+
+       if ((pid = fork()) < 0) {
+               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+               LOGE("Error: fork() failed: %s", err_msg);
+               exit(EXIT_FAILURE);
+       } else if (pid != 0) {
+               close(fds[1]);
+               /* Read in a string from the pipe */
+               if (read(fds[0], msg, sizeof(msg)) <= 0) {
+                       LOGE("Failed to read from a file descriptor [%d]", fds[0]);
+                       close(fds[0]);
+                       return;
+               }
+               close(fds[0]);
+
+               /* Parent process closes up output side of pipe */
+               if (!strcmp(msg, MSG_DONE)) {
+                       LOGI("Successfully daemonized");
+                       exit(EXIT_SUCCESS);
+               } else {
+                       LOGE("Daemonizing failed after fork");
+                       exit(EXIT_FAILURE);
+               }
+       } else if (pid == 0) {
+               /* Child process closes up input side of pipe */
+               close(fds[0]);
+               *notify_fd = fds[1];
+       }
+}
+
+pid_t ms_daemonize(int *notify_fd)
+{
+       pid_t pid;
+       int fd, result;
+
+       muse_return_val_if_fail(notify_fd, MUSE_ERR);
+
+       ms_fork(notify_fd);
+
+       if ((pid = setsid()) < 0) {
+               LOGE("create new session");
+               exit(EXIT_FAILURE);
+       }
+
+       /* change the file mode mask */
+       umask(0);
+
+       result = chdir("/");
+       LOGD("result = %d sid: %d pgid: %d pid: %d ppid: %d", result, (int)getsid(0), (int)getpgid(0), (int)pid, (int)getppid());
+
+       /* redirect fds to /dev/null */
+       fd = open("/dev/null", O_RDWR);
+       if (!muse_core_fd_is_valid(fd)) {
+               LOGE("Critical Error : %d is invalid", fd);
+               exit(EXIT_SUCCESS);
+       }
+
+       close(STDIN_FILENO);
+       close(STDOUT_FILENO);
+       close(STDERR_FILENO);
+
+       dup2(fd, STDIN_FILENO);
+       dup2(fd, STDOUT_FILENO);
+       dup2(fd, STDERR_FILENO);
+
+       close(fd);
+
+       return pid;
+}
+
+void ms_daemonize_complete(int notify_fd)
+{
+       LOGW("Enter");
+
+       muse_return_if_fail(muse_core_fd_is_valid(notify_fd));
+
+#ifdef MUSE_REGISTER_VIP
+       proc_stat_set_vip_process();
+#endif
+
+       write(notify_fd, MSG_DONE, strlen(MSG_DONE) + 1);
+       LOGI("[%d] Notify parent process that child initialization is done", notify_fd);
+       close(notify_fd);
+
+       LOGW("Leave");
+}
+
+void ms_gst_init(char **cmd)
+{
+       gint *argc = NULL;
+       gchar **argv = NULL;
+       GError *err = NULL;
+       gboolean ret = FALSE;
+       int gst_param_cnt;
+
+#ifdef MUSE_TTRACE_LOG
+       trace_begin("MUSE:gst_init");
+#endif
+
+       gst_param_cnt = ms_config_get_gst_param_cnt();
+
+       argc = malloc(sizeof(gint));
+       muse_return_if_fail(argc);
+
+       /* add gst_param */
+       argv = malloc(sizeof(gchar *) * (gst_param_cnt + 1));
+       if (!argv) {
+               LOGE("argv memory leak allocatoin failed");
+               free(argc);
+               return;
+       }
+
+       memset(argv, 0, sizeof(gchar *) * (gst_param_cnt + 1));
+
+       *argc = 0;
+       argv[*argc] = (gchar *)cmd[0];
+       (*argc)++;
+       for (; (*argc) <= gst_param_cnt; (*argc)++)
+               argv[*argc] = ms_config_get_gst_param_str((*argc) - 1);
+
+       /* initializing gstreamer */
+       ret = gst_init_check(argc, &argv, &err);
+       if (!ret) {
+               LOGE("Could not initialize GStreamer: %s ", err ? err->message : "unknown error occurred");
+               if (err)
+                       g_error_free(err);
+       }
+
+       /* release */
+       free(argv);
+       free(argc);
+
+       LOGI("complete to initialize gstreamer");
+
+#ifdef MUSE_TTRACE_LOG
+       trace_end();
+#endif
+}
+
+int ms_pidfile_create(const char *path, pid_t pid)
+{
+       int fd;
+       struct flock lock;
+       char pid_buf[MUSE_MSG_LEN] = {'\0',};
+       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
+
+       muse_return_val_if_fail(path, MM_ERROR_INVALID_ARGUMENT);
+       muse_core_remove_symlink(path);
+       fd = open(path, O_WRONLY | O_CREAT, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
+
+       if (!muse_core_fd_is_valid(fd)) {
+               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+               LOGE("Fail to open pidfile [%s] : %s", path, err_msg);
+               return MM_ERROR_FILE_NOT_FOUND;
+       }
+
+       lock.l_type = F_WRLCK;
+       lock.l_start = 0;
+       lock.l_whence = SEEK_SET;
+       lock.l_len = 0;
+
+       if (fcntl(fd, F_SETLK, &lock) < 0) {
+               if (errno != EACCES && errno != EAGAIN) {
+                       strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+                       LOGE("Fail to lock pidfile [%s] : %s", path, err_msg);
+               } else {
+                       LOGE("process is already running");
+               }
+               close(fd);
+               return MM_ERROR_FILE_INTERNAL;
+       }
+
+       if (ftruncate(fd, 0) < 0) {
+               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+               LOGE("Fail to truncate pidfile [%s] : %s", path, err_msg);
+               close(fd);
+               return MM_ERROR_FILE_INTERNAL;
+       }
+
+       memset(pid_buf, 0, sizeof(pid_buf));
+       snprintf(pid_buf, sizeof(pid_buf), "%u", pid);
+
+       if (write(fd, pid_buf, strlen(pid_buf)) != (int)strlen(pid_buf)) {
+               strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
+               LOGE("Fail to write pid to pidfile [%s] : %s", path, err_msg);
+               close(fd);
+               return MM_ERROR_FILE_WRITE;
+       }
+
+       close(fd);
+       return MM_ERROR_NONE;
+}
+
+void ms_init(char **argv)
+{
+       int idx;
+       pid_t pid;
+       int notify_fd;
+       muse_module_cmd_dispatchfunc *cmd_dispatcher = NULL;
+
+       LOGD("Enter");
+
+       ms_setup_syslog();
+
+       pid = ms_daemonize(&notify_fd);
+
+       if (ms_pidfile_create(MUSE_DEFAULT_PIDFILE, pid) != MM_ERROR_NONE)
+               exit(EXIT_FAILURE);
+       else
+               LOGD("MUSE_DEFAULT_PIDFILE(%s) file was created", MUSE_DEFAULT_PIDFILE);
+
+       _ms_init();
+
+       muse_return_if_fail(ms_get_instance());
+       ms_get_instance()->pid = pid;
+
+       muse_return_if_fail(ms_open_lockfile() == MM_ERROR_NONE);
+
+       ms_new();
+
+       ms_daemonize_complete(notify_fd);
+
+#ifdef MUSE_TTRACE_LOG
+       trace_end();
+#endif
+
+#ifdef MUSE_TTRACE_LOG
+       trace_begin("MUSE:preloading module");
+#endif
+       for (idx = 0; idx < ms_config_get_host_cnt(); idx++) {
+               if (0 == strncmp(ms_config_get_preloaded_value(idx), "yes", strlen("yes") + 1)) {
+                       g_module_symbol(ms_module_open(idx), CMD_DISPATCHER, (gpointer *)&cmd_dispatcher);
+                       if (cmd_dispatcher && cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE])
+                               cmd_dispatcher[MUSE_MODULE_COMMAND_INITIALIZE](NULL);
+               }
+       }
+#ifdef MUSE_TTRACE_LOG
+       trace_end();
+#endif
+
+       ms_system_subscribe_external_event(ms_get_instance()->system);
+
+       ms_diag_thread_create();
+
+#ifdef MUSE_USE_WATCHDOG
+       if (!ms_watchdog_attach(ms_get_instance()->watchdog)) {
+               LOGE("watchdog thread failed");
+               ms_log_process_info(pid);
+               return;
+       }
+#endif
+
+       ms_gst_init(argv);
+
        LOGD("Leaver");
 }
 
@@ -615,18 +931,30 @@ int ms_deinit(void)
        muse_return_val_if_fail(muse_server->security, retval);
        muse_return_val_if_fail(muse_server->watchdog, retval);
        muse_return_val_if_fail(muse_server->workqueue, retval);
+       muse_return_val_if_fail(muse_server->diag_thread, retval);
 
        ms_recursive_rmdir(MUSE_DATA_ROOT_PATH);
 
        ms_set_state(MUSE_SERVER_STATE_IDLE);
 
+       ms_diag_thread_destroy();
+
 #ifdef MUSE_USE_WATCHDOG
+       ms_watchdog_detach(muse_server->watchdog);
+
        if (ms_watchdog_deinit(muse_server->watchdog) == MM_ERROR_NONE)
                free(muse_server->watchdog);
        else
                LOGE("Fail to deinitialize server watchdog");
 #endif
 
+#ifdef MUSE_USE_LWIPC
+       if (LwipcResetEvent(MUSE_SERVER_READY) < 0)
+               LOGE("Fail to reset light weight IPC");
+#else
+       ms_remove_ready_file();
+#endif
+
        retval = muse_server->retval;
        muse_core_fd_close(muse_server->msg_fd);
        muse_core_fd_close(muse_server->data_fd);
@@ -724,7 +1052,7 @@ void ms_new(void)
        int i, j;
 
        for (i = 0; i < MUSE_CHANNEL_MAX; i++) {
-               if (ms_config_is_on_demand() == TRUE && i == MUSE_CHANNEL_MSG)
+               if (ms_config_is_on_demand() && i == MUSE_CHANNEL_MSG)
                        fd[i] = SD_LISTEN_FDS_START;
                else
                        fd[i] = _ms_new(i);
@@ -740,83 +1068,17 @@ void ms_new(void)
        _ms_create_new_server_from_fd(fd, READ | PERSIST);
 }
 
-int ms_run(char **cmd, int notify_fd)
+void ms_run(void)
 {
-       char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
-       GError *error = NULL;
-
-#ifndef MUSE_USE_LWIPC
-       int ready_fd;
-#endif
-
        LOGW("Enter");
 
-       muse_return_val_if_fail(muse_core_fd_is_valid(notify_fd), MUSE_ERR);
-       muse_return_val_if_fail(_ms_run() == MM_ERROR_NONE, MUSE_ERR);
-       muse_return_val_if_fail(muse_server, MUSE_ERR);
-
-       muse_server->main_loop = g_main_loop_new(NULL, FALSE);
-       muse_return_val_if_fail(muse_server->main_loop, MUSE_ERR);
-
-       ms_new();
-
-       muse_server->diag_thread = g_thread_try_new("muse_server_diag_thread", _ms_diag_thread, muse_server->main_loop, &error);
-       if (!muse_server->diag_thread && error) {
-               snprintf(err_msg, sizeof(err_msg), "diag_thread creation failed : %s", error->message);
-               LOGE("%s", err_msg);
-               g_error_free(error);
-               ms_log_process_info(muse_server->pid);
-       }
-
-#ifdef MUSE_USE_LWIPC
-       _ms_wait_event();
-
-       ms_set_state(MUSE_SERVER_STATE_READY);
-
-       if (LwipcEventDone(MUSE_SERVER_READY) < 0)
-               LOGE("Fail to send server ready done event");
-#else
-       ready_fd = creat(MUSE_SERVER_READY, 0644);
-       if (muse_core_fd_is_valid(ready_fd)) {
-               LOGD("MUSE_SERVER_READY(%s) file was created", MUSE_SERVER_READY);
-
-               close(ready_fd);
-               ms_set_state(MUSE_SERVER_STATE_READY);
-       } else {
-               LOGE("[%d] Fail to create MUSE_SERVER_READY(%s)", ready_fd, MUSE_SERVER_READY);
-       }
-#endif
-
-#ifdef MUSE_REGISTER_VIP
-       proc_stat_set_vip_process();
-#endif
-
-       ms_system_subscribe_external_event(muse_server->system);
-
-       write(notify_fd, MSG_DONE, strlen(MSG_DONE) + 1);
-       LOGI("[%d] Notify parent process that child initialization is done", notify_fd);
-       close(notify_fd);
-
-#ifdef MUSE_USE_WATCHDOG
-       if (!ms_watchdog_attach(muse_server->watchdog)) {
-               LOGE("watchdog thread failed");
-               ms_log_process_info(muse_server->pid);
-               return ms_deinit();
-       }
-#endif
-
-       ms_gst_init(cmd);
+       muse_return_if_fail(muse_server->main_loop);
+       muse_return_if_fail(ms_create_ready_file());
 
        LOGI("g_main_loop_run");
        g_main_loop_run(muse_server->main_loop);
 
-#ifdef MUSE_USE_WATCHDOG
-       ms_watchdog_detach(muse_server->watchdog);
-#endif
-
        LOGW("Leave");
-
-       return ms_deinit();
 }
 
 void ms_cmd_dispatch(muse_module_h m, muse_module_command_e cmd)
@@ -955,3 +1217,47 @@ gboolean ms_is_server_ready(void)
        return muse_server->state == MUSE_SERVER_STATE_READY;
 }
 
+gboolean ms_create_ready_file(void)
+{
+       LOGD("Enter");
+#ifndef MUSE_USE_LWIPC
+       int ready_fd;
+#endif
+
+#ifdef MUSE_USE_LWIPC
+       _ms_wait_event();
+
+       ms_set_state(MUSE_SERVER_STATE_READY);
+
+       if (LwipcEventDone(MUSE_SERVER_READY) < 0) {
+               LOGE("Fail to send server ready done event");
+               return FALSE;
+       }
+#else
+       ready_fd = creat(MUSE_SERVER_READY, 0644);
+       if (muse_core_fd_is_valid(ready_fd)) {
+               LOGD("MUSE_SERVER_READY(%s) file was created", MUSE_SERVER_READY);
+
+               close(ready_fd);
+               ms_set_state(MUSE_SERVER_STATE_READY);
+       } else {
+               LOGE("[%d] Fail to create MUSE_SERVER_READY(%s)", ready_fd, MUSE_SERVER_READY);
+               return FALSE;
+       }
+#endif
+       LOGD("Leave");
+
+       return TRUE;
+
+}
+
+void ms_remove_ready_file(void)
+{
+#ifdef MUSE_USE_LWIPC
+       if (LwipcResetEvent(MUSE_SERVER_READY) < 0)
+               LOGE("Fail to reset light weight IPC");
+#else
+       if (remove(MUSE_SERVER_READY) == MUSE_ERR)
+               LOGE("remove %s failed", MUSE_SERVER_READY);
+#endif
+}
index 6010935758e279a38033f001d8bffe0d712b60d2..7b72db958744eebfc760469864b7d5a1eac69d8f 100644 (file)
@@ -30,10 +30,6 @@ struct sigaction ms_bus_old_action;
 struct sigaction ms_xcpu_old_action;
 struct sigaction ms_pipe_old_action;
 
-#ifdef MUSE_USE_LWIPC
-#include <lwipc.h>
-#endif
-
 static GMutex signal_lock;
 
 static void _ms_signal_handler(int signo);
@@ -147,13 +143,7 @@ static void _ms_signal_sigaction(int signo, siginfo_t *si, void *arg)
        muse_return_if_fail(si);
        muse_return_if_fail(arg);
 
-#ifdef MUSE_USE_LWIPC
-       if (LwipcResetEvent(MUSE_SERVER_READY) < 0)
-               LOGE("Fail to reset light weight IPC");
-#else
-       if (remove(MUSE_SERVER_READY) == MUSE_ERR)
-               LOGE("remove %s failed", MUSE_SERVER_READY);
-#endif
+       ms_remove_ready_file();
 
        ms_config_remove_lockfile();