«
Previous
|
Next
»
Revision dbbd2afa
Added by david.sorber over 2 years ago
- ID dbbd2afaf6410ef19291da7d0d18b16407571023
- Parent 4fd46efa
| src/CopyManager.cc | ||
|---|---|---|
|
: r_options(options),
|
||
|
m_terminate(false),
|
||
|
m_running(false),
|
||
|
m_iterationError(false),
|
||
|
p_mainThread(nullptr),
|
||
|
p_counterThread(nullptr),
|
||
|
m_totalEntries(0),
|
||
| ... | ... | |
|
// Recursively iterate over the source directory and add each entry to the
|
||
|
// queue
|
||
|
const std::string& srcPath(r_options.getSrcPath());
|
||
|
for (const auto& dirEntry : sfs::recursive_directory_iterator(srcPath))
|
||
|
try
|
||
|
{
|
||
|
// Flow control -- delay until the entry queue is below the specified
|
||
|
// threshold size before proceeding
|
||
|
while (m_entryQueue.size() >= r_options.getFlowControlThreshold())
|
||
|
{
|
||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||
|
}
|
||
|
for (const auto &dirEntry: sfs::recursive_directory_iterator(srcPath)) {
|
||
|
// Flow control -- delay until the entry queue is below the specified
|
||
|
// threshold size before proceeding
|
||
|
while (m_entryQueue.size() >= r_options.getFlowControlThreshold()) {
|
||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||
|
}
|
||
|
|
||
|
// std::cout << "PATH: " << dirEntry << std::endl;
|
||
|
m_entryQueue.push_back(dirEntry);
|
||
|
// std::cout << "PATH: " << dirEntry << std::endl;
|
||
|
m_entryQueue.push_back(dirEntry);
|
||
|
}
|
||
|
}
|
||
|
catch (const std::filesystem::filesystem_error& exp)
|
||
|
{
|
||
|
LOG(error) << "Exception while iterating... terminating";
|
||
|
m_iterationError = true;
|
||
|
terminate();
|
||
|
}
|
||
|
|
||
|
// Add copy thread terminators
|
||
| ... | ... | |
|
std::error_code errorCode;
|
||
|
int fromFd = 0;
|
||
|
int toFd = 0;
|
||
|
std::string srcPath;
|
||
|
uid_t eUid = geteuid();
|
||
|
gid_t eGid = getegid();
|
||
|
|
||
|
while (true)
|
||
|
{
|
||
| ... | ... | |
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (m_terminate)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// TODO: restructure this
|
||
|
if (entry.is_directory())
|
||
|
{
|
||
|
// Directory entry
|
||
|
// const char* destDirPath = entry.path().string().c_str();
|
||
|
// rc = stat(destDirPath, &statBuf);
|
||
|
//--- Directory entry
|
||
|
|
||
|
// Stat directory if preserving perms, owner, or group
|
||
|
if (r_options.getPreservePerms() || r_options.getPreserveOwner() ||
|
||
|
r_options.getPreserveGroup())
|
||
|
{
|
||
|
srcPath.assign(entry.path().string());
|
||
|
rc = stat(srcPath.c_str(), &statBuf);
|
||
|
if (rc != 0)
|
||
|
{
|
||
|
LOG(error) << "Unable to stat(): " << srcPath << " -- "
|
||
|
<< errno << " -- " << std::strerror(errno);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Create destination path
|
||
|
auto destDirPath = sfs::path{r_options.getDestPath()} /
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
// Preserve permissions
|
||
|
if (r_options.getPreservePerms() && rc == 0)
|
||
|
{
|
||
|
rc = chmod(destDirPath.string().c_str(), statBuf.st_mode);
|
||
|
if (rc != 0)
|
||
|
{
|
||
|
LOG(error) << "Unable to chmod(): " << destDirPath << " -- "
|
||
|
<< errno << " -- " << std::strerror(errno);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Preserve owner / group
|
||
|
if (r_options.getPreserveOwner() || r_options.getPreserveGroup())
|
||
|
{
|
||
|
uid_t newUid = r_options.getPreserveOwner() ? statBuf.st_uid : eUid;
|
||
|
gid_t newGid = r_options.getPreserveGroup() ? statBuf.st_gid : eGid;
|
||
|
rc = chown(srcPath.c_str(), newUid, newGid);
|
||
|
if (rc != 0)
|
||
|
{
|
||
|
LOG(error) << "Unable to chown(): " << srcPath << " -- "
|
||
|
<< errno << " -- " << std::strerror(errno);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
incProcessedEntries();
|
||
|
LOG(debug) << "Created directory: " << entry.path();
|
||
|
}
|
||
|
else if (entry.is_regular_file())
|
||
|
{
|
||
|
// Regular file entry
|
||
|
//--- Regular file entry
|
||
|
|
||
|
// Remove filename from file path
|
||
|
auto fileDirPath = entry.path();
|
||
| ... | ... | |
|
while (rc > 0)
|
||
|
{
|
||
|
rc = sendfile(toFd, fromFd, 0, count);
|
||
|
if (m_terminate)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (rc < 0)
|
||
|
{
|
||
| ... | ... | |
|
close(toFd);
|
||
|
incProcessedEntries();
|
||
|
|
||
|
LOG(debug) << "Copy: " << entry.path().string()
|
||
|
<< " to: " << destFilePath.string();
|
||
|
if (! m_terminate)
|
||
|
{
|
||
|
LOG(debug) << "Copy: " << entry.path().string()
|
||
|
<< " to: " << destFilePath.string();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
| ... | ... | |
|
void DBS::CopyManager::counterThreadBody()
|
||
|
{
|
||
|
const std::string& srcPath(r_options.getSrcPath());
|
||
|
for (const auto& dirEntry : sfs::recursive_directory_iterator(srcPath))
|
||
|
try
|
||
|
{
|
||
|
if (dirEntry.is_directory() || dirEntry.is_regular_file())
|
||
|
{
|
||
|
incTotalEntries();
|
||
|
}
|
||
|
else
|
||
|
for (const auto& dirEntry : sfs::recursive_directory_iterator(srcPath))
|
||
|
{
|
||
|
incInvalidEntries();
|
||
|
if (m_terminate)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (dirEntry.is_directory() || dirEntry.is_regular_file())
|
||
|
{
|
||
|
incTotalEntries();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
incInvalidEntries();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (const std::filesystem::filesystem_error& exp)
|
||
|
{
|
||
|
LOG(error) << "Exception while iterating... terminating";
|
||
|
m_iterationError = true;
|
||
|
terminate();
|
||
|
}
|
||
|
}
|
||
WIP; adding options to preserve file/directory permissions, owner, and
group.