|
@@ -141,7 +141,7 @@ bool CConfigEnvHelper::addRoxieServers(const char* xmlArg)
|
|
|
StringBuffer sFarmName;
|
|
|
StringBuffer xpath;
|
|
|
|
|
|
- if (strlen(pszFarm))
|
|
|
+ if (pszFarm && strlen(pszFarm))
|
|
|
{
|
|
|
xpath.clear().appendf("RoxieCluster[@name='%s']/"XML_TAG_ROXIE_FARM, pszRoxieCluster);
|
|
|
pFarm = getSoftwareNode(xpath.str(), pszFarm);
|
|
@@ -186,50 +186,6 @@ bool CConfigEnvHelper::addRoxieServers(const char* xmlArg)
|
|
|
pFarm->addPropInt("@requestArrayThreads", 5);
|
|
|
pFarm->addProp("@aclName", "");
|
|
|
}
|
|
|
-
|
|
|
- Owned<IPropertyTreeIterator> iter = pSrcTree->getElements(XML_TAG_COMPONENT);
|
|
|
- StringBuffer sNotAdded;
|
|
|
- xpath.clear().appendf("RoxieCluster[@name='%s']/"XML_TAG_ROXIE_FARM"[@name='%s']/"XML_TAG_ROXIE_SERVER, pszRoxieCluster, sFarmName.str());
|
|
|
- ForEach (*iter)
|
|
|
- {
|
|
|
- IPropertyTree* pFolder = &iter->query();
|
|
|
-
|
|
|
- const char* pszName = pFolder->queryProp(XML_ATTR_NAME);
|
|
|
-
|
|
|
- // Check if we can add this computer
|
|
|
- if (checkComputerUse(pszName, pFarm))
|
|
|
- {
|
|
|
- StringBuffer sServerName( sFarmName), sbUniqueName;
|
|
|
- sServerName.append("_s");
|
|
|
- createUniqueName(sServerName.str(), xpath.str(), sbUniqueName);
|
|
|
-
|
|
|
- // Add process node
|
|
|
- IPropertyTree* pServer = createPTree(XML_TAG_ROXIE_SERVER);
|
|
|
- pServer->setProp(XML_ATTR_NAME, sbUniqueName.str());
|
|
|
- pServer->addProp(XML_ATTR_COMPUTER, pszName);
|
|
|
-
|
|
|
- IPropertyTree* pLegacyServer = addLegacyServer(sbUniqueName, pServer, pFarm, pszRoxieCluster);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- sNotAdded.append('\n');
|
|
|
- sNotAdded.append(pszName);
|
|
|
- sNotAdded.append(" ( ");
|
|
|
- sNotAdded.append( pFolder->queryProp(XML_ATTR_NETADDRESS) );
|
|
|
- sNotAdded.append(" )");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- xpath.clear().appendf("Software/RoxieCluster[@name='%s']", pszRoxieCluster);
|
|
|
- IPropertyTree* pRoxieCluster = m_pRoot->queryPropTree(xpath.str());
|
|
|
- renameInstances(pRoxieCluster);
|
|
|
-
|
|
|
- if (sNotAdded.length())
|
|
|
- {
|
|
|
- StringBuffer sMsg("The following servers were already allocated to the farm and could not be added:\n");
|
|
|
- sMsg.append(sNotAdded.str());
|
|
|
- }
|
|
|
-
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -610,30 +566,57 @@ bool CConfigEnvHelper::deleteRoxieServers(const char* xmlArg)
|
|
|
{
|
|
|
Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<RoxieData/>");
|
|
|
const char* pszRoxieCluster = pSrcTree->queryProp("@roxieName");
|
|
|
- unsigned int nComputers = 0;//computers.size();
|
|
|
+ const char* pParentName = pSrcTree->queryPropTree(XML_TAG_ROXIE_FARM) != NULL ? pSrcTree->queryPropTree(XML_TAG_ROXIE_FARM)->queryProp("@parent"): "";
|
|
|
+ const char* pRoxiePortName = pSrcTree->queryPropTree(XML_TAG_ROXIE_FARM) != NULL ? pSrcTree->queryPropTree(XML_TAG_ROXIE_FARM)->queryProp(XML_ATTR_NAME): "";
|
|
|
+ unsigned int nComputers = 0;
|
|
|
StringBuffer xpath;
|
|
|
xpath.clear().appendf("Software/RoxieCluster[@name='%s']", pszRoxieCluster);
|
|
|
IPropertyTree* pRoxieCluster = m_pRoot->queryPropTree(xpath.str());
|
|
|
- StringBuffer sFarmName;
|
|
|
|
|
|
- Owned<IPropertyTreeIterator> iterFarm = pSrcTree->getElements(XML_TAG_ROXIE_FARM);
|
|
|
- ForEach (*iterFarm)
|
|
|
+ if (pRoxiePortName && *pRoxiePortName && pParentName && *pParentName && strcmp(pParentName, "Roxie Ports") == 0)
|
|
|
{
|
|
|
- IPropertyTree* pFarm = &iterFarm->query();
|
|
|
- const char* pszFarm = pFarm->queryProp(XML_ATTR_NAME);
|
|
|
- deleteFarm(pRoxieCluster, pszFarm);
|
|
|
- }
|
|
|
+ StringBuffer sFarmName;
|
|
|
|
|
|
- Owned<IPropertyTreeIterator> iterServer = pSrcTree->getElements(XML_TAG_ROXIE_SERVER);
|
|
|
- ForEach (*iterServer)
|
|
|
- {
|
|
|
- IPropertyTree* pServer = &iterServer->query();
|
|
|
+ Owned<IPropertyTreeIterator> iterFarm = pSrcTree->getElements(XML_TAG_ROXIE_FARM);
|
|
|
+ ForEach (*iterFarm)
|
|
|
+ {
|
|
|
+ IPropertyTree* pFarm = &iterFarm->query();
|
|
|
+ const char* pszFarm = pFarm->queryProp(XML_ATTR_NAME);
|
|
|
|
|
|
- const char* pszName = pServer->queryProp(XML_ATTR_NAME);
|
|
|
- const char* pszFarm = pServer->queryProp("@parent");
|
|
|
- deleteServer(pRoxieCluster, pszFarm, pszName);
|
|
|
+ if (pszFarm == NULL || *pszFarm == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (strcmp(pszFarm, pRoxiePortName) == 0)
|
|
|
+ {
|
|
|
+ deleteFarm(pRoxieCluster, pszFarm);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
+ Owned<IPropertyTreeIterator> iter = pRoxieCluster->getElements(XML_TAG_ROXIE_SERVER);
|
|
|
+
|
|
|
+ IPropertyTree *pTree = NULL;
|
|
|
+
|
|
|
+ int count = 1;
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ StringBuffer xpath2(XML_TAG_ROXIE_SERVER);
|
|
|
+ xpath2.appendf("[%d]", count);
|
|
|
+ count++;
|
|
|
+
|
|
|
+ pTree = pRoxieCluster->queryPropTree(xpath2.str());
|
|
|
+ if (pSrcTree->queryPropTree(XML_TAG_ROXIE_ONLY_SLAVE) == NULL) //probably an old config
|
|
|
+ throw MakeStringException(-1, "Error modifying roxie cluster! Possible using an old version of the config?" );
|
|
|
+ if (pTree && (!strcmp(pSrcTree->queryPropTree(XML_TAG_ROXIE_ONLY_SLAVE)->queryProp(XML_ATTR_NAME), "Roxie Cluster") || !strcmp(pTree->queryProp(XML_ATTR_NAME), pSrcTree->queryPropTree(XML_TAG_ROXIE_ONLY_SLAVE)->queryProp(XML_ATTR_NAME))))
|
|
|
+ {
|
|
|
+ pRoxieCluster->removeTree(pTree);
|
|
|
+ count--;
|
|
|
+ }
|
|
|
+ } while (pTree);
|
|
|
+
|
|
|
Owned<IPropertyTreeIterator> iterSlaves = pSrcTree->getElements(XML_TAG_ROXIE_ONLY_SLAVE);
|
|
|
ForEach (*iterSlaves)
|
|
|
{
|
|
@@ -776,20 +759,18 @@ bool CConfigEnvHelper::handleRoxieSlaveConfig(const char* xmlArg)
|
|
|
try
|
|
|
{
|
|
|
Owned<IPropertyTree> pSrcTree = createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<RoxieData/>");
|
|
|
- const char* type = pSrcTree->queryProp(XML_ATTR_TYPE);
|
|
|
const char* pszRoxie = pSrcTree->queryProp("@roxieName");
|
|
|
- const char* val1 = pSrcTree->queryProp("@val1");
|
|
|
- const char* sOffset = pSrcTree->queryProp("@val2");
|
|
|
|
|
|
StringBuffer xpath;
|
|
|
- xpath.clear().appendf("Software/RoxieCluster[@name='%s']", pszRoxie);
|
|
|
+ xpath.clear().appendf("%s/%s[%s='%s']", XML_TAG_SOFTWARE, XML_TAG_ROXIECLUSTER, XML_ATTR_NAME, pszRoxie);
|
|
|
IPropertyTree* pRoxie = m_pRoot->queryPropTree(xpath.str());
|
|
|
|
|
|
if (!pRoxie)
|
|
|
throw MakeStringException(-1, "Cannot find roxie with name %s", pszRoxie);
|
|
|
|
|
|
- Owned<IPropertyTreeIterator> iterComputers = pSrcTree->getElements("Computer");
|
|
|
+ Owned<IPropertyTreeIterator> iterComputers = pSrcTree->getElements(XML_TAG_INSTANCES"/"XML_TAG_INSTANCE);
|
|
|
IPropertyTreePtrArray computers;
|
|
|
+
|
|
|
ForEach (*iterComputers)
|
|
|
{
|
|
|
IPropertyTree* pComp = &iterComputers->query();
|
|
@@ -801,72 +782,23 @@ bool CConfigEnvHelper::handleRoxieSlaveConfig(const char* xmlArg)
|
|
|
computers.push_back(pComputer);
|
|
|
}
|
|
|
|
|
|
- m_numChannels = atoi(val1);
|
|
|
- m_numDataCopies = 0;
|
|
|
- const char* confType;
|
|
|
- char chDrive;
|
|
|
-
|
|
|
- if (!strcmp(type, "Circular"))
|
|
|
- {
|
|
|
- if (!GenerateCyclicRedConfig(pRoxie, computers, val1, sOffset))
|
|
|
- return false;
|
|
|
-
|
|
|
- confType = "cyclic redundancy";
|
|
|
- chDrive = 'c';
|
|
|
-
|
|
|
- pRoxie->setProp("@cyclicOffset", sOffset);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (!strcmp(type, "Overloaded"))
|
|
|
- {
|
|
|
- if (!GenerateOverloadedConfig(pRoxie, computers, val1))
|
|
|
- return false;
|
|
|
-
|
|
|
- confType = "overloaded";
|
|
|
- chDrive = 'c';
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (!strcmp(type, "Full"))
|
|
|
- {
|
|
|
- m_numDataCopies = atoi( val1 );
|
|
|
- confType = "full redundancy";
|
|
|
- }
|
|
|
- else //no redundancy
|
|
|
- {
|
|
|
- m_numDataCopies = 1;
|
|
|
- confType = "simple";
|
|
|
- }
|
|
|
-
|
|
|
- if (!GenerateFullRedConfig(pRoxie, m_numDataCopies, computers))
|
|
|
- return false;
|
|
|
- }
|
|
|
+ RemoveSlaves(pRoxie, true);
|
|
|
+ RemoveSlaves(pRoxie, false);
|
|
|
|
|
|
- if (pRoxie->hasProp("@cyclicOffset"))
|
|
|
- pRoxie->removeProp("@cyclicOffset");
|
|
|
- }
|
|
|
- //give legacy slaves unique names
|
|
|
- UINT i = 1;
|
|
|
- Owned<IPropertyTreeIterator> it = pRoxie->getElements(XML_TAG_ROXIE_SLAVE);
|
|
|
- ForEach( *it)
|
|
|
+ for (int i=0; i<computers.size(); i++)
|
|
|
{
|
|
|
- StringBuffer name;
|
|
|
- name.append('s').append(i);
|
|
|
-
|
|
|
- IPropertyTree* pLegacySlave = &it->query();
|
|
|
- pLegacySlave->setProp(XML_ATTR_NAME, name.str() );
|
|
|
+ IPropertyTree* pComputer = computers[i];
|
|
|
+ const char* szComputer = pComputer->queryProp(XML_ATTR_NAME);
|
|
|
+ const char* netAddress = pComputer->queryProp(XML_ATTR_NETADDRESS);
|
|
|
+ const char* pCompName = pComputer->queryProp(XML_ATTR_NAME);
|
|
|
+
|
|
|
+ IPropertyTree *pTree = addNode(XML_TAG_ROXIE_SERVER, pRoxie);
|
|
|
+ pTree->setProp(XML_ATTR_NAME, szComputer);
|
|
|
+ pTree->setProp(XML_ATTR_NETADDRESS, netAddress);
|
|
|
+ pTree->setProp(XML_ATTR_COMPUTER, pCompName);
|
|
|
}
|
|
|
|
|
|
- pRoxie->setProp("@slaveConfig", confType);
|
|
|
- pRoxie->setPropInt("@clusterWidth", computers.size());
|
|
|
- pRoxie->setPropInt("@numChannels", m_numChannels);
|
|
|
- pRoxie->setPropInt("@numDataCopies", m_numDataCopies);
|
|
|
- pRoxie->setProp("@localSlave", computers.size() > 1 ? "false" : "true");
|
|
|
-
|
|
|
- //change all legacy servers
|
|
|
- Owned<IPropertyTreeIterator> iterServers = pRoxie->getElements(XML_TAG_ROXIE_SERVER);
|
|
|
- }
|
|
|
+ }
|
|
|
catch (IException *e)
|
|
|
{
|
|
|
StringBuffer msg;
|
|
@@ -874,161 +806,27 @@ bool CConfigEnvHelper::handleRoxieSlaveConfig(const char* xmlArg)
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
- throw MakeStringException(-1, "Unknown exception in generating slave configuration!" );
|
|
|
+ throw MakeStringException(-1, "Unknown exception adding servers" );
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool CConfigEnvHelper::GenerateCyclicRedConfig(IPropertyTree* pRoxie, IPropertyTreePtrArray& computers,
|
|
|
- const char* copies, const char* pszOffset)
|
|
|
-{
|
|
|
- const int nComputers = computers.size();
|
|
|
- if (!nComputers)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (!EnsureInRange(copies, min(2, nComputers), max(nComputers, 1), "Channel redundancy") ||
|
|
|
- !EnsureInRange(pszOffset, min(1, nComputers-1), nComputers-1, "Channel offset"))
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- const int offset = atoi( pszOffset );
|
|
|
- m_numDataCopies = atoi( copies );
|
|
|
-
|
|
|
- const int minOffset = min(1, nComputers-1);
|
|
|
- if( offset < minOffset )
|
|
|
- throw MakeStringException(-1, "Offset cannot be less than %d", minOffset);
|
|
|
- if ( offset > nComputers )
|
|
|
- throw MakeStringException(-1, "Offset cannot be greater than %d", nComputers);
|
|
|
-
|
|
|
- RemoveSlaves(pRoxie, true);
|
|
|
- RemoveSlaves(pRoxie, false);
|
|
|
-
|
|
|
- for (int i=0; i<nComputers; i++)
|
|
|
- {
|
|
|
- IPropertyTree* pComputer = computers[i];
|
|
|
- const char* szComputer = pComputer->queryProp(XML_ATTR_NAME);
|
|
|
- const char* netAddress = pComputer->queryProp(XML_ATTR_NETADDRESS);
|
|
|
-
|
|
|
- StringBuffer name;
|
|
|
- name.appendf("s%d", i+1);
|
|
|
-
|
|
|
- IPropertyTree* pSlave = pRoxie->addPropTree(XML_TAG_ROXIE_ONLY_SLAVE, createPTree());
|
|
|
- pSlave->addProp(XML_ATTR_NAME, name.str());
|
|
|
- pSlave->addProp(XML_ATTR_COMPUTER, szComputer);
|
|
|
-
|
|
|
- const int baseChannel = i; //channel for first copy of slave (0 based)
|
|
|
- int channel;
|
|
|
- for (int c=0; c<m_numDataCopies; c++)
|
|
|
- {
|
|
|
- channel = 1 + ((baseChannel + c*(nComputers-offset)) % nComputers);
|
|
|
-
|
|
|
- IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
|
|
|
- pInstance->setPropInt("@number", channel);
|
|
|
-
|
|
|
- StringBuffer strTemp;
|
|
|
- strTemp.append(c);
|
|
|
-
|
|
|
- pInstance->addProp(XML_ATTR_LEVEL, strTemp.str());
|
|
|
- }
|
|
|
- }
|
|
|
- m_numChannels = nComputers;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool CConfigEnvHelper::GenerateOverloadedConfig(IPropertyTree* pRoxie, IPropertyTreePtrArray& computers, const char* copies)
|
|
|
-{
|
|
|
- const UINT nComputers = computers.size();
|
|
|
- if (!nComputers)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (!EnsureInRange(copies, 1, 0, "Channels per host"))
|
|
|
- return false;
|
|
|
-
|
|
|
- m_numDataCopies = atoi( copies );
|
|
|
-
|
|
|
- RemoveSlaves(pRoxie, true);
|
|
|
- RemoveSlaves(pRoxie, false);
|
|
|
-
|
|
|
- int channel = 1;
|
|
|
- for (UINT i=0; i<nComputers; i++)
|
|
|
- {
|
|
|
- IPropertyTree* pComputer = computers[i];
|
|
|
- const char* szComputer = pComputer->queryProp(XML_ATTR_NAME);
|
|
|
- const char* netAddress = pComputer->queryProp(XML_ATTR_NETADDRESS);
|
|
|
-
|
|
|
- StringBuffer name;
|
|
|
- name.appendf("s%d", i+1);
|
|
|
-
|
|
|
- IPropertyTree* pSlave = pRoxie->addPropTree(XML_TAG_ROXIE_ONLY_SLAVE, createPTree());
|
|
|
- pSlave->addProp(XML_ATTR_NAME, name.str());
|
|
|
- pSlave->addProp(XML_ATTR_COMPUTER, szComputer);
|
|
|
-
|
|
|
- for (int c=0; c<m_numDataCopies; c++)
|
|
|
- {
|
|
|
- IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
|
|
|
- pInstance->setPropInt("@number", channel + c*nComputers);
|
|
|
-
|
|
|
- StringBuffer strTemp;
|
|
|
- strTemp.append(c);
|
|
|
-
|
|
|
- pInstance->addProp(XML_ATTR_LEVEL, strTemp.str());
|
|
|
- }
|
|
|
- channel++;
|
|
|
- }
|
|
|
- m_numChannels = m_numDataCopies*nComputers;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool CConfigEnvHelper::GenerateFullRedConfig(IPropertyTree* pRoxie, int copies, IPropertyTreePtrArray& computers)
|
|
|
-{
|
|
|
- int nComputers = computers.size();
|
|
|
- if (!nComputers)
|
|
|
- return false;
|
|
|
-
|
|
|
- StringBuffer sbCopies;
|
|
|
- sbCopies.appendf("%d", copies);
|
|
|
- //if full redundancy is selected then check channel redundancy
|
|
|
- if (copies != 1 && !EnsureInRange(sbCopies.str(), min(2, nComputers), (nComputers+1)/2, "Channel redundancy"))
|
|
|
- return false;
|
|
|
-
|
|
|
- const int maxChannel = nComputers / copies;
|
|
|
-
|
|
|
- RemoveSlaves(pRoxie, true);
|
|
|
- RemoveSlaves(pRoxie, false);
|
|
|
-
|
|
|
- int channel = 0;
|
|
|
- nComputers = maxChannel * copies;
|
|
|
- for (int i=0; i<nComputers; i++)
|
|
|
- {
|
|
|
- IPropertyTree* pComputer = computers[i];
|
|
|
- const char* szComputer = pComputer->queryProp(XML_ATTR_NAME);
|
|
|
- const char* netAddress = pComputer->queryProp(XML_ATTR_NETADDRESS);
|
|
|
-
|
|
|
- StringBuffer name;
|
|
|
- name.appendf("s%d", i+1);
|
|
|
-
|
|
|
- IPropertyTree* pSlave = pRoxie->addPropTree(XML_TAG_ROXIE_ONLY_SLAVE, createPTree());
|
|
|
- pSlave->addProp(XML_ATTR_NAME, name.str());
|
|
|
- pSlave->addProp(XML_ATTR_COMPUTER, szComputer);
|
|
|
-
|
|
|
- IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
|
|
|
- pInstance->setPropInt("@number", 1 + (channel % maxChannel));
|
|
|
- pInstance->addProp(XML_ATTR_LEVEL, "0");
|
|
|
-
|
|
|
- channel++;
|
|
|
-
|
|
|
- }
|
|
|
- m_numChannels = maxChannel;
|
|
|
- return true;
|
|
|
-}
|
|
|
|
|
|
void CConfigEnvHelper::RemoveSlaves(IPropertyTree* pRoxie, bool bLegacySlaves/*=false*/)
|
|
|
{
|
|
|
IPropertyTree* pChild;
|
|
|
while ((pChild = pRoxie->queryPropTree( bLegacySlaves ? XML_TAG_ROXIE_SLAVE "[1]" : "RoxieSlave[1]")) != NULL)
|
|
|
pRoxie->removeTree( pChild );
|
|
|
+
|
|
|
+ IPropertyTree *pTree = NULL;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ pTree = pRoxie->queryPropTree(XML_TAG_ROXIE_SERVER"[1]");
|
|
|
+
|
|
|
+ if (pTree)
|
|
|
+ pRoxie->removeTree(pTree);
|
|
|
+ } while (pTree);
|
|
|
}
|
|
|
|
|
|
void CConfigEnvHelper::RenameThorInstances(IPropertyTree* pThor)
|