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