ewmscp  ..
gpfsCommon.cpp
Go to the documentation of this file.
1 #include "gpfsCommon.h"
2 #include <gpfs.h>
3 #include <throwcall.h>
4 #include "outputHandlerGpfs.h"
5 #include "errMsgQueue.h"
6 #include "timer.h"
7 
8 gpfsIoCommon::gpfsIoCommon(const std::string& aPath):
9  posixFileIoCommon(aPath),
10  leastRecentlyAccessedBlock(0),
11  leastRecentlyReleasedBlock(0) {
12 }
13 
14 void gpfsIoCommon::releaseUsedBlocks(size_t aBlockSize) {
16  static_cast<off_t>(aBlockSize * usedBlockMap.size())) {
17  gpfs_fcntl_handler fcntl;
18  auto& hint = fcntl.buffer.add<gpfsFreeRange_t>(GPFS_FREE_RANGE);
19  hint.start = leastRecentlyReleasedBlock;
21  timerInst(gpfsFreeRange);
22  fcntl.call(fd, path);
24  }
25 }
26 void gpfsIoCommon::handleParallelUsedBlocks(size_t aBlockSize, off_t offset) {
27  std::lock_guard<decltype(blockBookkeepingMutex)> lock(blockBookkeepingMutex);
28  auto index = (offset - leastRecentlyAccessedBlock) / aBlockSize;
29  if (index < usedBlockMap.size()) {
30  usedBlockMap.set(index);
31  if (usedBlockMap.all()) {
34  nextUsedBlockMap.reset();
35  releaseUsedBlocks(aBlockSize);
36  }
37  } else if (index - usedBlockMap.size() < nextUsedBlockMap.size()) {
38  nextUsedBlockMap.set(index - usedBlockMap.size());
39  } else {
41  path, "parallel read",
42  "blocks scattered to far, ", index, " blocks difference");
43  }
44 }
46  auto castHandle = dynamic_cast<outputHandler::posixFile::writerPosixFile*>(handle);
48  if (size != 0) {
49  timerInst(gpfs_fputattrs);
50  throwcall::good0(gpfs_fputattrs(castHandle->fd, GPFS_ATTRFLAG_NO_PLACEMENT, buffer),
51  "can't set gpfs attributes for", castHandle->path);
52  }
53 }
54 
55 std::unique_ptr<ioHandle::attrDataType> gpfsIoCommon::getAttrData(const outputHandler::base* aOutputHandler) {
56  auto attrData = std::unique_ptr<gpfsIoCommon::attrDataType>(new gpfsIoCommon::attrDataType());
57  attrData->fill(*this); // get the posix part: the xattrs
58  if (dynamic_cast<const outputHandler::Gpfs*>(aOutputHandler)) { // we work all in gpfs
59  // remove system attrs
60  attrData->xattrs.remove_if([](const decltype(attrData->xattrs)::value_type & item) {
61  return item.first.find("system.") == 0;
62  });
63  timerInst(gpfs_fgetattrs);
64  throwcall::good0(gpfs_fgetattrs(fd, GPFS_ATTRFLAG_NO_PLACEMENT,
65  attrData->buffer,
66  sizeof(attrData->buffer),
67  &(attrData->size)),
68  "can't get gpfs attributes for ", path);
69  }
70  if (attrData->size > 0 && !attrData->xattrs.empty()) {
71  return std::unique_ptr<ioHandle::attrDataType>(attrData.release());
72  } else { // no xattr data found
73  return nullptr;
74  }
75 }
76 
77 std::unique_ptr<acl::list> gpfsIoCommon::getAclData() {
78  gpfs_acl_handler aclHandler;
79  aclHandler.get(fd, path);
80  return aclFromGpfs(aclHandler, path);
81 }
82 
83 std::unique_ptr<acl::list> gpfsIoCommon::aclFromGpfs(const gpfs_acl_handler& gpfsAcl,
84  const std::string& aPath) {
85  auto acl = std::unique_ptr<acl::list>(new acl::list());
86  acl->entries.reserve(gpfsAcl.size()); // we will have this many aces
87  static_assert(static_cast<unsigned short>(acl::list::entryType::flagsType::file_inherit_ace) == ACE4_FLAG_FILE_INHERIT &&
88  static_cast<unsigned short>(acl::list::entryType::flagsType::directory_inherit_ace) == ACE4_FLAG_DIR_INHERIT &&
89  static_cast<unsigned short>(acl::list::entryType::flagsType::no_propagate_inherit_ace) == ACE4_FLAG_NO_PROPAGATE &&
90  static_cast<unsigned short>(acl::list::entryType::flagsType::inherit_only_ace) == ACE4_FLAG_INHERIT_ONLY &&
91  static_cast<unsigned short>(acl::list::entryType::flagsType::identifier_group) == ACE4_FLAG_GROUP_ID &&
92  static_cast<unsigned short>(acl::list::entryType::flagsType::inherited_ace) == ACE4_FLAG_INHERITED,
93  "incompatible flag bit maps between gpfs and rich acl");
94  static_assert(static_cast<unsigned int>(acl::list::entryType::maskType::read_data) == ACE4_MASK_READ &&
95  static_cast<unsigned int>(acl::list::entryType::maskType::list_directory) == ACE4_MASK_LIST_DIR &&
96  static_cast<unsigned int>(acl::list::entryType::maskType::write_data) == ACE4_MASK_WRITE &&
97  static_cast<unsigned int>(acl::list::entryType::maskType::add_file) == ACE4_MASK_ADD_FILE &&
98  static_cast<unsigned int>(acl::list::entryType::maskType::append_data) == ACE4_MASK_APPEND &&
99  static_cast<unsigned int>(acl::list::entryType::maskType::add_subdirectory) == ACE4_MASK_ADD_SUBDIR &&
100  static_cast<unsigned int>(acl::list::entryType::maskType::read_named_attrs) == ACE4_MASK_READ_NAMED &&
101  static_cast<unsigned int>(acl::list::entryType::maskType::write_named_attrs) == ACE4_MASK_WRITE_NAMED &&
102  static_cast<unsigned int>(acl::list::entryType::maskType::execute) == ACE4_MASK_EXECUTE &&
103  static_cast<unsigned int>(acl::list::entryType::maskType::execute) == ACE4_MASK_SEARCH &&
104  static_cast<unsigned int>(acl::list::entryType::maskType::delete_child) == ACE4_MASK_DELETE_CHILD &&
105  static_cast<unsigned int>(acl::list::entryType::maskType::read_attributes) == ACE4_MASK_READ_ATTR &&
106  static_cast<unsigned int>(acl::list::entryType::maskType::write_attributes) == ACE4_MASK_WRITE_ATTR &&
107  static_cast<unsigned int>(acl::list::entryType::maskType::delete_) == ACE4_MASK_DELETE &&
108  static_cast<unsigned int>(acl::list::entryType::maskType::read_acl) == ACE4_MASK_READ_ACL &&
109  static_cast<unsigned int>(acl::list::entryType::maskType::write_acl) == ACE4_MASK_WRITE_ACL &&
110  static_cast<unsigned int>(acl::list::entryType::maskType::write_owner) == ACE4_MASK_WRITE_OWNER &&
111  static_cast<unsigned int>(acl::list::entryType::maskType::synchronize) == ACE4_MASK_SYNCHRONIZE,
112  "incompatible mask bit maps between gpfs and rich acl");
113  static_assert(static_cast<unsigned char>(acl::list::entryType::typeValue::access_allowed_ace_type) == ACE4_TYPE_ALLOW &&
114  static_cast<unsigned char>(acl::list::entryType::typeValue::access_denied_ace_type) == ACE4_TYPE_DENY,
115  "incompatible ace type bit maps between gpfs and rich acl");
116 
117  // std::cerr << "n:" << acl.acl_nace << "\n";
118  // std::cerr << "len: " << acl.acl_len << "\n";
119  // std::cerr << "level: " << acl.acl_level << "\n";
120  // std::cerr << "version: " << acl.acl_version << "\n";
121  // std::cerr << "type: " << acl.acl_type << "\n";
122  for (const auto gpfs_ace : gpfsAcl) {
123  acl->entries.emplace_back();
124  auto& rich_ace = acl->entries.back();
125 
126  // std::cerr<<i<<": type:"<<gpfs_ace->aceType << "\n";
127  // std::cerr<<i<<": flag:"<<gpfs_ace->aceFlags << "\n";
128  // std::cerr<<i<<": iflag:"<<gpfs_ace->aceIFlags << "\n";
129  // std::cerr<<i<<": mask:"<<gpfs_ace->aceMask << "\n";
130  // std::cerr<<i<<": who:"<<gpfs_ace->aceWho << "\n";
131  // transfer only flags valid in both repesentations
132  rich_ace.setType(gpfs_ace.aceType & (ACE4_TYPE_ALLOW |
133  ACE4_TYPE_DENY));
134  rich_ace.setFlags(gpfs_ace.aceFlags & (ACE4_FLAG_FILE_INHERIT |
135  ACE4_FLAG_DIR_INHERIT |
136  ACE4_FLAG_NO_PROPAGATE |
137  ACE4_FLAG_INHERIT_ONLY |
138  ACE4_FLAG_GROUP_ID |
139  ACE4_FLAG_INHERITED));
140  rich_ace.setMask(gpfs_ace.aceMask);
141  if (gpfs_ace.aceIFlags & ACE4_IFLAG_SPECIAL_ID) {
142  switch (gpfs_ace.aceWho) {
143  case ACE4_SPECIAL_OWNER:
144  rich_ace.e_id = acl::list::entryType::specialIdType::owner_special_id;
145  break;
146  case ACE4_SPECIAL_GROUP:
147  rich_ace.e_id = acl::list::entryType::specialIdType::group_special_id;
148  break;
149  case ACE4_SPECIAL_EVERYONE:
150  rich_ace.e_id = acl::list::entryType::specialIdType::everyone_special_id;
151  break;
152  default:
153  throw std::runtime_error("unknon special acl id on " + aPath);
154  }
156  } else {
157  rich_ace.e_id = gpfs_ace.aceWho;
158  }
159  }
160  return acl;
161 }
162 
163 
gpfsIoCommon::attrDataType
Definition: gpfsCommon.h:18
gpfsIoCommon::usedBlockMap
std::bitset< 64 > usedBlockMap
Definition: gpfsCommon.h:12
acl::list::entryType::maskType::write_acl
@ write_acl
gpfsIoCommon::handleParallelUsedBlocks
void handleParallelUsedBlocks(size_t aBlockSize, off_t offset)
Definition: gpfsCommon.cpp:26
gpfsIoCommon::blockBookkeepingMutex
std::mutex blockBookkeepingMutex
Definition: gpfsCommon.h:14
errMsgQueue.h
acl::list::entryType::maskType::read_attributes
@ read_attributes
acl::list::entryType::flagsType::no_propagate_inherit_ace
@ no_propagate_inherit_ace
outputHandler::posixFile::writerPosixFile
Definition: outputHandlerPosixFile.h:13
acl::list::entryType::maskType::delete_
@ delete_
acl::list::entryType::typeValue::access_denied_ace_type
@ access_denied_ace_type
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
gpfsIoCommon::attrDataType::size
int size
Definition: gpfsCommon.h:21
acl::list::entryType::maskType::synchronize
@ synchronize
gpfsIoCommon::releaseUsedBlocks
void releaseUsedBlocks(size_t aBlockSize)
Definition: gpfsCommon.cpp:14
acl::list::entryType::maskType::add_subdirectory
@ add_subdirectory
acl::list::entryType::maskType::write_owner
@ write_owner
acl::list::entryType::maskType::read_data
@ read_data
acl::list::entryType::maskType::read_acl
@ read_acl
acl::list::entryType::flagsType::special_who
@ special_who
acl::list::entryType::maskType::execute
@ execute
gpfsIoCommon::nextUsedBlockMap
std::bitset< 64 > nextUsedBlockMap
Definition: gpfsCommon.h:13
posixFileIoCommon::fd
int fd
Definition: posixFileCommon.h:21
acl::list::entryType::maskType::append_data
@ append_data
gpfs_acl_handler
class for handling non-opaque gpfs acls
Definition: gpfsFcntlHandler.h:33
acl::list::entryType::flagsType::inherit_only_ace
@ inherit_only_ace
gpfsIoCommon::aclFromGpfs
static std::unique_ptr< acl::list > aclFromGpfs(const gpfs_acl_handler &acl, const std::string &aPath)
Definition: gpfsCommon.cpp:83
acl::list::entryType::maskType::write_named_attrs
@ write_named_attrs
gpfsIoCommon::attrDataType::buffer
char buffer[0x10000]
Definition: gpfsCommon.h:20
errMsg::level::debug
@ debug
outputHandlerGpfs.h
acl::list::entryType::maskType::write_data
@ write_data
gpfs_fcntl_handler
class for handling gpfs_fcnt calls with their very special parameter handling
Definition: gpfsFcntlHandler.h:6
gpfsIoCommon::attrDataType::set
void set(ioHandle *handle) override
set this set of attributes on the file described by handle
Definition: gpfsCommon.cpp:45
acl::list::entryType::maskType::add_file
@ add_file
posixFileIoCommon::gpfsIoCommon
friend class gpfsIoCommon
Definition: posixFileCommon.h:18
gpfs_acl_handler::get
void get(int fd, const std::string &path)
Definition: gpfsFcntlHandler.cpp:99
gpfsIoCommon::getAclData
std::unique_ptr< acl::list > getAclData() override
get acls
Definition: gpfsCommon.cpp:77
outputHandler::base
Definition: outputHandler.h:17
timer.h
throwcall.h
acl::list::entryType::typeValue::access_allowed_ace_type
@ access_allowed_ace_type
gpfsCommon.h
acl::list
Definition: acl.h:8
posixFileIoCommon::attrDataType::set
void set(ioHandle *handle) override
set this set of attributes on the file described by handle
Definition: posixFileCommon.cpp:171
gpfs_fcntl_handler::buffer
union gpfs_fcntl_handler::@2 buffer
acl::list::entryType::flagsType::identifier_group
@ identifier_group
gpfsIoCommon::leastRecentlyReleasedBlock
off_t leastRecentlyReleasedBlock
Definition: gpfsCommon.h:11
gpfs_acl_handler::size
size_t size() const
Definition: gpfsFcntlHandler.h:44
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
gpfsIoCommon::getAttrData
std::unique_ptr< ioHandle::attrDataType > getAttrData(const outputHandler::base *aOutputHandler) override
get attributes in the optimal way for setting with aOutputHandler
Definition: gpfsCommon.cpp:55
posixFileIoCommon
base class for posixFile reader and writer class with the common stuff like fd, path and xattr handli...
Definition: posixFileCommon.h:17
acl::list::entryType::flagsType::inherited_ace
@ inherited_ace
acl::list::entryType::flagsType::directory_inherit_ace
@ directory_inherit_ace
outputHandler::Gpfs
Definition: outputHandlerGpfs.h:9
gpfs_fcntl_handler::call
void call(int fd, const std::string &path)
Definition: gpfsFcntlHandler.cpp:15
acl::list::entryType::flagsType::file_inherit_ace
@ file_inherit_ace
acl::list::entryType::maskType::write_attributes
@ write_attributes
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
acl::list::entryType::maskType::list_directory
@ list_directory
gpfsIoCommon::leastRecentlyAccessedBlock
off_t leastRecentlyAccessedBlock
Definition: gpfsCommon.h:10
acl::list::entryType::maskType::delete_child
@ delete_child
acl::list::entryType::maskType::read_named_attrs
@ read_named_attrs
posixFileIoCommon::path
const std::string & path
Definition: posixFileCommon.h:20
acl
Definition: acl.cpp:10