From b4e9810b61982b3a5fbd534067e4cc0e343cf97e Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Thu, 22 Feb 2018 14:01:49 +0900 Subject: [PATCH] Update message IPC mechanism [Version] 0.3.33 [Profile] Common [Issue Type] Update Change-Id: Ia0d22c3d05c3d2de2a96c969a7e625809e019d48 Signed-off-by: Jeongmo Yang --- core/include/muse_core.h | 12 +++ core/include/muse_core_internal.h | 2 + core/src/muse_core.c | 163 +++++++++++++++++++++++++++++--------- packaging/mused.spec | 2 +- server/src/muse_server_ipc.c | 39 +-------- server/src/muse_server_private.c | 2 +- 6 files changed, 144 insertions(+), 76 deletions(-) diff --git a/core/include/muse_core.h b/core/include/muse_core.h index 7757204..7cfe4c3 100644 --- a/core/include/muse_core.h +++ b/core/include/muse_core.h @@ -35,6 +35,7 @@ extern "C" { #define MUSE_SERVER_READY "/tmp/.muse_server_ready" #define MUSE_DATA_HEAD 0xda1a6ead +#define MUSE_MSG_HEAD 0xda1a6eae #define MUSE_PARAM_HANDLE "handle" #define MUSE_PARAM_RETURN "ret" #define MUSE_PARAM_EVENT "event" @@ -83,12 +84,23 @@ typedef enum { MUSE_CHANNEL_MAX } muse_channel_e; +typedef enum { + MUSE_MSG_TYPE_NORMAL, + MUSE_MSG_TYPE_FDS +} muse_msg_type_e; + typedef struct muse_external_storage_info { int id; int state; const char *path; } muse_external_storage_info_t; +typedef struct muse_msg_info { + unsigned int marker; + muse_msg_type_e type; + int size; +} muse_msg_info_t; + extern const char *UDS_files[MUSE_CHANNEL_MAX]; int muse_core_connection_close(int sock_fd); diff --git a/core/include/muse_core_internal.h b/core/include/muse_core_internal.h index 872bad0..8ecc109 100644 --- a/core/include/muse_core_internal.h +++ b/core/include/muse_core_internal.h @@ -150,6 +150,8 @@ typedef struct muse_recv_data { /* Dynamic allocated data area */ } muse_recv_data_t; +bool muse_core_msg_recv_len(int fd, char *buf, int msg_len); + #ifdef __cplusplus } #endif diff --git a/core/src/muse_core.c b/core/src/muse_core.c index f388907..94e9954 100644 --- a/core/src/muse_core.c +++ b/core/src/muse_core.c @@ -28,6 +28,7 @@ #define MUSE_WATCHDOG_TIMER_PERIOD 5 static GMutex msg_lock; +static GMutex msg_ipc_lock; static int _muse_get_valid_fd_count(int *fds); static void _muse_msg_json_set_error(muse_core_msg_parse_err_e *err, int jerr); @@ -277,6 +278,7 @@ int muse_core_msg_send(int sock_fd, const char *msg) int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf) { int ret = MM_ERROR_NONE; + muse_msg_info_t msg_info = {0,}; struct cmsghdr *cptr; struct msghdr msg; struct iovec iov; @@ -288,9 +290,38 @@ int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf) g_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT); g_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT); + if (!fds) + msg_info.type = MUSE_MSG_TYPE_NORMAL; + else + msg_info.type = MUSE_MSG_TYPE_FDS; + + msg_info.marker = MUSE_MSG_HEAD; + msg_info.size = strlen(buf); + + /*LOGD("send [t:%d,s:%d] [%s]", msg_info.type, msg_info.size, buf);*/ + + g_mutex_lock(&msg_ipc_lock); + + ret = send(sock_fd, &msg_info, sizeof(muse_msg_info_t), 0); + if (ret != sizeof(muse_msg_info_t)) { + LOGE("msg info [t:%d,s:%d] send failed : %d, errno %d", + msg_info.type, msg_info.size, ret, errno); + + goto _MSG_SEND_DONE; + } + + if (msg_info.type == MUSE_MSG_TYPE_NORMAL) { + ret = send(sock_fd, buf, msg_info.size, 0); + if (ret != (int)msg_info.size) + LOGE("send failed : %d, [%s], errno %d", ret, buf, errno); + + goto _MSG_SEND_DONE; + } + + /* MUSE_MSG_TYPE_FDS */ memset(&iov, 0, sizeof(iov)); iov.iov_base = (void *)buf; - iov.iov_len = strlen(buf); + iov.iov_len = msg_info.size; memset(&msg, 0, sizeof(msg)); msg.msg_name = NULL; @@ -298,26 +329,21 @@ int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf) msg.msg_iov = &iov; msg.msg_iovlen = 1; - if (!fds) { /* when muse_core_msg_send is called */ - msg.msg_control = NULL; - msg.msg_controllen = 0; - } else { - msg.msg_control = data; - msg.msg_controllen = sizeof(data); + msg.msg_control = data; + msg.msg_controllen = sizeof(data); - cptr = CMSG_FIRSTHDR(&msg); - if (cptr) { - fd_cnt = _muse_get_valid_fd_count(fds); - cptr->cmsg_len = CMSG_LEN(sizeof(int) * fd_cnt); - cptr->cmsg_level = SOL_SOCKET; - cptr->cmsg_type = SCM_RIGHTS; - fdptr = (int *)CMSG_DATA(cptr); + cptr = CMSG_FIRSTHDR(&msg); + if (cptr) { + fd_cnt = _muse_get_valid_fd_count(fds); + cptr->cmsg_len = CMSG_LEN(sizeof(int) * fd_cnt); + cptr->cmsg_level = SOL_SOCKET; + cptr->cmsg_type = SCM_RIGHTS; + fdptr = (int *)CMSG_DATA(cptr); - memcpy(fdptr, fds, sizeof(int) * fd_cnt); + memcpy(fdptr, fds, sizeof(int) * fd_cnt); - /* the value of msg_controllen increases after memcpy so reassignes the orginal value */ - msg.msg_controllen = cptr->cmsg_len; - } + /* the value of msg_controllen increases after memcpy so reassignes the orginal value */ + msg.msg_controllen = cptr->cmsg_len; } if ((ret = sendmsg(sock_fd, &msg, 0)) == MUSE_ERR) { @@ -325,6 +351,9 @@ int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf) LOGE("[%d] fail to send msg - [error %s %d]", sock_fd, err_msg, errno); } +_MSG_SEND_DONE: + g_mutex_unlock(&msg_ipc_lock); + return ret; } @@ -336,39 +365,64 @@ int muse_core_msg_recv(int sock_fd, char *msg) int muse_core_msg_recv_fd(int sock_fd, char *buf, int *out_fd) { - int ret = MM_ERROR_NONE; + int ret = 0; struct cmsghdr *cptr; struct msghdr msg; struct iovec iov; + muse_msg_info_t msg_info = {0,}; char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)]; char err_msg[MUSE_MSG_LEN_MAX] = {'\0',}; g_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT); - memset(&iov, 0, sizeof(iov)); - iov.iov_base = (void *)buf; - iov.iov_len = MUSE_MSG_MAX_LENGTH; - - memset(&msg, 0, sizeof(msg)); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = data; - msg.msg_controllen = sizeof(data); + /* get msg type and length */ + if (!muse_core_msg_recv_len(sock_fd, (char *)&msg_info, sizeof(muse_msg_info_t))) { + LOGE("msg info receive failed"); + return -1; + } - if ((ret = recvmsg(sock_fd, &msg, 0)) == MUSE_ERR) { - strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX); - LOGE("fail to receive msg (%s)", err_msg); - return ret; + if (msg_info.marker != MUSE_MSG_HEAD) { + LOGE("invalid marker 0x%x", msg_info.marker); + return -1; } - if (out_fd) { - cptr = CMSG_FIRSTHDR(&msg); - if (cptr) - memcpy(out_fd, CMSG_DATA(cptr), cptr->cmsg_len - CMSG_LEN(0)); + if (msg_info.type == MUSE_MSG_TYPE_NORMAL) { + if (!muse_core_msg_recv_len(sock_fd, buf, msg_info.size)) { + LOGE("msg receive failed"); + return -1; + } + + ret = msg_info.size; + } else { + memset(&iov, 0, sizeof(iov)); + iov.iov_base = (void *)buf; + iov.iov_len = msg_info.size; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = data; + msg.msg_controllen = sizeof(data); + + if ((ret = recvmsg(sock_fd, &msg, 0)) == MUSE_ERR) { + strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX); + LOGE("fail to receive msg (%s)", err_msg); + return ret; + } + + if (out_fd) { + cptr = CMSG_FIRSTHDR(&msg); + if (cptr) + memcpy(out_fd, CMSG_DATA(cptr), cptr->cmsg_len - CMSG_LEN(0)); + } } + buf[ret] = '\0'; + + /*LOGD("recv [t:%d,s:%d] [%s]", msg_info.type, msg_info.size, buf);*/ + return ret; } @@ -563,6 +617,39 @@ void muse_core_msg_object_free(void *jobj) g_mutex_unlock(&msg_lock); } +bool muse_core_msg_recv_len(int fd, char *buf, int msg_len) +{ + int offset = 0; + int recv_len = 0; + char err_msg[MUSE_MSG_LEN_MAX] = {'\0',}; + + if (!muse_core_fd_is_valid(fd) || !buf || msg_len <= 0) { + LOGE("invalid param : fd %d, buf %p, msg_len %d", fd, buf, msg_len); + return false; + } + + do { + recv_len = recv(fd, buf + offset, msg_len - offset, 0); + if (recv_len < 0) { + strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX); + LOGE("[fd %d] recv : %s (%d)", fd, err_msg, errno); + return false; + } else if (recv_len == 0) { + LOGD("EOF"); + return false; + } + + offset += recv_len; + } while (offset < msg_len); + + if (offset != msg_len) { + LOGE("invalid length received : try %d -> result %d", msg_len, offset); + return false; + } + + return true; +} + void muse_core_fd_state_dump(int fd) { struct stat sb = { 0, }; diff --git a/packaging/mused.spec b/packaging/mused.spec index 0924d3a..5acf88e 100644 --- a/packaging/mused.spec +++ b/packaging/mused.spec @@ -1,6 +1,6 @@ Name: mused Summary: A multimedia daemon -Version: 0.3.32 +Version: 0.3.33 Release: 0 Group: System/Libraries License: Apache-2.0 diff --git a/server/src/muse_server_ipc.c b/server/src/muse_server_ipc.c index 4d16eaa..e61a0e7 100644 --- a/server/src/muse_server_ipc.c +++ b/server/src/muse_server_ipc.c @@ -19,6 +19,7 @@ * */ +#include "muse_core_internal.h" #include "muse_server_private.h" #define MSG_THREAD_NAME "msg" @@ -30,7 +31,6 @@ static void _ms_ipc_module_cleanup(muse_module_h m, void *jobj); static gboolean _ms_ipc_module_instance_creation_is_allowed(int module_idx); static gpointer _ms_ipc_dispatch_worker(gpointer data); -static gboolean _ms_ipc_receive_message(int fd, char *buf, int msg_len); 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); @@ -211,39 +211,6 @@ static gpointer _ms_ipc_dispatch_worker(gpointer data) return NULL; } -static gboolean _ms_ipc_receive_message(int fd, char *buf, int msg_len) -{ - int offset = 0; - int recv_len = 0; - char err_msg[MUSE_MSG_LEN_MAX] = {'\0',}; - - if (!muse_core_fd_is_valid(fd) || !buf || msg_len <= 0) { - LOGE("invalid param : fd %d, buf %p, msg_len %d", fd, buf, msg_len); - return FALSE; - } - - do { - recv_len = recv(fd, buf + offset, msg_len - offset, 0); - if (recv_len < 0) { - strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX); - LOGE("[fd %d] recv : %s (%d)", fd, err_msg, errno); - return FALSE; - } else if (recv_len == 0) { - LOGD("EOF"); - return FALSE; - } - - offset += recv_len; - } while (offset < msg_len); - - if (offset != msg_len) { - LOGE("invalid length received : try %d -> result %d", msg_len, offset); - return FALSE; - } - - return TRUE; -} - static gboolean _ms_ipc_data_processing(int fd, muse_recv_data_head_t *header, muse_channel_info_t *ch) { char *raw_data = NULL; @@ -276,7 +243,7 @@ static gboolean _ms_ipc_data_processing(int fd, muse_recv_data_head_t *header, m memcpy(raw_data, header, sizeof(muse_recv_data_head_t)); /* receive data */ - if (!_ms_ipc_receive_message(fd, raw_data + sizeof(muse_recv_data_head_t), header->size)) { + if (!muse_core_msg_recv_len(fd, raw_data + sizeof(muse_recv_data_head_t), header->size)) { LOGE("receive data failed - length %d", header->size); goto _PROCESSING_FAILED; } @@ -315,7 +282,7 @@ static gpointer _ms_ipc_data_worker(gpointer data) /* get data */ while (1) { - if (!_ms_ipc_receive_message(fd, recv_buf, sizeof(muse_recv_data_head_t))) + if (!muse_core_msg_recv_len(fd, recv_buf, sizeof(muse_recv_data_head_t))) break; if (!_ms_ipc_data_processing(fd, (muse_recv_data_head_t *)recv_buf, ch)) { diff --git a/server/src/muse_server_private.c b/server/src/muse_server_private.c index 0338c75..9695731 100644 --- a/server/src/muse_server_private.c +++ b/server/src/muse_server_private.c @@ -222,7 +222,7 @@ static void _ms_get_module_addr(int fd, intptr_t *module_addr) char recv_buf[MUSE_MSG_LEN_MAX] = {'\0',}; do { - if (recv(fd, recv_buf, MUSE_MSG_LEN_MAX, 0) == MUSE_ERR) { + if (muse_core_msg_recv_fd(fd, recv_buf, NULL) <= 0) { strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX); LOGE("failed to receive message for module %s", err_msg); return; -- 2.7.4