Aslo create wrapper of sendto() to retry if errno is ENOMEM/ENOBUFFS/EINTR. And return for other errors, do not assert() cause coredump. --- src/mds/mds_dt_tipc.c | 47 +++++++++++++++++++---- src/mds/mds_dt_tipc.h | 3 ++ src/mds/mds_tipc_fctrl_portid.cc | 65 +++++++++++++++----------------- 3 files changed, 74 insertions(+), 41 deletions(-)
diff --git a/src/mds/mds_dt_tipc.c b/src/mds/mds_dt_tipc.c index fdf0da7fb..b0f38ee49 100644 --- a/src/mds/mds_dt_tipc.c +++ b/src/mds/mds_dt_tipc.c @@ -51,6 +51,7 @@ #include "mds_tipc_recvq_stats.h" #include "base/osaf_utility.h" #include "base/osaf_poll.h" +#include "base/osaf_time.h" #ifndef SOCK_CLOEXEC enum { SOCK_CLOEXEC = 0x80000 }; @@ -523,9 +524,7 @@ uint32_t mdtm_tipc_destroy(void) MDTM_REASSEMBLY_QUEUE *reassem_queue = NULL; MDTM_REASSEMBLY_KEY reassembly_key; - /* close sockets first */ - close(tipc_cb.BSRsock); - close(tipc_cb.Dsock); + mds_tipc_fctrl_shutdown(); /* Destroy receiving task */ if (mdtm_destroy_rcv_task() != NCSCC_RC_SUCCESS) { @@ -537,7 +536,6 @@ uint32_t mdtm_tipc_destroy(void) NULL); m_NCS_IPC_RELEASE(&tipc_cb.tmr_mbx, (NCS_IPC_CB)mdtm_mailbox_mbx_cleanup); - mds_tipc_fctrl_shutdown(); /* Clear reference hdl list */ while (mdtm_ref_hdl_list_hdr != NULL) { /* Store temporary the pointer of entry to be deleted */ @@ -587,6 +585,9 @@ uint32_t mdtm_tipc_destroy(void) handle = 0; mdtm_global_frag_num = 0; + close(tipc_cb.BSRsock); + close(tipc_cb.Dsock); + return NCSCC_RC_SUCCESS; } @@ -3135,6 +3136,37 @@ uint32_t mdtm_add_frag_hdr(uint8_t *buf_ptr, uint16_t len, uint32_t seq_num, return NCSCC_RC_SUCCESS; } +/********************************************************* + + Function NAME: mds_retry_sendto + + DESCRIPTION: wrapper of sendto() for retry purpose + + ARGUMENTS: same as sendto() + + RETURNS: same as sendto() + +*********************************************************/ +ssize_t mds_retry_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + int retry = 5; + ssize_t send_len = 0; + while (retry >= 0) { + send_len = sendto(sockfd, buf, len, flags, dest_addr, addrlen); + if (send_len == len) { + return send_len; + } else if (retry-- > 0) { + if (errno != ENOMEM && + errno != ENOBUFS && + errno != EINTR) + break; + osaf_nanosleep(&kTenMilliseconds); + } + } + return send_len; +} + /********************************************************* Function NAME: mdtm_sendto @@ -3176,7 +3208,8 @@ static uint32_t mdtm_sendto(uint8_t *buffer, uint16_t buff_len, } #endif if (mds_tipc_fctrl_trysend(buffer, buff_len, id) == NCSCC_RC_SUCCESS) { - send_len = sendto(tipc_cb.BSRsock, buffer, buff_len, 0, + send_len = mds_retry_sendto( + tipc_cb.BSRsock, buffer, buff_len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (send_len == buff_len) { m_MDS_LOG_INFO("MDTM: Successfully sent message"); @@ -3222,8 +3255,8 @@ static uint32_t mdtm_mcast_sendto(void *buffer, size_t size, server_addr.addr.nameseq.lower = HTONL(MDS_MDTM_LOWER_INSTANCE); /*This can be scope-down to dest_svc_id server_inst TBD*/ server_addr.addr.nameseq.upper = HTONL(MDS_MDTM_UPPER_INSTANCE); - int send_len = - sendto(tipc_cb.BSRsock, buffer, size, 0, + ssize_t send_len = + mds_retry_sendto(tipc_cb.BSRsock, buffer, size, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (send_len == size) { diff --git a/src/mds/mds_dt_tipc.h b/src/mds/mds_dt_tipc.h index e73a11b09..65175839e 100644 --- a/src/mds/mds_dt_tipc.h +++ b/src/mds/mds_dt_tipc.h @@ -107,4 +107,7 @@ extern uint32_t mds_mdtm_node_subscribe_tipc(MDS_SVC_HDL svc_hdl, MDS_SUBTN_REF_VAL *subtn_ref_val); extern uint32_t mds_mdtm_node_unsubscribe_tipc(MDS_SUBTN_REF_VAL subtn_ref_val); +ssize_t mds_retry_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); + #endif // MDS_MDS_DT_TIPC_H_ diff --git a/src/mds/mds_tipc_fctrl_portid.cc b/src/mds/mds_tipc_fctrl_portid.cc index dab2b8c69..6b033b0e5 100644 --- a/src/mds/mds_tipc_fctrl_portid.cc +++ b/src/mds/mds_tipc_fctrl_portid.cc @@ -17,11 +17,14 @@ #include "mds/mds_tipc_fctrl_portid.h" #include "base/ncssysf_def.h" -#include "base/osaf_time.h" #include "mds/mds_dt.h" #include "mds/mds_log.h" +extern "C" { +#include "mds/mds_dt_tipc.h" +} + namespace mds { int max_retry_send = 100; @@ -156,18 +159,10 @@ uint32_t TipcPortId::Send(uint8_t* data, uint16_t length) { server_addr.family = AF_TIPC; server_addr.addrtype = TIPC_ADDR_ID; server_addr.addr.id = id_; - int retry = 5; - while (retry >= 0) { - ssize_t send_len = sendto(bsrsock_, data, length, 0, - (struct sockaddr *)&server_addr, sizeof(server_addr)); - - if (send_len == length) { - return NCSCC_RC_SUCCESS; - } else if (retry-- > 0) { - assert(errno == ENOMEM || errno == ENOBUFS); - osaf_nanosleep(&kTenMilliseconds); - } - } + ssize_t send_len = mds_retry_sendto(bsrsock_, data, length, 0, + (struct sockaddr *)&server_addr, sizeof(server_addr)); + if (send_len == length) + return NCSCC_RC_SUCCESS; m_MDS_LOG_ERR("FCTRL: sendto() failed, Error[%s]", strerror(errno)); return NCSCC_RC_FAILURE; } @@ -291,13 +286,15 @@ uint32_t TipcPortId::ReceiveData(uint32_t mseq, uint16_t mfrag, if (mfrag == 0) { // this is not fragment, the snd_type field is always present in message rcving_mbcast_ = false; - if (snd_type == MDS_SENDTYPE_BCAST || snd_type == MDS_SENDTYPE_RBCAST) { + if (snd_type == MDS_SENDTYPE_BCAST || + snd_type == MDS_SENDTYPE_RBCAST) { rcving_mbcast_ = true; } } else { // this is fragment, the snd_type is only present in the first fragment if ((mfrag & 0x7fff) == 1 && - (snd_type == MDS_SENDTYPE_BCAST || snd_type == MDS_SENDTYPE_RBCAST)) { + (snd_type == MDS_SENDTYPE_BCAST || + snd_type == MDS_SENDTYPE_RBCAST)) { rcving_mbcast_ = true; } } @@ -451,25 +448,25 @@ void TipcPortId::ReceiveChunkAck(uint16_t fseq, uint16_t chksize) { if (msg == nullptr) { break; } else { - if (Send(msg->msg_data_, msg->header_.msg_len_) == NCSCC_RC_SUCCESS) { - retry = 0; - send_msg_cnt++; - msg->is_sent_ = true; - m_MDS_LOG_NOTIFY("FCTRL: [me] --> [node:%x, ref:%u], " - "SndQData[fseq:%u, len:%u], " - "sndwnd[acked:%u, send:%u, nacked:%" PRIu64 "]", - id_.node, id_.ref, - msg->header_.fseq_, msg->header_.msg_len_, - sndwnd_.acked_.v(), sndwnd_.send_.v(), sndwnd_.nacked_space_); - } else if (send_msg_cnt == 0) { - // If not retry, all messages are kept in queue - // and no more trigger to send messages - retry++; - assert(retry < max_retry_send); - continue; - } else { - break; - } + if (Send(msg->msg_data_, msg->header_.msg_len_) == NCSCC_RC_SUCCESS) { + retry = 0; + send_msg_cnt++; + msg->is_sent_ = true; + m_MDS_LOG_NOTIFY("FCTRL: [me] --> [node:%x, ref:%u], " + "SndQData[fseq:%u, len:%u], " + "sndwnd[acked:%u, send:%u, nacked:%" PRIu64 "]", + id_.node, id_.ref, + msg->header_.fseq_, msg->header_.msg_len_, + sndwnd_.acked_.v(), sndwnd_.send_.v(), sndwnd_.nacked_space_); + } else if (send_msg_cnt == 0) { + // If not retry, all messages are kept in queue + // and no more trigger to send messages + retry++; + assert(retry < max_retry_send); + continue; + } else { + break; + } } } // no more unsent message, back to kEnabled -- 2.17.1 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel