27 #include <boost/function.hpp>
28 #include <boost/any.hpp>
34 #include <sys/param.h>
42 #include <sys/types.h>
43 #if defined(osx_platform)
44 #include <sys/malloc.h>
55 #if defined(solaris_platform)
56 #include <sys/statvfs.h>
59 #if defined(osx_platform)
60 #include <sys/param.h>
61 #include <sys/mount.h>
64 #if defined(linux_platform)
71 #define NB_READ_TOUT_SEC 60
72 #define NB_WRITE_TOUT_SEC 60
85 const std::string& _phy_path,
86 std::string& _ret_string ) {
89 std::string vault_path;
93 if ( _phy_path.compare( 0, 1,
"/" ) != 0 &&
94 _phy_path.compare( 0, vault_path.size(), vault_path ) != 0 ) {
95 _ret_string = vault_path;
97 _ret_string += _phy_path;
101 _ret_string = _phy_path;
122 std::string full_path;
124 data_obj->physical_path(),
126 if ( ( result =
ASSERT_PASS( ret,
"Failed generating full path for object." ) ).ok() ) {
127 data_obj->physical_path( full_path );
137 template<
typename DEST_TYPE >
146 ret = _ctx.
valid< DEST_TYPE >();
147 if ( ( result =
ASSERT_PASS( ret,
"resource context is invalid." ) ).ok() ) {
166 if ( ( result =
ASSERT_PASS( ret,
"non_blocking_check_params_and_path - resource context is invalid" ) ).ok() ) {
177 const std::string& path,
183 while ( !done && result.
ok() ) {
184 pos = path.find_first_of(
'/', pos + 1 );
186 subdir = path.substr( 0, pos );
192 subdir.c_str(), strerror( errno ),
status );
194 if ( pos == std::string::npos ) {
223 result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." );
237 result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." );
251 result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." );
261 const std::string* ) {
265 result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." );
280 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
285 size_t found = fco->physical_path().find_last_of(
"/" );
286 std::string path = fco->physical_path().substr( 0, found + 1 );
289 #if defined(solaris_platform)
290 struct statvfs statbuf;
292 struct statfs statbuf;
295 #if defined(solaris_platform) || defined(sgi_platform) || \
296 defined(aix_platform) || defined(linux_platform) || \
297 defined(osx_platform)
298 #if defined(solaris_platform)
299 status = statvfs( path.c_str(), &statbuf );
301 #if defined(sgi_platform)
302 status = statfs( path.c_str(), &statbuf,
sizeof(
struct statfs ), 0 );
304 status = statfs( path.c_str(), &statbuf );
311 if ( ( result =
ASSERT_ERROR(
status >= 0, err_status,
"Statfs error for \"%s\", status = %d.",
312 path.c_str(), err_status ) ).ok() ) {
314 #if defined(sgi_platform)
315 if ( statbuf.f_frsize > 0 ) {
316 fssize = statbuf.f_frsize;
319 fssize = statbuf.f_bsize;
321 fssize *= statbuf.f_bavail;
324 #if defined(aix_platform) || defined(osx_platform) || \
325 defined(linux_platform)
326 fssize = statbuf.f_bavail * statbuf.f_bsize;
329 #if defined(sgi_platform)
330 fssize = statbuf.f_bfree * statbuf.f_bsize;
332 result.
code( fssize );
351 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
358 if ( ( result =
ASSERT_PASS( ret,
"Error determining freespace on system." ) ).ok() ) {
361 file_size, ret.
code() ) ).ok() ) {
365 mode_t myMask = umask( ( mode_t ) 0000 );
366 int fd = open( fco->physical_path().c_str(), O_RDWR | O_CREAT | O_EXCL, fco->mode() );
371 ( void ) umask( ( mode_t ) myMask );
378 int null_fd = open(
"/dev/null", O_RDWR, 0 );
379 fd = open( fco->physical_path().c_str(), O_RDWR | O_CREAT | O_EXCL, fco->mode() );
381 if ( null_fd >= 0 ) {
391 std::stringstream msg;
392 msg <<
"create error for \"";
393 msg << fco->physical_path();
394 msg <<
"\", errno = \"";
395 msg << strerror( errsav );
400 fco->file_descriptor(
status );
406 fco->file_descriptor( fd );
427 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
435 int flags = fco->flags();
437 #if defined(osx_platform)
439 if ( flags & 0x200 ) {
440 flags = flags ^ 0x200;
441 flags = flags | O_TRUNC;
447 int fd = open( fco->physical_path().c_str(), flags, fco->mode() );
454 int null_fd = open(
"/dev/null", O_RDWR, 0 );
455 fd = open( fco->physical_path().c_str(), flags, fco->mode() );
457 if ( null_fd >= 0 ) {
465 fco->file_descriptor( fd );
471 std::stringstream msg;
472 msg <<
"Open error for \"";
473 msg << fco->physical_path();
474 msg <<
"\", errno = \"";
475 msg << strerror( errsav );
476 msg <<
"\", status = ";
505 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
516 int fd = fco->file_descriptor();
518 bzero( &tv,
sizeof( tv ) );
526 tmpPtr = (
char * ) _buf;
528 while ( toRead > 0 ) {
533 if ( _len - toRead > 0 ) {
534 return CODE( _len - toRead );
537 std::stringstream msg;
538 msg <<
"timeout error.";
543 if ( errno == EINTR ) {
548 std::stringstream msg;
549 msg <<
"file read error.";
555 nbytes = read( fco->file_descriptor(), (
void * ) tmpPtr, toRead );
557 if ( errno == EINTR ) {
562 else if ( toRead == _len ) {
570 else if ( nbytes == 0 ) {
579 result.
code( _len - toRead );
599 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
604 int fd = fco->file_descriptor();
611 bzero( &tv,
sizeof( tv ) );
620 tmpPtr = (
char * ) _buf;
622 while ( toWrite > 0 ) {
630 if ( errno == EINTR ) {
640 nbytes = write( fco->file_descriptor(), (
void * ) tmpPtr, _len );
642 if ( errno == EINTR ) {
676 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
684 int status = close( fco->file_descriptor() );
689 if ( !( result =
ASSERT_ERROR(
status >= 0, err_status,
"Close error for file: \"%s\", errno = \"%s\", status = %d.",
690 fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
691 result.
code( err_status );
711 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
719 int status = unlink( fco->physical_path().c_str() );
724 if ( !( result =
ASSERT_ERROR(
status >= 0, err_status,
"Unlink error for \"%s\", errno = \"%s\", status = %d.",
725 fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
727 result.
code( err_status );
742 struct stat* _statbuf ) {
751 if ( ( result =
ASSERT_PASS( ret,
"resource context is invalid." ) ).ok() ) {
759 int status = stat( fco->physical_path().c_str(), _statbuf );
764 if ( ( result =
ASSERT_ERROR(
status >= 0, err_status,
"Stat error for \"%s\", errno = \"%s\", status = %d.",
765 fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
785 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
793 long long status = lseek( fco->file_descriptor(), _offset, _whence );
798 if ( ( result =
ASSERT_ERROR(
status >= 0, err_status,
"Lseek error for \"%s\", errno = \"%s\", status = %ld.",
799 fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
819 if ( ( result =
ASSERT_PASS( ret,
"resource context is invalid." ) ).ok() ) {
827 mode_t myMask = umask( ( mode_t ) 0000 );
828 int status = mkdir( fco->physical_path().c_str(), fco->mode() );
832 umask( ( mode_t ) myMask );
838 if ( ( result =
ASSERT_ERROR(
status >= 0, err_status,
"Mkdir error for \"%s\", errno = \"%s\", status = %d.",
839 fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
856 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
864 int status = rmdir( fco->physical_path().c_str() );
869 result =
ASSERT_ERROR(
status >= 0, err_status,
"Rmdir error for \"%s\", errno = \"%s\", status = %d.",
870 fco->physical_path().c_str(), strerror( errno ), err_status );
885 irods::error ret = non_blocking_check_params_and_path< irods::collection_object >( _ctx );
886 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
894 DIR* dir_ptr = opendir( fco->physical_path().c_str() );
902 if (
NULL != dir_ptr ) {
905 fco->directory_pointer( dir_ptr );
908 std::stringstream msg;
909 msg <<
"Opendir error for \"";
910 msg << fco->physical_path();
911 msg <<
"\", errno = \"";
912 msg << strerror( errno );
913 msg <<
"\", status = ";
916 result =
ERROR( err_status, msg.str() );
932 irods::error ret = non_blocking_check_params_and_path< irods::collection_object >( _ctx );
933 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
941 int status = closedir( fco->directory_pointer() );
946 result =
ASSERT_ERROR(
status >= 0, err_status,
"Closedir error for \"%s\", errno = \"%s\", status = %d.",
947 fco->physical_path().c_str(), strerror( errno ), err_status );
963 irods::error ret = non_blocking_check_params_and_path< irods::collection_object >( _ctx );
964 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
976 struct dirent * tmp_dirent = readdir( fco->directory_pointer() );
980 if ( ( result =
ASSERT_ERROR( tmp_dirent !=
NULL, -1,
"End of directory list reached." ) ).ok() ) {
984 if ( !( *_dirent_ptr ) ) {
995 #if defined(solaris_platform)
1003 if ( ( result =
ASSERT_ERROR( errno == 0,
status,
"Readdir error, status = %d, errno= \"%s\".",
1004 status, strerror( errno ) ) ).ok() ) {
1018 const char* _new_file_name ) {
1024 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
1028 std::string new_full_path;
1030 if ( ( result =
ASSERT_PASS( ret,
"Unable to generate full path for destination file: \"%s\".",
1031 _new_file_name ) ).ok() ) {
1039 std::string new_path = new_full_path;
1040 std::size_t last_slash = new_path.find_last_of(
'/' );
1041 new_path.erase( last_slash );
1043 if ( ( result =
ASSERT_PASS( ret,
"Mkdir error for \"%s\".", new_path.c_str() ) ).ok() ) {
1049 int status =
rename( fco->physical_path().c_str(), new_full_path.c_str() );
1056 std::stringstream msg;
1057 msg <<
"non_blocking_file_rename: rename error for ";
1058 msg << fco->physical_path();
1060 msg << new_full_path;
1061 msg <<
", errno = ";
1062 msg << strerror( errno );
1063 msg <<
", status = ";
1081 irods::error ret = non_blocking_check_params_and_path< irods::file_object >( _ctx );
1083 std::stringstream msg;
1084 msg << __FUNCTION__ <<
" - Invalid parameters or physical path.";
1085 return PASSMSG( msg.str(), ret );
1094 int status = truncate( file_obj->physical_path().c_str(),
1104 std::stringstream msg;
1105 msg <<
"non_blocking_file_truncate: rename error for ";
1106 msg << file_obj->physical_path();
1107 msg <<
", errno = '";
1108 msg << strerror( errno );
1109 msg <<
"', status = ";
1122 const char* srcFileName,
1123 const char* destFileName ) {
1126 int inFd = open( srcFileName, O_RDONLY, 0 );
1128 struct stat statbuf;
1129 int status = stat( srcFileName, &statbuf );
1135 std::stringstream msg_stream;
1136 msg_stream <<
"Stat of \"" << srcFileName <<
"\" error, status = " << stat_err_status;
1137 result =
ERROR( stat_err_status, msg_stream.str() );
1139 else if ( inFd < 0 ) {
1140 std::stringstream msg_stream;
1141 msg_stream <<
"Open error for srcFileName \"" << srcFileName <<
"\", status = " <<
status;
1142 result =
ERROR( open_err_status, msg_stream.str() );
1144 else if ( ( statbuf.st_mode & S_IFREG ) == 0 ) {
1146 std::stringstream msg_stream;
1147 msg_stream <<
"srcFileName \"" << srcFileName <<
"\" is not a regular file.";
1151 int outFd = open( destFileName, O_WRONLY | O_CREAT | O_TRUNC,
mode );
1154 std::stringstream msg_stream;
1155 msg_stream <<
"Open error for destFileName \"" << destFileName <<
"\", status = " <<
status;
1156 result =
ERROR( err_status, msg_stream.str() );
1158 else if ( ( statbuf.st_mode & S_IFREG ) == 0 ) {
1160 std::stringstream msg_stream;
1161 msg_stream <<
"destFileName \"" << destFileName <<
"\" is not a regular file.";
1165 size_t trans_buff_size;
1174 std::vector<char> myBuf( trans_buff_size );
1178 while ( result.
ok() && ( bytesRead = read( inFd, (
void * ) myBuf.data(), trans_buff_size ) ) > 0 ) {
1179 int bytesWritten = write( outFd, (
void * ) myBuf.data(), bytesRead );
1181 if ( ( result =
ASSERT_ERROR( bytesWritten > 0, err_status,
"Write error for srcFileName %s, status = %d",
1182 destFileName,
status ) ).ok() ) {
1183 bytesCopied += bytesWritten;
1189 if ( result.
ok() ) {
1191 bytesCopied, statbuf.st_size, srcFileName );
1205 const char* _cache_file_name ) {
1211 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
1229 const char* _cache_file_name ) {
1235 if ( ( result =
ASSERT_PASS( ret,
"Invalid parameters or physical path." ) ).ok() ) {
1253 const std::string& _curr_host,
1254 float& _out_vote ) {
1259 int resc_status = 0;
1261 if ( ( result =
ASSERT_PASS( get_ret,
"Failed to get \"status\" property." ) ).ok() ) {
1272 std::string host_name;
1274 if ( ( result =
ASSERT_PASS( get_ret,
"Failed to get \"location\" property." ) ).ok() ) {
1278 if ( _curr_host == host_name ) {
1296 const std::string& _resc_name,
1297 const std::string& _curr_host,
1298 float& _out_vote ) {
1307 int resc_status = 0;
1309 if ( ( result =
ASSERT_PASS( get_ret,
"Failed to get \"status\" property." ) ).ok() ) {
1317 std::string host_name;
1319 if ( ( result =
ASSERT_PASS( get_ret,
"Failed to get \"location\" property." ) ).ok() ) {
1323 bool curr_host = ( _curr_host == host_name );
1327 bool need_repl = ( _file_obj->repl_requested() > -1 );
1332 std::vector< irods::physical_object > objs = _file_obj->replicas();
1333 std::vector< irods::physical_object >::iterator itr = objs.begin();
1337 for ( ; itr != objs.end(); ++itr ) {
1341 std::string last_resc;
1343 parser.set_string( itr->resc_hier() );
1344 parser.last_resc( last_resc );
1348 bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() );
1349 bool resc_us = ( _resc_name == last_resc );
1350 bool is_dirty = ( itr->is_dirty() != 1 );
1408 const std::string* _opr,
1409 const std::string* _curr_host,
1411 float* _out_vote ) {
1417 if ( ( result =
ASSERT_PASS( ret,
"Invalid resource context." ) ).ok() ) {
1429 std::string resc_name;
1431 if ( ( result =
ASSERT_PASS( ret,
"Failed in get property for name." ) ).ok() ) {
1443 result =
ASSERT_PASS( ret,
"Failed redirecting for open." );
1451 result =
ASSERT_PASS( ret,
"Failed redirecting for create." );
1499 rodsLog(
LOG_NOTICE,
"non_blocking_resource::post_disconnect_maintenance_operation - [%s]",
1511 const std::string& _inst_name,
1512 const std::string& _context ) :
1530 return ERROR( -1,
"nop" );
1554 using namespace irods;
1555 using namespace std;
1574 function<error(plugin_context&,void*,int)>(
1589 function<error(plugin_context&, struct stat*)>(
1604 function<error(plugin_context&,struct rodsDirent**)>(
1609 function<error(plugin_context&, const char*)>(
1619 function<error(plugin_context&, long long, int)>(
1634 function<error(plugin_context&, const char*)>(
1639 function<error(plugin_context&, const char*)>(
1659 function<error(plugin_context&, const std::string*)>(
1669 function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(