diff --git a/dali/base/dadfs.cpp b/dali/base/dadfs.cpp index 5c4da62b457..8eeac19b9bc 100644 --- a/dali/base/dadfs.cpp +++ b/dali/base/dadfs.cpp @@ -10756,10 +10756,11 @@ class CInitGroups void constructStorageGroups(bool force, StringBuffer &messages) { - Owned storage = getGlobalConfigSP()->getPropTree("storage"); + Owned globalConfig = getGlobalConfig(); + Owned storage = globalConfig->getPropTree("storage"); if (storage) { - normalizeHostGroups(); + normalizeHostGroups(globalConfig); Owned planes = storage->getElements("planes"); ForEach(*planes) diff --git a/dali/base/dafdesc.cpp b/dali/base/dafdesc.cpp index b3def355529..5b47e2707eb 100644 --- a/dali/base/dafdesc.cpp +++ b/dali/base/dafdesc.cpp @@ -3786,7 +3786,7 @@ static void doInitializeStorageGroups(bool createPlanesFromGroups, IPropertyTree } //Ensure that host groups that are defined in terms of other host groups are expanded out so they have an explicit list of hosts - normalizeHostGroups(); + normalizeHostGroups(newGlobalConfiguration); //The following can be removed once the storage planes have better integration setupContainerizedStorageLocations(); diff --git a/dali/base/dameta.cpp b/dali/base/dameta.cpp index 44dcbe481e8..f35dfab9f0c 100644 --- a/dali/base/dameta.cpp +++ b/dali/base/dameta.cpp @@ -21,10 +21,12 @@ #include "dautils.hpp" -// Expand indirect hostGroups so each hostGroups has an expanded list of host names -void normalizeHostGroups() +//Expand indirect hostGroups so each hostGroups has an expanded list of host names +//This function cannot use (directly or indirectly) getGlobalConfig(), because it may be called when creating +//a new config. +void normalizeHostGroups(IPropertyTree * globalConfig) { - Owned hostGroupIter = getGlobalConfigSP()->getElements("storage/hostGroups"); + Owned hostGroupIter = globalConfig->getElements("storage/hostGroups"); //Process the groups in order - so that multiple levels of indirection are supported ForEach (*hostGroupIter) { @@ -33,7 +35,15 @@ void normalizeHostGroups() { const char * name = cur.queryProp("@name"); const char * baseGroup = cur.queryProp("@hostGroup"); - Owned match = getHostGroup(baseGroup, true); + if (!baseGroup) + throw makeStringExceptionV(-1, "HostGroup %s with no hosts does not have a base hostgroup", name ? name : ""); + + //Cannot call getHostGroup() because that uses getGlobalConfig() + VStringBuffer xpath("storage/hostGroups[@name='%s']", baseGroup); + IPropertyTree * match = globalConfig->queryPropTree(xpath); + if (!match) + throw makeStringExceptionV(-1, "No entry found for hostGroup: '%s'", baseGroup); + StringArray hosts; Owned hostIter = match->getElements("hosts"); ForEach (*hostIter) diff --git a/dali/base/dameta.hpp b/dali/base/dameta.hpp index c791db82960..f392f56e5f8 100644 --- a/dali/base/dameta.hpp +++ b/dali/base/dameta.hpp @@ -58,6 +58,6 @@ constexpr ResolveOptions operator &(ResolveOptions l, ResolveOptions r) { return */ extern da_decl IPropertyTree * resolveLogicalFilenameFromDali(const char * filename, IUserDescriptor * user, ResolveOptions options); -extern da_decl void normalizeHostGroups(); // Expand indirect hostGroups so each hostGroups has an expanded list of host names +extern da_decl void normalizeHostGroups(IPropertyTree * globalConfig); // Expand indirect hostGroups so each hostGroups has an expanded list of host names #endif diff --git a/dali/base/dautils.cpp b/dali/base/dautils.cpp index 7ad40dfd672..d25e0a7ef9a 100644 --- a/dali/base/dautils.cpp +++ b/dali/base/dautils.cpp @@ -88,8 +88,9 @@ bool getPlaneHost(StringBuffer &host, IPropertyTree *plane, unsigned which) if (!hostGroup) return false; - if (which >= hostGroup->getCount("hosts")) - throw makeStringException(0, "getPlaneHost: index out of range"); + unsigned maxHosts = hostGroup->getCount("hosts"); + if (which >= maxHosts) + throw makeStringExceptionV(0, "getPlaneHost: index %u out of range 1..%u", which, maxHosts); VStringBuffer xpath("hosts[%u]", which+1); // which is 0 based host.append(hostGroup->queryProp(xpath)); return true;