irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

libmsi_update_unixfilesystem_resource_free_space.cpp
Go to the documentation of this file.
1 #include "msParam.h"
2 #include "rcMisc.h"
3 #include "rsGeneralAdmin.hpp"
4 #include "irods_ms_plugin.hpp"
8 #include "generalAdmin.h"
9 #include "irods_log.hpp"
10 #include <sys/statvfs.h>
11 #include <boost/filesystem.hpp>
12 #include <boost/lexical_cast.hpp>
13 
15 
16 int
18  if (rei == NULL) {
19  rodsLog(LOG_ERROR, "[%s]: input rei is NULL", __FUNCTION__);
21  }
22 
23  if (resource_name_msparam == NULL) {
24  rodsLog(LOG_ERROR, "[%s]: resource_name_msparam is NULL", __FUNCTION__);
26  }
27  if (resource_name_msparam->type == NULL) {
28  rodsLog(LOG_ERROR, "[%s]: resource_name_msparam->type is NULL", __FUNCTION__);
30  }
31  if (strcmp(resource_name_msparam->type, STR_MS_T)) {
32  rodsLog(LOG_ERROR, "[%s]: first argument should be STR_MS_T, was [%s]", __FUNCTION__, resource_name_msparam->type);
33  return USER_PARAM_TYPE_ERR;
34  }
35 
36  const char* resource_name_cstring = static_cast<char*>(resource_name_msparam->inOutStruct);
37  if (resource_name_cstring == NULL) {
38  rodsLog(LOG_ERROR, "[%s]: input resource_name_msparam->inOutStruct is NULL", __FUNCTION__);
40  }
41 
43  const irods::error resource_manager_resolve_error = resc_mgr.resolve(resource_name_cstring, resource_ptr );
44  if (!resource_manager_resolve_error.ok()) {
45  rodsLog(LOG_ERROR, "[%s]: failed to resolve resource [%s]", __FUNCTION__, resource_name_cstring);
46  irods::log(resource_manager_resolve_error);
47  return resource_manager_resolve_error.status();
48  }
49 
50  std::string resource_type_unnormalized;
51  const irods::error get_resource_type_error = resource_ptr->get_property<std::string>(irods::RESOURCE_TYPE, resource_type_unnormalized);
52  if (!get_resource_type_error.ok()) {
53  rodsLog(LOG_ERROR, "[%s]: failed to get resource type for [%s]", __FUNCTION__, resource_name_cstring);
54  irods::log(get_resource_type_error);
55  return get_resource_type_error.status();
56  }
57 
58  std::string resource_type_normalized = irods::normalize_resource_type(resource_type_unnormalized);
59  if (resource_type_normalized != "unixfilesystem") {
60  return rei->status;
61  }
62 
63  std::string resource_vault_path;
64  const irods::error get_resource_vault_path_error = resource_ptr->get_property<std::string>(irods::RESOURCE_PATH, resource_vault_path);
65  if (!get_resource_vault_path_error.ok()) {
66  rodsLog(LOG_ERROR, "[%s]: failed to get resource path for [%s]", __FUNCTION__, resource_name_cstring);
67  irods::log(get_resource_vault_path_error);
68  return get_resource_vault_path_error.status();
69  }
70 
71  boost::filesystem::path path_to_stat{resource_vault_path};
72  const auto absolute_vault_path{boost::filesystem::absolute(path_to_stat)};
73  while(!boost::filesystem::exists(path_to_stat)) {
74  rodsLog(LOG_NOTICE, "[%s]: path to stat [%s] for resource [%s] doesn't exist, moving to parent", __FUNCTION__, path_to_stat.string().c_str(), resource_name_cstring);
75  path_to_stat = path_to_stat.parent_path();
76  if (path_to_stat.empty()) {
77  rodsLog(LOG_ERROR, "[%s]: could not find existing path from vault path [%s] for resource [%s]", __FUNCTION__, resource_vault_path.c_str(), resource_name_cstring);
79  }
80  }
81 
82  // Using the root directory as a vault path is bad - do not allow it to be used for updating free space
83  if (absolute_vault_path.root_path() == path_to_stat) {
84  rodsLog(LOG_ERROR, "[%s]: could not find existing non-root path from vault path [%s] for resource [%s]", __FUNCTION__, resource_vault_path.c_str(), resource_name_cstring);
86  }
87 
88  struct statvfs statvfs_buf;
89  const int statvfs_ret = statvfs(path_to_stat.string().c_str(), &statvfs_buf);
90  if (statvfs_ret != 0) {
91  rodsLog(LOG_ERROR, "[%s]: statvfs() of [%s] for resource [%s] failed with return %d and errno %d", __FUNCTION__, path_to_stat.string().c_str(), resource_name_cstring, statvfs_ret, errno);
93  }
94 
95  uintmax_t free_space_in_bytes;
96  if (statvfs_buf.f_bavail > ULONG_MAX / statvfs_buf.f_frsize) {
97  rodsLog(LOG_NOTICE, "[%s]: statvfs() of resource [%s] reports free space in excess of ULONG_MAX f_bavail %ju f_frsize %ju failed with return %d and errno %d", __FUNCTION__, resource_name_cstring, static_cast<uintmax_t>(statvfs_buf.f_bavail), static_cast<uintmax_t>(statvfs_buf.f_frsize));
98  free_space_in_bytes = ULONG_MAX;
99  } else {
100  free_space_in_bytes = statvfs_buf.f_bavail * statvfs_buf.f_frsize;
101  }
102  const std::string free_space_in_bytes_string = boost::lexical_cast<std::string>(free_space_in_bytes);
103 
104  if (rei->rsComm == NULL) {
105  rodsLog(LOG_ERROR, "[%s]: input rei->rsComm is NULL", __FUNCTION__);
107  }
108 
109  generalAdminInp_t admin_in;
110  memset(&admin_in, 0, sizeof(admin_in));
111  admin_in.arg0 = "modify";
112  admin_in.arg1 = "resource";
113  admin_in.arg2 = resource_name_cstring;
114  admin_in.arg3 = "freespace";
115  admin_in.arg4 = free_space_in_bytes_string.c_str();
116 
117 
118  rodsEnv service_account_environment;
119  const int getRodsEnv_ret = getRodsEnv(&service_account_environment);
120  if (getRodsEnv_ret < 0) {
121  rodsLog(LOG_ERROR, "[%s]: getRodsEnv failure [%d]", __FUNCTION__, getRodsEnv_ret);
122  return getRodsEnv_ret;
123  }
124 
125  rErrMsg_t errMsg;
126  memset(&errMsg, 0, sizeof(errMsg));
127  rcComm_t *admin_connection = rcConnect(service_account_environment.rodsHost, service_account_environment.rodsPort,
128  service_account_environment.rodsUserName, service_account_environment.rodsZone, 0, &errMsg);
129  if (admin_connection == NULL) {
130  char *mySubName = NULL;
131  const char *myName = rodsErrorName(errMsg.status, &mySubName);
132  rodsLog(LOG_ERROR, "[%s]: rcConnect failure [%s] [%s] [%d] [%s]", __FUNCTION__,
133  myName, mySubName, errMsg.status, errMsg.msg);
134  return errMsg.status;
135  }
136 
137  const int clientLogin_ret = clientLogin(admin_connection);
138  if (clientLogin_ret != 0) {
139  rodsLog(LOG_ERROR, "[%s]: clientLogin failure [%d]", __FUNCTION__, clientLogin_ret);
140  return clientLogin_ret;
141  }
142 
143  const int rcGeneralAdmin_ret = rcGeneralAdmin(admin_connection, &admin_in);
144  rcDisconnect(admin_connection);
145  if (rcGeneralAdmin_ret < 0) {
146  printErrorStack(admin_connection->rError);
147  rodsLog(LOG_ERROR, "[%s]: rcGeneralAdmin failure [%d]", __FUNCTION__, rcGeneralAdmin_ret);
148  }
149  return rcGeneralAdmin_ret;
150 }
151 
152 extern "C"
155  msvc->add_operation<
156  msParam_t*,
157  ruleExecInfo_t*>("msi_update_unixfilesystem_resource_free_space",
158  std::function<int(
159  msParam_t*,
161  return msvc;
162 }
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
rcComm_t
Definition: rcConnect.h:95
NULL
#define NULL
Definition: rodsDef.h:70
SYS_INTERNAL_NULL_INPUT_ERR
@ SYS_INTERNAL_NULL_INPUT_ERR
Definition: rodsErrorTable.h:92
SYS_INVALID_RESC_INPUT
@ SYS_INVALID_RESC_INPUT
Definition: rodsErrorTable.h:100
irods::normalize_resource_type
std::string normalize_resource_type(const std::string &resource_type)
Definition: irods_plugin_name_generator.cpp:20
rodsEnv::rodsPort
int rodsPort
Definition: getRodsEnv.h:11
irods_ms_plugin.hpp
getRodsEnv
int getRodsEnv(rodsEnv *myRodsEnv)
Definition: getRodsEnv.cpp:112
rErrMsg_t
Definition: rodsError.h:19
generalAdminInp_t
Definition: generalAdmin.h:6
msParam.h
RuleExecInfo::status
int status
Definition: irods_re_structs.hpp:19
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
rodsEnv::rodsZone
char rodsZone[64]
Definition: getRodsEnv.h:18
rcComm_t::rError
rError_t * rError
Definition: rcConnect.h:106
rErrMsg_t::status
int status
Definition: rodsError.h:20
generalAdmin.h
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
rcGeneralAdmin
int rcGeneralAdmin(rcComm_t *conn, generalAdminInp_t *generalAdminInp)
Definition: rcGeneralAdmin.cpp:49
rcMisc.h
irods::RESOURCE_PATH
const std::string RESOURCE_PATH("resource_property_path")
generalAdminInp_t::arg4
const char * arg4
Definition: generalAdmin.h:11
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
generalAdminInp_t::arg0
const char * arg0
Definition: generalAdmin.h:7
rodsErrorName
const char * rodsErrorName(int errorValue, char **subName)
Definition: rodsLog.cpp:373
MsParam::type
char * type
Definition: msParam.h:78
STR_MS_T
#define STR_MS_T
Definition: msParam.h:21
rodsEnv::rodsUserName
char rodsUserName[64]
Definition: getRodsEnv.h:9
rsGeneralAdmin.hpp
RuleExecInfo::rsComm
rsComm_t * rsComm
Definition: irods_re_structs.hpp:22
generalAdminInp_t::arg3
const char * arg3
Definition: generalAdmin.h:10
irods_resource_plugin.hpp
printErrorStack
int printErrorStack(rError_t *rError)
Definition: rcMisc.cpp:2327
rcConnect
rcComm_t * rcConnect(const char *rodsHost, int rodsPort, const char *userName, const char *rodsZone, int reconnFlag, rErrMsg_t *errMsg)
Definition: rcConnect.cpp:30
irods::RESOURCE_TYPE
const std::string RESOURCE_TYPE("resource_property_type")
generalAdminInp_t::arg1
const char * arg1
Definition: generalAdmin.h:8
irods::resource_manager::resolve
error resolve(std::string, resource_ptr &)
Definition: irods_resource_manager.cpp:51
irods::ms_table_entry::add_operation
error add_operation(const std::string &_op, std::function< int(types_t...)> _f)
Definition: irods_ms_plugin.hpp:68
rErrMsg_t::msg
char msg[1024]
Definition: rodsError.h:21
MsParam
Definition: msParam.h:76
irods::log
void log(const error &)
Definition: irods_log.cpp:13
generalAdminInp_t::arg2
const char * arg2
Definition: generalAdmin.h:9
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
irods::error
Definition: irods_error.hpp:23
int
typedef int((*funcPtr)())
irods::ms_table_entry
Definition: irods_ms_plugin.hpp:28
USER_PARAM_TYPE_ERR
@ USER_PARAM_TYPE_ERR
Definition: rodsErrorTable.h:254
irods_plugin_name_generator.hpp
rcDisconnect
int rcDisconnect(rcComm_t *conn)
Definition: rcConnect.cpp:246
RuleExecInfo
Definition: irods_re_structs.hpp:18
irods_resource_manager.hpp
irods::resource_manager
Definition: irods_resource_manager.hpp:30
irods::error::status
bool status() const
Definition: irods_error.cpp:187
MsParam::inOutStruct
void * inOutStruct
Definition: msParam.h:80
clientLogin
int clientLogin(rcComm_t *conn, const char *_context, const char *_scheme_override)
Definition: clientLogin.cpp:222
rodsEnv
Definition: getRodsEnv.h:8
msi_update_unixfilesystem_resource_free_space
int msi_update_unixfilesystem_resource_free_space(msParam_t *resource_name_msparam, ruleExecInfo_t *rei)
Definition: libmsi_update_unixfilesystem_resource_free_space.cpp:17
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
rodsEnv::rodsHost
char rodsHost[64]
Definition: getRodsEnv.h:10
irods_log.hpp
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
plugin_factory
irods::ms_table_entry * plugin_factory()
Definition: libmsi_update_unixfilesystem_resource_free_space.cpp:153