List:Commits« Previous MessageNext Message »
From:tomas Date:March 27 2007 7:58am
Subject:bk commit into 5.1 tree (tomas:1.2473)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-03-27 09:58:33+02:00, tomas@stripped +10 -0
  Merge whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-telco-gca-single-user
  into  whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-telco-6.1
  MERGE: 1.2403.8.4

  storage/ndb/include/ndbapi/NdbDictionary.hpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.87.1.1

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.112.2.2

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.45.2.1

  storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.46.1.2

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.131.1.3

  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.41.2.1

  storage/ndb/src/ndbapi/ClusterMgr.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.31.1.4

  storage/ndb/src/ndbapi/NdbDictionary.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.67.1.1

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2007-03-27 09:58:29+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.157.2.1

  storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp@stripped, 2007-03-27 09:58:30+02:00, tomas@stripped +0 -0
    Auto merged
    MERGE: 1.71.1.1

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tomas
# Host:	whalegate.ndb.mysql.com
# Root:	/home/tomas/mysql-5.1-telco-6.1/RESYNC

--- 1.88/storage/ndb/include/ndbapi/NdbDictionary.hpp	2007-02-21 14:57:08 +01:00
+++ 1.89/storage/ndb/include/ndbapi/NdbDictionary.hpp	2007-03-27 09:58:29 +02:00
@@ -577,6 +577,15 @@
    */
   class Table : public Object {
   public:
+    /*
+     * Single user mode specifies access rights to table during single user mode
+     */
+    enum SingleUserMode {
+      SingleUserModeLocked    = NDB_SUM_LOCKED,
+      SingleUserModeReadOnly  = NDB_SUM_READONLY,
+      SingleUserModeReadWrite = NDB_SUM_READ_WRITE
+    };
+
     /** 
      * @name General
      * @{
@@ -895,6 +904,13 @@
      */
     void setMinRows(Uint64 minRows);
     Uint64 getMinRows() const;
+
+    /**
+     * Set/Get SingleUserMode
+     */
+    void setSingleUserMode(enum SingleUserMode);
+    enum SingleUserMode getSingleUserMode() const;
+
 
     /** @} *******************************************************************/
 

--- 1.116/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-03-09 12:17:30 +01:00
+++ 1.117/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-03-27 09:58:29 +02:00
@@ -462,6 +462,7 @@
   w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount);
   w.add(DictTabInfo::MinRowsLow, tablePtr.p->minRowsLow);
   w.add(DictTabInfo::MinRowsHigh, tablePtr.p->minRowsHigh);
+  w.add(DictTabInfo::SingleUserMode, tablePtr.p->singleUserMode);
 
   if(signal)
   {
@@ -1873,6 +1874,7 @@
   tablePtr.p->m_bits = 0;
   tablePtr.p->minRowsLow = 0;
   tablePtr.p->minRowsHigh = 0;
+  tablePtr.p->singleUserMode = 0;
   tablePtr.p->tableType = DictTabInfo::UserTable;
   tablePtr.p->primaryTableId = RNIL;
   // volatile elements
@@ -5702,7 +5704,9 @@
     signal->theData[4] = (Uint32)tabPtr.p->tableType;
     signal->theData[5] = createTabPtr.p->key;
     signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey;
-    sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 7, JBB);
+    signal->theData[7] = (Uint32)tabPtr.p->singleUserMode;
+
+    sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 8, JBB);
     return;
   }
   
@@ -6132,6 +6136,7 @@
   tablePtr.p->minRowsHigh = c_tableDesc.MinRowsHigh;
   tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag; 
   tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag; 
+  tablePtr.p->singleUserMode = c_tableDesc.SingleUserMode;
   
   Uint64 maxRows =
     (((Uint64)tablePtr.p->maxRowsHigh) << 32) + tablePtr.p->maxRowsLow;

--- 1.48/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-03-09 12:17:31 +01:00
+++ 1.49/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-03-27 09:58:29 +02:00
@@ -375,6 +375,11 @@
 
     Uint32 fragmentCount;
     Uint32 m_tablespace_id;
+
+    /*
+     * Access rights to table during single user mode
+     */
+    Uint8 singleUserMode;
   };
 
   typedef Ptr<TableRecord> TableRecordPtr;

--- 1.48/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-03-21 15:36:49 +01:00
+++ 1.49/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-03-27 09:58:29 +02:00
@@ -709,6 +709,7 @@
     Uint8 tcindxrec;
+    Uint8 singleUserMode;
     ReturnSignal returnsignal;
     Uint8 timeOutCounter;
     
@@ -959,10 +960,21 @@
   /********************************************************/
   struct TableRecord {
     Uint32 currentSchemaVersion;
-    Uint8 enabled;
-    Uint8 dropping;
+    Uint16 m_flags;
     Uint8 tableType;
-    Uint8 storedTable;
+    Uint8 singleUserMode;
+
+    enum {
+      TR_ENABLED      = 1 << 0,
+      TR_DROPPING     = 1 << 1,
+      TR_STORED_TABLE = 1 << 2
+    };
+    Uint8 get_enabled()     const { return (m_flags & TR_ENABLED)      != 0; }
+    Uint8 get_dropping()    const { return (m_flags & TR_DROPPING)     != 0; }
+    Uint8 get_storedTable() const { return (m_flags & TR_STORED_TABLE) != 0; }
+    void set_enabled(Uint8 f)     { f ? m_flags |= (Uint16)TR_ENABLED      : m_flags &= ~(Uint16)TR_ENABLED; }
+    void set_dropping(Uint8 f)    { f ? m_flags |= (Uint16)TR_DROPPING     : m_flags &= ~(Uint16)TR_DROPPING; }
+    void set_storedTable(Uint8 f) { f ? m_flags |= (Uint16)TR_STORED_TABLE : m_flags &= ~(Uint16)TR_STORED_TABLE; }
 
     Uint8 noOfKeyAttr;
     Uint8 hasCharAttr;
@@ -970,7 +982,7 @@
     Uint8 hasVarKeys;
 
     bool checkTable(Uint32 schemaVersion) const {
-      return enabled && !dropping && 
+      return get_enabled() && !get_dropping() && 
 	(table_version_major(schemaVersion) == table_version_major(currentSchemaVersion));
     }
 
@@ -1837,9 +1849,14 @@
 			Uint32 transid2);
   void removeMarkerForFailedAPI(Signal* signal, Uint32 nodeId, Uint32 bucket);
 
-  bool getAllowStartTransaction() const {
-    if(getNodeState().getSingleUserMode())
-      return true;
+  bool getAllowStartTransaction(Uint32 nodeId, Uint32 table_single_user_mode) const {
+    if (unlikely(getNodeState().getSingleUserMode()))
+    {
+      if (getNodeState().getSingleUserApi() == nodeId || table_single_user_mode)
+        return true;
+      else
+        return false;
+    }
     return getNodeState().startLevel < NodeState::SL_STOPPING_2;
   }
   

--- 1.136/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-03-21 15:36:49 +01:00
+++ 1.137/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-03-27 09:58:29 +02:00
@@ -330,19 +330,21 @@
   tabptr.i = signal->theData[0];
   ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord);
   tabptr.p->currentSchemaVersion = signal->theData[1];
-  tabptr.p->storedTable = (bool)signal->theData[2];
+  tabptr.p->m_flags = 0;
+  tabptr.p->set_storedTable((bool)signal->theData[2]);
   BlockReference retRef = signal->theData[3];
   tabptr.p->tableType = (Uint8)signal->theData[4];
   BlockReference retPtr = signal->theData[5];
   Uint32 noOfKeyAttr = signal->theData[6];
+  tabptr.p->singleUserMode = (Uint8)signal->theData[7];
   ndbrequire(noOfKeyAttr <= MAX_ATTRIBUTES_IN_INDEX);
 
   const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tabptr.i);
   ndbrequire(noOfKeyAttr == desc->noOfKeyAttr);
 
-  ndbrequire(tabptr.p->enabled == false);
-  tabptr.p->enabled = true;
-  tabptr.p->dropping = false;
+  ndbrequire(tabptr.p->get_enabled() == false);
+  tabptr.p->set_enabled(true);
+  tabptr.p->set_dropping(false);
   tabptr.p->noOfKeyAttr = desc->noOfKeyAttr;
   tabptr.p->hasCharAttr = desc->hasCharAttr;
   tabptr.p->noOfDistrKeys = desc->noOfDistrKeys;
@@ -366,7 +368,7 @@
   Uint32 senderRef = req->senderRef;
   Uint32 senderData = req->senderData;
   
-  if(!tabPtr.p->enabled){
+  if(!tabPtr.p->get_enabled()){
     jam();
     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
     ref->senderRef = reference();
@@ -378,7 +380,7 @@
     return;
   }
 
-  if(tabPtr.p->dropping){
+  if(tabPtr.p->get_dropping()){
     jam();
     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
     ref->senderRef = reference();
@@ -390,7 +392,7 @@
     return;
   }
   
-  tabPtr.p->dropping = true;
+  tabPtr.p->set_dropping(true);
   tabPtr.p->dropTable.senderRef = senderRef;
   tabPtr.p->dropTable.senderData = senderData;
 
@@ -426,7 +428,7 @@
   tabPtr.i = conf->tableId;
   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
   
-  ndbrequire(tabPtr.p->dropping == true);
+  ndbrequire(tabPtr.p->get_dropping() == true);
   Uint32 nodeId = refToNode(conf->senderRef);
   tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
   
@@ -456,7 +458,7 @@
   tabPtr.i = ref->tableId;
   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
   
-  ndbrequire(tabPtr.p->dropping == true);
+  ndbrequire(tabPtr.p->get_dropping() == true);
   Uint32 nodeId = refToNode(ref->senderRef);
   tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
   
@@ -493,7 +495,7 @@
   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->get_enabled() && tabPtr.p->get_dropping()){
       if(tabPtr.p->dropTable.waitDropTabCount.isWaitingFor(nodeId)){
         jam();
 	conf->senderRef = calcLqhBlockRef(nodeId);
@@ -534,7 +536,7 @@
   Uint32 senderData = req->senderData;
   DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
   
-  if(!tabPtr.p->enabled && rt == DropTabReq::OnlineDropTab){
+  if(!tabPtr.p->get_enabled() && rt == DropTabReq::OnlineDropTab){
     jam();
     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
     ref->senderRef = reference();
@@ -546,7 +548,7 @@
     return;
   }
 
-  if(!tabPtr.p->dropping && rt == DropTabReq::OnlineDropTab){
+  if(!tabPtr.p->get_dropping() && rt == DropTabReq::OnlineDropTab){
     jam();
     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
     ref->senderRef = reference();
@@ -558,8 +560,8 @@
     return;
   }
   
-  tabPtr.p->enabled = false;
-  tabPtr.p->dropping = false;
+  tabPtr.p->set_enabled(false);
+  tabPtr.p->set_dropping(false);
   
   DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
   conf->tableId = tabPtr.i;
@@ -1202,16 +1204,14 @@
   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))
+	Uint32 errCode = 0;
+	if(!local)
 	  {
 	    switch(sl){
 	    case NodeState::SL_STARTING:
@@ -1219,6 +1219,8 @@
 	      break;
 	    case NodeState::SL_STOPPING_1:
 	    case NodeState::SL_STOPPING_2:
+              if (getNodeState().getSingleUserMode())
+                break;
 	    case NodeState::SL_STOPPING_3:
 	    case NodeState::SL_STOPPING_4:
 	      if(getNodeState().stopping.systemShutdown)
@@ -1227,16 +1229,18 @@
 		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 (errCode)
+            {
+              signal->theData[0] = tapiPointer;
+              signal->theData[1] = errCode;
+              sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
+              return;
+            }
 	  }//if (!(sl == SL_SINGLEUSER))
       } //if
     }
@@ -1724,8 +1728,14 @@
      * Initialize object before starting error handling
      */
     initApiConnectRec(signal, apiConnectptr.p, true);
+start_failure:
     switch(getNodeState().startLevel){
     case NodeState::SL_STOPPING_2:
+      if (getNodeState().getSingleUserMode())
+      {
+        terrorCode  = ZCLUSTER_IN_SINGLEUSER_MODE;
+        break;
+      }
     case NodeState::SL_STOPPING_3:
     case NodeState::SL_STOPPING_4:
       if(getNodeState().stopping.systemShutdown)
@@ -1736,6 +1746,12 @@
     case NodeState::SL_SINGLEUSER:
       terrorCode  = ZCLUSTER_IN_SINGLEUSER_MODE;
       break;
+    case NodeState::SL_STOPPING_1:
+      if (getNodeState().getSingleUserMode())
+      {
+        terrorCode  = ZCLUSTER_IN_SINGLEUSER_MODE;
+        break;
+      }
     default:
       terrorCode = ZWRONG_STATE;
       break;
@@ -1757,6 +1773,13 @@
     return;
   }
     
+  case 60:
+  {
+    jam();
+    initApiConnectRec(signal, apiConnectptr.p, true);
+    apiConnectptr.p->m_exec_flag = 1;
+    goto start_failure;
+  }
   default:
     jam();
     systemErrorLab(signal, __LINE__);
@@ -2377,6 +2400,7 @@
   regApiPtr->buddyPtr = RNIL;
   regApiPtr->currSavePointId = 0;
   regApiPtr->m_transaction_nodes.clear();
+  regApiPtr->singleUserMode = 0;
   // Trigger data
   releaseFiredTriggerData(&regApiPtr->theFiredTriggers),
   // Index data
@@ -2486,6 +2510,7 @@
 /*****************************************************************************/
 void Dbtc::execTCKEYREQ(Signal* signal) 
 {
+  Uint32 sendersNodeId = refToNode(signal->getSendersBlockRef());
   UintR compare_transid1, compare_transid2;
   UintR titcLenAiInTckeyreq;
   UintR TkeyLength;
@@ -2529,9 +2554,12 @@
   bool isIndexOpReturn = regApiPtr->indexOpReturn;
   regApiPtr->isIndexOp = false; // Reset marker
   regApiPtr->m_exec_flag |= TexecFlag;
+  TableRecordPtr localTabptr;
+  localTabptr.i = TtabIndex;
+  localTabptr.p = &tableRecord[TtabIndex];
   switch (regApiPtr->apiConnectstate) {
   case CS_CONNECTED:{
-    if (TstartFlag == 1 && getAllowStartTransaction() == true){
+    if (TstartFlag == 1 && getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == true){
       //---------------------------------------------------------------------
       // Initialise API connect record if transaction is started.
       //---------------------------------------------------------------------
@@ -2539,7 +2567,7 @@
       initApiConnectRec(signal, regApiPtr);
       regApiPtr->m_exec_flag = TexecFlag;
     } else {
-      if(getAllowStartTransaction() == true){
+      if(getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == true){
 	/*------------------------------------------------------------------
 	 * WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN 
 	 * RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO 
@@ -2549,9 +2577,9 @@
 	return;
       } else {
 	/**
-	 * getAllowStartTransaction() == false
+	 * getAllowStartTransaction(sendersNodeId) == false
 	 */
-	TCKEY_abort(signal, 57);
+	TCKEY_abort(signal, TexecFlag ? 60 : 57);
 	return;
       }//if
     }
@@ -2566,6 +2594,13 @@
        *  the state will be CS_STARTED
        */
       jam();
+      if (unlikely(getNodeState().getSingleUserMode()) &&
+          getNodeState().getSingleUserApi() != sendersNodeId &&
+          !localTabptr.p->singleUserMode)
+      {
+	TCKEY_abort(signal, TexecFlag ? 60 : 57);
+        return;
+      }
       initApiConnectRec(signal, regApiPtr);
       regApiPtr->m_exec_flag = TexecFlag;
     } else { 
@@ -2586,6 +2621,10 @@
   case CS_ABORTING:
     if (regApiPtr->abortState == AS_IDLE) {
       if (TstartFlag == 1) {
+        if(getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == false){
+          TCKEY_abort(signal, TexecFlag ? 60 : 57);
+          return;
+        }
 	//--------------------------------------------------------------------
 	// Previous transaction had been aborted and the abort was completed. 
 	// It is then OK to start a new transaction again.
@@ -2649,9 +2688,6 @@
     return;
   }//switch
   
-  TableRecordPtr localTabptr;
-  localTabptr.i = TtabIndex;
-  localTabptr.p = &tableRecord[TtabIndex];
   if (localTabptr.p->checkTable(tcKeyReq->tableSchemaVersion)) {
     ;
   } else {
@@ -2710,6 +2746,8 @@
   regTcPtr->savePointId = regApiPtr->currSavePointId;
   regApiPtr->executingIndexOp = RNIL;
 
+  regApiPtr->singleUserMode |= 1 << localTabptr.p->singleUserMode;
+
   if (TcKeyReq::getExecutingTrigger(Treqinfo)) {
     // Save the TcOperationPtr for fireing operation
     regTcPtr->triggeringOperation = TsenderData;
@@ -2841,7 +2879,7 @@
      *   THIS VARIABLE CONTROLS THE INTERVAL BETWEEN LCP'S AND 
      *   TEMP TABLES DON'T PARTICIPATE.
      * -------------------------------------------------------------------- */
-    if (localTabptr.p->storedTable) {
+    if (localTabptr.p->get_storedTable()) {
       coperationsize = ((Toperationsize + TattrLen) + TkeyLength) + 17;
     }
     c_counters.cwriteCount = TwriteCount + 1;
@@ -4674,6 +4712,7 @@
   regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
   regApiPtr->commitAckMarker = TcommitAckMarker;
   regApiPtr->m_transaction_nodes = Tnodes;
+  regApiPtr->singleUserMode = 0;
 
   gcpPtr.i = TgcpPointer;
   ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
@@ -4685,6 +4724,7 @@
   regTmpApiPtr->firstTcConnect = RNIL;
   regTmpApiPtr->lastTcConnect = RNIL;
   regTmpApiPtr->m_transaction_nodes.clear();
+  regTmpApiPtr->singleUserMode = 0;
   releaseAllSeizedIndexOperations(regTmpApiPtr);
 }//Dbtc::copyApi()
 
@@ -6154,9 +6194,11 @@
 void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr) 
 {
   Uint32 end_ptr, time_passed, time_out_value, mask_value;
+  Uint32 old_mask_value= 0;
   const Uint32 api_con_sz= capiConnectFilesize;
   const Uint32 tc_timer= ctcTimer;
   const Uint32 time_out_param= ctimeOutValue;
+  const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
 
   ctimeOutCheckHeartbeat = tc_timer;
 
@@ -6177,16 +6219,50 @@
     jam();
     mask_value= 31;
   }
+  if (time_out_param != old_time_out_param &&
+      getNodeState().getSingleUserMode())
+  {
+    // abort during single user mode, use old_mask_value as flag
+    // and calculate value to be used for connections with allowed api
+    if (old_time_out_param > 300) {
+      jam();
+      old_mask_value= 63;
+    } else if (old_time_out_param < 30) {
+      jam();
+      old_mask_value= 7;
+    } else {
+      jam();
+      old_mask_value= 31;
+    }
+  }
   for ( ; api_con_ptr < end_ptr; api_con_ptr++) {
     Uint32 api_timer= getApiConTimer(api_con_ptr);
     jam();
     if (api_timer != 0) {
+      Uint32 error= ZTIME_OUT_ERROR;
       time_out_value= time_out_param + (api_con_ptr & mask_value);
+      if (unlikely(old_mask_value)) // abort during single user mode
+      {
+        apiConnectptr.i = api_con_ptr;
+        ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
+        if ((getNodeState().getSingleUserApi() ==
+             refToNode(apiConnectptr.p->ndbapiBlockref)) ||
+            !(apiConnectptr.p->singleUserMode & (1 << NDB_SUM_LOCKED)))
+        {
+          // api allowed during single user, use original timeout
+          time_out_value=
+            old_time_out_param + (api_con_ptr & old_mask_value);
+        }
+        else
+        {
+          error= ZCLUSTER_IN_SINGLEUSER_MODE;
+        }
+      }
       time_passed= tc_timer - api_timer;
       if (time_passed > time_out_value) 
       {
         jam();
-        timeOutFoundLab(signal, api_con_ptr, ZTIME_OUT_ERROR);
+        timeOutFoundLab(signal, api_con_ptr, error);
 	api_con_ptr++;
 	break;
       }
@@ -6226,7 +6302,8 @@
 	<< " code: " << errCode);
   switch (apiConnectptr.p->apiConnectstate) {
   case CS_STARTED:
-    if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){
+    if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec &&
+       errCode != ZCLUSTER_IN_SINGLEUSER_MODE){
       jam();
       /*
       We are waiting for application to continue the transaction. In this
@@ -6798,6 +6875,33 @@
   c_scan_frag_pool.getPtr(ptr, TscanConPtr);
   DEBUG(TscanConPtr << " timeOutFoundFragLab: scanFragState = "<< ptr.p->scanFragState);
 
+  const Uint32 time_out_param= ctimeOutValue;
+  const Uint32 old_time_out_param= c_abortRec.oldTimeOutValue;
+  
+  if (unlikely(time_out_param != old_time_out_param && 
+	       getNodeState().getSingleUserMode()))
+  {
+    jam();
+    ScanRecordPtr scanptr;
+    scanptr.i = ptr.p->scanRec;
+    ptrCheckGuard(scanptr, cscanrecFileSize, scanRecord);
+    ApiConnectRecordPtr TlocalApiConnectptr;
+    TlocalApiConnectptr.i = scanptr.p->scanApiRec;
+    ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
+    
+    if (refToNode(TlocalApiConnectptr.p->ndbapiBlockref) == 
+	getNodeState().getSingleUserApi())
+    {
+      jam();
+      Uint32 val = ctcTimer - ptr.p->scanFragTimer;
+      if (val <= old_time_out_param)
+      {
+	jam();
+	goto next;
+      }
+    }
+  }
+
   /*-------------------------------------------------------------------------*/
   // The scan fragment has expired its timeout. Check its state to decide
   // what to do.
@@ -6859,6 +6963,7 @@
     break;
   }//switch
   
+next:  
   signal->theData[0] = TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL;
   signal->theData[1] = TscanConPtr + 1;
   sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
@@ -8078,6 +8183,7 @@
   apiConnectptr.p->ndbapiConnect = 0;
   apiConnectptr.p->buddyPtr = RNIL;
   apiConnectptr.p->m_transaction_nodes.clear();
+  apiConnectptr.p->singleUserMode = 0;
   setApiConTimer(apiConnectptr.i, 0, __LINE__);
   switch(ttransStatus){
   case LqhTransConf::Committed:
@@ -8690,6 +8796,14 @@
     }
   }
   
+  if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
+      getNodeState().getSingleUserApi() !=
+      refToNode(apiConnectptr.p->ndbapiBlockref))
+  {
+    errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
+    goto SCAN_TAB_error;
+  }
+
   seizeTcConnect(signal);
   tcConnectptr.p->apiConnect = apiConnectptr.i;
   tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN;
@@ -9985,6 +10099,7 @@
     apiConnectptr.p->buddyPtr = RNIL;
     apiConnectptr.p->currSavePointId = 0;
     apiConnectptr.p->m_transaction_nodes.clear();
+    apiConnectptr.p->singleUserMode = 0;
   }//for
   apiConnectptr.i = tiacTmp - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -10013,6 +10128,7 @@
       apiConnectptr.p->buddyPtr = RNIL;
       apiConnectptr.p->currSavePointId = 0;
       apiConnectptr.p->m_transaction_nodes.clear();
+      apiConnectptr.p->singleUserMode = 0;
     }//for
   apiConnectptr.i = (2 * tiacTmp) - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -10041,6 +10157,7 @@
     apiConnectptr.p->buddyPtr = RNIL;
     apiConnectptr.p->currSavePointId = 0;
     apiConnectptr.p->m_transaction_nodes.clear();
+    apiConnectptr.p->singleUserMode = 0;
   }//for
   apiConnectptr.i = (3 * tiacTmp) - 1;
   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
@@ -10225,10 +10342,11 @@
     refresh_watch_dog();
     ptrAss(tabptr, tableRecord);
     tabptr.p->currentSchemaVersion = 0;
-    tabptr.p->storedTable = true;
+    tabptr.p->m_flags = 0;
+    tabptr.p->set_storedTable(true);
     tabptr.p->tableType = 0;
-    tabptr.p->enabled = false;
-    tabptr.p->dropping = false;
+    tabptr.p->set_enabled(false);
+    tabptr.p->set_dropping(false);
     tabptr.p->noOfKeyAttr = 0;
     tabptr.p->hasCharAttr = 0;
     tabptr.p->noOfDistrKeys = 0;
@@ -10362,6 +10480,7 @@
   apiConnectptr.p->firstTcConnect = RNIL;
   apiConnectptr.p->lastTcConnect = RNIL;
   apiConnectptr.p->m_transaction_nodes.clear();
+  apiConnectptr.p->singleUserMode = 0;
 
   // MASV let state be CS_ABORTING until all 
   // signals in the "air" have been received. Reset to CS_CONNECTED
@@ -11276,7 +11395,7 @@
   const Uint32 senderData = req->senderData;
   const BlockReference senderRef = req->senderRef;
   
-  if(getAllowStartTransaction() == true && !getNodeState().getSingleUserMode()){
+  if(getAllowStartTransaction(refToNode(senderRef), 0) == true && !getNodeState().getSingleUserMode()){
     jam();
 
     ref->senderData = senderData;
@@ -11704,6 +11823,17 @@
     regApiPtr->transid[1] = tcIndxReq->transId2;
   }//if
 
+  if (getNodeState().startLevel == NodeState::SL_SINGLEUSER &&
+      getNodeState().getSingleUserApi() !=
+      refToNode(regApiPtr->ndbapiBlockref))
+  {
+    terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
+    regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
+    apiConnectptr = transPtr;
+    abortErrorLab(signal);
+    return;
+  }
+
   if (ERROR_INSERTED(8036) || !seizeIndexOperation(regApiPtr, indexOpPtr)) {
     jam();
     // Failed to allocate index operation
@@ -13544,9 +13674,9 @@
 
 Uint32 
 Dbtc::TableRecord::getErrorCode(Uint32 schemaVersion) const {
-  if(!enabled)
+  if(!get_enabled())
     return ZNO_SUCH_TABLE;
-  if(dropping)
+  if(get_dropping())
     return ZDROP_TABLE_IN_PROGRESS;
   if(table_version_major(schemaVersion) != table_version_major(currentSchemaVersion))
     return ZWRONG_SCHEMA_VERSION_ERROR;

--- 1.47/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2007-03-13 21:45:52 +01:00
+++ 1.48/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2007-03-27 09:58:29 +02:00
@@ -1686,6 +1686,7 @@
   //w.add(DictTabInfo::NoOfVariable, (Uint32)0);
   //w.add(DictTabInfo::KeyLength, 1);
   w.add(DictTabInfo::TableTypeVal, (Uint32)table.tableType);
+  w.add(DictTabInfo::SingleUserMode, (Uint32)NDB_SUM_READ_WRITE);
 
   for (unsigned i = 0; i < table.columnCount; i++) {
     const SysColumn& column = table.columnList[i];

--- 1.38/storage/ndb/src/ndbapi/ClusterMgr.cpp	2007-02-26 17:53:46 +01:00
+++ 1.39/storage/ndb/src/ndbapi/ClusterMgr.cpp	2007-03-27 09:58:29 +02:00
@@ -408,7 +408,7 @@
   }
   
   if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED  ||
-			  node.m_state.startLevel == NodeState::SL_SINGLEUSER)){
+			  node.m_state.getSingleUserMode())){
     set_node_alive(node, true);
   } else {
     set_node_alive(node, false);

--- 1.68/storage/ndb/src/ndbapi/NdbDictionary.cpp	2007-02-21 14:57:08 +01:00
+++ 1.69/storage/ndb/src/ndbapi/NdbDictionary.cpp	2007-03-27 09:58:29 +02:00
@@ -495,6 +495,18 @@
   return m_impl.getFrmLength();
 }
 
+enum NdbDictionary::Table::SingleUserMode
+NdbDictionary::Table::getSingleUserMode() const
+{
+  return (enum SingleUserMode)m_impl.m_single_user_mode;
+}
+
+void
+NdbDictionary::Table::setSingleUserMode(enum NdbDictionary::Table::SingleUserMode mode)
+{
+  m_impl.m_single_user_mode = (Uint8)mode;
+}
+
 void
 NdbDictionary::Table::setTablespaceNames(const void *data, Uint32 len)
 {

--- 1.159/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2007-03-09 14:42:11 +01:00
+++ 1.160/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2007-03-27 09:58:29 +02:00
@@ -470,6 +470,7 @@
   m_tablespace_name.clear();
   m_tablespace_id = ~0;
   m_tablespace_version = ~0;
+  m_single_user_mode = 0;
 }
 
 bool
@@ -663,6 +664,15 @@
       DBUG_RETURN(false);
     }
   }
+  
+  if(m_single_user_mode != obj.m_single_user_mode)
+  {
+    DBUG_PRINT("info",("m_single_user_mode %d != %d",
+                       (int32)m_single_user_mode,
+                       (int32)obj.m_single_user_mode));
+    DBUG_RETURN(false);
+  }
+
   DBUG_RETURN(true);
 }
 
@@ -726,6 +736,8 @@
   m_keyLenInWords = org.m_keyLenInWords;
   m_fragmentCount = org.m_fragmentCount;
   
+  m_single_user_mode = org.m_single_user_mode;
+
   if (m_index != 0)
     delete m_index;
   m_index = org.m_index;
@@ -2103,6 +2115,7 @@
   impl->m_kvalue = tableDesc->TableKValue;
   impl->m_minLoadFactor = tableDesc->MinLoadFactor;
   impl->m_maxLoadFactor = tableDesc->MaxLoadFactor;
+  impl->m_single_user_mode = tableDesc->SingleUserMode;
 
   impl->m_indexType = (NdbDictionary::Object::Type)
     getApiConstant(tableDesc->TableType,
@@ -2564,6 +2577,7 @@
   tmpTab->MinRowsLow = (Uint32)(impl.m_min_rows & 0xFFFFFFFF);
   tmpTab->DefaultNoPartFlag = impl.m_default_no_part_flag;
   tmpTab->LinearHashFlag = impl.m_linear_flag;
+  tmpTab->SingleUserMode = impl.m_single_user_mode;
 
   if (impl.m_ts_name.length())
   {

--- 1.72/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2007-02-21 14:57:08 +01:00
+++ 1.73/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2007-03-27 09:58:30 +02:00
@@ -204,6 +204,7 @@
   int m_maxLoadFactor;
   Uint16 m_keyLenInWords;
   Uint16 m_fragmentCount;
+  Uint8 m_single_user_mode;
 
   NdbIndexImpl * m_index;
   NdbColumnImpl * getColumn(unsigned attrId);
Thread
bk commit into 5.1 tree (tomas:1.2473)tomas27 Mar