// --------------------------------------------------------------
// CxaTM_RMMessage::send_rm
// Purpose - send the message to the RM
// Caller may lock.
// --------------------------------------------------------------
int CxaTM_RMMessage::send_rm() 
{
   short lv_ret = -1;
   int   lv_xaError = XA_OK;

   XATrace(XATM_TraceExit,
           ("XATM: CxaTM_RMMessage::send_rm ENTRY. msgid=%d, retries=%d/%d.\n", 
            iv_msgid, sendAttempts(), RM()->maxSendRetries()));
   lock();
   // Make sure that this CxaTM_RMMessage object doesn't already have a link outstanding
   if (msgid())
   {
      tm_log_event(DTM_XATM_SENDTORM_FAILED, SQ_LOG_CRIT, "DTM_XATM_SENDTORM_FAILED",
                   -1, RM()->getRmid(), -1, -1, msgid());
      XATrace(XATM_TraceError, ("XATM: CxaTM_RMMessage::send_rm : XATM Message object "
                                "already has a link outstanding, msgid %d\n", msgid()));
      abort();
   }

   if (iv_reqLen > RM_MAX_DATA || iv_rspLen > RM_MAX_DATA)
   {
      // EMS DTM_XATM_SENDTORM_FAILED
      tm_log_event(DTM_XATM_SENDTORM_FAILED2, SQ_LOG_CRIT, "DTM_XATM_SENDTORM_FAILED2",
                   -1,RM()->getRmid(),-1,-1,-1,XAER_RMFAIL,-1,-1,-1,-1,-1,-1,-1,
                   RM_MAX_DATA,iv_reqLen,iv_rspLen);
      XATrace(XATM_TraceError, ("XATM: CxaTM_RMMessage::send_rm : "
                                " Request or reply buffer too large, returning XAER_RMFAIL.\n"));
      lv_xaError = XAER_RMFAIL;
   }
   else
   {
      inc_sendAttempts();
      lv_ret = link();
   }

   if (lv_ret)
   {
      // EMS DTM_XATM_SENDTORM_FAILED
      tm_log_event(DTM_XATM_SENDTORM_FAILED, SQ_LOG_CRIT, "DTM_XATM_SENDTORM_FAILED", lv_ret, ip_RM->getRmid());
      lv_xaError = XAER_RMFAIL;
   }
   unlock();

   XATrace((lv_xaError?XATM_TraceExitError:XATM_TraceExit),
           ("XATM: CxaTM_RMMessage::send_rm EXIT returning %s, BMSG_LINK_ returned %d, msgid=%d, retries=%d/%d.\n", 
            XAtoa(lv_xaError), lv_ret, iv_msgid, sendAttempts(), RM()->maxSendRetries()));
   return lv_xaError;
} //CxaTM_RMMessage::send_rm
示例#2
0
void message_filter::remove_filter(u16 const & msg_type, u32 const & msg_subtype)
{
	msg_type_subtype_t msgid(msg_type, msg_subtype);
	filters_map_t::iterator tmp_iter = m_filters.find(msgid);
	R_ASSERT2(tmp_iter != m_filters.end(), "message filter not found");
	m_filters.erase(tmp_iter);
}
// --------------------------------------------------------------
// CxaTM_RMMessage::can_we_retrySend
// Purpose - Determines whether we can retry the send to an RM.  
// Returns:
//    true  - retry the send to an RM
//    false - do not retry the send. This could be because we got an 
//            error on the send or we've exceeded the retries.
// pp_xaError output:
//    XA_OK if the retry was successful, or 
//    XAER_RMFAIL if retries exceeded.
//    XAER_*   Any error returned by RM()->send_rm().
// --------------------------------------------------------------
bool CxaTM_RMMessage::can_we_retrySend(int *pp_xaError) 
{
   bool lv_success = false;

   XATrace(XATM_TraceExit,
           ("XATM: CxaTM_RMMessage::can_we_retrySend ENTRY RM %d, XA error=%d.\n",
            RM()->getRmid(), *pp_xaError));


   lock();
   if (sendAttempts() >= RM()->maxSendRetries())
   {
      XATrace(XATM_TraceError,("XATM: CxaTM_RMMessage::can_we_retrySend rmid=%d, "
              "msgid=%d, sendAttempts=%d. Retries exceeded.\n",
              RM()->getRmid(), msgid(), sendAttempts()));
      *pp_xaError = XAER_RMFAIL;
   }
   else
      if (*pp_xaError == XA_RETRY)
         lv_success = true;

   unlock();

   XATrace(XATM_TraceExit,
           ("XATM: CxaTM_RMMessage::can_we_retrySend EXIT RM %d, XA error=%d, returning %d.\n",
            RM()->getRmid(), *pp_xaError, lv_success));
   return lv_success;
} //CxaTM_RMMessage::can_we_retrySend
示例#4
0
void message_filter::filter(u16 const & msg_type,
								u32 const & msg_subtype,
								msg_type_subtype_func_t const & found_func)
{
	msg_type_subtype_t msgid(msg_type, msg_subtype);
	R_ASSERT2(m_filters.find(msgid) == m_filters.end(), "message filter already exist");
	m_filters.insert(std::make_pair(msgid, found_func));
}
// --------------------------------------------------------------
// CxaTM_RM::checkError
// Check the error returned by BMSG_BREAK_ and determine whether
// to retry the LINK.
// If break returns an error we retry the link - resend the 
// message to the RM.
// We don't need to cancel/abandon the message. If Seabed 
// returned an error it already abandoned it.
// pv_breakError - return code from BMSG_BREAK_.
// pp_xaError will contain the XA error code on return.
// pv_softRetry - true (default) Will retry true (retry link) if an
//                     XA_RETRY occurs.  This happens if a 
//                     FEPATHDOWN, FENOLCB, or an XA_RETRY occur.
//                false Will return retry = false if one of these
//                     errors occurs. This allows the XA_RETRY to
//                     be passed up to the next level for xa_recover.
// pv_transid only used for event messages (error reporting).
// return code
//    true = retry link.
//    false = Don't retry. Retries exceeded or error is not 
//            retryable.
// --------------------------------------------------------------
bool CxaTM_RMMessage::checkError(short pv_breakError, int *pp_xaError, 
                                 bool pv_softRetry, int64 pv_transid)
{
   bool lv_retryLink = false;
   *pp_xaError = XA_OK;
   char la_buf[DTM_STRING_BUF_SIZE];
   CTmTxKey lv_txn = (CTmTxKey) pv_transid;

   XATrace(XATM_TraceExit,
           ("XATM: CxaTM_RMMessage::checkError ENTRY txn ID (%d,%d) msgid=%d, breakError=%d, "
            "rmid=%d, softRetry=%d.\n", lv_txn.node(), lv_txn.seqnum(), iv_msgid, pv_breakError, 
            RM()->getRmid(), pv_softRetry));

   lock();
   // For XARM clients connecting to a DTM TM, we always retry the error.
   // DTM TMs don't run as process pairs, but we are attempting to send to
   // a specific node which might go down and switch to a spare. Also the
   // TSE might switch to it's backup.
   // If it's a retryable error (FEPATHDOWN (201) or FEOWNERSHIP (200)) or
   // FENOLCB (30) from a TSE then we'll retry. 
   if ((tm_XARM_generic_library() && pv_breakError) || 
       pv_breakError == FEPATHDOWN ||
       pv_breakError == FEOWNERSHIP ||
      pv_breakError == FENOLCB )
   {
      // Retry sending the request to the RM.  This is used to deal with failovers.
      if (ip_RM->inc_totalRetries())
      {
         sprintf(la_buf, "Retrying send to RM. BMSG_BREAK_ failed for Txn ID (%d,%d) with "
                 "error %d, rmid=%d, msgid=%d, retries=%d/%d\n", 
                 lv_txn.node(), lv_txn.seqnum(), pv_breakError, RM()->getRmid(), msgid(), 
                 sendAttempts(), RM()->maxSendRetries());

         tm_log_event(DTM_TM_INFO_MSGBRK_FAIL3, SQ_LOG_WARNING,
                      "DTM_TM_INFO_MSGBRK_FAIL3", pv_breakError, RM()->getRmid(),lv_txn.node(),lv_txn.seqnum(),
                      msgid(),-1,-1,-1, sendAttempts(),-1,-1,-1,-1,-1,-1,-1,RM()->getRMnameDetail());
         XATrace(XATM_TraceError,("XATM: CxaTM_RMMessage::checkError : %s", la_buf));
      }
      if ((pv_breakError == FEPATHDOWN) || (pv_breakError == FENOLCB))          
         *pp_xaError = XA_RETRY;

      lv_retryLink = can_we_retrySend(pp_xaError);
   }
   else
   {
      if (pv_breakError == FEOK)
      {
         *pp_xaError = getRmError();
         if (*pp_xaError != XA_OK)
         {
            XATrace(XATM_TraceDetail,("XATM: CxaTM_RMMessage::checkError : "
                    "XA error %s encountered.\n", XAtoa(*pp_xaError)));
            // If the RM responds XA_RETRY, we retry as for a break error, but allow
            // this to retry forever.
            if (*pp_xaError == XA_RETRY)
            {
               lv_retryLink = can_we_retrySend(pp_xaError);
               clear_sendAttempts();
            }
         }
      }
      else
      {
         sprintf(la_buf, "RM connection error. txn ID (%d,%d) BMSG_BREAK_ failed with "
                 "error %d, rmid=%d, msgid=%d, retries=%d/%d\n", 
                 lv_txn.node(), lv_txn.seqnum(), pv_breakError, RM()->getRmid(), msgid(), 
                 sendAttempts(), RM()->maxSendRetries());

         tm_log_event(DTM_TM_INFO_MSGBRK_FAIL4, SQ_LOG_WARNING,
                      "DTM_TM_INFO_MSGBRK_FAIL4",pv_breakError, RM()->getRmid(), 
                      lv_txn.node(),lv_txn.seqnum(),msgid(),-1,-1,-1, sendAttempts(),
                      -1,-1,-1,-1,-1,-1,-1,RM()->getRMnameDetail());
         XATrace(XATM_TraceError,("XATM: CxaTM_RMMessage::checkError : %s", la_buf));
         *pp_xaError = XAER_RMFAIL;
      }
   }
   unlock();

   if (!pv_softRetry && *pp_xaError == XA_RETRY)
      lv_retryLink = false;

   XATrace(XATM_TraceExit,
           ("XATM: CxaTM_RMMessage::checkError EXIT txn ID (%d,%d) msgid=%d, returning "
            "retryLink=%d, xaError=%s.\n",
            lv_txn.node(), lv_txn.seqnum(), msgid(), lv_retryLink, XAtoa(*pp_xaError)));
   return lv_retryLink;
} //CxaTM_RMMessage::checkError
// --------------------------------------------------------------
// CxaTM_RMMessage::release_from_RMmsgList
// Purpose: Release this meesage from the RMs msgList.
// --------------------------------------------------------------
void CxaTM_RMMessage::release_from_RMmsgList()
{
    // Remove the message from the RMs message list but reuse it for the retry
    RM()->msgList()->remove(msgid());
    msgid(0);
} //CxaTM_RMMessage::release_from_RMmsgList
示例#7
0
void client(int clinx, char *name, long id, int inx) {
    int            ferr;
    int            lerr;
    bool           ok;
    int            match;
    Util_AA<int>   msgid(MAX_SENDS);
    Util_AA<char>  recv_buffer(MAX_SENDS * BUFSIZ);
    Util_AA<short> recv_buffer3(MAX_SENDS * BUFSIZ);
    RT             results;
    int            send;
    Util_AA<char>  send_buffer(MAX_SENDS * BUFSIZ);
    Util_AA<short> send_buffer2(MAX_SENDS * BUFSIZ);
    int            send_len;
    MS_SRE_LDONE   sre_ldone;

    for (send = 0; send < MAX_SENDS; send++) {
        sprintf(&send_buffer.ip_v[send * BUFSIZ],
                "hello, greetings from %s, name=%s, id=%ld, inx=%d, send=%d",
                my_name, name, id, inx, send);
        while (clinx >= 0) {
            strcat(&send_buffer.ip_v[send * BUFSIZ], "!");
            clinx--;
        }
        send_len = (int) strlen(&send_buffer.ip_v[send * BUFSIZ]) + 1;
        ferr =
          XMSG_LINK_(TPT_REF(phandle),                         // phandle
                            &msgid.ip_v[send],                        // msgid
                            &send_buffer2.ip_v[send * BUFSIZ],        // reqctrl
                            (ushort) (inx & 1),                       // reqctrlsize
                            &recv_buffer3.ip_v[send * BUFSIZ],        // replyctrl
                            1,                                        // replyctrlmax
                            &send_buffer.ip_v[send * BUFSIZ],         // reqdata
                            (ushort) send_len,                        // reqdatasize
                            &recv_buffer.ip_v[send * BUFSIZ],         // replydata
                            BUFSIZ,                                   // replydatamax
                            (SB_Tag_Type)                             // linkertag
                              &send_buffer.ip_v[send * BUFSIZ],
                            0,                                        // pri
                            0,                                        // xmitclass
                            XMSG_LINK_LDONEQ);                        // linkopts
        util_check("XMSG_LINK_", ferr);
    }
    for (send = 0; send < MAX_SENDS;) {
        lerr = XWAIT(LDONE, -1);
        TEST_CHK_WAITIGNORE(lerr);
        for (;;) {
            lerr = XMSG_LISTEN_((short *) &sre_ldone, // sre
                                0,                    // listenopts
                                0);                   // listenertag
            if (lerr == XSRETYPE_NOWORK)
                break;
            send++;
            assert(lerr == XSRETYPE_LDONE);
            ok = false;
            for (match = 0; match < MAX_SENDS; match++) {
                if (sre_ldone.sre_linkTag ==
                    (SB_Tag_Type) &send_buffer.ip_v[match * BUFSIZ]) {
                    ok = true;
                    break;
                }
            }
            assert(ok);
            ferr = XMSG_BREAK_(msgid.ip_v[match],
                               results.u.s,
                               TPT_REF(phandle));
            util_check("XMSG_BREAK_", ferr);
            assert(results.u.t.ctrl_size == (uint) (inx & 1));
            assert(results.u.t.data_size >
                   (strlen(&send_buffer.ip_v[match * BUFSIZ]) + 14));
            assert(results.u.t.errm == RT_DATA_RCVD); // data
            printf("%s\n", &recv_buffer.ip_v[match * BUFSIZ]);
        }
    }
}