DbtcMain.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:428k
- /* Copyright (C) 2003 MySQL AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- #define DBTC_C
- #include "Dbtc.hpp"
- #include "md5_hash.hpp"
- #include <RefConvert.hpp>
- #include <ndb_limits.h>
- #include <signaldata/EventReport.hpp>
- #include <signaldata/TcKeyReq.hpp>
- #include <signaldata/TcKeyConf.hpp>
- #include <signaldata/TcKeyRef.hpp>
- #include <signaldata/KeyInfo.hpp>
- #include <signaldata/AttrInfo.hpp>
- #include <signaldata/TransIdAI.hpp>
- #include <signaldata/TcRollbackRep.hpp>
- #include <signaldata/NodeFailRep.hpp>
- #include <signaldata/ReadNodesConf.hpp>
- #include <signaldata/NFCompleteRep.hpp>
- #include <signaldata/LqhKey.hpp>
- #include <signaldata/TcCommit.hpp>
- #include <signaldata/TcContinueB.hpp>
- #include <signaldata/TcKeyFailConf.hpp>
- #include <signaldata/AbortAll.hpp>
- #include <signaldata/ScanFrag.hpp>
- #include <signaldata/ScanTab.hpp>
- #include <signaldata/PrepDropTab.hpp>
- #include <signaldata/DropTab.hpp>
- #include <signaldata/AlterTab.hpp>
- #include <signaldata/CreateTrig.hpp>
- #include <signaldata/DropTrig.hpp>
- #include <signaldata/FireTrigOrd.hpp>
- #include <signaldata/TrigAttrInfo.hpp>
- #include <signaldata/CreateIndx.hpp>
- #include <signaldata/DropIndx.hpp>
- #include <signaldata/AlterIndx.hpp>
- #include <signaldata/ScanTab.hpp>
- #include <signaldata/SystemError.hpp>
- #include <signaldata/DumpStateOrd.hpp>
- #include <signaldata/DisconnectRep.hpp>
- #include <signaldata/TcHbRep.hpp>
- #include <signaldata/PrepDropTab.hpp>
- #include <signaldata/DropTab.hpp>
- #include <signaldata/TcIndx.hpp>
- #include <signaldata/IndxKeyInfo.hpp>
- #include <signaldata/IndxAttrInfo.hpp>
- #include <signaldata/PackedSignal.hpp>
- #include <AttributeHeader.hpp>
- #include <signaldata/DictTabInfo.hpp>
- #include <NdbOut.hpp>
- #include <DebuggerNames.hpp>
- // Use DEBUG to print messages that should be
- // seen only when we debug the product
- #ifdef VM_TRACE
- #define DEBUG(x) ndbout << "DBTC: "<< x << endl;
- #else
- #define DEBUG(x)
- #endif
-
- #define INTERNAL_TRIGGER_TCKEYREQ_JBA 0
- #ifdef VM_TRACE
- NdbOut &
- operator<<(NdbOut& out, Dbtc::ConnectionState state){
- switch(state){
- case Dbtc::CS_CONNECTED: out << "CS_CONNECTED"; break;
- case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break;
- case Dbtc::CS_STARTED: out << "CS_STARTED"; break;
- case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break;
- case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break;
- case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break;
- case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break;
- case Dbtc::CS_RESTART: out << "CS_RESTART"; break;
- case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break;
- case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break;
- case Dbtc::CS_COMPLETE_SENT: out << "CS_COMPLETE_SENT"; break;
- case Dbtc::CS_PREPARE_TO_COMMIT: out << "CS_PREPARE_TO_COMMIT"; break;
- case Dbtc::CS_COMMIT_SENT: out << "CS_COMMIT_SENT"; break;
- case Dbtc::CS_START_COMMITTING: out << "CS_START_COMMITTING"; break;
- case Dbtc::CS_COMMITTING: out << "CS_COMMITTING"; break;
- case Dbtc::CS_REC_COMMITTING: out << "CS_REC_COMMITTING"; break;
- case Dbtc::CS_WAIT_ABORT_CONF: out << "CS_WAIT_ABORT_CONF"; break;
- case Dbtc::CS_WAIT_COMPLETE_CONF: out << "CS_WAIT_COMPLETE_CONF"; break;
- case Dbtc::CS_WAIT_COMMIT_CONF: out << "CS_WAIT_COMMIT_CONF"; break;
- case Dbtc::CS_FAIL_ABORTING: out << "CS_FAIL_ABORTING"; break;
- case Dbtc::CS_FAIL_ABORTED: out << "CS_FAIL_ABORTED"; break;
- case Dbtc::CS_FAIL_PREPARED: out << "CS_FAIL_PREPARED"; break;
- case Dbtc::CS_FAIL_COMMITTING: out << "CS_FAIL_COMMITTING"; break;
- case Dbtc::CS_FAIL_COMMITTED: out << "CS_FAIL_COMMITTED"; break;
- case Dbtc::CS_FAIL_COMPLETED: out << "CS_FAIL_COMPLETED"; break;
- case Dbtc::CS_START_SCAN: out << "CS_START_SCAN"; break;
- default:
- out << "Unknown: " << (int)state; break;
- }
- return out;
- }
- NdbOut &
- operator<<(NdbOut& out, Dbtc::OperationState state){
- out << (int)state;
- return out;
- }
- NdbOut &
- operator<<(NdbOut& out, Dbtc::AbortState state){
- out << (int)state;
- return out;
- }
- NdbOut &
- operator<<(NdbOut& out, Dbtc::ReturnSignal state){
- out << (int)state;
- return out;
- }
- NdbOut &
- operator<<(NdbOut& out, Dbtc::ScanRecord::ScanState state){
- out << (int)state;
- return out;
- }
- NdbOut &
- operator<<(NdbOut& out, Dbtc::ScanFragRec::ScanFragState state){
- out << (int)state;
- return out;
- }
- #endif
- void
- Dbtc::updateBuddyTimer(ApiConnectRecordPtr apiPtr)
- {
- if (apiPtr.p->buddyPtr != RNIL) {
- jam();
- ApiConnectRecordPtr buddyApiPtr;
- buddyApiPtr.i = apiPtr.p->buddyPtr;
- ptrCheckGuard(buddyApiPtr, capiConnectFilesize, apiConnectRecord);
- if (getApiConTimer(buddyApiPtr.i) != 0) {
- if ((apiPtr.p->transid[0] == buddyApiPtr.p->transid[0]) &&
- (apiPtr.p->transid[1] == buddyApiPtr.p->transid[1])) {
- jam();
- setApiConTimer(buddyApiPtr.i, ctcTimer, __LINE__);
- } else {
- jam();
- // Not a buddy anymore since not the same transid
- apiPtr.p->buddyPtr = RNIL;
- }//if
- }//if
- }//if
- }
- void Dbtc::execCONTINUEB(Signal* signal)
- {
- UintR tcase;
- jamEntry();
- tcase = signal->theData[0];
- UintR Tdata0 = signal->theData[1];
- UintR Tdata1 = signal->theData[2];
- UintR Tdata2 = signal->theData[3];
- switch (tcase) {
- case TcContinueB::ZRETURN_FROM_QUEUED_DELIVERY:
- jam();
- ndbrequire(false);
- return;
- case TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER:
- jam();
- tcNodeFailptr.i = Tdata0;
- ptrCheckGuard(tcNodeFailptr, 1, tcFailRecord);
- completeTransAtTakeOverLab(signal, Tdata1);
- return;
- case TcContinueB::ZCONTINUE_TIME_OUT_CONTROL:
- jam();
- timeOutLoopStartLab(signal, Tdata0);
- return;
- case TcContinueB::ZNODE_TAKE_OVER_COMPLETED:
- jam();
- tnodeid = Tdata0;
- tcNodeFailptr.i = 0;
- ptrAss(tcNodeFailptr, tcFailRecord);
- nodeTakeOverCompletedLab(signal);
- return;
- case TcContinueB::ZINITIALISE_RECORDS:
- jam();
- initialiseRecordsLab(signal, Tdata0, Tdata2, signal->theData[4]);
- return;
- case TcContinueB::ZSEND_COMMIT_LOOP:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- tcConnectptr.i = Tdata1;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- commit020Lab(signal);
- return;
- case TcContinueB::ZSEND_COMPLETE_LOOP:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- tcConnectptr.i = Tdata1;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- complete010Lab(signal);
- return;
- case TcContinueB::ZHANDLE_FAILED_API_NODE:
- jam();
- handleFailedApiNode(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::ZTRANS_EVENT_REP:
- jam();
- /* -------------------------------------------------------------------- */
- // Report information about transaction activity once per second.
- /* -------------------------------------------------------------------- */
- if (c_counters.c_trans_status == TransCounters::Timer){
- Uint32 len = c_counters.report(signal);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, len, JBB);
-
- c_counters.reset();
- signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1);
- }
- return;
- case TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL:
- jam();
- timeOutLoopStartFragLab(signal, Tdata0);
- return;
- case TcContinueB::ZABORT_BREAK:
- jam();
- tcConnectptr.i = Tdata0;
- apiConnectptr.i = Tdata1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->counter--;
- abort015Lab(signal);
- return;
- case TcContinueB::ZABORT_TIMEOUT_BREAK:
- jam();
- tcConnectptr.i = Tdata0;
- apiConnectptr.i = Tdata1;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- apiConnectptr.p->counter--;
- sendAbortedAfterTimeout(signal, 1);
- return;
- case TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS:
- jam();
- removeMarkerForFailedAPI(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::ZWAIT_ABORT_ALL:
- jam();
- checkAbortAllTimeout(signal, Tdata0);
- return;
- case TcContinueB::ZCHECK_SCAN_ACTIVE_FAILED_LQH:
- jam();
- checkScanActiveInFailedLqh(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:
- jam();
- checkWaitDropTabFailedLqh(signal, Tdata0, Tdata1);
- return;
- case TcContinueB::TRIGGER_PENDING:
- jam();
- ApiConnectRecordPtr transPtr;
- transPtr.i = Tdata0;
- ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
- transPtr.p->triggerPending = false;
- executeTriggers(signal, &transPtr);
- return;
- case TcContinueB::DelayTCKEYCONF:
- jam();
- apiConnectptr.i = Tdata0;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- sendtckeyconf(signal, Tdata1);
- return;
- default:
- ndbrequire(false);
- }//switch
- }
- void Dbtc::execDIGETNODESREF(Signal* signal)
- {
- jamEntry();
- terrorCode = signal->theData[1];
- releaseAtErrorLab(signal);
- }
- void Dbtc::execINCL_NODEREQ(Signal* signal)
- {
- jamEntry();
- tblockref = signal->theData[0];
- hostptr.i = signal->theData[1];
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- hostptr.p->hostStatus = HS_ALIVE;
- hostptr.p->takeOverStatus = TOS_IDLE;
- signal->theData[0] = cownref;
- sendSignal(tblockref, GSN_INCL_NODECONF, signal, 1, JBB);
- }
- void Dbtc::execREAD_NODESREF(Signal* signal)
- {
- jamEntry();
- ndbrequire(false);
- }
- void Dbtc::execTC_SCHVERREQ(Signal* signal)
- {
- jamEntry();
- tabptr.i = signal->theData[0];
- ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord);
- tabptr.p->currentSchemaVersion = signal->theData[1];
- tabptr.p->storedTable = (bool)signal->theData[2];
- BlockReference retRef = signal->theData[3];
- tabptr.p->tableType = (Uint8)signal->theData[4];
- BlockReference retPtr = signal->theData[5];
- ndbrequire(tabptr.p->enabled == false);
- tabptr.p->enabled = true;
- tabptr.p->dropping = false;
-
- signal->theData[0] = tabptr.i;
- signal->theData[1] = retPtr;
- sendSignal(retRef, GSN_TC_SCHVERCONF, signal, 2, JBB);
- }//Dbtc::execTC_SCHVERREQ()
- void
- Dbtc::execPREP_DROP_TAB_REQ(Signal* signal)
- {
- jamEntry();
-
- PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
-
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
-
- if(!tabPtr.p->enabled){
- jam();
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = PrepDropTabRef::NoSuchTable;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
- if(tabPtr.p->dropping){
- jam();
- PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = PrepDropTabRef::DropInProgress;
- sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
- PrepDropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->dropping = true;
- tabPtr.p->dropTable.senderRef = senderRef;
- tabPtr.p->dropTable.senderData = senderData;
- {
- WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
- req->tableId = tabPtr.i;
- req->senderRef = reference();
-
- HostRecordPtr hostPtr;
- tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor();
- for (hostPtr.i = 1; hostPtr.i < MAX_NDB_NODES; hostPtr.i++) {
- jam();
- ptrAss(hostPtr, hostRecord);
- if (hostPtr.p->hostStatus == HS_ALIVE) {
- jam();
- tabPtr.p->dropTable.waitDropTabCount.setWaitingFor(hostPtr.i);
- sendSignal(calcLqhBlockRef(hostPtr.i), GSN_WAIT_DROP_TAB_REQ,
- signal, WaitDropTabReq::SignalLength, JBB);
- }//for
- }//if
-
- ndbrequire(tabPtr.p->dropTable.waitDropTabCount.done() != true);
- }
- }
- void
- Dbtc::execWAIT_DROP_TAB_CONF(Signal* signal)
- {
- jamEntry();
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
- TableRecordPtr tabPtr;
- tabPtr.i = conf->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- ndbrequire(tabPtr.p->dropping == true);
- Uint32 nodeId = refToNode(conf->senderRef);
- tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
-
- if(!tabPtr.p->dropTable.waitDropTabCount.done()){
- jam();
- return;
- }
-
- {
- PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = tabPtr.p->dropTable.senderData;
- sendSignal(tabPtr.p->dropTable.senderRef, GSN_PREP_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
- tabPtr.p->dropTable.senderRef = 0;
- }
- }
- void
- Dbtc::execWAIT_DROP_TAB_REF(Signal* signal)
- {
- jamEntry();
- WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr();
- TableRecordPtr tabPtr;
- tabPtr.i = ref->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- ndbrequire(tabPtr.p->dropping == true);
- Uint32 nodeId = refToNode(ref->senderRef);
- tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
-
- ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable ||
- ref->errorCode == WaitDropTabRef::NF_FakeErrorREF);
-
- if(!tabPtr.p->dropTable.waitDropTabCount.done()){
- jam();
- return;
- }
-
- {
- PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = tabPtr.p->dropTable.senderData;
- sendSignal(tabPtr.p->dropTable.senderRef, GSN_PREP_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
- tabPtr.p->dropTable.senderRef = 0;
- }
- }
- void
- Dbtc::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId)
- {
-
- TableRecordPtr tabPtr;
- tabPtr.i = tableId;
- WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
- conf->tableId = tableId;
- const Uint32 RT_BREAK = 16;
- for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabrecFilesize; i++, tabPtr.i++){
- jam();
- ptrAss(tabPtr, tableRecord);
- if(tabPtr.p->enabled && tabPtr.p->dropping){
- if(tabPtr.p->dropTable.waitDropTabCount.isWaitingFor(nodeId)){
- jam();
- conf->senderRef = calcLqhBlockRef(nodeId);
- execWAIT_DROP_TAB_CONF(signal);
- tabPtr.i++;
- break;
- }
- }
- }
-
- if(tabPtr.i == ctabrecFilesize){
- /**
- * Finished
- */
- jam();
- return;
- }
-
- signal->theData[0] = TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
- signal->theData[1] = nodeId;
- signal->theData[2] = tabPtr.i;
- sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
- }
- void
- Dbtc::execDROP_TAB_REQ(Signal* signal)
- {
- jamEntry();
- DropTabReq* req = (DropTabReq*)signal->getDataPtr();
-
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
-
- Uint32 senderRef = req->senderRef;
- Uint32 senderData = req->senderData;
- DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
-
- if(!tabPtr.p->enabled && rt == DropTabReq::OnlineDropTab){
- jam();
- DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = DropTabRef::NoSuchTable;
- sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
- DropTabRef::SignalLength, JBB);
- return;
- }
- if(!tabPtr.p->dropping && rt == DropTabReq::OnlineDropTab){
- jam();
- DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
- ref->senderRef = reference();
- ref->senderData = senderData;
- ref->tableId = tabPtr.i;
- ref->errorCode = DropTabRef::DropWoPrep;
- sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
- DropTabRef::SignalLength, JBB);
- return;
- }
-
- tabPtr.p->enabled = false;
- tabPtr.p->dropping = false;
-
- DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
- conf->tableId = tabPtr.i;
- conf->senderRef = reference();
- conf->senderData = senderData;
- sendSignal(senderRef, GSN_DROP_TAB_CONF, signal,
- PrepDropTabConf::SignalLength, JBB);
- }
- void Dbtc::execALTER_TAB_REQ(Signal * signal)
- {
- AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
- const Uint32 senderRef = req->senderRef;
- const Uint32 senderData = req->senderData;
- const Uint32 changeMask = req->changeMask;
- const Uint32 tableId = req->tableId;
- const Uint32 tableVersion = req->tableVersion;
- const Uint32 gci = req->gci;
- AlterTabReq::RequestType requestType =
- (AlterTabReq::RequestType) req->requestType;
- TableRecordPtr tabPtr;
- tabPtr.i = req->tableId;
- ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
- tabPtr.p->currentSchemaVersion = tableVersion;
- // Request handled successfully
- AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
- conf->senderRef = reference();
- conf->senderData = senderData;
- conf->changeMask = changeMask;
- conf->tableId = tableId;
- conf->tableVersion = tableVersion;
- conf->gci = gci;
- conf->requestType = requestType;
- sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
- AlterTabConf::SignalLength, JBB);
- }
- /* ***************************************************************************/
- /* START / RESTART */
- /* ***************************************************************************/
- void Dbtc::execREAD_CONFIG_REQ(Signal* signal)
- {
- const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
- Uint32 ref = req->senderRef;
- Uint32 senderData = req->senderData;
- ndbrequire(req->noOfParameters == 0);
-
- jamEntry();
-
- const ndb_mgm_configuration_iterator * p =
- theConfiguration.getOwnConfigIterator();
- ndbrequire(p != 0);
-
- UintR apiConnect;
- UintR tcConnect;
- UintR tables;
- UintR localScan;
- UintR tcScan;
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_API_CONNECT, &apiConnect));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TC_CONNECT, &tcConnect));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TABLE, &tables));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_LOCAL_SCAN, &localScan));
- ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_SCAN, &tcScan));
- ccacheFilesize = (apiConnect/3) + 1;
- capiConnectFilesize = apiConnect;
- ctcConnectFilesize = tcConnect;
- ctabrecFilesize = tables;
- cscanrecFileSize = tcScan;
- cscanFragrecFileSize = localScan;
- initRecords();
- initialiseRecordsLab(signal, 0, ref, senderData);
- Uint32 val = 3000;
- ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val);
- set_timeout_value(val);
- val = 3000;
- ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &val);
- set_appl_timeout_value(val);
- val = 1;
- //ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_TRANSACTION_TAKEOVER, &val);
- set_no_parallel_takeover(val);
- ctimeOutCheckDelay = 50; // 500ms
- }//Dbtc::execSIZEALT_REP()
- void Dbtc::execSTTOR(Signal* signal)
- {
- Uint16 tphase;
- jamEntry();
- /* START CASE */
- tphase = signal->theData[1];
- csignalKey = signal->theData[6];
- switch (tphase) {
- case ZSPH1:
- jam();
- startphase1x010Lab(signal);
- return;
- default:
- jam();
- sttorryLab(signal); /* START PHASE 255 */
- return;
- }//switch
- }//Dbtc::execSTTOR()
- void Dbtc::sttorryLab(Signal* signal)
- {
- signal->theData[0] = csignalKey;
- signal->theData[1] = 3; /* BLOCK CATEGORY */
- signal->theData[2] = 2; /* SIGNAL VERSION NUMBER */
- signal->theData[3] = ZSPH1;
- signal->theData[4] = 255;
- sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
- }//Dbtc::sttorryLab()
- /* ***************************************************************************/
- /* INTERNAL START / RESTART */
- /*****************************************************************************/
- void Dbtc::execNDB_STTOR(Signal* signal)
- {
- Uint16 tndbstartphase;
- Uint16 tstarttype;
- jamEntry();
- tusersblkref = signal->theData[0];
- tnodeid = signal->theData[1];
- tndbstartphase = signal->theData[2]; /* START PHASE */
- tstarttype = signal->theData[3]; /* START TYPE */
- switch (tndbstartphase) {
- case ZINTSPH1:
- jam();
- intstartphase1x010Lab(signal);
- return;
- case ZINTSPH2:
- jam();
- intstartphase2x010Lab(signal);
- return;
- case ZINTSPH3:
- jam();
- intstartphase3x010Lab(signal); /* SEIZE CONNECT RECORD IN EACH LQH*/
- // Start transaction event reporting.
- c_counters.c_trans_status = TransCounters::Timer;
- c_counters.reset();
- signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
- return;
- case ZINTSPH6:
- jam();
- csystemStart = SSS_TRUE;
- break;
- default:
- jam();
- break;
- }//switch
- ndbsttorry010Lab(signal);
- return;
- }//Dbtc::execNDB_STTOR()
- void Dbtc::ndbsttorry010Lab(Signal* signal)
- {
- signal->theData[0] = cownref;
- sendSignal(cndbcntrblockref, GSN_NDB_STTORRY, signal, 1, JBB);
- }//Dbtc::ndbsttorry010Lab()
- void
- Dbtc::set_timeout_value(Uint32 timeOut)
- {
- timeOut = timeOut / 10;
- if (timeOut < 2) {
- jam();
- timeOut = 100;
- }//if
- ctimeOutValue = timeOut;
- }
- void
- Dbtc::set_appl_timeout_value(Uint32 timeOut)
- {
- if (timeOut)
- {
- timeOut /= 10;
- if (timeOut < ctimeOutValue) {
- jam();
- c_appl_timeout_value = ctimeOutValue;
- }//if
- }
- c_appl_timeout_value = timeOut;
- }
- void
- Dbtc::set_no_parallel_takeover(Uint32 noParallelTakeOver)
- {
- if (noParallelTakeOver == 0) {
- jam();
- noParallelTakeOver = 1;
- } else if (noParallelTakeOver > MAX_NDB_NODES) {
- jam();
- noParallelTakeOver = MAX_NDB_NODES;
- }//if
- cnoParallelTakeOver = noParallelTakeOver;
- }
- /* ***************************************************************************/
- /* S T A R T P H A S E 1 X */
- /* INITIALISE BLOCKREF AND BLOCKNUMBERS */
- /* ***************************************************************************/
- void Dbtc::startphase1x010Lab(Signal* signal)
- {
- csystemStart = SSS_FALSE;
- ctimeOutCheckCounter = 0;
- ctimeOutCheckFragCounter = 0;
- ctimeOutMissedHeartbeats = 0;
- ctimeOutCheckHeartbeat = 0;
- ctimeOutCheckLastHeartbeat = 0;
- ctimeOutCheckActive = TOCS_FALSE;
- ctimeOutCheckFragActive = TOCS_FALSE;
- sttorryLab(signal);
- }//Dbtc::startphase1x010Lab()
- /*****************************************************************************/
- /* I N T S T A R T P H A S E 1 X */
- /* INITIALISE ALL RECORDS. */
- /*****************************************************************************/
- void Dbtc::intstartphase1x010Lab(Signal* signal)
- {
- cownNodeid = tnodeid;
- cownref = calcTcBlockRef(cownNodeid);
- clqhblockref = calcLqhBlockRef(cownNodeid);
- cdihblockref = calcDihBlockRef(cownNodeid);
- cdictblockref = calcDictBlockRef(cownNodeid);
- cndbcntrblockref = calcNdbCntrBlockRef(cownNodeid);
- cerrorBlockref = calcNdbCntrBlockRef(cownNodeid);
- coperationsize = 0;
- cfailure_nr = 0;
- ndbsttorry010Lab(signal);
- }//Dbtc::intstartphase1x010Lab()
- /*****************************************************************************/
- /* I N T S T A R T P H A S E 2 X */
- /* SET-UP LOCAL CONNECTIONS. */
- /*****************************************************************************/
- void Dbtc::intstartphase2x010Lab(Signal* signal)
- {
- tcConnectptr.i = cfirstfreeTcConnect;
- intstartphase2x020Lab(signal);
- }//Dbtc::intstartphase2x010Lab()
- void Dbtc::intstartphase2x020Lab(Signal* signal)
- {
- if (tcConnectptr.i == RNIL) {
- jam();
- ndbsttorry010Lab(signal);
- return;
- }//if
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcConnectptr.p->tcConnectstate = OS_CONNECTING_DICT;
- /* ****************** */
- /* DISEIZEREQ < */
- /* ****************** */
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = cownref;
- sendSignal(cdihblockref, GSN_DISEIZEREQ, signal, 2, JBB);
- }//Dbtc::intstartphase2x020Lab()
- void Dbtc::execDISEIZECONF(Signal* signal)
- {
- jamEntry();
- tcConnectptr.i = signal->theData[0];
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- tcConnectptr.p->dihConnectptr = signal->theData[1];
- tcConnectptr.i = tcConnectptr.p->nextTcConnect;
- intstartphase2x020Lab(signal);
- }//Dbtc::execDISEIZECONF()
- /*****************************************************************************/
- /* I N T S T A R T P H A S E 3 X */
- /* PREPARE DISTRIBUTED CONNECTIONS */
- /*****************************************************************************/
- void Dbtc::intstartphase3x010Lab(Signal* signal)
- {
- signal->theData[0] = cownref;
- sendSignal(cndbcntrblockref, GSN_READ_NODESREQ, signal, 1, JBB);
- }//Dbtc::intstartphase3x010Lab()
- void Dbtc::execREAD_NODESCONF(Signal* signal)
- {
- UintR guard0;
- jamEntry();
- ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
- csystemnodes = readNodes->noOfNodes;
- cmasterNodeId = readNodes->masterNodeId;
- con_lineNodes = 0;
- arrGuard(csystemnodes, MAX_NDB_NODES);
- guard0 = csystemnodes - 1;
- arrGuard(guard0, MAX_NDB_NODES); // Check not zero nodes
- for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
- jam();
- if (NodeBitmask::get(readNodes->allNodes, i)) {
- hostptr.i = i;
- ptrCheckGuard(hostptr, chostFilesize, hostRecord);
- hostptr.p->takeOverStatus = TOS_IDLE;
-
- if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
- jam();
- hostptr.p->hostStatus = HS_DEAD;
- } else {
- jam();
- con_lineNodes++;
- hostptr.p->hostStatus = HS_ALIVE;
- }//if
- }//if
- }//for
- ndbsttorry010Lab(signal);
- }//Dbtc::execREAD_NODESCONF()
- /*****************************************************************************/
- /* A P I _ F A I L R E Q */
- // An API node has failed for some reason. We need to disconnect all API
- // connections to the API node. This also includes
- /*****************************************************************************/
- void Dbtc::execAPI_FAILREQ(Signal* signal)
- {
- /***************************************************************************
- * Set the block reference to return API_FAILCONF to. Set the number of api
- * connects currently closing to one to indicate that we are still in the
- * process of going through the api connect records. Thus checking for zero
- * can only be true after all api connect records have been checked.
- **************************************************************************/
- jamEntry();
- capiFailRef = signal->theData[1];
- arrGuard(signal->theData[0], MAX_NODES);
- capiConnectClosing[signal->theData[0]] = 1;
- handleFailedApiNode(signal, signal->theData[0], (UintR)0);
- }
- void
- Dbtc::handleFailedApiNode(Signal* signal,
- UintR TapiFailedNode,
- UintR TapiConnectPtr)
- {
- UintR TloopCount = 0;
- arrGuard(TapiFailedNode, MAX_NODES);
- apiConnectptr.i = TapiConnectPtr;
- do {
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- const UintR TapiNode = refToNode(apiConnectptr.p->ndbapiBlockref);
- if (TapiNode == TapiFailedNode) {
- #ifdef VM_TRACE
- if (apiConnectptr.p->apiFailState != ZFALSE) {
- ndbout << "Error in previous API fail handling discovered" << endl
- << " apiConnectptr.i = " << apiConnectptr.i << endl
- << " apiConnectstate = " << apiConnectptr.p->apiConnectstate
- << endl
- << " ndbapiBlockref = " << hex
- << apiConnectptr.p->ndbapiBlockref << endl
- << " apiNode = " << refToNode(apiConnectptr.p->ndbapiBlockref)
- << endl;
- if (apiConnectptr.p->lastTcConnect != RNIL){
- jam();
- tcConnectptr.i = apiConnectptr.p->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- ndbout << " tcConnectptr.i = " << tcConnectptr.i << endl
- << " tcConnectstate = " << tcConnectptr.p->tcConnectstate
- << endl;
- }
- }//if
- #endif
-
- apiConnectptr.p->returnsignal = RS_NO_RETURN;
- /***********************************************************************/
- // The connected node is the failed node.
- /**********************************************************************/
- switch(apiConnectptr.p->apiConnectstate) {
- case CS_DISCONNECTED:
- /*********************************************************************/
- // These states do not need any special handling.
- // Simply continue with the next.
- /*********************************************************************/
- jam();
- break;
- case CS_ABORTING:
- /*********************************************************************/
- // This could actually mean that the API connection is already
- // ready to release if the abortState is IDLE.
- /*********************************************************************/
- if (apiConnectptr.p->abortState == AS_IDLE) {
- jam();
- releaseApiCon(signal, apiConnectptr.i);
- } else {
- jam();
- capiConnectClosing[TapiFailedNode]++;
- apiConnectptr.p->apiFailState = ZTRUE;
- }//if
- break;
- case CS_WAIT_ABORT_CONF:
- case CS_WAIT_COMMIT_CONF:
- case CS_START_COMMITTING:
- case CS_PREPARE_TO_COMMIT:
- case CS_COMMITTING:
- case CS_COMMIT_SENT:
- /*********************************************************************/
- // These states indicate that an abort process or commit process is
- // already ongoing. We will set a state in the api record indicating
- // that the API node has failed.
- // Also we will increase the number of outstanding api records to
- // wait for before we can respond with API_FAILCONF.
- /*********************************************************************/
- jam();
- capiConnectClosing[TapiFailedNode]++;
- apiConnectptr.p->apiFailState = ZTRUE;
- break;
- case CS_START_SCAN:
- /*********************************************************************/
- // The api record was performing a scan operation. We need to check
- // on the scan state. Since completing a scan process might involve
- // sending several signals we will increase the loop count by 64.
- /*********************************************************************/
- jam();
- apiConnectptr.p->apiFailState = ZTRUE;
- capiConnectClosing[TapiFailedNode]++;
- ScanRecordPtr scanPtr;
- scanPtr.i = apiConnectptr.p->apiScanRec;
- ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
- close_scan_req(signal, scanPtr, true);
-
- TloopCount += 64;
- break;
- case CS_CONNECTED:
- /*********************************************************************/
- // The api record is connected to failed node. We need to release the
- // connection and set it in a disconnected state.
- /*********************************************************************/
- jam();
- releaseApiCon(signal, apiConnectptr.i);
- break;
- case CS_REC_COMMITTING:
- case CS_RECEIVING:
- case CS_STARTED:
- /*********************************************************************/
- // The api record was in the process of performing a transaction but
- // had not yet sent all information.
- // We need to initiate an ABORT since the API will not provide any
- // more information.
- // Since the abort can send many signals we will insert a real-time
- // break after checking this record.
- /*********************************************************************/
- jam();
- apiConnectptr.p->apiFailState = ZTRUE;
- capiConnectClosing[TapiFailedNode]++;
- abort010Lab(signal);
- TloopCount = 256;
- break;
- case CS_PREPARED:
- jam();
- case CS_REC_PREPARING:
- jam();
- case CS_START_PREPARING:
- jam();
- /*********************************************************************/
- // Not implemented yet.
- /*********************************************************************/
- systemErrorLab(signal);
- break;
- case CS_RESTART:
- jam();
- case CS_COMPLETING:
- jam();
- case CS_COMPLETE_SENT:
- jam();
- case CS_WAIT_COMPLETE_CONF:
- jam();
- case CS_FAIL_ABORTING:
- jam();
- case CS_FAIL_ABORTED:
- jam();
- case CS_FAIL_PREPARED:
- jam();
- case CS_FAIL_COMMITTING:
- jam();
- case CS_FAIL_COMMITTED:
- /*********************************************************************/
- // These states are only valid on copy and fail API connections.
- /*********************************************************************/
- default:
- jam();
- systemErrorLab(signal);
- break;
- }//switch
- } else {
- jam();
- }//if
- apiConnectptr.i++;
- if (apiConnectptr.i > ((capiConnectFilesize / 3) - 1)) {
- jam();
- /**
- * Finished with scanning connection record
- *
- * Now scan markers
- */
- removeMarkerForFailedAPI(signal, TapiFailedNode, 0);
- return;
- }//if
- } while (TloopCount++ < 256);
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE;
- signal->theData[1] = TapiFailedNode;
- signal->theData[2] = apiConnectptr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- }//Dbtc::handleFailedApiNode()
- void
- Dbtc::removeMarkerForFailedAPI(Signal* signal,
- Uint32 nodeId,
- Uint32 startBucket)
- {
- TcFailRecordPtr node_fail_ptr;
- node_fail_ptr.i = 0;
- ptrAss(node_fail_ptr, tcFailRecord);
- if(node_fail_ptr.p->failStatus != FS_IDLE) {
- jam();
- DEBUG("Restarting removeMarkerForFailedAPI");
- /**
- * TC take-over in progress
- * needs to restart as this
- * creates new markers
- */
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
- signal->theData[1] = nodeId;
- signal->theData[2] = 0;
- sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 500, 3);
- return;
- }
- CommitAckMarkerIterator iter;
- m_commitAckMarkerHash.next(startBucket, iter);
-
- const Uint32 RT_BREAK = 256;
- for(Uint32 i = 0; i<RT_BREAK || iter.bucket == startBucket; i++){
- jam();
-
- if(iter.curr.i == RNIL){
- jam();
- /**
- * Done with iteration
- */
- capiConnectClosing[nodeId]--;
- if (capiConnectClosing[nodeId] == 0) {
- jam();
- /********************************************************************/
- // No outstanding ABORT or COMMIT's of this failed API node.
- // We can respond with API_FAILCONF
- /********************************************************************/
- signal->theData[0] = nodeId;
- signal->theData[1] = cownref;
- sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
- }
- return;
- }
-
- if(iter.curr.p->apiNodeId == nodeId){
- jam();
-
- /**
- * Check so that the record is not still in use
- *
- */
- ApiConnectRecordPtr apiConnectPtr;
- apiConnectPtr.i = iter.curr.p->apiConnectPtr;
- ptrCheckGuard(apiConnectPtr, capiConnectFilesize, apiConnectRecord);
- if(apiConnectPtr.p->commitAckMarker == iter.curr.i){
- jam();
- /**
- * The record is still active
- *
- * Don't remove it, but continueb instead
- */
- break;
- }
- sendRemoveMarkers(signal, iter.curr.p);
- m_commitAckMarkerHash.release(iter.curr);
-
- break;
- }
- m_commitAckMarkerHash.next(iter);
- }
-
- signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
- signal->theData[1] = nodeId;
- signal->theData[2] = iter.bucket;
- sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
- }
- void Dbtc::handleApiFailState(Signal* signal, UintR TapiConnectptr)
- {
- ApiConnectRecordPtr TlocalApiConnectptr;
- UintR TfailedApiNode;
- TlocalApiConnectptr.i = TapiConnectptr;
- ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
- TfailedApiNode = refToNode(TlocalApiConnectptr.p->ndbapiBlockref);
- arrGuard(TfailedApiNode, MAX_NODES);
- capiConnectClosing[TfailedApiNode]--;
- releaseApiCon(signal, TapiConnectptr);
- TlocalApiConnectptr.p->apiFailState = ZFALSE;
- if (capiConnectClosing[TfailedApiNode] == 0) {
- jam();
- signal->theData[0] = TfailedApiNode;
- signal->theData[1] = cownref;
- sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
- }//if
- }//Dbtc::handleApiFailState()
- /****************************************************************************
- * T C S E I Z E R E Q
- * THE APPLICATION SENDS A REQUEST TO SEIZE A CONNECT RECORD TO CARRY OUT A
- * TRANSACTION
- * TC BLOCK TAKE OUT A CONNECT RECORD FROM THE FREE LIST AND ESTABLISHES ALL
- * NECESSARY CONNECTION BEFORE REPLYING TO THE APPLICATION BLOCK
- ****************************************************************************/
- void Dbtc::execTCSEIZEREQ(Signal* signal)
- {
- UintR tapiPointer;
- BlockReference tapiBlockref; /* SENDER BLOCK REFERENCE*/
-
- jamEntry();
- tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
- tapiBlockref = signal->theData[1]; /* SENDERS BLOCK REFERENCE*/
-
- const NodeState::StartLevel sl =
- (NodeState::StartLevel)getNodeState().startLevel;
- const NodeId senderNodeId = refToNode(tapiBlockref);
- const bool local = senderNodeId == getOwnNodeId() || senderNodeId == 0;
-
- if(!(senderNodeId == getNodeState().getSingleUserApi()) &&
- !getNodeState().getSingleUserMode()) {
- if(!(sl==NodeState::SL_SINGLEUSER &&
- senderNodeId == getNodeState().getSingleUserApi())) {
- if (!(sl == NodeState::SL_STARTED ||
- (sl == NodeState::SL_STARTING && local == true))) {
- jam();
-
- Uint32 errCode;
- if(!(sl == NodeState::SL_SINGLEUSER && local))
- {
- switch(sl){
- case NodeState::SL_STARTING:
- errCode = ZSYSTEM_NOT_STARTED_ERROR;
- break;
- case NodeState::SL_STOPPING_1:
- case NodeState::SL_STOPPING_2:
- case NodeState::SL_STOPPING_3:
- case NodeState::SL_STOPPING_4:
- if(getNodeState().stopping.systemShutdown)
- errCode = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
- else
- errCode = ZNODE_SHUTDOWN_IN_PROGRESS;
- break;
- case NodeState::SL_SINGLEUSER:
- errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- break;
- default:
- errCode = ZWRONG_STATE;
- break;
- }
- signal->theData[0] = tapiPointer;
- signal->theData[1] = errCode;
- sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
- return;
- }//if (!(sl == SL_SINGLEUSER))
- } //if
- }
- }
-
- seizeApiConnect(signal);
- if (terrorCode == ZOK) {
- jam();
- apiConnectptr.p->ndbapiConnect = tapiPointer;
- apiConnectptr.p->ndbapiBlockref = tapiBlockref;
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = apiConnectptr.i;
- sendSignal(tapiBlockref, GSN_TCSEIZECONF, signal, 2, JBB);
- return;
- }
- signal->theData[0] = tapiPointer;
- signal->theData[1] = terrorCode;
- sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
- }//Dbtc::execTCSEIZEREQ()
- /****************************************************************************/
- /* T C R E L E A S E Q */
- /* REQUEST TO RELEASE A CONNECT RECORD */
- /****************************************************************************/
- void Dbtc::execTCRELEASEREQ(Signal* signal)
- {
- UintR tapiPointer;
- BlockReference tapiBlockref; /* SENDER BLOCK REFERENCE*/
- jamEntry();
- tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
- tapiBlockref = signal->theData[1];/* SENDERS BLOCK REFERENCE*/
- tuserpointer = signal->theData[2];
- if (tapiPointer >= capiConnectFilesize) {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 3, JBB);
- return;
- } else {
- jam();
- apiConnectptr.i = tapiPointer;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- if (apiConnectptr.p->apiConnectstate == CS_DISCONNECTED) {
- jam();
- signal->theData[0] = tuserpointer;
- sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB);
- } else {
- if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) {
- if (apiConnectptr.p->apiConnectstate == CS_CONNECTED ||
- (apiConnectptr.p->apiConnectstate == CS_ABORTING &&
- apiConnectptr.p->abortState == AS_IDLE) ||
- (apiConnectptr.p->apiConnectstate == CS_STARTED &&
- apiConnectptr.p->firstTcConnect == RNIL))
- {
- jam(); /* JUST REPLY OK */
- releaseApiCon(signal, apiConnectptr.i);
- signal->theData[0] = tuserpointer;
- sendSignal(tapiBlockref,
- GSN_TCRELEASECONF, signal, 1, JBB);
- } else {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- signal->theData[3] = apiConnectptr.p->apiConnectstate;
- sendSignal(tapiBlockref,
- GSN_TCRELEASEREF, signal, 4, JBB);
- }
- } else {
- jam();
- signal->theData[0] = tuserpointer;
- signal->theData[1] = ZINVALID_CONNECTION;
- signal->theData[2] = __LINE__;
- signal->theData[3] = tapiBlockref;
- signal->theData[4] = apiConnectptr.p->ndbapiBlockref;
- sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 5, JBB);
- }//if
- }//if
- }//Dbtc::execTCRELEASEREQ()
- /****************************************************************************/
- // Error Handling for TCKEYREQ messages
- /****************************************************************************/
- void Dbtc::signalErrorRefuseLab(Signal* signal)
- {
- ptrGuard(apiConnectptr);
- if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) {
- jam();
- apiConnectptr.p->abortState = AS_IDLE;
- apiConnectptr.p->apiConnectstate = CS_ABORTING;
- }//if
- sendSignalErrorRefuseLab(signal);
- }//Dbtc::signalErrorRefuseLab()
- void Dbtc::sendSignalErrorRefuseLab(Signal* signal)
- {
- ndbassert(false);
- ptrGuard(apiConnectptr);
- if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) {
- jam();
- ndbrequire(false);
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = signal->theData[ttransid_ptr];
- signal->theData[2] = signal->theData[ttransid_ptr + 1];
- signal->theData[3] = ZSIGNAL_ERROR;
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP,
- signal, 4, JBB);
- }
- }//Dbtc::sendSignalErrorRefuseLab()
- void Dbtc::abortBeginErrorLab(Signal* signal)
- {
- apiConnectptr.p->transid[0] = signal->theData[ttransid_ptr];
- apiConnectptr.p->transid[1] = signal->theData[ttransid_ptr + 1];
- abortErrorLab(signal);
- }//Dbtc::abortBeginErrorLab()
- void Dbtc::printState(Signal* signal, int place)
- {
- #ifdef VM_TRACE // Change to if 0 to disable these printouts
- ndbout << "-- Dbtc::printState -- " << endl;
- ndbout << "Received from place = " << place
- << " apiConnectptr.i = " << apiConnectptr.i
- << " apiConnectstate = " << apiConnectptr.p->apiConnectstate << endl;
- ndbout << "ctcTimer = " << ctcTimer
- << " ndbapiBlockref = " << hex <<apiConnectptr.p->ndbapiBlockref
- << " Transid = " << apiConnectptr.p->transid[0]
- << " " << apiConnectptr.p->transid[1] << endl;
- ndbout << " apiTimer = " << getApiConTimer(apiConnectptr.i)
- << " counter = " << apiConnectptr.p->counter
- << " lqhkeyconfrec = " << apiConnectptr.p->lqhkeyconfrec
- << " lqhkeyreqrec = " << apiConnectptr.p->lqhkeyreqrec << endl;
- ndbout << "abortState = " << apiConnectptr.p->abortState
- << " apiScanRec = " << apiConnectptr.p->apiScanRec
- << " returncode = " << apiConnectptr.p->returncode << endl;
- ndbout << "tckeyrec = " << apiConnectptr.p->tckeyrec
- << " returnsignal = " << apiConnectptr.p->returnsignal
- << " apiFailState = " << apiConnectptr.p->apiFailState << endl;
- if (apiConnectptr.p->cachePtr != RNIL) {
- jam();
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = apiConnectptr.p->cachePtr;
- if (TcachePtr < TcacheFilesize) {
- jam();
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- ndbout << "currReclenAi = " << regCachePtr->currReclenAi
- << " attrlength = " << regCachePtr->attrlength
- << " tableref = " << regCachePtr->tableref
- << " keylen = " << regCachePtr->keylen << endl;
- } else {
- jam();
- systemErrorLab(signal);
- }//if
- }//if
- #endif
- return;
- }//Dbtc::printState()
- void
- Dbtc::TCKEY_abort(Signal* signal, int place)
- {
- switch (place) {
- case 0:
- jam();
- terrorCode = ZSTATE_ERROR;
- apiConnectptr.p->firstTcConnect = RNIL;
- printState(signal, 4);
- abortBeginErrorLab(signal);
- return;
- case 1:
- jam();
- printState(signal, 3);
- sendSignalErrorRefuseLab(signal);
- return;
- case 2:{
- printState(signal, 6);
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
- const Uint32 t1 = tcKeyReq->transId1;
- const Uint32 t2 = tcKeyReq->transId2;
- signal->theData[0] = apiConnectptr.p->ndbapiConnect;
- signal->theData[1] = t1;
- signal->theData[2] = t2;
- signal->theData[3] = ZABORT_ERROR;
- ndbrequire(false);
- sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP,
- signal, 4, JBB);
- return;
- }
- case 3:
- jam();
- printState(signal, 7);
- noFreeConnectionErrorLab(signal);
- return;
- case 4:
- jam();
- terrorCode = ZERO_KEYLEN_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 5:
- jam();
- terrorCode = ZNO_AI_WITH_UPDATE;
- releaseAtErrorLab(signal);
- return;
- case 6:
- jam();
- warningHandlerLab(signal);
- return;
- case 7:
- jam();
- tabStateErrorLab(signal);
- return;
- case 8:
- jam();
- wrongSchemaVersionErrorLab(signal);
- return;
- case 9:
- jam();
- terrorCode = ZSTATE_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 10:
- jam();
- systemErrorLab(signal);
- return;
- case 11:
- jam();
- terrorCode = ZMORE_AI_IN_TCKEYREQ_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 12:
- jam();
- terrorCode = ZSIMPLE_READ_WITHOUT_AI;
- releaseAtErrorLab(signal);
- return;
- case 13:
- jam();
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_WAIT_KEYINFO:
- jam();
- printState(signal, 8);
- terrorCode = ZSTATE_ERROR;
- abortErrorLab(signal);
- return;
- default:
- jam();
- /********************************************************************/
- /* MISMATCH BETWEEN STATE ON API CONNECTION AND THIS */
- /* PARTICULAR TC CONNECT RECORD. THIS MUST BE CAUSED BY NDB */
- /* INTERNAL ERROR. */
- /********************************************************************/
- systemErrorLab(signal);
- return;
- }//switch
- return;
- case 15:
- jam();
- terrorCode = ZSCAN_NODE_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 16:
- jam();
- systemErrorLab(signal);
- return;
- case 17:
- jam();
- systemErrorLab(signal);
- return;
- case 18:
- jam();
- warningHandlerLab(signal);
- return;
- case 19:
- jam();
- return;
- case 20:
- jam();
- warningHandlerLab(signal);
- return;
- case 21:
- jam();
- systemErrorLab(signal);
- return;
- case 22:
- jam();
- systemErrorLab(signal);
- return;
- case 23:
- jam();
- systemErrorLab(signal);
- return;
- case 24:
- jam();
- seizeAttrbuferrorLab(signal);
- return;
- case 25:
- jam();
- warningHandlerLab(signal);
- return;
- case 26:
- jam();
- return;
- case 27:
- systemErrorLab(signal);
- jam();
- return;
- case 28:
- jam();
- // NOT USED
- return;
- case 29:
- jam();
- systemErrorLab(signal);
- return;
- case 30:
- jam();
- systemErrorLab(signal);
- return;
- case 31:
- jam();
- systemErrorLab(signal);
- return;
- case 32:
- jam();
- systemErrorLab(signal);
- return;
- case 33:
- jam();
- systemErrorLab(signal);
- return;
- case 34:
- jam();
- systemErrorLab(signal);
- return;
- case 35:
- jam();
- systemErrorLab(signal);
- return;
- case 36:
- jam();
- systemErrorLab(signal);
- return;
- case 37:
- jam();
- systemErrorLab(signal);
- return;
- case 38:
- jam();
- systemErrorLab(signal);
- return;
- case 39:
- jam();
- systemErrorLab(signal);
- return;
- case 40:
- jam();
- systemErrorLab(signal);
- return;
- case 41:
- jam();
- systemErrorLab(signal);
- return;
- case 42:
- jam();
- systemErrorLab(signal);
- return;
- case 43:
- jam();
- systemErrorLab(signal);
- return;
- case 44:
- jam();
- systemErrorLab(signal);
- return;
- case 45:
- jam();
- systemErrorLab(signal);
- return;
- case 46:
- jam();
- systemErrorLab(signal);
- return;
- case 47:
- jam();
- terrorCode = apiConnectptr.p->returncode;
- releaseAtErrorLab(signal);
- return;
- case 48:
- jam();
- terrorCode = ZCOMMIT_TYPE_ERROR;
- releaseAtErrorLab(signal);
- return;
- case 49:
- jam();
- abortErrorLab(signal);
- return;
- case 50:
- jam();
- systemErrorLab(signal);
- return;
- case 51:
- jam();
- abortErrorLab(signal);
- return;
- case 52:
- jam();
- abortErrorLab(signal);
- return;
- case 53:
- jam();
- abortErrorLab(signal);
- return;
- case 54:
- jam();
- abortErrorLab(signal);
- return;
- case 55:
- jam();
- printState(signal, 5);
- sendSignalErrorRefuseLab(signal);
- return;
-
- case 56:{
- jam();
- terrorCode = ZNO_FREE_TC_MARKER;
- abortErrorLab(signal);
- return;
- }
- case 57:{
- jam();
- /**
- * Initialize object before starting error handling
- */
- initApiConnectRec(signal, apiConnectptr.p, true);
- switch(getNodeState().startLevel){
- case NodeState::SL_STOPPING_2:
- case NodeState::SL_STOPPING_3:
- case NodeState::SL_STOPPING_4:
- if(getNodeState().stopping.systemShutdown)
- terrorCode = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
- else
- terrorCode = ZNODE_SHUTDOWN_IN_PROGRESS;
- break;
- case NodeState::SL_SINGLEUSER:
- terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
- break;
- default:
- terrorCode = ZWRONG_STATE;
- break;
- }
- abortErrorLab(signal);
- return;
- }
- case 58:{
- jam();
- releaseAtErrorLab(signal);
- return;
- }
- case 59:{
- jam();
- terrorCode = ZABORTINPROGRESS;
- abortErrorLab(signal);
- return;
- }
-
- default:
- jam();
- systemErrorLab(signal);
- return;
- }//switch
- }
- void Dbtc::execKEYINFO(Signal* signal)
- {
- UintR compare_transid1, compare_transid2;
- jamEntry();
- apiConnectptr.i = signal->theData[0];
- tmaxData = 20;
- if (apiConnectptr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal);
- return;
- }//if
- ptrAss(apiConnectptr, apiConnectRecord);
- ttransid_ptr = 1;
- compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
- compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- jam();
- printState(signal, 10);
- sendSignalErrorRefuseLab(signal);
- return;
- }//if
- switch (apiConnectptr.p->apiConnectstate) {
- case CS_RECEIVING:
- case CS_REC_COMMITTING:
- case CS_START_SCAN:
- jam();
- /*empty*/;
- break;
- /* OK */
- case CS_ABORTING:
- jam();
- return; /* IGNORE */
- case CS_CONNECTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. */
- /****************************************************************>*/
- printState(signal, 11);
- signalErrorRefuseLab(signal);
- return;
- case CS_STARTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED */
- /* WE ALSO NEED TO ABORT THIS TRANSACTION. */
- /****************************************************************>*/
- terrorCode = ZSIGNAL_ERROR;
- printState(signal, 2);
- abortErrorLab(signal);
- return;
- default:
- jam();
- warningHandlerLab(signal);
- return;
- }//switch
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = apiConnectptr.p->cachePtr;
- UintR TtcTimer = ctcTimer;
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- if (TcachePtr >= TcacheFilesize) {
- TCKEY_abort(signal, 42);
- return;
- }//if
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- cachePtr.i = TcachePtr;
- cachePtr.p = regCachePtr;
- tcConnectptr.i = apiConnectptr.p->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- switch (tcConnectptr.p->tcConnectstate) {
- case OS_WAIT_KEYINFO:
- jam();
- tckeyreq020Lab(signal);
- return;
- case OS_WAIT_SCAN:
- break;
- default:
- jam();
- terrorCode = ZSTATE_ERROR;
- abortErrorLab(signal);
- return;
- }//switch
- UintR TdataPos = 0;
- UintR TkeyLen = regCachePtr->keylen;
- UintR Tlen = regCachePtr->save1;
- do {
- if (cfirstfreeDatabuf == RNIL) {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- linkKeybuf(signal);
- arrGuard(TdataPos, 19);
- databufptr.p->data[0] = signal->theData[TdataPos + 3];
- databufptr.p->data[1] = signal->theData[TdataPos + 4];
- databufptr.p->data[2] = signal->theData[TdataPos + 5];
- databufptr.p->data[3] = signal->theData[TdataPos + 6];
- Tlen = Tlen + 4;
- TdataPos = TdataPos + 4;
- if (Tlen < TkeyLen) {
- jam();
- if (TdataPos >= tmaxData) {
- jam();
- /*----------------------------------------------------*/
- /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/
- /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/
- /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/
- /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/
- /*----------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = Tlen;
- return;
- }//if
- } else {
- jam();
- return;
- }//if
- } while (1);
- return;
- }//Dbtc::execKEYINFO()
- /*---------------------------------------------------------------------------*/
- /* */
- /* MORE THAN FOUR WORDS OF KEY DATA. WE NEED TO PACK THIS IN KEYINFO SIGNALS.*/
- /* WE WILL ALWAYS PACK 4 WORDS AT A TIME. */
- /*---------------------------------------------------------------------------*/
- void Dbtc::packKeyData000Lab(Signal* signal,
- BlockReference TBRef,
- Uint32 totalLen)
- {
- CacheRecord * const regCachePtr = cachePtr.p;
- jam();
- Uint32 len = 0;
- databufptr.i = regCachePtr->firstKeybuf;
- signal->theData[0] = tcConnectptr.i;
- signal->theData[1] = apiConnectptr.p->transid[0];
- signal->theData[2] = apiConnectptr.p->transid[1];
- Uint32 * dst = signal->theData+3;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
-
- do {
- jam();
- databufptr.i = databufptr.p->nextDatabuf;
- dst[len + 0] = databufptr.p->data[0];
- dst[len + 1] = databufptr.p->data[1];
- dst[len + 2] = databufptr.p->data[2];
- dst[len + 3] = databufptr.p->data[3];
- len += 4;
- if (totalLen <= 4) {
- jam();
- /*---------------------------------------------------------------------*/
- /* LAST PACK OF KEY DATA HAVE BEEN SENT */
- /*---------------------------------------------------------------------*/
- /* THERE WERE UNSENT INFORMATION, SEND IT. */
- /*---------------------------------------------------------------------*/
- sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB);
- return;
- } else if(len == KeyInfo::DataLength){
- jam();
- len = 0;
- sendSignal(TBRef, GSN_KEYINFO, signal, 3 + KeyInfo::DataLength, JBB);
- }
- totalLen -= 4;
- ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
- } while (1);
- }//Dbtc::packKeyData000Lab()
- void Dbtc::tckeyreq020Lab(Signal* signal)
- {
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR TdataPos = 0;
- UintR TkeyLen = regCachePtr->keylen;
- UintR Tlen = regCachePtr->save1;
- do {
- if (cfirstfreeDatabuf == RNIL) {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- linkKeybuf(signal);
- arrGuard(TdataPos, 19);
- databufptr.p->data[0] = signal->theData[TdataPos + 3];
- databufptr.p->data[1] = signal->theData[TdataPos + 4];
- databufptr.p->data[2] = signal->theData[TdataPos + 5];
- databufptr.p->data[3] = signal->theData[TdataPos + 6];
- Tlen = Tlen + 4;
- TdataPos = TdataPos + 4;
- if (Tlen < TkeyLen) {
- jam();
- if (TdataPos >= tmaxData) {
- jam();
- /*----------------------------------------------------*/
- /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/
- /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/
- /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/
- /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/
- /*----------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = Tlen;
- tcConnectptr.p->tcConnectstate = OS_WAIT_KEYINFO;
- return;
- }//if
- } else {
- jam();
- tckeyreq050Lab(signal);
- return;
- }//if
- } while (1);
- return;
- }//Dbtc::tckeyreq020Lab()
- /* ------------------------------------------------------------------------- */
- /* ------- SAVE ATTRIBUTE INFORMATION IN OPERATION RECORD ------- */
- /* ------------------------------------------------------------------------- */
- void Dbtc::saveAttrbuf(Signal* signal)
- {
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
- UintR TattrbufFilesize = cattrbufFilesize;
- UintR TTcfirstAttrbuf = regCachePtr->firstAttrbuf;
- UintR Tlen = signal->length() - 3;
- AttrbufRecord *localAttrbufRecord = attrbufRecord;
- AttrbufRecord * const regAttrPtr = &localAttrbufRecord[TfirstfreeAttrbuf];
- if (TfirstfreeAttrbuf >= TattrbufFilesize) {
- TCKEY_abort(signal, 21);
- return;
- }//if
- UintR Tnext = regAttrPtr->attrbuf[ZINBUF_NEXT];
- if (TTcfirstAttrbuf == RNIL) {
- jam();
- regCachePtr->firstAttrbuf = TfirstfreeAttrbuf;
- } else {
- AttrbufRecordPtr saAttrbufptr;
- saAttrbufptr.i = regCachePtr->lastAttrbuf;
- jam();
- if (saAttrbufptr.i >= TattrbufFilesize) {
- TCKEY_abort(signal, 22);
- return;
- }//if
- saAttrbufptr.p = &localAttrbufRecord[saAttrbufptr.i];
- saAttrbufptr.p->attrbuf[ZINBUF_NEXT] = TfirstfreeAttrbuf;
- }//if
- cfirstfreeAttrbuf = Tnext;
- regAttrPtr->attrbuf[ZINBUF_NEXT] = RNIL;
- regCachePtr->lastAttrbuf = TfirstfreeAttrbuf;
- regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = Tlen;
- UintR Tdata1 = signal->theData[3];
- UintR Tdata2 = signal->theData[4];
- UintR Tdata3 = signal->theData[5];
- UintR Tdata4 = signal->theData[6];
- UintR Tdata5 = signal->theData[7];
- UintR Tdata6 = signal->theData[8];
- UintR Tdata7 = signal->theData[9];
- UintR Tdata8 = signal->theData[10];
- regAttrPtr->attrbuf[0] = Tdata1;
- regAttrPtr->attrbuf[1] = Tdata2;
- regAttrPtr->attrbuf[2] = Tdata3;
- regAttrPtr->attrbuf[3] = Tdata4;
- regAttrPtr->attrbuf[4] = Tdata5;
- regAttrPtr->attrbuf[5] = Tdata6;
- regAttrPtr->attrbuf[6] = Tdata7;
- regAttrPtr->attrbuf[7] = Tdata8;
- if (Tlen > 8) {
- Tdata1 = signal->theData[11];
- Tdata2 = signal->theData[12];
- Tdata3 = signal->theData[13];
- Tdata4 = signal->theData[14];
- Tdata5 = signal->theData[15];
- Tdata6 = signal->theData[16];
- Tdata7 = signal->theData[17];
- regAttrPtr->attrbuf[8] = Tdata1;
- regAttrPtr->attrbuf[9] = Tdata2;
- regAttrPtr->attrbuf[10] = Tdata3;
- regAttrPtr->attrbuf[11] = Tdata4;
- regAttrPtr->attrbuf[12] = Tdata5;
- regAttrPtr->attrbuf[13] = Tdata6;
- regAttrPtr->attrbuf[14] = Tdata7;
- jam();
- if (Tlen > 15) {
- Tdata1 = signal->theData[18];
- Tdata2 = signal->theData[19];
- Tdata3 = signal->theData[20];
- Tdata4 = signal->theData[21];
- Tdata5 = signal->theData[22];
- Tdata6 = signal->theData[23];
- Tdata7 = signal->theData[24];
- jam();
- regAttrPtr->attrbuf[15] = Tdata1;
- regAttrPtr->attrbuf[16] = Tdata2;
- regAttrPtr->attrbuf[17] = Tdata3;
- regAttrPtr->attrbuf[18] = Tdata4;
- regAttrPtr->attrbuf[19] = Tdata5;
- regAttrPtr->attrbuf[20] = Tdata6;
- regAttrPtr->attrbuf[21] = Tdata7;
- }//if
- }//if
- }//Dbtc::saveAttrbuf()
- void Dbtc::execATTRINFO(Signal* signal)
- {
- UintR compare_transid1, compare_transid2;
- UintR Tdata1 = signal->theData[0];
- UintR Tlength = signal->length();
- UintR TapiConnectFilesize = capiConnectFilesize;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- jamEntry();
- apiConnectptr.i = Tdata1;
- ttransid_ptr = 1;
- if (Tdata1 >= TapiConnectFilesize) {
- DEBUG("Drop ATTRINFO, wrong apiConnectptr");
- TCKEY_abort(signal, 18);
- return;
- }//if
- UintR Tdata2 = signal->theData[1];
- UintR Tdata3 = signal->theData[2];
- ApiConnectRecord * const regApiPtr = &localApiConnectRecord[Tdata1];
- compare_transid1 = regApiPtr->transid[0] ^ Tdata2;
- compare_transid2 = regApiPtr->transid[1] ^ Tdata3;
- apiConnectptr.p = regApiPtr;
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- DEBUG("Drop ATTRINFO, wrong transid, lenght="<<Tlength
- << " transid("<<hex<<Tdata2<<", "<<Tdata3);
- TCKEY_abort(signal, 19);
- return;
- }//if
- if (Tlength < 4) {
- DEBUG("Drop ATTRINFO, wrong length = " << Tlength);
- TCKEY_abort(signal, 20);
- return;
- }
- Tlength -= 3;
- UintR TcompREC_COMMIT = (regApiPtr->apiConnectstate == CS_REC_COMMITTING);
- UintR TcompRECEIVING = (regApiPtr->apiConnectstate == CS_RECEIVING);
- UintR TcompBOTH = TcompREC_COMMIT | TcompRECEIVING;
- if (TcompBOTH) {
- jam();
- if (ERROR_INSERTED(8015)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- if (ERROR_INSERTED(8016)) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- CacheRecord *localCacheRecord = cacheRecord;
- UintR TcacheFilesize = ccacheFilesize;
- UintR TcachePtr = regApiPtr->cachePtr;
- UintR TtcTimer = ctcTimer;
- CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
- if (TcachePtr >= TcacheFilesize) {
- TCKEY_abort(signal, 43);
- return;
- }//if
- UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
- UintR TcurrReclenAi = regCachePtr->currReclenAi;
- UintR TattrLen = regCachePtr->attrlength;
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- cachePtr.i = TcachePtr;
- cachePtr.p = regCachePtr;
- TcurrReclenAi = TcurrReclenAi + Tlength;
- regCachePtr->currReclenAi = TcurrReclenAi;
- int TattrlengthRemain = TattrLen - TcurrReclenAi;
- if (TfirstfreeAttrbuf == RNIL) {
- DEBUG("No more attrinfo buffers");
- TCKEY_abort(signal, 24);
- return;
- }//if
- saveAttrbuf(signal);
- if (TattrlengthRemain == 0) {
- /****************************************************************>*/
- /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS */
- /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
- /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
- /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER */
- /* OPERATIONS. */
- /****************************************************************>*/
- UintR TlastConnect = regApiPtr->lastTcConnect;
- if (TcompRECEIVING) {
- jam();
- regApiPtr->apiConnectstate = CS_STARTED;
- } else {
- jam();
- regApiPtr->apiConnectstate = CS_START_COMMITTING;
- }//if
- tcConnectptr.i = TlastConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- attrinfoDihReceivedLab(signal);
- } else if (TattrlengthRemain < 0) {
- jam();
- DEBUG("ATTRINFO wrong total length="<<Tlength
- <<", TattrlengthRemain="<<TattrlengthRemain
- <<", TattrLen="<<TattrLen
- <<", TcurrReclenAi="<<TcurrReclenAi);
- tcConnectptr.i = regApiPtr->lastTcConnect;
- ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
- aiErrorLab(signal);
- }//if
- return;
- } else if (regApiPtr->apiConnectstate == CS_START_SCAN) {
- jam();
- scanAttrinfoLab(signal, Tlength);
- return;
- } else {
- switch (regApiPtr->apiConnectstate) {
- case CS_ABORTING:
- jam();
- /* JUST IGNORE THE SIGNAL*/
- // DEBUG("Drop ATTRINFO, CS_ABORTING");
- return;
- case CS_CONNECTED:
- jam();
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL.*/
- // DEBUG("Drop ATTRINFO, CS_CONNECTED");
- return;
- case CS_STARTED:
- jam();
- /****************************************************************>*/
- /* MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND */
- /* SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED */
- /* WE ALSO NEED TO ABORT THIS TRANSACTION. */
- /****************************************************************>*/
- terrorCode = ZSIGNAL_ERROR;
- printState(signal, 1);
- abortErrorLab(signal);
- return;
- default:
- jam();
- /****************************************************************>*/
- /* SIGNAL RECEIVED IN AN UNEXPECTED STATE. WE IGNORE SIGNAL */
- /* SINCE WE DO NOT REALLY KNOW WHERE THE ERROR OCCURRED. */
- /****************************************************************>*/
- DEBUG("Drop ATTRINFO, illegal state="<<regApiPtr->apiConnectstate);
- printState(signal, 9);
- return;
- }//switch
- }//if
- }//Dbtc::execATTRINFO()
- /* *********************************************************************>> */
- /* */
- /* MODULE: HASH MODULE */
- /* DESCRIPTION: CONTAINS THE HASH VALUE CALCULATION */
- /* *********************************************************************> */
- void Dbtc::hash(Signal* signal)
- {
- DatabufRecordPtr locDatabufptr;
- UintR ti;
- UintR Tdata0;
- UintR Tdata1;
- UintR Tdata2;
- UintR Tdata3;
- UintR* Tdata32;
- Uint64 Tdata[512];
- CacheRecord * const regCachePtr = cachePtr.p;
- Tdata32 = (UintR*)&Tdata[0];
- Tdata0 = regCachePtr->keydata[0];
- Tdata1 = regCachePtr->keydata[1];
- Tdata2 = regCachePtr->keydata[2];
- Tdata3 = regCachePtr->keydata[3];
- Tdata32[0] = Tdata0;
- Tdata32[1] = Tdata1;
- Tdata32[2] = Tdata2;
- Tdata32[3] = Tdata3;
- if (regCachePtr->keylen > 4) {
- locDatabufptr.i = regCachePtr->firstKeybuf;
- ti = 4;
- while (locDatabufptr.i != RNIL) {
- ptrCheckGuard(locDatabufptr, cdatabufFilesize, databufRecord);
- Tdata0 = locDatabufptr.p->data[0];
- Tdata1 = locDatabufptr.p->data[1];
- Tdata2 = locDatabufptr.p->data[2];
- Tdata3 = locDatabufptr.p->data[3];
- Tdata32[ti ] = Tdata0;
- Tdata32[ti + 1] = Tdata1;
- Tdata32[ti + 2] = Tdata2;
- Tdata32[ti + 3] = Tdata3;
- locDatabufptr.i = locDatabufptr.p->nextDatabuf;
- ti += 4;
- }//while
- }//if
- UintR ThashValue;
- UintR TdistrHashValue;
- ThashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen);
- if (regCachePtr->distributionGroupIndicator == 1) {
- if (regCachePtr->distributionGroupType == 1) {
- jam();
- TdistrHashValue = (regCachePtr->distributionGroup << 6);
- } else {
- jam();
- Tdata32[0] = regCachePtr->distributionGroup;
- TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)1);
- }//if
- } else if (regCachePtr->distributionKeyIndicator == 1) {
- jam();
- TdistrHashValue = md5_hash((Uint64*)&Tdata32[0],
- (UintR)regCachePtr->distributionKeySize);
- } else {
- jam();
- TdistrHashValue = ThashValue;
- }//if
- thashValue = ThashValue;
- tdistrHashValue = TdistrHashValue;
- }//Dbtc::hash()
- /*
- INIT_API_CONNECT_REC
- ---------------------------
- */
- /* ========================================================================= */
- /* ======= INIT_API_CONNECT_REC ======= */
- /* */
- /* ========================================================================= */
- void Dbtc::initApiConnectRec(Signal* signal,
- ApiConnectRecord * const regApiPtr,
- bool releaseIndexOperations)
- {
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
- UintR TfailureNr = cfailure_nr;
- UintR TtransCount = c_counters.ctransCount;
- UintR Ttransid0 = tcKeyReq->transId1;
- UintR Ttransid1 = tcKeyReq->transId2;
- regApiPtr->m_exec_flag = 0;
- regApiPtr->returncode = 0;
- regApiPtr->returnsignal = RS_TCKEYCONF;
- ndbassert(regApiPtr->firstTcConnect == RNIL);
- regApiPtr->firstTcConnect = RNIL;
- regApiPtr->lastTcConnect = RNIL;
- regApiPtr->globalcheckpointid = 0;
- regApiPtr->lqhkeyconfrec = 0;
- regApiPtr->lqhkeyreqrec = 0;
- regApiPtr->tckeyrec = 0;
- regApiPtr->tcindxrec = 0;
- regApiPtr->failureNr = TfailureNr;
- regApiPtr->transid[0] = Ttransid0;
- regApiPtr->transid[1] = Ttransid1;
- regApiPtr->commitAckMarker = RNIL;
- regApiPtr->buddyPtr = RNIL;
- regApiPtr->currSavePointId = 0;
- // Trigger data
- releaseFiredTriggerData(®ApiPtr->theFiredTriggers),
- // Index data
- regApiPtr->indexOpReturn = false;
- regApiPtr->noIndexOp = 0;
- if(releaseIndexOperations)
- releaseAllSeizedIndexOperations(regApiPtr);
- c_counters.ctransCount = TtransCount + 1;
- }//Dbtc::initApiConnectRec()
- int
- Dbtc::seizeTcRecord(Signal* signal)
- {
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- TcConnectRecord *localTcConnectRecord = tcConnectRecord;
- UintR TfirstfreeTcConnect = cfirstfreeTcConnect;
- UintR TtcConnectFilesize = ctcConnectFilesize;
- tcConnectptr.i = TfirstfreeTcConnect;
- if (TfirstfreeTcConnect >= TtcConnectFilesize) {
- int place = 3;
- if (TfirstfreeTcConnect != RNIL) {
- place = 10;
- }//if
- TCKEY_abort(signal, place);
- return 1;
- }//if
- //--------------------------------------------------------------------------
- // Optimised version of ptrAss(tcConnectptr, tcConnectRecord)
- //--------------------------------------------------------------------------
- TcConnectRecord * const regTcPtr =
- &localTcConnectRecord[TfirstfreeTcConnect];
- UintR TconcurrentOp = c_counters.cconcurrentOp;
- UintR TlastTcConnect = regApiPtr->lastTcConnect;
- UintR TtcConnectptrIndex = tcConnectptr.i;
- TcConnectRecordPtr tmpTcConnectptr;
- cfirstfreeTcConnect = regTcPtr->nextTcConnect;
- tcConnectptr.p = regTcPtr;
- c_counters.cconcurrentOp = TconcurrentOp + 1;
- regTcPtr->prevTcConnect = TlastTcConnect;
- regTcPtr->nextTcConnect = RNIL;
- regTcPtr->accumulatingTriggerData.i = RNIL;
- regTcPtr->accumulatingTriggerData.p = NULL;
- regTcPtr->noFiredTriggers = 0;
- regTcPtr->noReceivedTriggers = 0;
- regTcPtr->triggerExecutionCount = 0;
- regTcPtr->triggeringOperation = RNIL;
- regTcPtr->isIndexOp = false;
- regTcPtr->indexOp = RNIL;
- regTcPtr->currentIndexId = RNIL;
- regApiPtr->lastTcConnect = TtcConnectptrIndex;
- if (TlastTcConnect == RNIL) {
- jam();
- regApiPtr->firstTcConnect = TtcConnectptrIndex;
- } else {
- tmpTcConnectptr.i = TlastTcConnect;
- jam();
- ptrCheckGuard(tmpTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
- tmpTcConnectptr.p->nextTcConnect = TtcConnectptrIndex;
- }//if
- return 0;
- }//Dbtc::seizeTcRecord()
- int
- Dbtc::seizeCacheRecord(Signal* signal)
- {
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TfirstfreeCacheRec = cfirstfreeCacheRec;
- UintR TcacheFilesize = ccacheFilesize;
- CacheRecord *localCacheRecord = cacheRecord;
- if (TfirstfreeCacheRec >= TcacheFilesize) {
- TCKEY_abort(signal, 41);
- return 1;
- }//if
- CacheRecord * const regCachePtr = &localCacheRecord[TfirstfreeCacheRec];
- regApiPtr->cachePtr = TfirstfreeCacheRec;
- cfirstfreeCacheRec = regCachePtr->nextCacheRec;
- cachePtr.i = TfirstfreeCacheRec;
- cachePtr.p = regCachePtr;
- #ifdef VM_TRACE
- // This is a good place to check that resources have
- // been properly released from CacheRecord
- ndbrequire(regCachePtr->firstKeybuf == RNIL);
- ndbrequire(regCachePtr->lastKeybuf == RNIL);
- #endif
- regCachePtr->firstKeybuf = RNIL;
- regCachePtr->lastKeybuf = RNIL;
- regCachePtr->firstAttrbuf = RNIL;
- regCachePtr->lastAttrbuf = RNIL;
- regCachePtr->currReclenAi = 0;
- return 0;
- }//Dbtc::seizeCacheRecord()
- /*****************************************************************************/
- /* T C K E Y R E Q */
- /* AFTER HAVING ESTABLISHED THE CONNECT, THE APPLICATION BLOCK SENDS AN */
- /* OPERATION REQUEST TO TC. ALL NECESSARY INFORMATION TO CARRY OUT REQUEST */
- /* IS FURNISHED IN PARAMETERS. TC STORES THIS INFORMATION AND ENQUIRES */
- /* FROM DIH ABOUT THE NODES WHICH MAY HAVE THE REQUESTED DATA */
- /*****************************************************************************/
- void Dbtc::execTCKEYREQ(Signal* signal)
- {
- UintR compare_transid1, compare_transid2;
- UintR titcLenAiInTckeyreq;
- UintR TkeyLength;
- const TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtr();
- UintR Treqinfo;
- jamEntry();
- /*-------------------------------------------------------------------------
- * Common error routines are used for several signals, they need to know
- * where to find the transaction identifier in the signal.
- *-------------------------------------------------------------------------*/
- const UintR TapiIndex = tcKeyReq->apiConnectPtr;
- const UintR TapiMaxIndex = capiConnectFilesize;
- const UintR TtabIndex = tcKeyReq->tableId;
- const UintR TtabMaxIndex = ctabrecFilesize;
- ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
- ttransid_ptr = 6;
- apiConnectptr.i = TapiIndex;
- if (TapiIndex >= TapiMaxIndex) {
- TCKEY_abort(signal, 6);
- return;
- }//if
- if (TtabIndex >= TtabMaxIndex) {
- TCKEY_abort(signal, 7);
- return;
- }//if
- Treqinfo = tcKeyReq->requestInfo;
- //--------------------------------------------------------------------------
- // Optimised version of ptrAss(tabptr, tableRecord)
- // Optimised version of ptrAss(apiConnectptr, apiConnectRecord)
- //--------------------------------------------------------------------------
- ApiConnectRecord * const regApiPtr = &localApiConnectRecord[TapiIndex];
- apiConnectptr.p = regApiPtr;
- Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo);
- Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
- bool isIndexOp = regApiPtr->isIndexOp;
- bool isIndexOpReturn = regApiPtr->indexOpReturn;
- regApiPtr->isIndexOp = false; // Reset marker
- regApiPtr->m_exec_flag |= TexecFlag;
- switch (regApiPtr->apiConnectstate) {
- case CS_CONNECTED:{
- if (TstartFlag == 1 && getAllowStartTransaction() == true){
- //---------------------------------------------------------------------
- // Initialise API connect record if transaction is started.
- //---------------------------------------------------------------------
- jam();
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else {
- if(getAllowStartTransaction() == true){
- /*------------------------------------------------------------------
- * WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN
- * RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO
- * ENSURE PROPER OPERATION OF THE COMMON ABORT HANDLING.
- *-----------------------------------------------------------------*/
- TCKEY_abort(signal, 0);
- return;
- } else {
- /**
- * getAllowStartTransaction() == false
- */
- TCKEY_abort(signal, 57);
- return;
- }//if
- }
- }
- break;
- case CS_STARTED:
- if(TstartFlag == 1 && regApiPtr->firstTcConnect == RNIL)
- {
- /**
- * If last operation in last transaction was a simple/dirty read
- * it does not have to be committed or rollbacked hence,
- * the state will be CS_STARTED
- */
- jam();
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else {
- //----------------------------------------------------------------------
- // Transaction is started already.
- // Check that the operation is on the same transaction.
- //-----------------------------------------------------------------------
- compare_transid1 = regApiPtr->transid[0] ^ tcKeyReq->transId1;
- compare_transid2 = regApiPtr->transid[1] ^ tcKeyReq->transId2;
- jam();
- compare_transid1 = compare_transid1 | compare_transid2;
- if (compare_transid1 != 0) {
- TCKEY_abort(signal, 1);
- return;
- }//if
- }
- break;
- case CS_ABORTING:
- if (regApiPtr->abortState == AS_IDLE) {
- if (TstartFlag == 1) {
- //--------------------------------------------------------------------
- // Previous transaction had been aborted and the abort was completed.
- // It is then OK to start a new transaction again.
- //--------------------------------------------------------------------
- jam();
- initApiConnectRec(signal, regApiPtr);
- regApiPtr->m_exec_flag = TexecFlag;
- } else if(TexecFlag) {
- TCKEY_abort(signal, 59);
- return;
- } else {
- //--------------------------------------------------------------------
- // The current transaction was aborted successfully.
- // We will not do anything before we receive an operation
- // with a start indicator. We will ignore this signal.
- //--------------------------------------------------------------------
- jam();
- DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, ==AS_IDLE");
- return;
- }//if
- } else {
- //----------------------------------------------------------------------
- // Previous transaction is still aborting
- //----------------------------------------------------------------------
- jam();
- if (TstartFlag == 1) {
- //--------------------------------------------------------------------
- // If a new transaction tries to start while the old is
- // still aborting, we will report this to the starting API.
- //--------------------------------------------------------------------
- TCKEY_abort(signal, 2);
- return;
- } else if(TexecFlag) {
- TCKEY_abort(signal, 59);
- return;
- }
- //----------------------------------------------------------------------
- // Ignore signals without start indicator set when aborting transaction.
- //----------------------------------------------------------------------
- DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, !=AS_IDLE");
- return;
- }//if
- break;
- case CS_START_COMMITTING:
- jam();
- if(isIndexOpReturn || TcKeyReq::getExecutingTrigger(Treqinfo)){
- break;
- }
- default:
- jam();
- /*----------------------------------------------------------------------
- * IN THIS CASE THE NDBAPI IS AN UNTRUSTED ENTITY THAT HAS SENT A SIGNAL
- * WHEN IT WAS NOT EXPECTED TO.
- * WE MIGHT BE IN A PROCESS TO RECEIVE, PREPARE,
- * COMMIT OR COMPLETE AND OBVIOUSLY THIS IS NOT A DESIRED EVENT.
- * WE WILL ALWAYS COMPLETE THE ABORT HANDLING BEFORE WE ALLOW
- * ANYTHING TO HAPPEN ON THIS CONNECTION AGAIN.
- * THUS THERE IS NO ACTION FROM THE API THAT CAN SPEED UP THIS PROCESS.
- *---------------------------------------------------------------------*/
- TCKEY_abort(signal, 55);
- return;
- }//switch
-
- TableRecordPtr localTabptr;
- localTabptr.i = TtabIndex;
- localTabptr.p = &tableRecord[TtabIndex];
- if (localTabptr.p->checkTable(tcKeyReq->tableSchemaVersion)) {
- ;
- } else {
- /*-----------------------------------------------------------------------*/
- /* THE API IS WORKING WITH AN OLD SCHEMA VERSION. IT NEEDS REPLACEMENT. */
- /* COULD ALSO BE THAT THE TABLE IS NOT DEFINED. */
- /*-----------------------------------------------------------------------*/
- TCKEY_abort(signal, 8);
- return;
- }//if
-
- //-------------------------------------------------------------------------
- // Error Insertion for testing purposes. Test to see what happens when no
- // more TC records available.
- //-------------------------------------------------------------------------
- if (ERROR_INSERTED(8032)) {
- TCKEY_abort(signal, 3);
- return;
- }//if
-
- if (seizeTcRecord(signal) != 0) {
- return;
- }//if
-
- if (seizeCacheRecord(signal) != 0) {
- return;
- }//if
-
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- CacheRecord * const regCachePtr = cachePtr.p;
- /*
- INIT_TC_CONNECT_REC
- -------------------------
- */
- /* ---------------------------------------------------------------------- */
- /* ------- INIT OPERATION RECORD WITH SIGNAL DATA AND RNILS ------- */
- /* */
- /* ---------------------------------------------------------------------- */
- UintR TapiVersionNo = tcKeyReq->getAPIVersion(tcKeyReq->attrLen);
- UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec;
- regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec + 1;
- regCachePtr->apiVersionNo = TapiVersionNo;
- UintR TapiConnectptrIndex = apiConnectptr.i;
- UintR TsenderData = tcKeyReq->senderData;
- UintR TattrLen = tcKeyReq->getAttrinfoLen(tcKeyReq->attrLen);
- UintR TattrinfoCount = c_counters.cattrinfoCount;
- regTcPtr->apiConnect = TapiConnectptrIndex;
- regTcPtr->clientData = TsenderData;
- regTcPtr->commitAckMarker = RNIL;
- regTcPtr->isIndexOp = isIndexOp;
- regTcPtr->indexOp = regApiPtr->executingIndexOp;
- regTcPtr->savePointId = regApiPtr->currSavePointId;
- regApiPtr->executingIndexOp = RNIL;
- if (TcKeyReq::getExecutingTrigger(Treqinfo)) {
- // Save the TcOperationPtr for fireing operation
- regTcPtr->triggeringOperation = TsenderData;
- }
- if (TexecFlag){
- Uint32 currSPId = regApiPtr->currSavePointId;
- regApiPtr->currSavePointId = ++currSPId;
- }
- regCachePtr->attrlength = TattrLen;
- c_counters.cattrinfoCount = TattrinfoCount + TattrLen;
- UintR TtabptrIndex = localTabptr.i;
- UintR TtableSchemaVersion = tcKeyReq->tableSchemaVersion;
- Uint8 TOperationType = tcKeyReq->getOperationType(Treqinfo);
- regCachePtr->tableref = TtabptrIndex;
- regCachePtr->schemaVersion = TtableSchemaVersion;
- regTcPtr->operation = TOperationType;
- Uint8 TSimpleFlag = tcKeyReq->getSimpleFlag(Treqinfo);
- Uint8 TDirtyFlag = tcKeyReq->getDirtyFlag(Treqinfo);
- Uint8 TInterpretedFlag = tcKeyReq->getInterpretedFlag(Treqinfo);
- Uint8 TDistrGroupFlag = tcKeyReq->getDistributionGroupFlag(Treqinfo);
- Uint8 TDistrGroupTypeFlag = tcKeyReq->getDistributionGroupTypeFlag(Treqinfo);
- Uint8 TDistrKeyFlag = tcKeyReq->getDistributionKeyFlag(Treqinfo);
- Uint8 TexecuteFlag = TexecFlag;
-
- regCachePtr->opSimple = TSimpleFlag;
- regCachePtr->opExec = TInterpretedFlag;
- regTcPtr->dirtyOp = TDirtyFlag;
- regCachePtr->distributionGroupIndicator = TDistrGroupFlag;
- regCachePtr->distributionGroupType = TDistrGroupTypeFlag;
- regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
- //-------------------------------------------------------------
- // The next step is to read the upto three conditional words.
- //-------------------------------------------------------------
- Uint32 TkeyIndex;
- Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
- {
- Uint32 TDistrGHIndex = tcKeyReq->getScanIndFlag(Treqinfo);
- Uint32 TDistrKeyIndex = TDistrGHIndex + TDistrGroupFlag;
- Uint32 TscanNode = tcKeyReq->getTakeOverScanNode(TOptionalDataPtr[0]);
- Uint32 TscanInfo = tcKeyReq->getTakeOverScanInfo(TOptionalDataPtr[0]);
- regCachePtr->scanTakeOverInd = TDistrGHIndex;
- regCachePtr->scanNode = TscanNode;
- regCachePtr->scanInfo = TscanInfo;
- regCachePtr->distributionGroup = TOptionalDataPtr[TDistrGHIndex];
- regCachePtr->distributionKeySize = TOptionalDataPtr[TDistrKeyIndex];
- TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
- }
- Uint32* TkeyDataPtr = &TOptionalDataPtr[TkeyIndex];
- UintR Tdata1 = TkeyDataPtr[0];
- UintR Tdata2 = TkeyDataPtr[1];
- UintR Tdata3 = TkeyDataPtr[2];
- UintR Tdata4 = TkeyDataPtr[3];
- UintR Tdata5;
- regCachePtr->keydata[0] = Tdata1;
- regCachePtr->keydata[1] = Tdata2;
- regCachePtr->keydata[2] = Tdata3;
- regCachePtr->keydata[3] = Tdata4;
- TkeyLength = tcKeyReq->getKeyLength(Treqinfo);
- Uint32 TAIDataIndex;
- if (TkeyLength > 8) {
- TAIDataIndex = TkeyIndex + 8;
- } else {
- if (TkeyLength == 0) {
- TCKEY_abort(signal, 4);
- return;
- }//if
- TAIDataIndex = TkeyIndex + TkeyLength;
- }//if
- Uint32* TAIDataPtr = &TOptionalDataPtr[TAIDataIndex];
- titcLenAiInTckeyreq = tcKeyReq->getAIInTcKeyReq(Treqinfo);
- regCachePtr->keylen = TkeyLength;
- regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq;
- regCachePtr->currReclenAi = titcLenAiInTckeyreq;
- Tdata1 = TAIDataPtr[0];
- Tdata2 = TAIDataPtr[1];
- Tdata3 = TAIDataPtr[2];
- Tdata4 = TAIDataPtr[3];
- Tdata5 = TAIDataPtr[4];
- regCachePtr->attrinfo0 = Tdata1;
- regCachePtr->attrinfo15[0] = Tdata2;
- regCachePtr->attrinfo15[1] = Tdata3;
- regCachePtr->attrinfo15[2] = Tdata4;
- regCachePtr->attrinfo15[3] = Tdata5;
- if (TOperationType == ZREAD) {
- Uint32 TreadCount = c_counters.creadCount;
- jam();
- regCachePtr->opLock = 0;
- c_counters.creadCount = TreadCount + 1;
- } else if(TOperationType == ZREAD_EX){
- Uint32 TreadCount = c_counters.creadCount;
- jam();
- TOperationType = ZREAD;
- regTcPtr->operation = ZREAD;
- regCachePtr->opLock = ZUPDATE;
- c_counters.creadCount = TreadCount + 1;
- } else {
- if(regApiPtr->commitAckMarker == RNIL){
- jam();
- CommitAckMarkerPtr tmp;
- if(!m_commitAckMarkerHash.seize(tmp)){
- TCKEY_abort(signal, 56);
- return;
- } else {
- regTcPtr->commitAckMarker = tmp.i;
- regApiPtr->commitAckMarker = tmp.i;
- tmp.p->transid1 = tcKeyReq->transId1;
- tmp.p->transid2 = tcKeyReq->transId2;
- tmp.p->apiNodeId = refToNode(regApiPtr->ndbapiBlockref);
- tmp.p->apiConnectPtr = TapiIndex;
- tmp.p->noOfLqhs = 0;
- m_commitAckMarkerHash.add(tmp);
- }
- }
-
- UintR TwriteCount = c_counters.cwriteCount;
- UintR Toperationsize = coperationsize;
- /* --------------------------------------------------------------------
- * THIS IS A TEMPORARY TABLE, DON'T UPDATE coperationsize.
- * THIS VARIABLE CONTROLS THE INTERVAL BETWEEN LCP'S AND
- * TEMP TABLES DON'T PARTICIPATE.
- * -------------------------------------------------------------------- */
- if (localTabptr.p->storedTable) {
- coperationsize = ((Toperationsize + TattrLen) + TkeyLength) + 17;
- }
- c_counters.cwriteCount = TwriteCount + 1;
- switch (TOperationType) {
- case ZUPDATE:
- jam();
- if (TattrLen == 0) {
- //TCKEY_abort(signal, 5);
- //return;
- }//if
- /*---------------------------------------------------------------------*/
- // The missing break is intentional since we also want to set the opLock
- // variable also for updates
- /*---------------------------------------------------------------------*/
- case ZINSERT:
- case ZDELETE:
- jam();
- regCachePtr->opLock = TOperationType;
- break;
- case ZWRITE:
- jam();
- // A write operation is originally an insert operation.
- regCachePtr->opLock = ZINSERT;
- break;
- default:
- TCKEY_abort(signal, 9);
- return;
- }//switch
- }//if
-
- Uint32 TabortOption = tcKeyReq->getAbortOption(Treqinfo);
- regTcPtr->m_execAbortOption = TabortOption;
-
- /*-------------------------------------------------------------------------
- * Check error handling per operation
- * If CommitFlag is set state accordingly and check for early abort
- *------------------------------------------------------------------------*/
- if (tcKeyReq->getCommitFlag(Treqinfo) == 1) {
- ndbrequire(TexecuteFlag);
- regApiPtr->apiConnectstate = CS_REC_COMMITTING;
- } else {
- /* ---------------------------------------------------------------------
- * PREPARE TRANSACTION IS NOT IMPLEMENTED YET.
- * ---------------------------------------------------------------------
- * ELSIF (TREQINFO => 3) (*) 1 = 1 THEN
- * IF PREPARE TRANSACTION THEN
- * API_CONNECTPTR:API_CONNECTSTATE = REC_PREPARING
- * SET STATE TO PREPARING
- * --------------------------------------------------------------------- */
- if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
- jam();
- // Trigger execution at commit
- regApiPtr->apiConnectstate = CS_REC_COMMITTING;
- } else {
- jam();
- regApiPtr->apiConnectstate = CS_RECEIVING;
- }//if
- }//if
- if (TkeyLength <= 4) {
- tckeyreq050Lab(signal);
- return;
- } else {
- if (cfirstfreeDatabuf != RNIL) {
- jam();
- linkKeybuf(signal);
- Tdata1 = TkeyDataPtr[4];
- Tdata2 = TkeyDataPtr[5];
- Tdata3 = TkeyDataPtr[6];
- Tdata4 = TkeyDataPtr[7];
- DatabufRecord * const regDataPtr = databufptr.p;
- regDataPtr->data[0] = Tdata1;
- regDataPtr->data[1] = Tdata2;
- regDataPtr->data[2] = Tdata3;
- regDataPtr->data[3] = Tdata4;
- } else {
- jam();
- seizeDatabuferrorLab(signal);
- return;
- }//if
- if (TkeyLength <= 8) {
- jam();
- tckeyreq050Lab(signal);
- return;
- } else {
- jam();
- /* --------------------------------------------------------------------
- * THE TCKEYREQ DIDN'T CONTAIN ALL KEY DATA,
- * SAVE STATE AND WAIT FOR KEYINFO
- * --------------------------------------------------------------------*/
- setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
- regCachePtr->save1 = 8;
- regTcPtr->tcConnectstate = OS_WAIT_KEYINFO;
- return;
- }//if
- }//if
- return;
- }//Dbtc::execTCKEYREQ()
- void Dbtc::tckeyreq050Lab(Signal* signal)
- {
- UintR tnoOfBackup;
- UintR tnoOfStandby;
- UintR tnodeinfo;
- hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
- CacheRecord * const regCachePtr = cachePtr.p;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- UintR TtcTimer = ctcTimer;
- UintR ThashValue = thashValue;
- UintR TdistrHashValue = tdistrHashValue;
- UintR TdihConnectptr = regTcPtr->dihConnectptr;
- UintR Ttableref = regCachePtr->tableref;
-
- TableRecordPtr localTabptr;
- localTabptr.i = Ttableref;
- localTabptr.p = &tableRecord[localTabptr.i];
- Uint32 schemaVersion = regCachePtr->schemaVersion;
- if(localTabptr.p->checkTable(schemaVersion)){
- ;
- } else {
- terrorCode = localTabptr.p->getErrorCode(schemaVersion);
- TCKEY_abort(signal, 58);
- return;
- }
-
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- regCachePtr->hashValue = ThashValue;
- signal->theData[0] = TdihConnectptr;
- signal->theData[1] = Ttableref;
- signal->theData[2] = TdistrHashValue;
- /*-------------------------------------------------------------*/
- /* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
- /* PROCEED IMMEDIATELY TO DIH. IN MULTI-THREADED VERSIONS WE */
- /* HAVE TO INSERT A MUTEX ON DIH TO ENSURE PROPER OPERATION. */
- /* SINCE THIS SIGNAL AND DIVERIFYREQ ARE THE ONLY SIGNALS SENT */
- /* TO DIH IN TRAFFIC IT SHOULD BE OK (3% OF THE EXECUTION TIME */
- /* IS SPENT IN DIH AND EVEN LESS IN REPLICATED NDB. */
- /*-------------------------------------------------------------*/
- EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
- UintR TerrorIndicator = signal->theData[0];
- jamEntry();
- if (TerrorIndicator != 0) {
- execDIGETNODESREF(signal);
- return;
- }
- /****************>>*/
- /* DIGETNODESCONF >*/
- /* ***************>*/
- UintR Tdata1 = signal->theData[1];
- UintR Tdata2 = signal->theData[2];
- UintR Tdata3 = signal->theData[3];
- UintR Tdata4 = signal->theData[4];
- UintR Tdata5 = signal->theData[5];
- UintR Tdata6 = signal->theData[6];
- regCachePtr->fragmentid = Tdata1;
- tnodeinfo = Tdata2;
- regTcPtr->tcNodedata[0] = Tdata3;
- regTcPtr->tcNodedata[1] = Tdata4;
- regTcPtr->tcNodedata[2] = Tdata5;
- regTcPtr->tcNodedata[3] = Tdata6;
- Uint8 Toperation = regTcPtr->operation;
- Uint8 Tdirty = regTcPtr->dirtyOp;
- tnoOfBackup = tnodeinfo & 3;
- tnoOfStandby = (tnodeinfo >> 8) & 3;
-
- regCachePtr->distributionKey = (tnodeinfo >> 16) & 255;
- if (Toperation == ZREAD) {
- if (Tdirty == 1) {
- jam();
- /*-------------------------------------------------------------*/
- /* A SIMPLE READ CAN SELECT ANY OF THE PRIMARY AND */
- /* BACKUP NODES TO READ. WE WILL TRY TO SELECT THIS */
- /* NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION */
- /* WITH SIMPLE READS. */
- /*-------------------------------------------------------------*/
- arrGuard(tnoOfBackup, 4);
- UintR Tindex;
- UintR TownNode = cownNodeid;
- for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) {
- UintR Tnode = regTcPtr->tcNodedata[Tindex];
- jam();
- if (Tnode == TownNode) {
- jam();
- regTcPtr->tcNodedata[0] = Tnode;
- }//if
- }//for
- if(ERROR_INSERTED(8048) || ERROR_INSERTED(8049))
- {
- for (Tindex = 0; Tindex <= tnoOfBackup; Tindex++)
- {
- UintR Tnode = regTcPtr->tcNodedata[Tindex];
- jam();
- if (Tnode != TownNode) {
- jam();
- regTcPtr->tcNodedata[0] = Tnode;
- ndbout_c("Choosing %d", Tnode);
- }//if
- }//for
- }
- }//if
- jam();
- regTcPtr->lastReplicaNo = 0;
- regTcPtr->noOfNodes = 1;
- } else {
- UintR TlastReplicaNo;
- jam();
- TlastReplicaNo = tnoOfBackup + tnoOfStandby;
- regTcPtr->lastReplicaNo = (Uint8)TlastReplicaNo;
- regTcPtr->noOfNodes = (Uint8)(TlastReplicaNo + 1);
- }//if
- if (regCachePtr->lenAiInTckeyreq == regCachePtr->attrlength) {
- /****************************************************************>*/
- /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS */
- /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
- /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
- /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER */
- /* OPERATIONS. WE KNOW THAT WE WILL WAIT FOR DICT NEXT. IT IS NOT */
- /* POSSIBLE FOR THE TC CONNECTION TO BE READY YET. */
- /****************************************************************>*/
- switch (regApiPtr->apiConnectstate) {
- case CS_RECEIVING:
- jam();
- regApiPtr->apiConnectstate = CS_STARTED;
- break;
- case CS_REC_COMMITTING:
- jam();
- regApiPtr->apiConnectstate = CS_START_COMMITTING;
- break;
- default:
- jam();
- systemErrorLab(signal);
- return;
- }//switch
- attrinfoDihReceivedLab(signal);
- return;
- } else {
- if (regCachePtr->lenAiInTckeyreq < regCachePtr->attrlength) {
- TtcTimer = ctcTimer;
- jam();
- setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
- regTcPtr->tcConnectstate = OS_WAIT_ATTR;
- return;
- } else {
- TCKEY_abort(signal, 11);
- return;
- }//if
- }//if
- return;
- }//Dbtc::tckeyreq050Lab()
- void Dbtc::attrinfoDihReceivedLab(Signal* signal)
- {
- CacheRecord * const regCachePtr = cachePtr.p;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- Uint16 Tnode = regTcPtr->tcNodedata[0];
- Uint16 TscanTakeOverInd = regCachePtr->scanTakeOverInd;
- Uint16 TscanNode = regCachePtr->scanNode;
- TableRecordPtr localTabptr;
- localTabptr.i = regCachePtr->tableref;
- localTabptr.p = &tableRecord[localTabptr.i];
- if(localTabptr.p->checkTable(regCachePtr->schemaVersion)){
- ;
- } else {
- terrorCode = localTabptr.p->getErrorCode(regCachePtr->schemaVersion);
- TCKEY_abort(signal, 58);
- return;
- }
- if ((TscanTakeOverInd == 1) &&
- (Tnode != TscanNode)) {
- TCKEY_abort(signal, 15);
- return;
- }//if
- arrGuard(Tnode, MAX_NDB_NODES);
- packLqhkeyreq(signal, calcLqhBlockRef(Tnode));
- }//Dbtc::attrinfoDihReceivedLab()
- void Dbtc::packLqhkeyreq(Signal* signal,
- BlockReference TBRef)
- {
- CacheRecord * const regCachePtr = cachePtr.p;
- UintR Tkeylen = regCachePtr->keylen;
- UintR TfirstAttrbuf = regCachePtr->firstAttrbuf;
- sendlqhkeyreq(signal, TBRef);
- if (Tkeylen > 4) {
- packKeyData000Lab(signal, TBRef, Tkeylen - 4);
- releaseKeys();
- }//if
- packLqhkeyreq040Lab(signal,
- TfirstAttrbuf,
- TBRef);
- }//Dbtc::packLqhkeyreq()
- void Dbtc::sendlqhkeyreq(Signal* signal,
- BlockReference TBRef)
- {
- UintR tslrAttrLen;
- UintR Tdata10;
- TcConnectRecord * const regTcPtr = tcConnectptr.p;
- ApiConnectRecord * const regApiPtr = apiConnectptr.p;
- CacheRecord * const regCachePtr = cachePtr.p;
- #ifdef ERROR_INSERT
- if (ERROR_INSERTED(8002)) {
- systemErrorLab(signal);
- }//if
- if (ERROR_INSERTED(8007)) {
- if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8008)) {
- if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
- CLEAR_ERROR_INSERT_VALUE;
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8009)) {
- if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
- return;
- }//if
- }//if
- if (ERROR_INSERTED(8010)) {
- if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
- return;
- }//if
- }//if
- #endif
- tslrAttrLen = 0;
- LqhKeyReq::setAttrLen(tslrAttrLen, regCachePtr->attrlength);
- /* ---------------------------------------------------------------------- */
- // Bit16 == 0 since StoredProcedures are not yet supported.
- /* ---------------------------------------------------------------------- */
- LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->distributionKey);
- LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
- Tdata10 = 0;
- LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
- LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
- LqhKeyReq::setLockType(Tdata10, regCachePtr->opLock);
- /* ---------------------------------------------------------------------- */
- // Indicate Application Reference is present in bit 15
- /* ---------------------------------------------------------------------- */
- LqhKeyReq::setApplicationAddressFlag(Tdata10, 1);
- LqhKeyReq::setDirtyFlag(Tdata10, regTcPtr->dirtyOp);
- LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
- LqhKeyReq::setSimpleFlag(Tdata10, regCachePtr->opSimple);
- LqhKeyReq::setOperation(Tdata10, regTcPtr->operation);
- /* -----------------------------------------------------------------------
- * Sequential Number of first LQH = 0, bit 22-23
- * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
- * IT IS ALSO SENT IN LQHKEYREQ
- * ----------------------------------------------------------------------- */
- LqhKeyReq::setAIInLqhKeyReq(Tdata10, regCachePtr->lenAiInTckeyreq);
- /* -----------------------------------------------------------------------
- * Bit 27 == 0 since TC record is the same as the client record.
- * Bit 28 == 0 since readLenAi can only be set after reading in LQH.
- * ----------------------------------------------------------------------- */
- //LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
- Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- if(commitAckMarker != RNIL){
- jam();
-
- LqhKeyReq::setMarkerFlag(Tdata10, 1);
- CommitAckMarker * tmp;
- tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
-
- /**
- * Populate LQH array
- */
- const Uint32 noOfLqhs = regTcPtr->noOfNodes;
- tmp->noOfLqhs = noOfLqhs;
- for(Uint32 i = 0; i<noOfLqhs; i++){
- tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
- }
- }
-
- /* ************************************************************> */
- /* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT */
- /* IS SENT TO A PRIMARY NODE. */
- /* ************************************************************> */
- UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
- LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtrSend();
- sig0 = tcConnectptr.i;
- sig2 = regCachePtr->hashValue;
- sig4 = cownref;
- sig5 = regTcPtr->savePointId;
- lqhKeyReq->clientConnectPtr = sig0;
- lqhKeyReq->attrLen = tslrAttrLen;
- lqhKeyReq->hashValue = sig2;
- lqhKeyReq->requestInfo = Tdata10;
- lqhKeyReq->tcBlockref = sig4;
- lqhKeyReq->savePointId = sig5;
- sig0 = regCachePtr->tableref + ((regCachePtr->schemaVersion << 16) & 0xFFFF0000);
- sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16);
- sig2 = regApiPtr->transid[0];
- sig3 = regApiPtr->transid[1];
- sig4 = regApiPtr->ndbapiBlockref;
- sig5 = regTcPtr->clientData;
- sig6 = regCachePtr->scanInfo;
- lqhKeyReq->tableSchemaVersion = sig0;
- lqhKeyReq->fragmentData = sig1;
- lqhKeyReq->transId1 = sig2;
- lqhKeyReq->transId2 = sig3;
- lqhKeyReq->scanInfo = sig6;
- lqhKeyReq->variableData[0] = sig4;
- lqhKeyReq->variableData[1] = sig5;
- UintR nextPos = 2;
- if (regTcPtr->lastReplicaNo > 1) {
- sig0 = (UintR)regTcPtr->tcNodedata[2] +
- (UintR)(regTcPtr->tcNodedata[3] << 16);
- lqhKeyReq->variableData[nextPos] = sig0;
- nextPos++;
- }//if
- sig0 = regCachePtr->keydata[0];
- sig1 = regCachePtr->keydata[1];
- sig2 = regCachePtr->keydata[2];
- sig3 = regCachePtr->keydata[3];
- UintR Tkeylen = regCachePtr->keylen;
- lqhKeyReq->variableData[nextPos + 0] = sig0;