diff --git a/CEP/BB/MWCommon/include/MWCommon/NodeDesc.h b/CEP/BB/MWCommon/include/MWCommon/NodeDesc.h index 2e67771d909ba8e9a5e059c3ab8945eb3261a395..1acd59b6099d34a603982130f02614871cb20c1a 100644 --- a/CEP/BB/MWCommon/include/MWCommon/NodeDesc.h +++ b/CEP/BB/MWCommon/include/MWCommon/NodeDesc.h @@ -24,7 +24,7 @@ namespace LOFAR { namespace CEP { /// It tells the name of the node and which file systems it has access to. /// /// Currently the information is made persistent in a LOFAR .parset file. - /// In the future it needs to use the Centrol Processor Resource Manager. + /// In the future it needs to use the Central Processor Resource Manager. class NodeDesc { @@ -40,9 +40,9 @@ namespace LOFAR { namespace CEP { void setName (const std::string& name) { itsName = name; } - /// Add a file system it has access to. - void addFileSys (const std::string& fsName) - { itsFileSys.push_back (fsName); } + /// Add a file system the node has access to. + // A possible leading /auto is removed from the mountPoint. + void addFileSys (const std::string& fsName, const string& mountPoint); /// Write it in parset format. void write (std::ostream& os, const std::string& prefix) const; @@ -55,9 +55,20 @@ namespace LOFAR { namespace CEP { const std::vector<std::string>& getFileSys() const { return itsFileSys; } + /// Get the mount points of the file systems. + const std::vector<std::string>& getMountPoints() const + { return itsMounts; } + + // Find the file system a file is on. + // The file must be given with its absolute file name. + // It does it by comparing the mount points with the leading part + // of the file name. + std::string findFileSys (const std::string& fileName) const; + private: - std::string itsName; //# full name of the node - std::vector<std::string> itsFileSys; //# name of file systems + std::string itsName; //# full name of the node + std::vector<std::string> itsFileSys; //# names of file systems + std::vector<std::string> itsMounts; //# and their mount points }; }} /// end namespaces diff --git a/CEP/BB/MWCommon/src/NodeDesc.cc b/CEP/BB/MWCommon/src/NodeDesc.cc index de8ea746672f0a37d4e380ffce908cd341d32c1c..ef29f42ec0a22f3289be07727f1bb6ec8c87216e 100644 --- a/CEP/BB/MWCommon/src/NodeDesc.cc +++ b/CEP/BB/MWCommon/src/NodeDesc.cc @@ -7,6 +7,7 @@ #include <MWCommon/NodeDesc.h> #include <Common/StreamUtil.h> +#include <Common/LofarLogger.h> #include <ostream> namespace std { @@ -20,12 +21,83 @@ namespace LOFAR { namespace CEP { { itsName = parset.getString ("NodeName"); itsFileSys = parset.getStringVector ("NodeFileSys"); + itsMounts = parset.getStringVector ("NodeMountPoints"); + ASSERT (itsFileSys.size() == itsMounts.size()); + for (uint i=0; i<itsMounts.size(); ++i) { + ASSERT (itsFileSys[i].size() > 0); + ASSERT (itsMounts[i].size() > 0 && itsMounts[i][0] == '/'); + } + } + + void NodeDesc::addFileSys (const string& fsName, + const string& mountPoint) + { + ASSERT (fsName.size() > 0); + string mp(mountPoint); + if (mp.size() > 5 && mp.substr(0,5) == "/auto") { + mp = mp.substr(5); + } + ASSERT (mp.size() > 0 && mp[0] == '/'); + itsFileSys.push_back (fsName); + itsMounts.push_back (mp); + } + + string NodeDesc::findFileSys (const string& fileName) const + { + // The file name must be absolute. + ASSERT (fileName.size() > 1 && fileName[0] == '/'); + // Determine the max nr of parts in the mount point. + // Remember the root filesys (a single /). + int nrp = 0; + int rootfs = -1; + for (uint i=0; i<itsMounts.size(); ++i) { + int nr=0; + const string& str = itsMounts[i]; + // A single / counts as no part. + if (str.size() == 1) { + rootfs = i; + } else { + for (uint j=0; j<str.size(); ++j) { + if (str[j] == '/') { + ++nr; + } + } + } + if (nr > nrp) { + nrp = nr; + } + } + // Find the slashes in the file name for each part. + vector<int> pos(nrp, -1); + int nr = 0; + for (uint i=1; i<fileName.size() && nr<nrp; ++i) { + if (fileName[i] == '/') { + pos[nr++] = i; + } + } + // Now compare if it matches the file name. + // Start with the longest possible string. + for (int p=nr-1; p>=0; --p) { + string filePart = fileName.substr(0,pos[p]); + for (uint i=0; i<itsMounts.size(); ++i) { + if (filePart == itsMounts[i]) { + return itsFileSys[i]; + } + } + } + // No match, so return root file system if there. + // Otherwise return empty string. + if (rootfs >= 0) { + return itsFileSys[rootfs]; + } + return ""; } void NodeDesc::write (ostream& os, const string& prefix) const { os << prefix << "NodeName = " << itsName << endl; - os << prefix << "NodeFileSys = " << itsFileSys << endl; + os << prefix << "NodeFileSys = " << itsFileSys << endl; + os << prefix << "NodeMountPoints = " << itsMounts << endl; } }} // end namespaces diff --git a/CEP/BB/MWCommon/test/tClusterDesc.cc b/CEP/BB/MWCommon/test/tClusterDesc.cc index 6c7799f342e784d4c6b7fd9144bb2ed8d77f3c77..a9d634d981a01f4ebc9c7b621b8c97b27169ae13 100644 --- a/CEP/BB/MWCommon/test/tClusterDesc.cc +++ b/CEP/BB/MWCommon/test/tClusterDesc.cc @@ -43,13 +43,13 @@ void doIt() cl.setName ("cl"); NodeDesc node1; node1.setName ("node1"); - node1.addFileSys ("fs0"); - node1.addFileSys ("fs1"); + node1.addFileSys ("fs0", "/auto/fs0"); + node1.addFileSys ("fs1", "/fs1"); cl.addNode (node1); NodeDesc node2; node2.setName ("node2"); - node2.addFileSys ("fs1"); - node2.addFileSys ("fs2"); + node2.addFileSys ("fs1", "/auto/fs1"); + node2.addFileSys ("fs2", "/fs2"); cl.addNode (node2); check(cl); // Write into parset file. diff --git a/CEP/BB/MWCommon/test/tNodeDesc.cc b/CEP/BB/MWCommon/test/tNodeDesc.cc index ceff7dc4476b864882fcef8c1db9c20436418db5..163f67559348d543ed1f1db18a24fa35786c9e5d 100644 --- a/CEP/BB/MWCommon/test/tNodeDesc.cc +++ b/CEP/BB/MWCommon/test/tNodeDesc.cc @@ -18,14 +18,20 @@ void check (const NodeDesc& node) ASSERT (node.getFileSys().size() == 2); ASSERT (node.getFileSys()[0] == "fs0"); ASSERT (node.getFileSys()[1] == "fs1"); + ASSERT (node.getMountPoints()[0] == "/fs0/fs1"); + ASSERT (node.getMountPoints()[1] == "/fs1"); + + ASSERT (node.findFileSys ("/fs1/abc") == "fs1"); + ASSERT (node.findFileSys ("/fs0/fs1/abc") == "fs0"); + ASSERT (node.findFileSys ("/fs0/abc") == ""); } void doIt() { NodeDesc node; node.setName ("node1"); - node.addFileSys ("fs0"); - node.addFileSys ("fs1"); + node.addFileSys ("fs0", "/auto/fs0/fs1"); + node.addFileSys ("fs1", "/fs1"); check(node); // Write into parset file. ofstream fos("tNodeDesc_tmp.fil"); @@ -36,6 +42,11 @@ void doIt() check(node2); node = node2; check(node); + // Chck that findFileSys handles a single / correctly. + node.addFileSys ("fs2", "/"); + ASSERT (node.findFileSys ("/fs1/abc") == "fs1"); + ASSERT (node.findFileSys ("/fs0/fs1/abc") == "fs0"); + ASSERT (node.findFileSys ("/fs0/abc") == "fs2"); } int main() diff --git a/CEP/BB/MWCommon/test/tWorkersDesc.cc b/CEP/BB/MWCommon/test/tWorkersDesc.cc index d41d8d7b5dbd55c265600ece61c1e8c331ce00ec..1319a1b8aa8cf7b2f1b67a9b0e0b1ebcb64269aa 100644 --- a/CEP/BB/MWCommon/test/tWorkersDesc.cc +++ b/CEP/BB/MWCommon/test/tWorkersDesc.cc @@ -19,19 +19,19 @@ void doIt1() cl.setName ("cl"); NodeDesc node0; node0.setName ("node0"); - node0.addFileSys ("fs0"); - node0.addFileSys ("fs1"); + node0.addFileSys ("fs0", "/fs0"); + node0.addFileSys ("fs1", "/fs1"); cl.addNode (node0); NodeDesc node1; node1.setName ("node1"); - node1.addFileSys ("fs1"); - node1.addFileSys ("fs2"); + node1.addFileSys ("fs1", "/fs1"); + node1.addFileSys ("fs2", "/fs2"); cl.addNode (node1); NodeDesc node2; node2.setName ("node2"); - node2.addFileSys ("fs0"); - node2.addFileSys ("fs1"); - node2.addFileSys ("fs2"); + node2.addFileSys ("fs0", "/fs0"); + node2.addFileSys ("fs1", "/fs1"); + node2.addFileSys ("fs2", "/fs2"); cl.addNode (node2); WorkersDesc wdesc(cl); // Now define all workers which can perform 2 work types. @@ -80,15 +80,15 @@ void doIt2() cl.setName ("cl"); NodeDesc node0; node0.setName ("node0"); - node0.addFileSys ("fs0"); + node0.addFileSys ("fs0", "/fs0"); cl.addNode (node0); NodeDesc node1; node1.setName ("node1"); - node1.addFileSys ("fs1"); + node1.addFileSys ("fs1", "/fs1"); cl.addNode (node1); NodeDesc node2; node2.setName ("node2"); - node2.addFileSys ("fs2"); + node2.addFileSys ("fs2", "/fs2"); cl.addNode (node2); WorkersDesc wdesc(cl); // Now define all workers which can perform 2 work types. diff --git a/CEP/BB/MWCommon/test/tfinddproc.in_cd b/CEP/BB/MWCommon/test/tfinddproc.in_cd index 06f24c07a9541724ff067c7f706a2f244abbd7ff..ddcf03f903fe98946b5fbc772c015adb2b582ae5 100644 --- a/CEP/BB/MWCommon/test/tfinddproc.in_cd +++ b/CEP/BB/MWCommon/test/tfinddproc.in_cd @@ -2,5 +2,7 @@ ClusterName = cl NNodes = 2 Node0.NodeName = node1 Node0.NodeFileSys = [node1:/usr] +Node0.NodeMountPoints = [/usr] Node1.NodeName = node2 Node1.NodeFileSys = [node1:/usr] +Node1.NodeMountPoints = [/usr] diff --git a/CEP/BB/MWCommon/test/tstartdproc.in_cd b/CEP/BB/MWCommon/test/tstartdproc.in_cd index 06f24c07a9541724ff067c7f706a2f244abbd7ff..ddcf03f903fe98946b5fbc772c015adb2b582ae5 100644 --- a/CEP/BB/MWCommon/test/tstartdproc.in_cd +++ b/CEP/BB/MWCommon/test/tstartdproc.in_cd @@ -2,5 +2,7 @@ ClusterName = cl NNodes = 2 Node0.NodeName = node1 Node0.NodeFileSys = [node1:/usr] +Node0.NodeMountPoints = [/usr] Node1.NodeName = node2 Node1.NodeFileSys = [node1:/usr] +Node1.NodeMountPoints = [/usr]