List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:February 17 2009 7:52am
Subject:bzr commit into mysql-5.1-telco-6.2 branch (jonas:2819)
View as plain text  
#At file:///home/jonas/src/telco-6.2/

 2819 Jonas Oreland	2009-02-17
      ndb - add new DD config variables
        FileSystemPathDD
        FileSystemPathDataFiles
        FileSystemPathUndoFiles
        InitialLogfileGroup
        InitialTablespace
modified:
  mysql-test/ndb/ndb_config_2_node.ini
  storage/ndb/include/kernel/RefConvert.hpp
  storage/ndb/include/kernel/signaldata/FsOpenReq.hpp
  storage/ndb/include/mgmapi/mgmapi_config_parameters.h
  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
  storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp
  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp
  storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
  storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp
  storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp
  storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp
  storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp
  storage/ndb/src/kernel/blocks/tsman.cpp
  storage/ndb/src/mgmsrv/ConfigInfo.cpp
  storage/ndb/test/run-test/conf-dl145a.cnf
  storage/ndb/test/run-test/conf-ndbmaster.cnf

=== modified file 'mysql-test/ndb/ndb_config_2_node.ini'
--- a/mysql-test/ndb/ndb_config_2_node.ini	2007-09-05 13:21:33 +0000
+++ b/mysql-test/ndb/ndb_config_2_node.ini	2009-02-17 07:52:13 +0000
@@ -20,6 +20,9 @@ DiskPageBufferMemory= CHOOSE_DiskPageBuf
 # test that the parameter exists
 InitialNoOfOpenFiles= 27
 
+FileSystemPathDD= CHOOSE_FILESYSTEM/uf
+FileSystemPathDataFiles= CHOOSE_FILESYSTEM/df
+
 #
 # Increase timeouts to cater for slow test-machines
 #   (possibly running several tests in parallell)

=== modified file 'storage/ndb/include/kernel/RefConvert.hpp'
--- a/storage/ndb/include/kernel/RefConvert.hpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/include/kernel/RefConvert.hpp	2009-02-17 07:52:13 +0000
@@ -27,6 +27,14 @@ BlockNumber refToBlock(BlockReference re
 }
 
 /**
+ * For allowing to write merge safe code
+ */
+inline
+BlockNumber refToMain(BlockReference ref){
+  return (BlockNumber)(ref >> 16);
+}
+
+/**
  * Convert BlockReference to NodeId
  */
 inline

=== modified file 'storage/ndb/include/kernel/signaldata/FsOpenReq.hpp'
--- a/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp	2007-05-14 08:34:21 +0000
+++ b/storage/ndb/include/kernel/signaldata/FsOpenReq.hpp	2009-02-17 07:52:13 +0000
@@ -99,6 +99,15 @@ private:
     S_LOG = 7,
     S_CTL = 8
   };
+
+  enum BasePathSpec
+  {
+    BP_FS = 0,     // FileSystemPath
+    BP_BACKUP = 1, // BackupDataDir
+    BP_DD_DF = 2,  // FileSystemPathDataFiles
+    BP_DD_UF = 3,  // FileSystemPathUndoFiles
+    BP_MAX = 4
+  };
   
   static Uint32 getVersion(const Uint32 fileNumber[]);
   static Uint32 getSuffix(const Uint32 fileNumber[]);

=== modified file 'storage/ndb/include/mgmapi/mgmapi_config_parameters.h'
--- a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2008-12-18 09:16:45 +0000
+++ b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h	2009-02-17 07:52:13 +0000
@@ -132,6 +132,12 @@
 #define CFG_DB_MAX_BUFFERED_EPOCHS    182 /* subscriptions */
 #define CFG_DB_SUMA_HANDOVER_TIMEOUT  183
 
+#define CFG_DB_DD_FILESYSTEM_PATH     193
+#define CFG_DB_DD_DATAFILE_PATH       194
+#define CFG_DB_DD_UNDOFILE_PATH       195
+#define CFG_DB_DD_LOGFILEGROUP_SPEC   196
+#define CFG_DB_DD_TABLEPACE_SPEC      197
+
 #define CFG_DB_SGA                    198 /* super pool mem */
 #define CFG_DB_DATA_MEM_2             199 /* used in special build in 5.1 */
 

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2008-11-21 10:51:05 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2009-02-17 07:52:13 +0000
@@ -16530,9 +16530,22 @@ Dbdict::create_fg_prepare_start(Signal* 
     {
       //fg.TS_DataGrow = group.m_grow_spec;
       fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
-      fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
 
       Ptr<Filegroup> lg_ptr;
+      if (fg.TS_LogfileGroupId == RNIL && fg.TS_LogfileGroupVersion == RNIL)
+      {
+        jam();
+        Filegroup_hash::Iterator it;
+        if (c_filegroup_hash.first(it))
+        {
+          jam();
+          fg.TS_LogfileGroupId = it.curr.p->key;
+          fg.TS_LogfileGroupVersion = it.curr.p->m_version;
+        }
+      }
+
+      fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
+
       if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
       {
         jam();
@@ -16719,6 +16732,28 @@ Dbdict::create_file_prepare_start(Signal
 
     // Get Filegroup
     FilegroupPtr fg_ptr;
+    if (f.FilegroupId == RNIL && f.FilegroupVersion == RNIL)
+    {
+      jam();
+      Filegroup_hash::Iterator it;
+      c_filegroup_hash.first(it);
+      while (!it.isNull())
+      {
+        jam();
+        if ((f.FileType == DictTabInfo::Undofile &&
+             it.curr.p->m_type == DictTabInfo::LogfileGroup) ||
+            (f.FileType == DictTabInfo::Datafile &&
+             it.curr.p->m_type == DictTabInfo::Tablespace))
+        {
+          jam();
+          f.FilegroupId = it.curr.p->key;
+          f.FilegroupVersion = it.curr.p->m_version;
+          break;
+        }
+        c_filegroup_hash.next(it);
+      }
+    }
+
     if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
       jam();
       op->m_errorCode = CreateFileRef::NoSuchFilegroup;

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2008-08-11 10:41:11 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp	2009-02-17 07:52:13 +0000
@@ -189,6 +189,10 @@ private:
   void execDIH_RESTARTREF(Signal* signal);
   void execCREATE_TABLE_REF(Signal* signal);
   void execCREATE_TABLE_CONF(Signal* signal);
+  void execCREATE_FILEGROUP_REF(Signal* signal);
+  void execCREATE_FILEGROUP_CONF(Signal* signal);
+  void execCREATE_FILE_REF(Signal* signal);
+  void execCREATE_FILE_CONF(Signal* signal);
   void execNDB_STTORRY(Signal* signal);
   void execNDB_STARTCONF(Signal* signal);
   void execREAD_NODESREQ(Signal* signal);
@@ -230,6 +234,7 @@ private:
   void systemErrorLab(Signal* signal, int line);
 
   void createSystableLab(Signal* signal, unsigned index);
+  void createDDObjects(Signal*, unsigned index);
   void crSystab7Lab(Signal* signal);
   void crSystab8Lab(Signal* signal);
   void crSystab9Lab(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp	2007-02-14 05:37:40 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp	2009-02-17 07:52:13 +0000
@@ -77,6 +77,10 @@ Ndbcntr::Ndbcntr(Block_context& ctx):
   addRecSignal(GSN_DIH_RESTARTREF, &Ndbcntr::execDIH_RESTARTREF);
   addRecSignal(GSN_CREATE_TABLE_REF, &Ndbcntr::execCREATE_TABLE_REF);
   addRecSignal(GSN_CREATE_TABLE_CONF, &Ndbcntr::execCREATE_TABLE_CONF);
+  addRecSignal(GSN_CREATE_FILEGROUP_REF, &Ndbcntr::execCREATE_FILEGROUP_REF);
+  addRecSignal(GSN_CREATE_FILEGROUP_CONF, &Ndbcntr::execCREATE_FILEGROUP_CONF);
+  addRecSignal(GSN_CREATE_FILE_REF, &Ndbcntr::execCREATE_FILE_REF);
+  addRecSignal(GSN_CREATE_FILE_CONF, &Ndbcntr::execCREATE_FILE_CONF);
   addRecSignal(GSN_NDB_STTORRY, &Ndbcntr::execNDB_STTORRY);
   addRecSignal(GSN_NDB_STARTCONF, &Ndbcntr::execNDB_STARTCONF);
   addRecSignal(GSN_READ_NODESREQ, &Ndbcntr::execREAD_NODESREQ);

=== modified file 'storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2008-04-25 10:59:17 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp	2009-02-17 07:52:13 +0000
@@ -50,6 +50,8 @@
 #include <NdbOut.hpp>
 #include <NdbTick.h>
 
+#include <signaldata/CreateFilegroup.hpp>
+
 // used during shutdown for reporting current startphase
 // accessed from Emulator.cpp, NdbShutdown()
 Uint32 g_currentStartPhase;
@@ -248,6 +250,131 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* s
   return;
 }//Ndbcntr::execSYSTEM_ERROR()
 
+
+struct ddentry
+{
+  Uint32 type;
+  const char * name;
+  Uint64 size;
+};
+
+/**
+ * f_dd[] = {
+ * { DictTabInfo::LogfileGroup, "DEFAULT-LG", 32*1024*1024 },
+ * { DictTabInfo::Undofile, "undofile.dat", 64*1024*1024 },
+ * { DictTabInfo::Tablespace, "DEFAULT-TS", 1024*1024 },
+ * { DictTabInfo::Datafile, "datafile.dat", 64*1024*1024 },
+ * { ~0, 0, 0 }
+ * };
+ */
+Vector<ddentry> f_dd;
+
+Uint64
+parse_size(const char * src)
+{
+  Uint64 num = 0;
+  char * endptr = 0;
+  num = strtoll(src, &endptr, 10);
+
+  if (endptr)
+  {
+    switch(* endptr){
+    case 'k':
+    case 'K':
+      num *= 1024;
+      break;
+    case 'm':
+    case 'M':
+      num *= 1024;
+      num *= 1024;
+      break;
+    case 'g':
+    case 'G':
+      num *= 1024;
+      num *= 1024;
+      num *= 1024;
+      break;
+    }
+  }
+  return num;
+}
+
+static
+int
+parse_spec(Vector<ddentry> & dst,
+           const char * src,
+           Uint32 type)
+{
+  const char * key;
+  Uint32 filetype;
+
+  struct ddentry group;
+  if (type == DictTabInfo::LogfileGroup)
+  {
+    key = "undo_buffer_size=";
+    group.size = 64*1024*1024;
+    group.name = "DEFAULT-LG";
+    group.type = type;
+    filetype = DictTabInfo::Undofile;
+  }
+  else
+  {
+    key = "extent_size=";
+    group.size = 1024*1024;
+    group.name = "DEFAULT-TS";
+    group.type = type;
+    filetype = DictTabInfo::Datafile;
+  }
+  size_t keylen = strlen(key);
+
+  BaseString arg(src);
+  Vector<BaseString> list;
+  arg.split(list, ";");
+
+  bool first = true;
+  for (Uint32 i = 0; i<list.size(); i++)
+  {
+    list[i].trim();
+    if (strncasecmp(list[i].c_str(), "name=", sizeof("name=")-1) == 0)
+    {
+      group.name= strdup(list[i].c_str() + sizeof("name=")-1);
+    }
+    else if (strncasecmp(list[i].c_str(), key, keylen) == 0)
+    {
+      group.size = parse_size(list[i].c_str() + keylen);
+    }
+    else
+    {
+      /**
+       * interpret as filespec
+       */
+      struct ddentry entry;
+      const char * path = list[i].c_str();
+      char * sizeptr = strchr(path, ':');
+      if (sizeptr == 0)
+      {
+        return -1;
+      }
+      * sizeptr = 0;
+
+      entry.name = strdup(path);
+      entry.size = parse_size(sizeptr + 1);
+      entry.type = filetype;
+
+      if (first)
+      {
+        /**
+         * push group aswell
+         */
+        first = false;
+        dst.push_back(group);
+      }
+      dst.push_back(entry);
+    }
+  }
+  return 0;
+}
+
 void 
 Ndbcntr::execREAD_CONFIG_REQ(Signal* signal)
 {
@@ -262,6 +389,50 @@ Ndbcntr::execREAD_CONFIG_REQ(Signal* sig
     m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
 
+  Uint32 dl = 0;
+  ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl);
+  if (dl == 0)
+  {
+    const char * lgspec = 0;
+    char buf[1024];
+    if (!ndb_mgm_get_string_parameter(p, CFG_DB_DD_LOGFILEGROUP_SPEC, &lgspec))
+    {
+      jam();
+
+      if (parse_spec(f_dd, lgspec, DictTabInfo::LogfileGroup))
+      {
+        BaseString::snprintf(buf, sizeof(buf),
+                             "Unable to parse InitalLogfileGroup: %s", lgspec);
+        progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
+      }
+    }
+
+    const char * tsspec = 0;
+    if (!ndb_mgm_get_string_parameter(p, CFG_DB_DD_TABLEPACE_SPEC, &tsspec))
+    {
+      if (f_dd.size() == 0)
+      {
+        warningEvent("InitalTablespace specified, "
+                     "but InitalLogfileGroup is not!");
+        warningEvent("Ignoring InitalTablespace: %s",
+                     tsspec);
+      }
+      else
+      {
+        if (parse_spec(f_dd, tsspec, DictTabInfo::Tablespace))
+        {
+          BaseString::snprintf(buf, sizeof(buf),
+                               "Unable to parse InitalTablespace: %s", tsspec);
+          progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
+        }
+      }
+    }
+  }
+
+  struct ddentry empty;
+  empty.type = ~0;
+  f_dd.push_back(empty);
+
   ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
   conf->senderRef = reference();
   conf->senderData = senderData;
@@ -1685,11 +1856,168 @@ void Ndbcntr::systemErrorLab(Signal* sig
 /*       |  :  |   :             |                   v                       */
 /*       | 2048|   0             |                   v                       */
 /*---------------------------------------------------------------------------*/
+void
+Ndbcntr::createDDObjects(Signal * signal, unsigned index)
+{
+  const ndb_mgm_configuration_iterator * p =
+    m_ctx.m_config.getOwnConfigIterator();
+  ndbrequire(p != 0);
+
+  Uint32 propPage[256];
+  LinearWriter w(propPage, 256);
+
+  const ddentry* entry = &f_dd[index];
+
+  switch(entry->type){
+  case DictTabInfo::LogfileGroup:
+  case DictTabInfo::Tablespace:
+  {
+    jam();
+
+    DictFilegroupInfo::Filegroup fg; fg.init();
+    BaseString::snprintf(fg.FilegroupName, sizeof(fg.FilegroupName),
+                         entry->name);
+    fg.FilegroupType = entry->type;
+    if (entry->type == DictTabInfo::LogfileGroup)
+    {
+      jam();
+      fg.LF_UndoBufferSize = Uint32(entry->size);
+    }
+    else
+    {
+      jam();
+      fg.TS_ExtentSize = Uint32(entry->size);
+      fg.TS_LogfileGroupId = RNIL;
+      fg.TS_LogfileGroupVersion = RNIL;
+    }
+
+    SimpleProperties::UnpackStatus s;
+    s = SimpleProperties::pack(w,
+                               &fg,
+                               DictFilegroupInfo::Mapping,
+                               DictFilegroupInfo::MappingSize, true);
+
+
+    Uint32 length = w.getWordsUsed();
+    LinearSectionPtr ptr[3];
+    ptr[0].p = &propPage[0];
+    ptr[0].sz = length;
+
+    CreateFilegroupReq * req = (CreateFilegroupReq*)signal->getDataPtrSend();
+    req->senderRef = reference();
+    req->senderData = index;
+    req->objType = entry->type;
+    sendSignal(DBDICT_REF, GSN_CREATE_FILEGROUP_REQ, signal,
+               CreateFilegroupReq::SignalLength, JBB, ptr, 1);
+    return;
+  }
+  case DictTabInfo::Undofile:
+  case DictTabInfo::Datafile:
+  {
+    jam();
+    Uint32 propPage[256];
+    LinearWriter w(propPage, 256);
+    DictFilegroupInfo::File f; f.init();
+    BaseString::snprintf(f.FileName, sizeof(f.FileName), entry->name);
+    f.FileType = entry->type;
+    f.FilegroupId = RNIL;
+    f.FilegroupVersion = RNIL;
+    f.FileSizeHi = Uint32(entry->size >> 32);
+    f.FileSizeLo = Uint32(entry->size);
+
+    SimpleProperties::UnpackStatus s;
+    s = SimpleProperties::pack(w,
+                               &f,
+                               DictFilegroupInfo::FileMapping,
+                               DictFilegroupInfo::FileMappingSize, true);
+
+    Uint32 length = w.getWordsUsed();
+    LinearSectionPtr ptr[3];
+    ptr[0].p = &propPage[0];
+    ptr[0].sz = length;
+
+    CreateFileReq * req = (CreateFileReq*)signal->getDataPtrSend();
+    req->senderRef = reference();
+    req->senderData = index;
+    req->objType = entry->type;
+    sendSignal(DBDICT_REF, GSN_CREATE_FILE_REQ, signal,
+               CreateFileReq::SignalLength, JBB, ptr, 1);
+    return;
+  }
+  default:
+    break;
+  }
+
+  startInsertTransactions(signal);
+}
+
+void
+Ndbcntr::execCREATE_FILEGROUP_REF(Signal* signal)
+{
+  jamEntry();
+  CreateFilegroupRef* ref = (CreateFilegroupRef*)signal->getDataPtr();
+  char buf[1024];
+
+  const ddentry* entry = &f_dd[ref->senderData];
+
+  if (entry->type == DictTabInfo::LogfileGroup)
+  {
+    BaseString::snprintf(buf, sizeof(buf), "create logfilegroup err %u",
+                         ref->errorCode);
+  }
+  else if (entry->type == DictTabInfo::Tablespace)
+  {
+    BaseString::snprintf(buf, sizeof(buf), "create tablespace err %u",
+                         ref->errorCode);
+  }
+  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
+}
+
+void
+Ndbcntr::execCREATE_FILEGROUP_CONF(Signal* signal)
+{
+  jamEntry();
+  CreateFilegroupConf* conf = (CreateFilegroupConf*)signal->getDataPtr();
+  createDDObjects(signal, conf->senderData + 1);
+}
+
+void
+Ndbcntr::execCREATE_FILE_REF(Signal* signal)
+{
+  jamEntry();
+  CreateFileRef* ref = (CreateFileRef*)signal->getDataPtr();
+  char buf[1024];
+
+  const ddentry* entry = &f_dd[ref->senderData];
+
+  if (entry->type == DictTabInfo::Undofile)
+  {
+    BaseString::snprintf(buf, sizeof(buf), "create undofile %s err %u",
+                         entry->name,
+                         ref->errorCode);
+  }
+  else if (entry->type == DictTabInfo::Datafile)
+  {
+    BaseString::snprintf(buf, sizeof(buf), "create datafile %s err %u",
+                         entry->name,
+                         ref->errorCode);
+  }
+  progError(__LINE__, NDBD_EXIT_INVALID_CONFIG, buf);
+}
+
+void
+Ndbcntr::execCREATE_FILE_CONF(Signal* signal)
+{
+  jamEntry();
+  CreateFileConf* conf = (CreateFileConf*)signal->getDataPtr();
+  createDDObjects(signal, conf->senderData + 1);
+}
+
 void Ndbcntr::createSystableLab(Signal* signal, unsigned index)
 {
   if (index >= g_sysTableCount) {
     ndbassert(index == g_sysTableCount);
-    startInsertTransactions(signal);
+    createDDObjects(signal, 0);
     return;
   }
   const SysTable& table = *g_sysTableList[index];
@@ -2780,25 +3108,30 @@ void Ndbcntr::execSTART_ORD(Signal* sign
 
 #define CLEAR_DX 13
 #define CLEAR_LCP 3
+#define CLEAR_DD 2
+// FileSystemPathDataFiles FileSystemPathUndoFiles
 
 void
 Ndbcntr::clearFilesystem(Signal* signal)
 {
-  const Uint32 lcp = c_fsRemoveCount >= CLEAR_DX;
-  
+  jam();
   FsRemoveReq * req  = (FsRemoveReq *)signal->getDataPtrSend();
   req->userReference = reference();
   req->userPointer   = 0;
   req->directory     = 1;
   req->ownDirectory  = 1;
 
-  if (lcp == 0)
+  const Uint32 DX = CLEAR_DX;
+  const Uint32 LCP = CLEAR_DX + CLEAR_LCP;
+  const Uint32 DD = CLEAR_DX + CLEAR_LCP + CLEAR_DD;
+
+  if (c_fsRemoveCount < DX)
   {
     FsOpenReq::setVersion(req->fileNumber, 3);
     FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL); // Can by any...
     FsOpenReq::v1_setDisk(req->fileNumber, c_fsRemoveCount);
   }
-  else
+  else if (c_fsRemoveCount < LCP)
   {
     FsOpenReq::setVersion(req->fileNumber, 5);
     FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
@@ -2806,6 +3139,18 @@ Ndbcntr::clearFilesystem(Signal* signal)
     FsOpenReq::v5_setTableId(req->fileNumber, 0);
     FsOpenReq::v5_setFragmentId(req->fileNumber, 0);
   }
+  else if (c_fsRemoveCount < DD)
+  {
+    FsOpenReq::setVersion(req->fileNumber, 6);
+    FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_DATA);
+    FsOpenReq::v5_setLcpNo(req->fileNumber,
+                           FsOpenReq::BP_DD_DF + c_fsRemoveCount - LCP);
+  }
+  else
+  {
+    ndbrequire(false);
+  }
+
   sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal, 
              FsRemoveReq::SignalLength, JBA);
   c_fsRemoveCount++;
@@ -2814,12 +3159,12 @@ Ndbcntr::clearFilesystem(Signal* signal)
 void
 Ndbcntr::execFSREMOVECONF(Signal* signal){
   jamEntry();
-  if(c_fsRemoveCount == CLEAR_DX + CLEAR_LCP){
+  if(c_fsRemoveCount == CLEAR_DX + CLEAR_LCP + CLEAR_DD){
     jam();
     sendSttorry(signal);
   } else {
     jam();
-    ndbrequire(c_fsRemoveCount < CLEAR_DX + CLEAR_LCP);
+    ndbrequire(c_fsRemoveCount < CLEAR_DX + CLEAR_LCP + CLEAR_DD);
     clearFilesystem(signal);
   }//if
 }
@@ -3132,3 +3477,5 @@ UpgradeStartup::execCNTR_MASTER_REPLY(Si
   block.progError(__LINE__,NDBD_EXIT_NDBREQUIRE,
 		  "UpgradeStartup::execCNTR_MASTER_REPLY");
 }
+
+template class Vector<ddentry>;

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Filename.cpp	2009-02-17 07:52:13 +0000
@@ -46,7 +46,7 @@ Filename::~Filename(){
 }
 
 void 
-Filename::set(Filename::NameSpec& spec,
+Filename::set(const BaseString basepath[],
 	      BlockReference blockReference, 
 	      const Uint32 filenumber[4], bool dir) 
 {
@@ -59,14 +59,14 @@ Filename::set(Filename::NameSpec& spec,
   if (version == 2)
   {
     sz = BaseString::snprintf(theName, sizeof(theName), "%s", 
-         spec.backup_path.c_str());
-    m_base_name = theName + spec.backup_path.length();
+                              basepath[FsOpenReq::BP_BACKUP].c_str());
+    m_base_name = theName + basepath[FsOpenReq::BP_BACKUP].length();
   }
   else
   {
     sz = BaseString::snprintf(theName, sizeof(theName), "%s", 
-         spec.fs_path.c_str());
-    m_base_name = theName + spec.fs_path.length();
+                              basepath[FsOpenReq::BP_FS].c_str());
+    m_base_name = theName + basepath[FsOpenReq::BP_FS].length();
   }
   
   switch(version){
@@ -153,6 +153,13 @@ Filename::set(Filename::NameSpec& spec,
     strcat(theName, buf);
     break;
   }
+  case 6:
+  {
+    Uint32 bp = FsOpenReq::v5_getLcpNo(filenumber);
+    sz = BaseString::snprintf(theName, sizeof(theName), "%s",
+                              basepath[bp].c_str());
+    break;
+  }
   default:
     ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","Wrong version");
   }
@@ -173,7 +180,7 @@ Filename::set(Filename::NameSpec& spec,
 }
 
 void 
-Filename::set(Filename::NameSpec& spec,
+Filename::set(const BaseString & basepath,
 	      SegmentedSectionPtr ptr, class SectionSegmentPool& pool)
 {
   char buf[PATH_MAX];
@@ -185,7 +192,8 @@ Filename::set(Filename::NameSpec& spec,
   }
   else 
   {
-    snprintf(theName, sizeof(theName), "%s%s", spec.fs_path.c_str(), buf);
-    m_base_name = theName + spec.fs_path.length();
+    snprintf(theName, sizeof(theName), "%s%s",
+             basepath.c_str(), buf);
+    m_base_name = theName + basepath.length();
   }
 }

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Filename.hpp	2009-02-17 07:52:13 +0000
@@ -62,19 +62,12 @@ public:
   Filename();
   ~Filename();
 
-  struct NameSpec {
-    NameSpec(BaseString& f, BaseString&b) :
-      fs_path(f), backup_path(b) {}
-    BaseString& fs_path;
-    BaseString& backup_path;
-  };
-  
-  void set(NameSpec& spec, 
+  void set(const BaseString basepath[],
 	   BlockReference, const Uint32 fileno[4], bool = false);
-  void set(NameSpec& spec, 
+  void set(const BaseString & basepath,
 	   SegmentedSectionPtr ptr, class SectionSegmentPool&);
   
-  const char* c_str() const;     // Complete name including dirname
+  const char* c_str() const;         // Complete name including dirname
   const char* get_base_name() const; // Exclude fs (or backup) path
 private:
   char theName[PATH_MAX];

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2008-10-24 11:00:37 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.cpp	2009-02-17 07:52:13 +0000
@@ -88,6 +88,53 @@ Ndbfs::~Ndbfs()
     delete theRequestPool;
 }
 
+static
+bool
+do_mkdir(const char * path)
+{
+#ifdef NDB_WIN32
+  return CreateDirectory(path, 0);
+#else
+  return ::mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP) == 0;
+#endif
+}
+
+static
+void
+add_path(BaseString& dst, const char * add)
+{
+  const char * tmp = dst.c_str();
+  unsigned len = dst.length();
+  unsigned dslen = (unsigned)strlen(DIR_SEPARATOR);
+
+  if (len > dslen && strcmp(tmp+(len - dslen), DIR_SEPARATOR) != 0)
+    dst.append(DIR_SEPARATOR);
+  dst.append(add);
+}
+
+static
+bool
+validate_path(BaseString & dst,
+              const char * path)
+{
+  char buf2[PATH_MAX];
+  memset(buf2, 0,sizeof(buf2));
+#ifdef NDB_WIN32
+  CreateDirectory(path, 0);
+  char* szFilePart;
+  if(!GetFullPathName(path, sizeof(buf2), buf2, &szFilePart) ||
+     (GetFileAttributes(buf2) & FILE_ATTRIBUTE_READONLY))
+    return false;
+#else
+  if (::realpath(path, buf2) == NULL ||
+      ::access(buf2, W_OK) != 0)
+    return false;
+#endif
+  dst.assign(buf2);
+  add_path(dst, "");
+  return true;
+}
+
 void 
 Ndbfs::execREAD_CONFIG_REQ(Signal* signal)
 {
@@ -99,12 +146,67 @@ Ndbfs::execREAD_CONFIG_REQ(Signal* signa
   const ndb_mgm_configuration_iterator * p = 
     m_ctx.m_config.getOwnConfigIterator();
   ndbrequire(p != 0);
-  theFileSystemPath.assfmt("%sndb_%u_fs%s", m_ctx.m_config.fileSystemPath(),
-			   getOwnNodeId(), DIR_SEPARATOR);
-  theBackupFilePath.assign(m_ctx.m_config.backupFilePath());
+  BaseString tmp;
+  tmp.assfmt("ndb_%u_fs%s", getOwnNodeId(), DIR_SEPARATOR);
+  m_base_path[FsOpenReq::BP_FS].assfmt("%s%s",
+                                       m_ctx.m_config.fileSystemPath(),
+                                       tmp.c_str());
+  m_base_path[FsOpenReq::BP_BACKUP].assign(m_ctx.m_config.backupFilePath());
 
   theRequestPool = new Pool<Request>;
 
+  const char * ddpath = 0;
+  ndb_mgm_get_string_parameter(p, CFG_DB_DD_FILESYSTEM_PATH, &ddpath);
+
+  {
+    const char * datapath = 0;
+    ndb_mgm_get_string_parameter(p, CFG_DB_DD_DATAFILE_PATH, &datapath);
+    if (datapath == 0)
+    {
+      if (ddpath)
+        datapath = ddpath;
+      else
+        datapath = m_ctx.m_config.fileSystemPath();
+    }
+
+    BaseString path;
+    add_path(path, datapath);
+    do_mkdir(path.c_str());
+    add_path(path, tmp.c_str());
+    do_mkdir(path.c_str());
+    if (!validate_path(m_base_path[FsOpenReq::BP_DD_DF], path.c_str()))
+    {
+      ERROR_SET(fatal, NDBD_EXIT_AFS_INVALIDPATH,
+                m_base_path[FsOpenReq::BP_DD_DF].c_str(),
+                "FileSystemPathDataFiles");
+    }
+  }
+
+  {
+    const char * undopath = 0;
+    ndb_mgm_get_string_parameter(p, CFG_DB_DD_UNDOFILE_PATH, &undopath);
+    if (undopath == 0)
+    {
+      if (ddpath)
+        undopath = ddpath;
+      else
+        undopath = m_ctx.m_config.fileSystemPath();
+    }
+
+    BaseString path;
+    add_path(path, undopath);
+    do_mkdir(path.c_str());
+    add_path(path, tmp.c_str());
+    do_mkdir(path.c_str());
+
+    if (!validate_path(m_base_path[FsOpenReq::BP_DD_UF], path.c_str()))
+    {
+      ERROR_SET(fatal, NDBD_EXIT_AFS_INVALIDPATH,
+                m_base_path[FsOpenReq::BP_DD_UF].c_str(),
+                "FileSystemPathUndoFiles");
+    }
+  }
+
   m_maxFiles = 0;
   ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles);
   Uint32 noIdleFiles = 27;
@@ -141,14 +243,7 @@ Ndbfs::execSTTOR(Signal* signal)
   if(signal->theData[1] == 0){ // StartPhase 0
     jam();
     
-    {
-#ifdef NDB_WIN32
-      CreateDirectory(theFileSystemPath.c_str(), 0);
-#else
-      mkdir(theFileSystemPath.c_str(),
-	    S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
-#endif
-    }      
+    do_mkdir(m_base_path[FsOpenReq::BP_FS].c_str());
     
     cownref = NDBFS_REF;
     // close all open files
@@ -182,7 +277,6 @@ Ndbfs::execFSOPENREQ(Signal* signal)
   const BlockReference userRef = fsOpenReq->userReference;
   AsyncFile* file = getIdleFile();
   ndbrequire(file != NULL);
-  Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
 
   Uint32 userPointer = fsOpenReq->userPointer;
   
@@ -208,12 +302,28 @@ Ndbfs::execFSOPENREQ(Signal* signal)
   
   if(signal->getNoOfSections() == 0){
     jam();
-    file->theFileName.set(spec, userRef, fsOpenReq->fileNumber);
+    file->theFileName.set(m_base_path, userRef, fsOpenReq->fileNumber);
   } else {
     jam();
     SegmentedSectionPtr ptr;
     signal->getSection(ptr, FsOpenReq::FILENAME);
-    file->theFileName.set(spec, ptr, g_sectionSegmentPool);
+    // QOD, should be arg to FSOPEN
+    if (refToMain(userRef) == TSMAN)
+    {
+      file->theFileName.set(m_base_path[FsOpenReq::BP_DD_DF],
+                            ptr, g_sectionSegmentPool);
+    }
+    else if (refToMain(userRef) == LGMAN)
+    {
+      file->theFileName.set(m_base_path[FsOpenReq::BP_DD_UF],
+                            ptr, g_sectionSegmentPool);
+    }
+    else
+    {
+      file->theFileName.set(m_base_path[FsOpenReq::BP_DD_UF],
+                            ptr, g_sectionSegmentPool);
+    }
+
     releaseSections(signal);
   }
   file->reportTo(&theFromThreads);
@@ -245,10 +355,11 @@ Ndbfs::execFSREMOVEREQ(Signal* signal)
   AsyncFile* file = getIdleFile();
   ndbrequire(file != NULL);
 
-  Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
-  file->theFileName.set(spec, userRef, req->fileNumber, req->directory);
+  Uint32 version = FsOpenReq::getVersion(req->fileNumber);
+  Uint32 bp = FsOpenReq::v5_getLcpNo(req->fileNumber);
+  file->theFileName.set(m_base_path, userRef, req->fileNumber, req->directory);
   file->reportTo(&theFromThreads);
-  
+
   Request* request = theRequestPool->get();
   request->action = Request::rmrf;
   request->par.rmrf.directory = req->directory;
@@ -258,7 +369,16 @@ Ndbfs::execFSREMOVEREQ(Signal* signal)
   request->file = file;
   request->theTrace = signal->getTrace();
   
+  if (version == 6)
+  {
+    if (m_base_path[FsOpenReq::BP_FS] == m_base_path[bp])
+      goto ignore;
+  }
+
   ndbrequire(forward(file, request));
+  return;
+ignore:
+  report(request, signal);
 }
 
 /*

=== modified file 'storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp'
--- a/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp	2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/blocks/ndbfs/Ndbfs.hpp	2009-02-17 07:52:13 +0000
@@ -21,7 +21,7 @@
 #include "Pool.hpp"
 #include "AsyncFile.hpp"
 #include "OpenFiles.hpp"
-
+#include <signaldata/FsOpenReq.hpp>
 
 
 // Because one NDB Signal request can result in multiple requests to
@@ -81,8 +81,7 @@ private:
   Vector<AsyncFile*> theIdleFiles; // List of idle AsyncFiles
   OpenFiles theOpenFiles;          // List of open AsyncFiles
 
-  BaseString theFileSystemPath;
-  BaseString theBackupFilePath;
+  BaseString m_base_path[FsOpenReq::BP_MAX];
   
   // Statistics variables
   Uint32 m_maxOpenedFiles;

=== modified file 'storage/ndb/src/kernel/blocks/tsman.cpp'
--- a/storage/ndb/src/kernel/blocks/tsman.cpp	2008-08-08 12:21:35 +0000
+++ b/storage/ndb/src/kernel/blocks/tsman.cpp	2009-02-17 07:52:13 +0000
@@ -1133,6 +1133,8 @@ Tsman::load_extent_page_callback(Signal*
   Ptr<Tablespace> ts_ptr;
   m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i);
   if (getNodeState().startLevel >= NodeState::SL_STARTED ||
+      (getNodeState().startLevel == NodeState::SL_STARTING &&
+       getNodeState().starting.restartType == NodeState::ST_INITIAL_START) ||
       (getNodeState().getNodeRestartInProgress() &&
        getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
   {

=== modified file 'storage/ndb/src/mgmsrv/ConfigInfo.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2008-11-03 08:30:23 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2009-02-17 07:52:13 +0000
@@ -1454,6 +1454,61 @@ const ConfigInfo::ParamInfo ConfigInfo::
     "false",
     "true"},
 
+  {
+    CFG_DB_DD_FILESYSTEM_PATH,
+    "FileSystemPathDD",
+    DB_TOKEN,
+    "Path to directory where the "DB_TOKEN_PRINT" node stores its disk-data/undo-files",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_STRING,
+    UNDEFINED,
+    0, 0 },
+
+  {
+    CFG_DB_DD_DATAFILE_PATH,
+    "FileSystemPathDataFiles",
+    DB_TOKEN,
+    "Path to directory where the "DB_TOKEN_PRINT" node stores its disk-data-files",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_STRING,
+    UNDEFINED,
+    0, 0 },
+
+  {
+    CFG_DB_DD_UNDOFILE_PATH,
+    "FileSystemPathUndoFiles",
+    DB_TOKEN,
+    "Path to directory where the "DB_TOKEN_PRINT" node stores its disk-undo-files",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_STRING,
+    UNDEFINED,
+    0, 0 },
+
+  {
+    CFG_DB_DD_LOGFILEGROUP_SPEC,
+    "InitialLogfileGroup",
+    DB_TOKEN,
+    "Logfile group that will be created during initial start",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_STRING,
+    UNDEFINED,
+    0, 0 },
+
+  {
+    CFG_DB_DD_TABLEPACE_SPEC,
+    "InitialTablespace",
+    DB_TOKEN,
+    "Tablespace that will be created during initial start",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_STRING,
+    UNDEFINED,
+    0, 0 },
+
   /***************************************************************************
    * API
    ***************************************************************************/

=== modified file 'storage/ndb/test/run-test/conf-dl145a.cnf'
--- a/storage/ndb/test/run-test/conf-dl145a.cnf	2007-06-04 08:32:32 +0000
+++ b/storage/ndb/test/run-test/conf-dl145a.cnf	2009-02-17 07:52:13 +0000
@@ -24,3 +24,6 @@ SendBufferMemory = 2M
 NoOfFragmentLogFiles = 4
 FragmentLogFileSize = 64M
 
+SharedGlobalMemory=256M
+InitialLogfileGroup=undo_buffer_size=64M;undofile01.dat:256M;undofile02.dat:128M
+InitialTablespace=datafile01.dat:128M;datafile02.dat:64M

=== modified file 'storage/ndb/test/run-test/conf-ndbmaster.cnf'
--- a/storage/ndb/test/run-test/conf-ndbmaster.cnf	2007-02-13 01:38:54 +0000
+++ b/storage/ndb/test/run-test/conf-ndbmaster.cnf	2009-02-17 07:52:13 +0000
@@ -21,3 +21,7 @@ BackupMemory = 64M
 MaxNoOfConcurrentScans = 100
 MaxNoOfSavedMessages= 1000
 SendBufferMemory = 2M
+
+SharedGlobalMemory=256M
+InitialLogfileGroup=undo_buffer_size=64M;undofile01.dat:256M;undofile02.dat:128M
+InitialTablespace=datafile01.dat:128M;datafile02.dat:64M

Thread
bzr commit into mysql-5.1-telco-6.2 branch (jonas:2819)Jonas Oreland17 Feb