ewmscp  ..
daosFsCommon.cpp
Go to the documentation of this file.
1 #include "daosFsCommon.h"
2 #include "genericStat.h"
3 #include "ewmscp.h"
4 #include "timer.h"
5 #include <throwcall.h>
6 #include <errMsgQueue.h>
7 #include <fcntl.h>
8 
9 #ifndef ENOATTR
10 #define ENOATTR ENODATA
11 #endif
12 
13 daosFsCommon::daosOptions::daosOptions(const std::string& optPrefix):
14  containerName('\0', optPrefix + "_container", "container name to use"),
15  poolName('\0', optPrefix + "_pool", "pool name to use"),
16  sysName('\0', optPrefix + "_sys", "sys name to use")
17 {
18 }
19 
20 
21 dfs_obj_t* daosFsCommon::getDirObj(const std::string& path) {
22  auto stripped = path.substr(0,path.find_last_of('/'));
23  auto it = pathMap.find(path);
24  if (it == pathMap.end()) {
25  dfs_obj_t* obj;
26  timerInst(dfs_lookup);
27  throwcall::good0(dfs_lookup(dfs, path.c_str(), flags, &obj, nullptr, nullptr),"can't lookup path", path);
28  auto result = pathMap.emplace(path, obj);
29  it = result.first;
30  }
31  return it->second;
32 }
33 
34 daosFsCommon::daosFsCommon(daosOptions& aOpt, bool isWriter): flags(isWriter ? O_RDWR : O_RDONLY), opt(aOpt) {
35  throwcall::good0(daos_pool_connect(opt.poolName.c_str(), opt.sysName.empty() ? nullptr : opt.sysName.c_str(), 0,
36  &poh, nullptr, nullptr),
37  "can't connect to pool ", opt.poolName, " on sys ", opt.sysName);
38  throwcall::good0(daos_cont_open(poh, opt.containerName.c_str(), 0,
39  &coh, nullptr, nullptr),
40  "can't open container ", opt.containerName, " in pool ", opt.poolName, " on sys ", opt.sysName);
41  throwcall::good0(dfs_mount(poh, coh, flags, &dfs),
42  "can't mount daos fs in containr ", opt.containerName, " in pool ", opt.poolName, " on sys ", opt.sysName);
43 }
45  for (auto& item: pathMap) {
46  throwcall::good0(dfs_release(item.second),
47  "can't release dir object for ", item.first);
48  }
49  throwcall::good0(dfs_umount(dfs),
50  "can't umount daos fs in containr ", opt.containerName, " in pool ", opt.poolName, " on sys ", opt.sysName);
51  throwcall::good0(daos_cont_close(coh, nullptr),
52  "can't close container ", opt.containerName, " in pool ", opt.poolName, " on sys ", opt.sysName);
53  throwcall::good0(daos_pool_disconnect(poh, nullptr),
54  "can't disconnect pool ", opt.poolName, " on sys ", opt.sysName);
55 }
56 
57 
58 bool daosFsCommon::pathExists(const std::string& path) {
59  struct stat statBuf;
60  timerInst(stat);
61  auto result = dfs_stat(dfs, getDirObj(path), path.c_str(), &statBuf);
62  if (result && (errno == ENOENT || errno == ENOTDIR)) {
63  return false;
64  }
65  throwcall::good0(result, "can't stat ", path);
66  return true;
67 };
68 std::unique_ptr<const genericStat> daosFsCommon::getStat(const std::string& path,
69  bool followLink) {
70  struct stat statBuf;
71  timerInst(stat);
72  auto result = dfs_stat(dfs, getDirObj(path), path.c_str(), &statBuf);
73  if (result && errno == ENOENT) {
74  return nullptr;
75  }
76  throwcall::good0(result, "can't stat", path);
77  if (followLink && S_ISLNK(statBuf.st_mode)) {
78  char buf[4096];
79  daos_size_t size = sizeof(buf);
80  dfs_obj_t* obj;
81  throwcall::good0(dfs_open(dfs, getDirObj(path), path.c_str(), 0x666, O_RDONLY, 0, 0, nullptr, &obj),
82  "can't open link", path);
83  throwcall::good0(dfs_get_symlink_value(obj, buf, &size),
84  "can't get symlink of link ", path);
85  throwcall::good0(dfs_release(obj), "can't relaese ",path);
86  return getStat(buf, true);
87  }
88  return std::unique_ptr<const genericStat>(new genericStat(statBuf, std::chrono::nanoseconds(1)));
89 };
90 
91 
92 std::string daosFsCommon::getXattr(const std::string& path,
93  const std::string& name) {
94  char buffer[512];
95 
96  dfs_obj_t* obj;
97  throwcall::good0(dfs_lookup(dfs, path.c_str(), flags,
98  &obj, nullptr, nullptr),
99  "can't lookup ", path);
100  timerInst(getxattr);
101  daos_size_t size = sizeof(buffer);
102  auto retval = dfs_getxattr(dfs, obj, name.c_str(), buffer, &size);
103  throwcall::good0(dfs_release(obj),"can't release ", path);
104  if (retval == -1) {
105  if (errno == ENOENT || errno == ENOATTR) {
106  return "";
107  }
108  throwcall::badval(retval, -1, "can't get xattr on ", path);
109  }
110  buffer[size] = '\0';
111  return buffer;
112 };
113 
114 
115 daosFsIoCommon::daosFsIoCommon(const std::string& aPath, daosFsCommon& aHandler):
116  path(aPath),
117  obj(nullptr),
118  handler(aHandler){
119 }
120 
121 
122 
123 std::unique_ptr<const genericStat> daosFsIoCommon::getStat() {
124  struct stat statBuf;
125  timerInst(stat);
126  throwcall::good0(dfs_ostat(handler.dfs, obj, &statBuf), "can't stat", path);
127  return std::unique_ptr<const genericStat>(new genericStat(statBuf, std::chrono::nanoseconds(1)));
128 }
129 void daosFsIoCommon::setXattr(const std::string& name, const std::string& value) {
130  timerInst(setxattr);
131  throwcall::good0(dfs_setxattr(handler.dfs, obj, name.c_str(), value.data(), value.size(), 0),
132  "can't set xattr '", name, "' to '", value, "' on ", path);
133 }
134 
135 std::string daosFsIoCommon::getXattr(const std::string& name) {
136  char buffer[512];
138  daos_size_t size = sizeof(buffer);
139  auto retval = dfs_getxattr(handler.dfs, obj, name.c_str(), buffer, &size);
140  if (retval != 0) {
141  if (errno != ENOATTR) {
142  throwcall::badval(retval, -1, "can't read xattr '", name, "' from ", path);
143  }
144  return "";
145  } else {
146  buffer[size] = '\0';
147  }
148  return buffer;
149 }
150 
151 void daosFsIoCommon::removeXattr(const std::string& name) {
152  timerInst(removexattr);
153  auto result = dfs_removexattr(handler.dfs, obj, name.c_str());
154  if (result && errno == ENOATTR) {
155  return; // be silent about this
156  }
157  throwcall::good0(result,
158  "can't remove xattr ", name, " from ", path);
159 }
160 
161 void daosFsIoCommon::attrDataType::add(const std::string& name, const std::string& value) {
162  xattrs.emplace_front(name, value);
163 }
165  for (const auto& item : xattrs) {
166  handle->setXattr(item.first, item.second);
167  }
168 }
169 
171  char buf[0x10000];
172  static timer::anchor la("listxattr");
174  daos_size_t size(sizeof(buf));
175  throwcall::good0(dfs_listxattr(aHandler.handler.dfs, aHandler.obj, buf, &size),
176  "can't get xattrs for ", aHandler.path);
177  li.stop();
178  for (auto readPtr = &buf[0]; readPtr < &buf[size];) {
179  add(readPtr, aHandler.getXattr(readPtr));
180  while (*readPtr++);
181  }
182 }
183 
184 std::unique_ptr<ioHandle::attrDataType> daosFsIoCommon::getAttrData(const outputHandler::base* /*aOutputHandler*/) {
185  auto attrData = std::unique_ptr<attrDataType>(new attrDataType());
186  attrData->fill(*this);
187  if (attrData->xattrs.empty()) {
188  return nullptr;
189  }
190  #if __GNUC__ >= 8
191  return attrData;
192  #else
193  return std::move(attrData);
194  #endif
195 }
daosFsCommon::daosOptions
Definition: daosFsCommon.h:20
daosFsIoCommon::obj
dfs_obj_t * obj
Definition: daosFsCommon.h:53
ENOATTR
#define ENOATTR
Definition: daosFsCommon.cpp:10
daosFsCommon::coh
daos_handle_t coh
Definition: daosFsCommon.h:14
ioHandle::setXattr
virtual void setXattr(const std::string &, const std::string &)
Definition: ioHandle.h:43
errMsgQueue.h
daosFsCommon::pathExists
bool pathExists(const std::string &path) override
Definition: daosFsCommon.cpp:58
genericStat.h
daosFsIoCommon::getStat
std::unique_ptr< const genericStat > getStat() override
Definition: daosFsCommon.cpp:123
daosFsCommon::flags
int flags
Definition: daosFsCommon.h:16
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
daosFsCommon::~daosFsCommon
~daosFsCommon() override
Definition: daosFsCommon.cpp:44
ioHandle::attrDataType::xattrs
std::forward_list< std::pair< std::string, std::string > > xattrs
Definition: ioHandle.h:24
daosFsIoCommon::getXattr
std::string getXattr(const std::string &name) override
get one extended attribute value
Definition: daosFsCommon.cpp:135
daosFsIoCommon::attrDataType::set
void set(ioHandle *handle) override
set this set of attributes on the file described by handle
Definition: daosFsCommon.cpp:164
daosFsIoCommon::attrDataType::fill
void fill(daosFsIoCommon &handler)
Definition: daosFsCommon.cpp:170
daosFsCommon
Definition: daosFsCommon.h:11
daosFsCommon::opt
daosOptions & opt
Definition: daosFsCommon.h:28
daosFsCommon::daosOptions::daosOptions
daosOptions(const std::string &optPrefix)
Definition: daosFsCommon.cpp:13
daosFsIoCommon::attrDataType
Definition: daosFsCommon.h:56
daosFsIoCommon::removeXattr
void removeXattr(const std::string &name) override
Definition: daosFsCommon.cpp:151
timer::instanceUnscoped::stop
void stop()
Definition: timer.h:107
daosFsCommon::getDirObj
dfs_obj_t * getDirObj(const std::string &path)
Definition: daosFsCommon.cpp:21
outputHandler::base
Definition: outputHandler.h:17
timer.h
throwcall.h
daosFsCommon::poh
daos_handle_t poh
Definition: daosFsCommon.h:13
daosFsCommon::daosOptions::poolName
options::single< std::string > poolName
Definition: daosFsCommon.h:24
timer::instanceUnscoped
Definition: timer.h:95
daosFsCommon::dfs
dfs_t * dfs
Definition: daosFsCommon.h:15
daosFsCommon::getStat
std::unique_ptr< const genericStat > getStat(const std::string &path, bool followLink) override
Definition: daosFsCommon.cpp:68
timer::anchor
Definition: timer.h:22
daosFsCommon::pathMap
std::map< std::string, dfs_obj_t * > pathMap
Definition: daosFsCommon.h:17
daosFsCommon::daosOptions::containerName
options::single< std::string > containerName
Definition: daosFsCommon.h:23
daosFsCommon::getXattr
std::string getXattr(const std::string &path, const std::string &name) override
Definition: daosFsCommon.cpp:92
daosFsIoCommon
base class for daosFs reader and writer class with the common stuff like fd, path and xattr handling
Definition: daosFsCommon.h:50
daosFsIoCommon::daosFsIoCommon
daosFsIoCommon(const std::string &aPath, daosFsCommon &aHandler)
Definition: daosFsCommon.cpp:115
timerInst
#define timerInst(subfunc)
Definition: timer.h:157
daosFsCommon.h
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
daosFsIoCommon::setXattr
void setXattr(const std::string &name, const std::string &value) override
Definition: daosFsCommon.cpp:129
daosFsIoCommon::path
const std::string & path
Definition: daosFsCommon.h:52
daosFsIoCommon::handler
daosFsCommon & handler
Definition: daosFsCommon.h:54
daosFsIoCommon::attrDataType::add
void add(const std::string &name, const std::string &value)
Definition: daosFsCommon.cpp:161
ewmscp.h
daosFsCommon::daosFsCommon
daosFsCommon(daosOptions &aOpt, bool isWriter)
Definition: daosFsCommon.cpp:34
daosFsIoCommon::getAttrData
std::unique_ptr< ioHandle::attrDataType > getAttrData(const outputHandler::base *aOutputHandler) override
get attributes in the optimal way for setting with aOutputHandler
Definition: daosFsCommon.cpp:184
daosFsCommon::daosOptions::sysName
options::single< std::string > sysName
Definition: daosFsCommon.h:25