ewmscp  ..
Classes | Public Member Functions | Static Private Attributes | List of all members
outputHandler::posixFile Class Reference

#include <outputHandlerPosixFile.h>

Inheritance diagram for outputHandler::posixFile:
[legend]
Collaboration diagram for outputHandler::posixFile:
[legend]

Classes

class  writerPosixFile
 

Public Member Functions

 posixFile ()=default
 
 ~posixFile () override=default
 
std::unique_ptr< writernewWriter (const std::string &path, bool mightAppend, size_t sourceSize, size_t readBlockSize, copyRequest::stateType &state, bool noWrite, std::unique_ptr< ioHandle::attrDataType > attrData, std::unique_ptr< acl::list > aclData) override
 
std::unique_ptr< writernewTmpWriter (std::string &path, size_t sourceSize, bool noWrite, std::unique_ptr< ioHandle::attrDataType > attrData, std::unique_ptr< acl::list > aclData) override
 
void ensureParentDirs (const std::string &path, const std::string &srcPath, inputHandler::base *InputHandler) override
 
void remove (const std::string &path, copyRequest::stateType &state) override
 
bool renameSimple (const std::string &fromPath, const std::string &toPath) override
 
base::renameRetvalType rename (const std::string &fromPath, const std::unique_ptr< const genericStat > &readInitialStat, const std::string &toPath, copyRequest::stateType &state) override
 
void createSymlink (const std::vector< char > &target, const std::string &path, uid_t uid, gid_t gid) override
 
void doAttributePreservations (const std::string &path, const genericStat &stat) override
 
size_t getMaxNameLength (const std::string &dirPath) override
 
- Public Member Functions inherited from outputHandler::base
 ~base () override=default
 
template<class C >
void shortenNameToMax (const std::string &path, C &pathBuf, const std::string &suffix)
 
- Public Member Functions inherited from pathHandler
virtual ~pathHandler ()=default
 
- Public Member Functions inherited from posixFileCommon
bool pathExists (const std::string &path) override
 
std::unique_ptr< const genericStatgetStat (const std::string &path, bool followLink) override
 
std::string getXattr (const std::string &path, const std::string &name) override
 

Static Private Attributes

static factoryTemplate< posixFilefactory
 

Additional Inherited Members

- Public Types inherited from outputHandler::base
enum  renameRetvalType { renameRetvalType::ok, renameRetvalType::fileChanged, renameRetvalType::fileVanished, renameRetvalType::cantHappen }
 
- Static Public Member Functions inherited from outputHandler::base
static basenewHandler (const std::string &name)
 
template<class T >
static void addAllowedNamesToOption (T &option)
 
- Protected Member Functions inherited from outputHandler::base
 base ()=default
 
- Static Protected Member Functions inherited from outputHandler::base
static std::map< std::string, factoryClass * > & getFactoryMap ()
 

Detailed Description

Definition at line 10 of file outputHandlerPosixFile.h.

Constructor & Destructor Documentation

◆ posixFile()

outputHandler::posixFile::posixFile ( )
default

◆ ~posixFile()

outputHandler::posixFile::~posixFile ( )
overridedefault

Member Function Documentation

◆ createSymlink()

void outputHandler::posixFile::createSymlink ( const std::vector< char > &  target,
const std::string &  path,
uid_t  uid,
gid_t  gid 
)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 217 of file outputHandlerPosixFile.cpp.

219  {
220  timerInst(symlink);
221  auto retval = symlink(target.data(), path.c_str());
222  if (retval != 0 && errno != EEXIST) {
223  throwcall::good0(retval, "can't create link at ", path);
224  }
225  if (static_cast<std::make_signed<decltype(gid)>::type>(gid) != -1
226  || static_cast<std::make_signed<decltype(uid)>::type>(uid) != -1) {
227  throwcall::good0(lchown(path.c_str(), uid, gid), "can't set owner/group (", uid, ",", gid, ") on ", path);
228  }
229  }

References gid, throwcall::good0(), timerInst, and uid.

Here is the call graph for this function:

◆ doAttributePreservations()

void outputHandler::posixFile::doAttributePreservations ( const std::string &  path,
const genericStat stat 
)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 440 of file outputHandlerPosixFile.cpp.

441  {
442  if (preserve.timestamps) {
443  struct timespec times[2];
444  times[0].tv_nsec = UTIME_OMIT; // leave atime unchanged
445  stat.getMtime(times[1]);
446  timerInst(utimensat);
447  throwcall::good0(utimensat(0, path.c_str(), times, 0), "can't set mtime on ", path);
448  }
449  if (preserve.mode) {
450  timerInst(chmod);
451  throwcall::good0(chmod(path.c_str(), stat.mode), "can't set mode of ", path);
452  } else {
453  auto oldmask = umask(0);
454  timerInst(chmod);
455  throwcall::good0(chmod(path.c_str(), modeBits & ~oldmask), "can't set mode of ", path);
456  umask(oldmask);
457  }
458 
459  if (gid != -1 || uid != -1) {
460  timerInst(chown);
461  throwcall::good0(chown(path.c_str(), uid, gid), "can't set owner/group (", uid, ",", gid, ") of ", path);
462  } else if (preserve.ownership) {
463  timerInst(chown);
464  throwcall::good0(chown(path.c_str(), stat.ownerUid, stat.ownerGid),
465  "can't set owner/group (", stat.ownerUid, ",", stat.ownerGid, ") of ",
466  path);
467  }
468  }

References genericStat::getMtime(), gid, throwcall::good0(), genericStat::mode, modeBits, genericStat::ownerGid, genericStat::ownerUid, preserve, timerInst, and uid.

Here is the call graph for this function:

◆ ensureParentDirs()

void outputHandler::posixFile::ensureParentDirs ( const std::string &  path,
const std::string &  srcPath,
inputHandler::base InputHandler 
)
overridevirtual

Implements outputHandler::base.

Definition at line 55 of file outputHandlerPosixFile.cpp.

57  {
58  std::vector<std::remove_reference<decltype(path)>::type::value_type> disposable_buffer(path.c_str(), path.c_str() + path.size() + 1);
59  std::string dir(dirname(disposable_buffer.data()));
60  struct stat statbuf;
61 
62  if (stat(dir.c_str(), &statbuf)) {
63  if (errno == ENOENT || errno == ENOTDIR) {
64  ensureParentDirs(dir, srcPath, InputHandler);
65  static timer::anchor A("mkdir");
67  auto result = mkdir(dir.c_str(), 0777u);
68  I.stop(slownessThreshold, dir);
69 
70  if (result != 0 && errno == EEXIST) {
71  return; // we lost a race with another copy process...
72  }
73 
74  throwcall::good0(result, "can't create directory ", dir);
75 
76  if (gid != -1 || uid != -1) {
77  timerInst(chown);
78  throwcall::good0(chown(dir.c_str(), uid, gid), "can't set owner/group (", uid, ",", gid, ") on ", dir);
79  }
80  }
81  } else if (! S_ISDIR(statbuf.st_mode)) {
83  dir, "ensure parents",
84  "is not a directory (st_mode is ", statbuf.st_mode, ") but should be");
85  }
86  if (requiredFsid != 0) {
87  struct statvfs fsstat;
88  timerInst(statvfs);
89  throwcall::good0(statvfs(dir.c_str(), &fsstat), "can't statvfs ", dir);
90  if ((fsstat.f_fsid & fsidMask) != requiredFsid) {
91  throw fatalException("wrong fs id 0x", std::hex, fsstat.f_fsid, " instead of ", requiredFsid);
92  }
93  }
94  }

References errMsg::emit(), outputHandler::fsidMask, gid, throwcall::good0(), errMsg::info, outputHandler::requiredFsid, outputHandler::slownessThreshold, timer::instanceUnscoped::stop(), timerInst, and uid.

Here is the call graph for this function:

◆ getMaxNameLength()

size_t outputHandler::posixFile::getMaxNameLength ( const std::string &  dirPath)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 470 of file outputHandlerPosixFile.cpp.

470  {
471  errno = 0;
472  timerInst(pathconf);
473  return throwcall::badval(pathconf(dirPath.c_str(), _PC_NAME_MAX), -1,"can't get max name lenght on", dirPath);
474  }

References throwcall::badval(), and timerInst.

Here is the call graph for this function:

◆ newTmpWriter()

std::unique_ptr< base::writer > outputHandler::posixFile::newTmpWriter ( std::string &  path,
size_t  sourceSize,
bool  noWrite,
std::unique_ptr< ioHandle::attrDataType attrData,
std::unique_ptr< acl::list aclData 
)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 35 of file outputHandlerPosixFile.cpp.

39  {
40  return std::unique_ptr<base::writer>(new writerPosixFile(path,
41  noWrite,
42  std::move(attrData),
43  std::move(aclData),
44  *this));
45  }

◆ newWriter()

std::unique_ptr< base::writer > outputHandler::posixFile::newWriter ( const std::string &  path,
bool  mightAppend,
size_t  sourceSize,
size_t  readBlockSize,
copyRequest::stateType state,
bool  noWrite,
std::unique_ptr< ioHandle::attrDataType attrData,
std::unique_ptr< acl::list aclData 
)
overridevirtual

Implements outputHandler::base.

Definition at line 20 of file outputHandlerPosixFile.cpp.

27  {
28  return std::unique_ptr<base::writer>(new writerPosixFile(path, mightAppend,
29  sourceSize, readBlockSize,
30  state, noWrite,
31  std::move(attrData),
32  std::move(aclData)));
33  }

◆ remove()

void outputHandler::posixFile::remove ( const std::string &  path,
copyRequest::stateType state 
)
overridevirtual

Implements outputHandler::base.

Definition at line 97 of file outputHandlerPosixFile.cpp.

97  {
98  struct stat dsttat;
99  {
100  timerInst(lstat);
101  auto retval = lstat(path.c_str(), &dsttat);
102 
103  if (retval && errno == ENOENT) {
105  return;
106  }
107  }
108  if (S_ISDIR(dsttat.st_mode)) {
109  timerInst(rmdir);
110  auto retval = rmdir(path.c_str());
111  if (retval) {
112  switch (errno) {
113  case ENOENT:
115  return;
116  case ENOTEMPTY:
117  case EEXIST: // POSIX.1 allows this also
119  path, "remove", "directory not empty but should be removed");
121  return;
122  }
123  throwcall::good0(retval, "can't remove directory ", path);
124  } else {
126  return;
127  }
128  } else {
129  timerInst(unlink);
130  auto retval = unlink(path.c_str());
131 
132  if (retval && errno == ENOENT) {
134  } else {
135  throwcall::good0(retval, "can't unlink ", path);
136  }
138  }
139  }

References copyRequest::done, errMsg::emit(), copyRequest::failed, throwcall::good0(), errMsg::info, timerInst, and copyRequest::vanished.

Here is the call graph for this function:

◆ rename()

base::renameRetvalType outputHandler::posixFile::rename ( const std::string &  fromPath,
const std::unique_ptr< const genericStat > &  readInitialStat,
const std::string &  toPath,
copyRequest::stateType state 
)
overridevirtual
Bug:
what if at the end a directory is renamed?

Implements outputHandler::base.

Definition at line 153 of file outputHandlerPosixFile.cpp.

156  {
157  struct stat fromPathStatBuf;
158  static timer::anchor A("stat");
160  auto statRetVal = stat(fromPath.c_str(), &fromPathStatBuf);
161  I.stop();
162  if (statRetVal && (errno == ENOENT || errno == ENOTDIR)) {
163  if (readInitialStat && readInitialStat->isDir()) { // no need to act, dirs are created on the fly
167  }
169  } else if (statRetVal) { // curious error
170  throwcall::good0(statRetVal, "can't stat '", fromPath, "'");
171  return base::renameRetvalType::cantHappen; // never reached
172  }
173  genericStat fromPathStat(fromPathStatBuf, std::chrono::nanoseconds(1));
174  if (!readInitialStat || (! readInitialStat->isDir() &&
175  (fromPathStat.size != readInitialStat->size
176  || !fromPathStat.isSameMtimeAs(*readInitialStat)))) {
177  // the copy on fromPath is not up to date, create a new copy
178  if (readInitialStat) {
179  std::string initialTime;
180  std::string finalTime;
181  readInitialStat->getMtime(initialTime);
182  fromPathStat.getMtime(finalTime);
184  fromPath, "move"
185  "file (", toPath, ") changed unexpectedly ("
186  , initialTime, " -> ", finalTime, ", "
187  , readInitialStat->size, " -> ", fromPathStat.size
188  , ", doing fresh copy");
189  } else {
191  fromPath, "move",
192  "file (", toPath, ") has no initial stat, doing fresh copy");
193  }
195  } else { // try to move the existing copy
196  timerInst(rename);
197  auto retval = std::rename(fromPath.c_str(), toPath.c_str());
198 
199  if (retval && (errno == ENOENT || errno == ENOTDIR)) {
200  if (readInitialStat->isDir()) { // no need to act, dirs are created on the fly
203  }
205  fromPath, "move",
206  "vanished unexpectedly, doing fresh copy");
207  // file was probably not copied yet, try to copy it from the move target
209  } else {
210  throwcall::good0(retval, "can't rename '", fromPath, "' to '", toPath, "'");
213  }
214  }
215  }

References outputHandler::base::cantHappen, copyRequest::done, errMsg::emit(), outputHandler::base::fileChanged, outputHandler::base::fileVanished, genericStat::getMtime(), throwcall::good0(), copyRequest::ignore, errMsg::info, genericStat::isDir(), genericStat::isSameMtimeAs(), outputHandler::base::ok, genericStat::size, timer::instanceUnscoped::stop(), and timerInst.

Referenced by outputHandler::Gpfs::rename(), and renameSimple().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ renameSimple()

bool outputHandler::posixFile::renameSimple ( const std::string &  fromPath,
const std::string &  toPath 
)
overridevirtual

Implements outputHandler::base.

Definition at line 141 of file outputHandlerPosixFile.cpp.

142  {
144  auto retval = std::rename(fromPath.c_str(), toPath.c_str());
145  if (retval && (errno == ENOENT || errno == ENOTDIR)) {
146  return false;
147  }
148  throwcall::good0(retval, "can't rename '", fromPath, "' to '", toPath, "'");
149  return true;
150  }

References throwcall::good0(), rename(), outputHandler::slownessThreshold, and timerInstTO.

Here is the call graph for this function:

Member Data Documentation

◆ factory

factoryTemplate<posixFile> outputHandler::posixFile::factory
staticprivate

Definition at line 11 of file outputHandlerPosixFile.h.


The documentation for this class was generated from the following files:
genericStat::ownerGid
gid_t ownerGid
Definition: genericStat.h:24
outputHandler::requiredFsid
static options::single< unsigned long > requiredFsid('\0', "requiredFsid", "required fsid of output file system", 0)
genericStat::mode
mode_t mode
Definition: genericStat.h:22
outputHandler::fsidMask
static options::single< unsigned long > fsidMask('\0', "fsidMask", "bit mask for required fsid of output file system", 0)
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
throwcall::badval
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
Definition: throwcall.h:54
genericStat
generic stat abstraction class Used to abstract the variants of the stat structure.
Definition: genericStat.h:12
fatalException
class for exceptions that should result in program termination
Definition: copyRequestTypes.h:11
copyRequest::stateBitType::ignore
@ ignore
errMsg::level::info
@ info
outputHandler::slownessThreshold
static options::single< timer::clock_type::duration > slownessThreshold('\0',"daosFsSlownessThreshold", "duration after which file operations are considered slow", std::chrono::milliseconds(10))
outputHandler::base::renameRetvalType::cantHappen
@ cantHappen
copyRequest::stateBitType::done
@ done
outputHandler::base::renameRetvalType::fileChanged
@ fileChanged
copyRequest::stateBitType::failed
@ failed
genericStat::getMtime
void getMtime(struct timespec &spec) const
Definition: genericStat.cpp:65
gid
options::single< int > gid
copyRequest::stateBitType::vanished
@ vanished
outputHandler::posixFile::ensureParentDirs
void ensureParentDirs(const std::string &path, const std::string &srcPath, inputHandler::base *InputHandler) override
Definition: outputHandlerPosixFile.cpp:55
genericStat::isDir
bool isDir() const
Definition: genericStat.cpp:92
genericStat::size
size_t size
Definition: genericStat.h:16
outputHandler::base::renameRetvalType::fileVanished
@ fileVanished
outputHandler::base::renameRetvalType::ok
@ ok
timer::instanceUnscoped
Definition: timer.h:95
timer::anchor
Definition: timer.h:22
preserve
decltype(preserve) preserve
set of properties to preserve in the copy
Definition: ewmscp.cpp:111
uid
options::single< int > uid
errMsg::emit
void emit(level aLogLevel, const location &loc, const std::string &aObject, const std::string &aAction, const Args &... args)
function to create and enqueue a message, this is the only way that messages should be created!
Definition: errMsgQueue.h:148
timerInst
#define timerInst(subfunc)
Definition: timer.h:157
timerInstTO
#define timerInstTO(subfunc, timeout, object)
Definition: timer.h:158
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
genericStat::ownerUid
uid_t ownerUid
Definition: genericStat.h:23
outputHandler::posixFile::rename
base::renameRetvalType rename(const std::string &fromPath, const std::unique_ptr< const genericStat > &readInitialStat, const std::string &toPath, copyRequest::stateType &state) override
Definition: outputHandlerPosixFile.cpp:153
modeBits
options::single< modeBitType > modeBits