From: YoungHun Kim Date: Wed, 17 Jul 2019 01:14:47 +0000 (+0900) Subject: Create the diag thread after daemonizing X-Git-Tag: submit/tizen/20190827.081232^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F01%2F210201%2F18;p=platform%2Fcore%2Fmultimedia%2Fmmsvc-core.git Create the diag thread after daemonizing - 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 --- diff --git a/packaging/mused.spec b/packaging/mused.spec index 21d1de85..f0a8f67d 100644 --- a/packaging/mused.spec +++ b/packaging/mused.spec @@ -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 diff --git a/server/include/muse_server_private.h b/server/include/muse_server_private.h index 8afed6c6..1e4c2fa3 100644 --- a/server/include/muse_server_private.h +++ b/server/include/muse_server_private.h @@ -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 } diff --git a/server/src/muse_server.c b/server/src/muse_server.c index d7957319..b6f2b080 100644 --- a/server/src/muse_server.c +++ b/server/src/muse_server.c @@ -20,211 +20,6 @@ */ #include "muse_server_private.h" -#include -#include - -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(¬ify_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(); } diff --git a/server/src/muse_server_config.c b/server/src/muse_server_config.c index a935eb9f..706cf1e4 100644 --- a/server/src/muse_server_config.c +++ b/server/src/muse_server_config.c @@ -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]); diff --git a/server/src/muse_server_ipc.c b/server/src/muse_server_ipc.c index f2be07b2..95acba81 100644 --- a/server/src/muse_server_ipc.c +++ b/server/src/muse_server_ipc.c @@ -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; } } diff --git a/server/src/muse_server_private.c b/server/src/muse_server_private.c index aaa2fea5..be058051 100644 --- a/server/src/muse_server_private.c +++ b/server/src/muse_server_private.c @@ -22,6 +22,8 @@ #include "muse_server_private.h" #include #include +#include +#include #ifdef MUSE_REGISTER_VIP #include @@ -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(¬ify_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 +} diff --git a/server/src/muse_server_signal.c b/server/src/muse_server_signal.c index 60109357..7b72db95 100644 --- a/server/src/muse_server_signal.c +++ b/server/src/muse_server_signal.c @@ -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 -#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();