ewmscp  ..
posixFileCommon.cpp
Go to the documentation of this file.
1 #include "posixFileCommon.h"
2 #include "genericStat.h"
3 #include "ewmscp.h"
4 #include "timer.h"
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <throwcall.h>
9 #include <errMsgQueue.h>
10 #ifdef WithXattr
11 #include <xattr.h>
12 #endif
13 #ifdef WithXattrUgly
14 #include WithXattrUgly
15 #endif
16 #ifndef ENOATTR
17 #define ENOATTR ENODATA
18 #endif
19 
20 bool posixFileCommon::pathExists(const std::string& path) {
21  struct stat statBuf;
22  timerInst(stat);
23  auto result = stat(path.c_str(), &statBuf);
24  if (result && (errno == ENOENT || errno == ENOTDIR)) {
25  return false;
26  }
27  throwcall::good0(result, "can't stat ", path);
28  return true;
29 };
30 std::unique_ptr<const genericStat> posixFileCommon::getStat(const std::string& path,
31  bool followLink) {
32  struct stat statBuf;
33  for (int retries = 100; retries; --retries) {
34  if (followLink) {
35  timerInst(stat);
36  auto result = stat(path.c_str(), &statBuf);
37  if (result && errno == ENOENT) {
38  return nullptr;
39  } else if (result && errno == ENOTDIR) {
41  path, "stat", "found @#$%@ gpfs err ", errno);
42  continue;
43  }
44  throwcall::good0(result, "can't stat", path);
45  } else {
46  timerInst(lstat);
47  auto result = lstat(path.c_str(), &statBuf);
48  if (result && errno == ENOENT) {
49  return nullptr;
50  } else if (result && errno == ENOTDIR) {
52  path, "lstat", "found @#$%@ gpfs err", errno);
53  continue;
54  }
55  throwcall::good0(result, "can't lstat", path);
56  }
57  break;
58  }
59  return std::unique_ptr<const genericStat>(new genericStat(statBuf, std::chrono::nanoseconds(1)));
60 };
61 
62 
63 std::string posixFileCommon::getXattr(const std::string& path,
64  const std::string& name) {
65  #if defined(WithXattr) || defined(WithXattrUgly)
66  char buffer[512];
67 
68  for (int i = 0; i < 100; i++) {
69  timerInst(lgetxattr);
70  auto retval = lgetxattr(path.c_str(), name.c_str(), buffer, sizeof(buffer));
71 
72  if (retval == -1) {
73  if (errno == ENOENT || errno == ENOATTR) {
74  return "";
75  } else if (errno == ENOTDIR) { // we ran against a GPFS bug
77  path, "lgetxattr",
78  "got a f*^%$&^%$ GPFS bug", errno);
79  continue; // try again
80  }
81  throwcall::badval(retval, -1, "can't get xattr on ", path);
82  }
83  buffer[retval] = '\0';
84  break;
85  }
86  return buffer;
87  #else
88  throw unimplementedActionError("no xattr support");
89  #endif
90 };
91 
92 // while (true) {
93 
94 // auto retval = lstat(source.c_str(), &readInitialStat);
95 
96 // if (retval && errno == ENOENT) {
97 // state |= stateBitType::vanished;
98 // return;
99 // } else if (retval && errno == ENOTDIR) {
100 // *errStream << statPrefix << __FILE__ << ":" << __LINE__ << ": found @#$%@ gpfs err on " << source << std::endl;
101 // continue;
102 // }
103 
104 // throwcall::good0(retval, "can't stat ", source);
105 // break;
106 //}
107 
108 
109 
110 posixFileIoCommon::posixFileIoCommon(const std::string& aPath):
111  path(aPath) {
112 }
113 
114 
115 
116 std::unique_ptr<const genericStat> posixFileIoCommon::getStat() {
117  struct stat statBuf;
118  timerInst(fstat);
119  throwcall::good0(fstat(fd, &statBuf), "can't stat", path);
120  return std::unique_ptr<const genericStat>(new genericStat(statBuf, std::chrono::nanoseconds(1)));
121 }
122 void posixFileIoCommon::setXattr(const std::string& name, const std::string& value) {
123  #if defined(WithXattr) || defined(WithXattrUgly)
124  timerInst(fsetxattr);
125  throwcall::good0(fsetxattr(fd, name.c_str(), value.data(), value.size(), 0),
126  "can't set xattr '", name, "' to '", value, "' on ", path);
127  #else
128  throw unimplementedActionError("no xattr support");
129  #endif
130 }
131 
132 std::string posixFileIoCommon::getXattr(const std::string& name) {
133  #if defined(WithXattr) || defined(WithXattrUgly)
134  char buffer[512];
136  auto retval = fgetxattr(fd, name.c_str(), buffer, sizeof(buffer));
137  if (retval == -1) {
138  if (errno != ENOATTR) {
139  throwcall::badval(retval, -1, "can't read xattr '", name, "' from ", path);
140  }
141  return "";
142  } else {
143  buffer[retval] = '\0';
144  }
145  return buffer;
146  #else
147  throw unimplementedActionError("no xattr support");
148  return ""; // newver reached
149  #endif
150 
151 }
152 
153 void posixFileIoCommon::removeXattr(const std::string& name) {
154  #if defined(WithXattr) || defined(WithXattrUgly)
155  timerInst(fremovexattr);
156  auto result = fremovexattr(fd, name.c_str());
157  if (result && errno == ENOATTR) {
158  return; // be silent about this
159  }
160  throwcall::good0(result,
161  "can't remove xattr ", name, " from ", path);
162  #else
163  throw unimplementedActionError("no xattr support");
164  #endif
165 
166 }
167 
168 void posixFileIoCommon::attrDataType::add(const std::string& name, const std::string& value) {
169  xattrs.emplace_front(name, value);
170 }
172  for (const auto& item : xattrs) {
173  handle->setXattr(item.first, item.second);
174  }
175 }
176 
177 #if defined(WithXattr) || defined(WithXattrUgly)
179  char buf[0x10000];
180  static timer::anchor la("flistxattr");
182  auto bufSize = throwcall::badval(flistxattr(handler.fd, buf, sizeof(buf)), -1,
183  "can't get xattrs for ", handler.path);
184  li.stop();
185  for (auto readPtr = &buf[0]; readPtr < &buf[bufSize];) {
186  add(readPtr, handler.getXattr(readPtr));
187  while (*readPtr++);
188  }
189 }
190 std::unique_ptr<ioHandle::attrDataType> posixFileIoCommon::getAttrData(const outputHandler::base* /*aOutputHandler*/) {
191  auto attrData = std::unique_ptr<attrDataType>(new attrDataType());
192  attrData->fill(*this);
193  if (attrData->xattrs.empty()) {
194  return nullptr;
195  }
196  #if __GNUC__ >= 8
197  return attrData;
198  #else
199  return std::move(attrData);
200  #endif
201 }
202 #else
204 };
205 std::unique_ptr<ioHandle::attrDataType> posixFileIoCommon::getAttrData(const outputHandler::base* aOutputHandler) {
206  return ioHandle::getAttrData(aOutputHandler);
207 }
208 #endif
209 
ioHandle::setXattr
virtual void setXattr(const std::string &, const std::string &)
Definition: ioHandle.h:43
errMsgQueue.h
genericStat.h
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
posixFileCommon::getXattr
std::string getXattr(const std::string &path, const std::string &name) override
Definition: posixFileCommon.cpp:63
genericStat
generic stat abstraction class Used to abstract the variants of the stat structure.
Definition: genericStat.h:12
posixFileIoCommon::getStat
std::unique_ptr< const genericStat > getStat() override
Definition: posixFileCommon.cpp:116
posixFileIoCommon::attrDataType::fill
void fill(posixFileIoCommon &handler)
Definition: posixFileCommon.cpp:203
errMsg::level::info
@ info
unimplementedActionError
class for exceptions that result from unimplemented functions Exceptions of this kind are to be throw...
Definition: copyRequestTypes.h:32
ioHandle::getAttrData
virtual std::unique_ptr< attrDataType > getAttrData(const outputHandler::base *)
get attributes in the optimal way for setting with aOutputHandler
Definition: ioHandle.h:69
ioHandle::attrDataType::xattrs
std::forward_list< std::pair< std::string, std::string > > xattrs
Definition: ioHandle.h:24
posixFileIoCommon::fd
int fd
Definition: posixFileCommon.h:21
posixFileIoCommon::setXattr
void setXattr(const std::string &name, const std::string &value) override
Definition: posixFileCommon.cpp:122
posixFileIoCommon::attrDataType::add
void add(const std::string &name, const std::string &value)
Definition: posixFileCommon.cpp:168
outputHandler::base
Definition: outputHandler.h:17
timer.h
throwcall.h
ENOATTR
#define ENOATTR
Definition: posixFileCommon.cpp:17
timer::instanceUnscoped
Definition: timer.h:95
posixFileIoCommon::attrDataType::set
void set(ioHandle *handle) override
set this set of attributes on the file described by handle
Definition: posixFileCommon.cpp:171
posixFileIoCommon::removeXattr
void removeXattr(const std::string &name) override
Definition: posixFileCommon.cpp:153
posixFileCommon::getStat
std::unique_ptr< const genericStat > getStat(const std::string &path, bool followLink) override
Definition: posixFileCommon.cpp:30
timer::anchor
Definition: timer.h:22
posixFileCommon.h
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
posixFileIoCommon
base class for posixFile reader and writer class with the common stuff like fd, path and xattr handli...
Definition: posixFileCommon.h:17
posixFileCommon::pathExists
bool pathExists(const std::string &path) override
Definition: posixFileCommon.cpp:20
ioHandle
class as base for inputHandler::base::reader and outputHandler::base::writer containing the common pa...
Definition: ioHandle.h:15
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
posixFileIoCommon::getAttrData
std::unique_ptr< ioHandle::attrDataType > getAttrData(const outputHandler::base *aOutputHandler) override
get attributes in the optimal way for setting with aOutputHandler
Definition: posixFileCommon.cpp:205
posixFileIoCommon::posixFileIoCommon
posixFileIoCommon(const std::string &aPath)
Definition: posixFileCommon.cpp:110
posixFileIoCommon::getXattr
std::string getXattr(const std::string &name) override
get one extended attribute value
Definition: posixFileCommon.cpp:132
posixFileIoCommon::path
const std::string & path
Definition: posixFileCommon.h:20
ewmscp.h