From 596a9553d90516375de169acdd513e4df26eab9d Mon Sep 17 00:00:00 2001 From: liqiang Date: Thu, 8 Jun 2023 15:27:06 +0800 Subject: uds remove MSG_WAITALL flags to timeout Signed-off-by: liqiang --- qtfs/ipc/uds_event.c | 16 ++++++++-------- qtfs/ipc/uds_main.c | 36 ++++++++++++++++++++++++++++++++++++ qtfs/ipc/uds_main.h | 1 + 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/qtfs/ipc/uds_event.c b/qtfs/ipc/uds_event.c index b046b69..047949b 100644 --- a/qtfs/ipc/uds_event.c +++ b/qtfs/ipc/uds_event.c @@ -214,7 +214,7 @@ int uds_event_build_step2(void *arg, int epfd, struct uds_event_global_var *p_ev struct uds_proxy_remote_conn_rsp rsp; int len; memset(buf, 0, sizeof(buf)); - len = recv(evt->fd, msg, sizeof(struct uds_proxy_remote_conn_req), MSG_WAITALL); + len = uds_recv_with_timeout(evt->fd, msg, sizeof(struct uds_proxy_remote_conn_req)); if (len == 0) { uds_err("recv err msg:%d errno:%d", len, errno); return EVENT_DEL; @@ -390,7 +390,7 @@ int uds_event_tcp_listener(void *arg, int epfd, struct uds_event_global_var *p_e int uds_build_connect2uds(struct uds_event *evt, struct uds_proxy_remote_conn_req *msg) { struct uds_conn_arg targ; - int len = recv(evt->fd, msg, sizeof(struct uds_proxy_remote_conn_req), MSG_WAITALL); + int len = uds_recv_with_timeout(evt->fd, msg, sizeof(struct uds_proxy_remote_conn_req)); if (len <= 0) { uds_err("recv failed, len:%d errno:%d", len, errno); return EVENT_ERR; @@ -441,7 +441,7 @@ err_ack: int uds_build_pipe_proxy(int efd, struct uds_event *evt, struct uds_stru_scm_pipe *msg) { - int len = recv(evt->fd, msg, sizeof(struct uds_stru_scm_pipe), MSG_WAITALL); + int len = uds_recv_with_timeout(evt->fd, msg, sizeof(struct uds_stru_scm_pipe)); if (len <= 0) { uds_err("recv failed, len:%d errno:%d", len, errno); return EVENT_ERR; @@ -477,7 +477,7 @@ int uds_event_remote_build(void *arg, int epfd, struct uds_event_global_var *p_e int len; int ret = EVENT_OK; memset(p_event_var->iov_base, 0, p_event_var->iov_len); - len = recv(evt->fd, bdmsg, sizeof(struct uds_tcp2tcp), MSG_WAITALL); + len = uds_recv_with_timeout(evt->fd, bdmsg, sizeof(struct uds_tcp2tcp)); if (len <= 0) { uds_err("read no msg from sock:%d, len:%d", evt->fd, len); return EVENT_DEL; @@ -711,7 +711,7 @@ int uds_msg_tcp2uds_scm_pipe(struct uds_tcp2tcp *p_msg, struct uds_event *evt, i int scmfd; int fd[SCM_PIPE_NUM]; struct uds_stru_scm_pipe *p_pipe = (struct uds_stru_scm_pipe *)p_msg->data; - int len = recv(evt->fd, p_pipe, p_msg->msglen, MSG_WAITALL); + int len = uds_recv_with_timeout(evt->fd, p_pipe, p_msg->msglen); if (len <= 0) { uds_err("recv data failed, len:%d", len); return EVENT_DEL; @@ -913,7 +913,7 @@ int uds_event_tcp2uds(void *arg, int epfd, struct uds_event_global_var *p_event_ msg.msg_controllen = p_event_var->msg_controlsendlen; while (1) { - int len = recv(evt->fd, p_msg, sizeof(struct uds_tcp2tcp), MSG_WAITALL); + int len = uds_recv_with_timeout(evt->fd, p_msg, sizeof(struct uds_tcp2tcp)); if (len <= 0) { uds_err("recv no msg maybe sock is closed, delete this tcp2uds event, len:%d.", len); goto close_event; @@ -932,7 +932,7 @@ int uds_event_tcp2uds(void *arg, int epfd, struct uds_event_global_var *p_event_ uds_err("normal msg repeat recv fd:%d", evt->fd); goto err; } - normal_msg_len = recv(evt->fd, p_event_var->iov_base_send, p_msg->msglen, MSG_WAITALL); + normal_msg_len = uds_recv_with_timeout(evt->fd, p_event_var->iov_base_send, p_msg->msglen); if (normal_msg_len <= 0) { uds_err("recv msg error:%d fd:%d", len, evt->fd); goto close_event; @@ -950,7 +950,7 @@ int uds_event_tcp2uds(void *arg, int epfd, struct uds_event_global_var *p_event_ } memset(p_scm->path, 0, sizeof(p_scm->path)); // SCM RIGHTS msg proc - len = recv(evt->fd, p_msg->data, p_msg->msglen, MSG_WAITALL); + len = uds_recv_with_timeout(evt->fd, p_msg->data, p_msg->msglen); if (len <= 0) { uds_err("recv data failed len:%d", p_msg->msglen); return EVENT_DEL; diff --git a/qtfs/ipc/uds_main.c b/qtfs/ipc/uds_main.c index adf0936..65ae81d 100644 --- a/qtfs/ipc/uds_main.c +++ b/qtfs/ipc/uds_main.c @@ -88,6 +88,42 @@ int uds_event_delete(int efd, int fd) return 0; } +int uds_recv_with_timeout(int fd, char *msg, int len) +{ +#define TMOUT_BLOCK_SIZE 1024 +#define TMOUT_UNIT_MS 20 +#define TMOUT_INTERVAL 1 +#define TMOUT_MAX_MS 1000 + int total_recv = 0; + int ret; + int tmout_ms = ((len / TMOUT_BLOCK_SIZE) + 1) * TMOUT_UNIT_MS; + if (len <= 0 || msg == NULL || fd < 0) { + uds_err("invalid param fd:%d len:%d or %s", fd, len, (msg == NULL) ? "msg is NULL" : "msg is not NULL"); + return 0; + } + if (tmout_ms > TMOUT_MAX_MS) + tmout_ms = TMOUT_MAX_MS; + do { + ret = recv(fd, &msg[total_recv], len - total_recv, 0); + if (ret < 0) { + uds_err("recv failed ret:%d errno:%d", ret, errno); + return ret; + } + total_recv += ret; + if (total_recv > len) { + uds_err("fatal error total recv:%d longger than target len:%d", total_recv, len); + return 0; + } + if (total_recv == len) { + return total_recv; + } + usleep(TMOUT_INTERVAL * 1000); + tmout_ms -= TMOUT_INTERVAL; + } while (tmout_ms > 0); + uds_err("Fatal error, the target recv len:%d and only %d length is received when it time out", len, total_recv); + return 0; +} + #pragma GCC diagnostic ignored "-Wpointer-to-int-cast" int uds_event_tmout_item(gpointer key, gpointer value, gpointer data) { diff --git a/qtfs/ipc/uds_main.h b/qtfs/ipc/uds_main.h index de400f8..f69e4b3 100644 --- a/qtfs/ipc/uds_main.h +++ b/qtfs/ipc/uds_main.h @@ -152,6 +152,7 @@ int uds_event_insert(int efd, struct uds_event *event); int uds_hash_insert_dirct(GHashTable *table, int key, struct uds_event *value); void *uds_hash_lookup_dirct(GHashTable *table, int key); int uds_hash_remove_dirct(GHashTable *table, int key); +int uds_recv_with_timeout(int fd, char *msg, int len); #ifdef QTFS_SERVER int uds_proxy_main(int argc, char *argv[]); -- 2.33.0