BUG: Foam::cp inadvertently creates recursive directories (fixes #2235)

- noticed by Robin Knowles with `decomposePar -fields -copyZero`

  The internals for the Foam:cp method combine the behaviour of
  a regular `cp` and `cp -R` combined.

  When source and target are both directories, the old implementation
  created a subdirectory for the contents.
  This normally fine,

      ok:  cp "path1/0/" to "path2/1" -> "path2/1/2"
      BUT: cp "path1/0/" to "path2/0" -> "path2/0/0" !!

  Now add check for the basenames first.
  If they are identical, we probably meant to copy directory contents
  only, without the additional subdir layer.

BUG: decomposePar -fields -copyZero copies the wrong directory

- was using the current time name (usually latest) instead of copying
  the 0 directory

ENH: accept 0.orig directories as a fallback to copy if the 0 directory
is missing
This commit is contained in:
Mark Olesen
2021-10-15 20:10:53 +02:00
parent 4a0646451d
commit fe8c630936
5 changed files with 85 additions and 49 deletions

View File

@ -687,46 +687,67 @@ int main(int argc, char *argv[])
if (copyZero)
{
// Copy the 0 directory into each of the processor directories
fileName prevTimePath;
for (label proci = 0; proci < mesh.nProcs(); ++proci)
{
Time processorDb
(
Time::controlDictName,
args.rootPath(),
args.caseName()/("processor" + Foam::name(proci))
);
processorDb.setTime(runTime);
// Copy the 0/ directory into each of the processor directories
// with fallback of 0.orig/ directory if necessary.
if (fileHandler().isDir(runTime.timePath()))
fileName inputDir(runTime.path()/"0");
bool canCopy = fileHandler().isDir(inputDir);
if (!canCopy)
{
// Try with "0.orig" instead
inputDir.ext("orig");
canCopy = fileHandler().isDir(inputDir);
}
if (canCopy)
{
// Avoid copying into the same directory multiple times
// (collated format). Don't need a hash here.
fileName prevOutputDir;
for (label proci = 0; proci < mesh.nProcs(); ++proci)
{
// Get corresponding directory name (to handle processors/)
const fileName timePath
Time processorDb
(
Time::controlDictName,
args.rootPath(),
args.caseName()/("processor" + Foam::name(proci))
);
// processorDb.setTime(runTime);
// Get corresponding directory name
// (to handle processors/)
const fileName outputDir
(
fileHandler().objectPath
(
IOobject
(
"",
processorDb.timeName(),
word::null, // name
"0", // instance (time == 0)
processorDb
),
word::null
)
);
if (timePath != prevTimePath)
if (outputDir != prevOutputDir)
{
Info<< "Processor " << proci
<< ": copying " << runTime.timePath() << nl
<< " to " << timePath << endl;
fileHandler().cp(runTime.timePath(), timePath);
<< ": copying \""
<< inputDir.name() << "/\" to "
<< runTime.relativePath(outputDir)
<< endl;
prevTimePath = timePath;
fileHandler().cp(inputDir, outputDir);
prevOutputDir = outputDir;
}
}
}
else
{
Info<< "No 0/ or 0.orig/ directory to copy" << nl;
}
}
else
{

View File

@ -2367,7 +2367,7 @@ int main(int argc, char *argv[])
}
if (!isDir(args.rootPath()))
if (!Foam::isDir(args.rootPath()))
{
FatalErrorInFunction
<< ": cannot open root directory " << args.rootPath()
@ -2393,7 +2393,7 @@ int main(int argc, char *argv[])
// want to delay constructing runTime until we've synced all time
// directories...
const fileName procDir(fileHandler().filePath(args.path()));
if (isDir(procDir))
if (Foam::isDir(procDir))
{
if (decompose)
{
@ -2580,7 +2580,7 @@ int main(int argc, char *argv[])
Info<< "Checking for mesh in " << meshPath << nl << endl;
boolList haveMesh(Pstream::nProcs(), false);
haveMesh[Pstream::myProcNo()] = isFile(meshPath);
haveMesh[Pstream::myProcNo()] = Foam::isFile(meshPath);
Pstream::gatherList(haveMesh);
Pstream::scatterList(haveMesh);
Info<< "Per processor mesh availability:" << nl
@ -2888,16 +2888,15 @@ int main(int argc, char *argv[])
selectedLagrangianFields
);
// If there are any "uniform" directories copy them from
// the master processor
// Copy any "uniform" directories from the master processor
if (Pstream::master())
{
fileName uniformDir0 = runTime.timePath()/"uniform";
if (isDir(uniformDir0))
const fileName uniformDir0(runTime.timePath()/"uniform");
if (Foam::isDir(uniformDir0))
{
Info<< "Detected additional non-decomposed files in "
<< uniformDir0 << endl;
cp(uniformDir0, baseRunTime.timePath());
Foam::cp(uniformDir0, baseRunTime.timePath());
}
}
}
@ -2993,7 +2992,7 @@ int main(int argc, char *argv[])
boolList haveMesh(Pstream::nProcs(), false);
haveMesh[Pstream::myProcNo()] = isFile(meshPath);
haveMesh[Pstream::myProcNo()] = Foam::isFile(meshPath);
Pstream::gatherList(haveMesh);
Pstream::scatterList(haveMesh);
Info<< "Per processor mesh availability:" << nl
@ -3130,17 +3129,13 @@ int main(int argc, char *argv[])
);
// Copy any uniform data
const fileName uniformDir("uniform");
if (isDir(baseRunTime.timePath()/uniformDir))
// Copy "uniform" data from the base directory
const fileName uniformDir0(baseRunTime.timePath()/"uniform");
if (Foam::isDir(uniformDir0))
{
Info<< "Detected additional non-decomposed files in "
<< baseRunTime.timePath()/uniformDir << endl;
cp
(
baseRunTime.timePath()/uniformDir,
runTime.timePath()/uniformDir
);
<< uniformDir0 << endl;
Foam::cp(uniformDir0, runTime.timePath());
}
}
}

View File

@ -64,7 +64,7 @@ int main(int argc, char *argv[])
// Back-up old optimisationDict, to maintain potential comments in it
if (Pstream::master())
{
cp(optDict.objectPath(), optDict.objectPath() + ".org");
Foam::cp(optDict.objectPath(), optDict.objectPath() + ".org");
}
// Construct mesh movement object and grab active design variables

View File

@ -7,7 +7,7 @@
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2011 Symscape
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -856,10 +856,20 @@ bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
}
else if (srcType == fileName::DIRECTORY)
{
// If dest is a directory, create the destination file name.
if (destFile.type() == fileName::DIRECTORY)
{
destFile /= src.components().last();
// Both are directories. Could mean copy contents or copy
// recursively. Don't actually know what the user wants,
// but assume that if names are identical == copy contents.
//
// So: "path1/foo" "path2/foo" copy contents
// So: "path1/foo" "path2/bar" copy directory
const word srcDirName = src.name();
if (destFile.name() != srcDirName)
{
destFile /= srcDirName;
}
}
// Make sure the destination directory extists.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -1047,14 +1047,24 @@ bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
return false;
}
ln(src, destFile);
Foam::ln(src, destFile);
}
else if (srcType == fileName::DIRECTORY)
{
// If dest is a directory, create the destination file name.
if (destFile.type() == fileName::DIRECTORY)
{
destFile /= src.components().last();
// Both are directories. Could mean copy contents or copy
// recursively. Don't actually know what the user wants,
// but assume that if names are identical == copy contents.
//
// So: "path1/foo" "path2/foo" copy contents
// So: "path1/foo" "path2/bar" copy directory
const word srcDirName = src.name();
if (destFile.name() != srcDirName)
{
destFile /= srcDirName;
}
}
// Make sure the destination directory exists.
@ -1101,7 +1111,7 @@ bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
}
// File to file.
cp(src/item, destFile/item, followLink);
Foam::cp(src/item, destFile/item, followLink);
}
// Copy sub directories.
@ -1123,7 +1133,7 @@ bool Foam::cp(const fileName& src, const fileName& dest, const bool followLink)
}
// Dir to Dir.
cp(src/item, destFile, followLink);
Foam::cp(src/item, destFile, followLink);
}
}
else