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)  

libunixfilesystem.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=-
2 // irods includes
3 #include "msParam.h"
4 #include "rcConnect.h"
5 #include "miscServerFunct.hpp"
6 #include "generalAdmin.h"
7 
8 // =-=-=-=-=-=-=-
10 #include "irods_file_object.hpp"
16 #include "irods_stacktrace.hpp"
20 
21 // =-=-=-=-=-=-=-
22 // stl includes
23 #include <iostream>
24 #include <sstream>
25 #include <vector>
26 #include <string>
27 
28 // =-=-=-=-=-=-=-
29 // boost includes
30 #include <boost/function.hpp>
31 #include <boost/any.hpp>
32 #include <boost/lexical_cast.hpp>
33 #include <boost/filesystem.hpp>
34 
35 // =-=-=-=-=-=-=-
36 // system includes
37 #ifndef _WIN32
38 #include <sys/file.h>
39 #include <sys/param.h>
40 #endif
41 #include <errno.h>
42 #include <sys/stat.h>
43 #include <string.h>
44 #ifndef _WIN32
45 #include <unistd.h>
46 #endif
47 #include <sys/types.h>
48 #if defined(osx_platform)
49 #include <sys/malloc.h>
50 #else
51 #include <malloc.h>
52 #endif
53 #include <fcntl.h>
54 #ifndef _WIN32
55 #include <sys/file.h>
56 #include <unistd.h>
57 #endif
58 #include <dirent.h>
59 
60 #if defined(solaris_platform)
61 #include <sys/statvfs.h>
62 #endif
63 
64 #if defined(osx_platform)
65 #include <sys/param.h>
66 #include <sys/mount.h>
67 #endif
68 
69 #if defined(linux_platform)
70 #include <sys/vfs.h>
71 #endif
72 #include <sys/stat.h>
73 
74 #include <string.h>
75 #include <sstream>
76 
77 
78 // =-=-=-=-=-=-=-
79 // 1. Define utility functions that the operations might need
80 const std::string DEFAULT_VAULT_DIR_MODE( "default_vault_directory_mode_kw" );
81 const std::string HIGH_WATER_MARK( "high_water_mark" ); // no longer used
82 const std::string REQUIRED_FREE_INODES_FOR_CREATE("required_free_inodes_for_create"); // no longer used
83 const std::string MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES("minimum_free_space_for_create_in_bytes");
84 
85 // =-=-=-=-=-=-=-
86 // NOTE: All storage resources must do this on the physical path stored in the file object and then update
87 // the file object's physical path with the full path
88 
90  int mode,
91  const char* srcFileName,
92  const char* destFileName ) {
93 
94  irods::error result = SUCCESS();
95 
96  int inFd = open( srcFileName, O_RDONLY, 0 );
97  int err_status = UNIX_FILE_OPEN_ERR - errno;
98  if ( inFd < 0 ) {
99  std::stringstream msg_stream;
100  msg_stream << "Open error for srcFileName \"" << srcFileName << "\", status = " << err_status;
101  result = ERROR( err_status, msg_stream.str() );
102  }
103  else {
104  struct stat statbuf;
105  int status = stat( srcFileName, &statbuf );
106  err_status = errno;
107  if ( status < 0 ) {
108  std::stringstream msg_stream;
109  msg_stream << "stat failed on \"" << srcFileName << "\", status: " << err_status;
110  result = ERROR( UNIX_FILE_STAT_ERR, msg_stream.str() );
111  }
112  else if ( ( statbuf.st_mode & S_IFREG ) == 0 ) {
113  std::stringstream msg_stream;
114  msg_stream << "srcFileName \"" << srcFileName << "\" is not a regular file.";
115  result = ERROR( UNIX_FILE_STAT_ERR, msg_stream.str() );
116  }
117  else {
118  int outFd = open( destFileName, O_WRONLY | O_CREAT | O_TRUNC, mode );
119  err_status = UNIX_FILE_OPEN_ERR - errno;
120  if ( outFd < 0 ) {
121  std::stringstream msg_stream;
122  msg_stream << "Open error for destFileName \"" << destFileName << "\", status = " << err_status;
123  result = ERROR( err_status, msg_stream.str() );
124  }
125  else {
126  size_t trans_buff_size;
127  try {
128  trans_buff_size = irods::get_advanced_setting<const int>(irods::CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS) * 1024 * 1024;
129  } catch ( const irods::exception& e ) {
130  close( inFd );
131  close( outFd );
132  return irods::error(e);
133  }
134 
135  std::vector<char> myBuf( trans_buff_size );
136  int bytesRead;
137  rodsLong_t bytesCopied = 0;
138  while ( result.ok() && ( bytesRead = read( inFd, ( void * ) myBuf.data(), trans_buff_size ) ) > 0 ) {
139  int bytesWritten = write( outFd, ( void * ) myBuf.data(), bytesRead );
140  err_status = UNIX_FILE_WRITE_ERR - errno;
141  if ( ( result = ASSERT_ERROR( bytesWritten > 0, err_status, "Write error for srcFileName %s, status = %d",
142  destFileName, status ) ).ok() ) {
143  bytesCopied += bytesWritten;
144  }
145  }
146 
147  close( outFd );
148 
149  if ( result.ok() ) {
150  result = ASSERT_ERROR( bytesCopied == statbuf.st_size, SYS_COPY_LEN_ERR, "Copied size %lld does not match source size %lld of %s",
151  bytesCopied, statbuf.st_size, srcFileName );
152  }
153  }
154  }
155  close( inFd );
156  }
157  return result;
158 }
159 
160 
161 
162 // =-=-=-=-=-=-=-
165  irods::plugin_property_map& _prop_map,
166  const std::string& _phy_path,
167  std::string& _ret_string ) {
168  irods::error result = SUCCESS();
169  irods::error ret;
170  std::string vault_path;
171  // TODO - getting vault path by property will not likely work for coordinating nodes
172  ret = _prop_map.get<std::string>( irods::RESOURCE_PATH, vault_path );
173  if ( ( result = ASSERT_ERROR( ret.ok(), SYS_INVALID_INPUT_PARAM, "resource has no vault path." ) ).ok() ) {
174  if ( _phy_path.compare( 0, 1, "/" ) != 0 &&
175  _phy_path.compare( 0, vault_path.size(), vault_path ) != 0 ) {
176  _ret_string = vault_path;
177  _ret_string += "/";
178  _ret_string += _phy_path;
179  }
180  else {
181  // The physical path already contains the vault path
182  _ret_string = _phy_path;
183  }
184  }
185 
186  return result;
187 
188 } // unix_generate_full_path
189 
190 // =-=-=-=-=-=-=-
193  irods::plugin_context& _ctx ) {
194  irods::error result = SUCCESS();
195 
196  // =-=-=-=-=-=-=-
197  // try dynamic cast on ptr, throw error otherwise
198  irods::data_object_ptr data_obj = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
199  if ( ( result = ASSERT_ERROR( data_obj.get(), SYS_INVALID_INPUT_PARAM, "Failed to cast fco to data_object." ) ).ok() ) {
200  // =-=-=-=-=-=-=-
201  // NOTE: Must do this for all storage resources
202  std::string full_path;
204  data_obj->physical_path(),
205  full_path );
206  if ( ( result = ASSERT_PASS( ret, "Failed generating full path for object." ) ).ok() ) {
207  data_obj->physical_path( full_path );
208  }
209  }
210 
211  return result;
212 
213 } // unix_check_path
214 
215 // =-=-=-=-=-=-=-
217 template< typename DEST_TYPE >
219  irods::plugin_context& _ctx ) {
220 
221  irods::error result = SUCCESS();
222  irods::error ret;
223 
224  // =-=-=-=-=-=-=-
225  // verify that the resc context is valid
226  ret = _ctx.valid< DEST_TYPE >();
227  if ( ( result = ASSERT_PASS( ret, "resource context is invalid." ) ).ok() ) {
228  result = unix_check_path( _ctx );
229  }
230 
231  return result;
232 
233 } // unix_check_params_and_path
234 
235 // =-=-=-=-=-=-=-
238  irods::plugin_context& _ctx ) {
239 
240  irods::error result = SUCCESS();
241  irods::error ret;
242 
243  // =-=-=-=-=-=-=-
244  // verify that the resc context is valid
245  ret = _ctx.valid();
246  if ( ( result = ASSERT_PASS( ret, "unix_check_params_and_path - resource context is invalid" ) ).ok() ) {
247  result = unix_check_path( _ctx );
248  }
249 
250  return result;
251 
252 } // unix_check_params_and_path
253 
254 // =-=-=-=-=-=-=-
255 //@brief Recursively make all of the dirs in the path
257  const std::string& path,
258  mode_t mode ) {
259  irods::error result = SUCCESS();
260  std::string subdir;
261  std::size_t pos = 0;
262  bool done = false;
263  while ( !done && result.ok() ) {
264  pos = path.find_first_of( '/', pos + 1 );
265  if ( pos > 0 ) {
266  subdir = path.substr( 0, pos );
267  int status = mkdir( subdir.c_str(), mode );
268 
269  // =-=-=-=-=-=-=-
270  // handle error cases
271  result = ASSERT_ERROR( status >= 0 || errno == EEXIST, UNIX_FILE_RENAME_ERR - errno, "mkdir error for \"%s\", errno = \"%s\", status = %d.",
272  subdir.c_str(), strerror( errno ), status );
273  }
274  if ( pos == std::string::npos ) {
275  done = true;
276  }
277  }
278 
279  return result;
280 
281 } // unix_file_mkdir_r
282 
283 // =-=-=-=-=-=-=-
284 // 2. Define operations which will be called by the file*
285 // calls declared in server/driver/include/fileDriver.h
286 // =-=-=-=-=-=-=-
287 
288 // =-=-=-=-=-=-=-
289 // NOTE :: to access properties in the _prop_map do the
290 // :: following :
291 // :: double my_var = 0.0;
292 // :: irods::error ret = _prop_map.get< double >( "my_key", my_var );
293 // =-=-=-=-=-=-=-
294 
298  irods::plugin_context& _ctx ) {
299  irods::error result = SUCCESS();
300 
301  // Check the operation parameters and update the physical path
303  result = ASSERT_PASS( ret, "Invalid parameters or physical path." );
304 
305  // NOOP
306  return result;
307 }
308 
312  irods::plugin_context& _ctx ) {
313  irods::error result = SUCCESS();
314 
315  // Check the operation parameters and update the physical path
317  result = ASSERT_PASS( ret, "Invalid parameters or physical path." );
318 
319  // NOOP
320  return result;
321 }
322 
326  irods::plugin_context& _ctx ) {
327  irods::error result = SUCCESS();
328 
329  // Check the operation parameters and update the physical path
331  result = ASSERT_PASS( ret, "Invalid parameters or physical path." );
332 
333  // NOOP
334  return result;
335 }
336 
340  irods::plugin_context& _ctx,
341  const std::string* ) {
342  irods::error result = SUCCESS();
343  // Check the operation parameters and update the physical path
345  result = ASSERT_PASS( ret, "Invalid parameters or physical path." );
346 
347  // NOOP
348  return result;
349 }
350 
351 // =-=-=-=-=-=-=-
352 // interface to determine free space on a device given a path
354  irods::plugin_context& _ctx ) {
355  irods::error result = SUCCESS();
356 
357  // =-=-=-=-=-=-=-
358  // Check the operation parameters and update the physical path
360  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
361 
362  // =-=-=-=-=-=-=-
363  // cast down the hierarchy to the desired object
364  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
365  size_t found = fco->physical_path().find_last_of( "/" );
366  std::string path = fco->physical_path().substr( 0, found + 1 );
367  int status = -1;
369 #if defined(solaris_platform)
370  struct statvfs statbuf;
371 #else
372  struct statfs statbuf;
373 #endif
374 
375 #if not defined(windows_platform)
376 #if defined(solaris_platform)
377  status = statvfs( path.c_str(), &statbuf );
378 #elif defined(sgi_platform)
379  status = statfs( path.c_str(), &statbuf, sizeof( struct statfs ), 0 );
380 #elif defined(aix_platform) || defined(linux_platform) || defined(osx_platform)
381  status = statfs( path.c_str(), &statbuf );
382 #endif
383 
384  // =-=-=-=-=-=-=-
385  // handle error, if any
386  int err_status = UNIX_FILE_GET_FS_FREESPACE_ERR - errno;
387  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Statfs error for \"%s\", status = %d.",
388  path.c_str(), err_status ) ).ok() ) {
389 
390 #if defined(sgi_platform)
391  if ( statbuf.f_frsize > 0 ) {
392  fssize = statbuf.f_frsize;
393  }
394  else {
395  fssize = statbuf.f_bsize;
396  }
397  fssize *= statbuf.f_bavail;
398 #endif
399 
400 #if defined(aix_platform) || defined(osx_platform) || \
401 defined(linux_platform)
402  fssize = statbuf.f_bavail * statbuf.f_bsize;
403 #elif defined(sgi_platform)
404  fssize = statbuf.f_bfree * statbuf.f_bsize;
405 #endif
406  result.code( fssize );
407  }
408 
409 #endif /* solaris_platform, sgi_platform .... */
410  }
411 
412  return result;
413 
414 } // unix_file_getfs_freespace
415 
417  const std::string& _path,
418  struct statfs& _sb ) {
419  namespace bfs = boost::filesystem;
420 
421  bfs::path vp( _path );
422 
423  // walk the vault path until we find an
424  // existing directory which we can stat
425  while( !bfs::exists( vp ) ) {
426  vp = vp.parent_path();
427  }
428 
429  if( vp.empty() ) {
430  std::string msg( "path does not exist [" );
431  msg += _path + "]";
432  return ERROR(
434  msg );
435  }
436 
437  int err = statfs( vp.string().c_str(), &_sb );
438  if( err < 0 ) {
439  std::stringstream msg;
440  msg << "statfs failed for ["
441  << _path << "] errno " << errno;
442  return ERROR(
443  errno,
444  msg.str() );
445  }
446 
447  return SUCCESS();
448 
449 } // stat_vault_path
450 
452  std::string resource_name;
453  irods::error ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, resource_name);
454  if (!ret.ok()) {
455  rodsLog(LOG_ERROR, "warn_if_deprecated_context_string_set: failed to get resource name");
456  }
457 
458  std::string holder;
459  ret = _ctx.prop_map().get<std::string>(HIGH_WATER_MARK, holder);
460  if (ret.code() != KEY_NOT_FOUND) {
461  rodsLog(LOG_NOTICE, "warn_if_deprecated_context_string_set: resource [%s] is using deprecated context string [%s]", resource_name.c_str(), HIGH_WATER_MARK.c_str());
462  }
463 
464  ret = _ctx.prop_map().get<std::string>(REQUIRED_FREE_INODES_FOR_CREATE, holder);
465  if (ret.code() != KEY_NOT_FOUND) {
466  rodsLog(LOG_NOTICE, "warn_if_deprecated_context_string_set: resource [%s] is using deprecated context string [%s]", resource_name.c_str(), REQUIRED_FREE_INODES_FOR_CREATE.c_str());
467  }
468 }
469 
471  std::string resource_name;
472  irods::error ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, resource_name);
473  if (!ret.ok()) {
474  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: failed to get resource name");
475  }
476 
477  if (_file_size < 0) {
478  return false;
479  }
480 
481  std::string minimum_free_space_string;
482  irods::error err = _ctx.prop_map().get<std::string>(MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES, minimum_free_space_string);
483  if (err.code() == KEY_NOT_FOUND) {
484  return false;
485  } else if (!err.ok()) {
486  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: failed to get MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES property for resource [%s]", resource_name.c_str());
487  irods::log(err);
488  return true;
489  }
490 
491  if (minimum_free_space_string.size()>0 && minimum_free_space_string[0] == '-') { // do sign check on string because boost::lexical_cast will wrap negative numbers around instead of throwing when casting string to unsigned
492  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: minimum free space < 0 [%s] for resource [%s]", minimum_free_space_string.c_str(), resource_name.c_str());
493  return true;
494  }
495 
496  uintmax_t minimum_free_space = 0;
497  try {
498  minimum_free_space = boost::lexical_cast<uintmax_t>(minimum_free_space_string);
499  } catch (const boost::bad_lexical_cast&) {
500  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: invalid MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES [%s] for resource [%s]", minimum_free_space_string.c_str(), resource_name.c_str());
501  return true;
502  }
503 
504  std::string resource_free_space_string;
505  err = _ctx.prop_map().get<std::string>(irods::RESOURCE_FREESPACE, resource_free_space_string);
506  if (!err.ok()) {
507  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: minimum free space constraint was requested, and failed to get resource free space for resource [%s]", resource_name.c_str());
508  irods::log(err);
509  return true;
510  }
511 
512  if (resource_free_space_string.size()>0 && resource_free_space_string[0] == '-') { // do sign check on string because boost::lexical_cast will wrap negative numbers around instead of throwing when casting string to unsigned
513  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: resource free space < 0 [%s] for resource [%s]", resource_free_space_string.c_str(), resource_name.c_str());
514  return true;
515  }
516 
517  uintmax_t resource_free_space = 0;
518  try {
519  resource_free_space = boost::lexical_cast<uintmax_t>(resource_free_space_string);
520  } catch (const boost::bad_lexical_cast&) {
521  rodsLog(LOG_ERROR, "replica_exceeds_resource_free_space: invalid free space [%s] for resource [%s]", resource_free_space_string.c_str(), resource_name.c_str());
522  return true;
523  }
524 
525  if (minimum_free_space > resource_free_space) {
526  return true;
527  }
528 
529  if (resource_free_space - minimum_free_space < static_cast<uint64_t>(_file_size)) {
530  return true;
531  }
532 
533  return false;
534 }
535 
536 // =-=-=-=-=-=-=-
537 // interface for POSIX create
539  irods::plugin_context& _ctx ) {
540  irods::error result = SUCCESS();
541 
542  // =-=-=-=-=-=-=-
543  // Check the operation parameters and update the physical path
545  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
546 
547  // =-=-=-=-=-=-=-
548  // get ref to fco
549  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
550 
551  char* kvp_str = getValByKey(
552  &fco->cond_input(),
554  if ( kvp_str ) {
555  irods::kvp_map_t kvp;
557  kvp_str,
558  kvp );
559  if ( !ret.ok() ) {
560  irods::log( PASS( ret ) );
561  }
562  else {
563  irods::kvp_map_t::iterator itr = kvp.begin();
564  for ( ; itr != kvp.end(); ++ itr ) {
565  rodsLog(
566  LOG_DEBUG,
567  "unix_file_create_plugin - kv_pass :: key [%s] - value [%s]",
568  itr->first.c_str(),
569  itr->second.c_str() );
570  } // for itr
571  }
572  }
573 
574  ret = unix_file_getfs_freespace( _ctx );
575  if ( ( result = ASSERT_PASS( ret, "Error determining freespace on system." ) ).ok() ) {
576  rodsLong_t file_size = fco->size();
577  if ( ( result = ASSERT_ERROR( file_size < 0 || ret.code() >= file_size, USER_FILE_TOO_LARGE, "File size: %ld is greater than space left on device: %ld",
578  file_size, ret.code() ) ).ok() ) {
579  // =-=-=-=-=-=-=-
580  // make call to umask & open for create
581  mode_t myMask = umask( ( mode_t ) 0000 );
582  int fd = open( fco->physical_path().c_str(), O_RDWR | O_CREAT | O_EXCL, fco->mode() );
583  int errsav = errno;
584 
585  // =-=-=-=-=-=-=-
586  // reset the old mask
587  ( void ) umask( ( mode_t ) myMask );
588 
589  // =-=-=-=-=-=-=-
590  // if we got a 0 descriptor, try again
591  if ( fd == 0 ) {
592 
593  close( fd );
594  int null_fd = open( "/dev/null", O_RDWR, 0 );
595 
596  // =-=-=-=-=-=-=-
597  // make call to umask & open for create
598  mode_t myMask = umask( ( mode_t ) 0000 );
599  fd = open( fco->physical_path().c_str(), O_RDWR | O_CREAT | O_EXCL, fco->mode() );
600  errsav = errno;
601  if ( null_fd >= 0 ) {
602  close( null_fd );
603  }
604  rodsLog( LOG_NOTICE, "unix_file_create_plugin: 0 descriptor" );
605 
606  // =-=-=-=-=-=-=-
607  // reset the old mask
608  ( void ) umask( ( mode_t ) myMask );
609  }
610 
611  // =-=-=-=-=-=-=-
612  // trap error case with bad fd
613  if ( fd < 0 ) {
614  int status = UNIX_FILE_CREATE_ERR - errsav;
615  std::stringstream msg;
616  msg << "create error for \"";
617  msg << fco->physical_path();
618  msg << "\", errno = \"";
619  msg << strerror( errsav );
620  msg << "\".";
621  // =-=-=-=-=-=-=-
622  // WARNING :: Major Assumptions are made upstream and use the FD also as a
623  // :: Status, if this is not done EVERYTHING BREAKS!!!!111one
624  fco->file_descriptor( status );
625  result = ERROR( status, msg.str() );
626  }
627  else {
628  // =-=-=-=-=-=-=-
629  // cache file descriptor in out-variable
630  fco->file_descriptor( fd );
631  result.code( fd );
632  }
633  }
634  }
635  }
636  // =-=-=-=-=-=-=-
637  // declare victory!
638  return result;
639 
640 } // unix_file_create_plugin
641 
642 // =-=-=-=-=-=-=-
643 // interface for POSIX Open
645  irods::plugin_context& _ctx ) {
646  irods::error result = SUCCESS();
647 
648  // =-=-=-=-=-=-=-
649  // Check the operation parameters and update the physical path
651  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
652 
653  // =-=-=-=-=-=-=-
654  // get ref to fco
655  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
656 
657  char* kvp_str = getValByKey(
658  &fco->cond_input(),
660  if ( kvp_str ) {
661  irods::kvp_map_t kvp;
663  kvp_str,
664  kvp );
665  if ( !ret.ok() ) {
666  irods::log( PASS( ret ) );
667  }
668  else {
669  irods::kvp_map_t::iterator itr = kvp.begin();
670  for ( ; itr != kvp.end(); ++ itr ) {
671  rodsLog(
672  LOG_DEBUG,
673  "unix_file_open_plugin - kv_pass :: key [%s] - value [%s]",
674  itr->first.c_str(),
675  itr->second.c_str() );
676  } // for itr
677  }
678  }
679 
680  // =-=-=-=-=-=-=-
681  // handle OSX weirdness...
682  int flags = fco->flags();
683 
684 #if defined(osx_platform)
685  // For osx, O_TRUNC = 0x0400, O_TRUNC = 0x200 for other system
686  if ( flags & 0x200 ) {
687  flags = flags ^ 0x200;
688  flags = flags | O_TRUNC;
689  }
690 #endif
691  // =-=-=-=-=-=-=-
692  // make call to open
693  errno = 0;
694  int fd = open( fco->physical_path().c_str(), flags, fco->mode() );
695  int errsav = errno;
696 
697  // =-=-=-=-=-=-=-
698  // if we got a 0 descriptor, try again
699  if ( fd == 0 ) {
700  close( fd );
701  int null_fd = open( "/dev/null", O_RDWR, 0 );
702  fd = open( fco->physical_path().c_str(), flags, fco->mode() );
703  errsav = errno;
704  if ( null_fd >= 0 ) {
705  close( null_fd );
706  }
707  rodsLog( LOG_NOTICE, "unix_file_open: 0 descriptor" );
708  }
709 
710  // =-=-=-=-=-=-=-
711  // trap error case with bad fd
712  if ( fd < 0 ) {
713  int status = UNIX_FILE_OPEN_ERR - errsav;
714  std::stringstream msg;
715  msg << "Open error for \"";
716  msg << fco->physical_path();
717  msg << "\", errno = \"";
718  msg << strerror( errsav );
719  msg << "\", status = \"";
720  msg << status;
721  msg << "\", flags = \"";
722  msg << flags;
723  msg << "\".";
724  result = ERROR( status, msg.str() );
725  }
726  else {
727  // =-=-=-=-=-=-=-
728  // cache status in the file object
729  fco->file_descriptor( fd );
730  result.code( fd );
731  }
732  }
733 
734  // =-=-=-=-=-=-=-
735  // declare victory!
736  return result;
737 
738 } // unix_file_open
739 
740 // =-=-=-=-=-=-=-
741 // interface for POSIX Read
743  irods::plugin_context& _ctx,
744  void* _buf,
745  int _len ) {
746  irods::error result = SUCCESS();
747 
748  // =-=-=-=-=-=-=-
749  // Check the operation parameters and update the physical path
751  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
752 
753  // =-=-=-=-=-=-=-
754  // get ref to fco
755  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
756 
757  // =-=-=-=-=-=-=-
758  // make the call to read
759  int status = read( fco->file_descriptor(), _buf, _len );
760 
761  // =-=-=-=-=-=-=-
762  // pass along an error if it was not successful
763  int err_status = UNIX_FILE_READ_ERR - errno;
764  if ( !( result = ASSERT_ERROR( status >= 0, err_status, "Read error for file: \"%s\", errno = \"%s\".",
765  fco->physical_path().c_str(), strerror( errno ) ) ).ok() ) {
766  result.code( err_status );
767  }
768  else {
769  result.code( status );
770  }
771  }
772 
773  // =-=-=-=-=-=-=-
774  // win!
775  return result;
776 
777 } // unix_file_read_plugin
778 
779 // =-=-=-=-=-=-=-
780 // interface for POSIX Write
782  irods::plugin_context& _ctx,
783  void* _buf,
784  int _len ) {
785  irods::error result = SUCCESS();
786 
787  // =-=-=-=-=-=-=-
788  // Check the operation parameters and update the physical path
790  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
791 
792  // =-=-=-=-=-=-=-
793  // get ref to fco
794  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
795 
796  // =-=-=-=-=-=-=-
797  // make the call to write
798  int status = write( fco->file_descriptor(), _buf, _len );
799 
800  // =-=-=-=-=-=-=-
801  // pass along an error if it was not successful
802  int err_status = UNIX_FILE_WRITE_ERR - errno;
803  if ( !( result = ASSERT_ERROR( status >= 0, err_status, "Write file: \"%s\", errno = \"%s\", status = %d.",
804  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
805  result.code( err_status );
806  }
807  else {
808  result.code( status );
809  }
810  }
811 
812  // =-=-=-=-=-=-=-
813  // win!
814  return result;
815 
816 } // unix_file_write_plugin
817 
818 // =-=-=-=-=-=-=-
819 // interface for POSIX Close
821  irods::plugin_context& _ctx ) {
822  irods::error result = SUCCESS();
823 
824  // =-=-=-=-=-=-=-
825  // Check the operation parameters and update the physical path
827  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
828 
829  // =-=-=-=-=-=-=-
830  // get ref to fco
831  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
832 
833  // =-=-=-=-=-=-=-
834  // make the call to close
835  int status = close( fco->file_descriptor() );
836 
837  // =-=-=-=-=-=-=-
838  // log any error
839  int err_status = UNIX_FILE_CLOSE_ERR - errno;
840  if ( !( result = ASSERT_ERROR( status >= 0, err_status, "Close error for file: \"%s\", errno = \"%s\", status = %d.",
841  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
842  result.code( err_status );
843  }
844  else {
845  result.code( status );
846  }
847  }
848 
849  return result;
850 
851 } // unix_file_close_plugin
852 
853 // =-=-=-=-=-=-=-
854 // interface for POSIX Unlink
856  irods::plugin_context& _ctx ) {
857  irods::error result = SUCCESS();
858 
859  // =-=-=-=-=-=-=-
860  // Check the operation parameters and update the physical path
862  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
863 
864  // =-=-=-=-=-=-=-
865  // get ref to fco
866  irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
867 
868  // =-=-=-=-=-=-=-
869  // make the call to unlink
870  int status = unlink( fco->physical_path().c_str() );
871 
872  // =-=-=-=-=-=-=-
873  // error handling
874  int err_status = UNIX_FILE_UNLINK_ERR - errno;
875  if ( !( result = ASSERT_ERROR( status >= 0, err_status, "Unlink error for \"%s\", errno = \"%s\", status = %d.",
876  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
877 
878  result.code( err_status );
879  }
880  else {
881  result.code( status );
882  }
883  }
884 
885  return result;
886 
887 } // unix_file_unlink_plugin
888 
889 // =-=-=-=-=-=-=-
890 // interface for POSIX Stat
892  irods::plugin_context& _ctx,
893  struct stat* _statbuf ) {
894  irods::error result = SUCCESS();
895  // =-=-=-=-=-=-=-
896  // NOTE:: this function assumes the object's physical path is
897  // correct and should not have the vault path
898  // prepended - hcj
899 
900  irods::error ret = _ctx.valid();
901  if ( ( result = ASSERT_PASS( ret, "resource context is invalid." ) ).ok() ) {
902 
903  // =-=-=-=-=-=-=-
904  // get ref to fco
905  irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
906 
907  // =-=-=-=-=-=-=-
908  // make the call to stat
909  int status = stat( fco->physical_path().c_str(), _statbuf );
910 
911  // =-=-=-=-=-=-=-
912  // return an error if necessary
913  int err_status = UNIX_FILE_STAT_ERR - errno;
914  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Stat error for \"%s\", errno = \"%s\", status = %d.",
915  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
916  result.code( status );
917  }
918  }
919 
920  return result;
921 
922 } // unix_file_stat_plugin
923 
924 // =-=-=-=-=-=-=-
925 // interface for POSIX lseek
927  irods::plugin_context& _ctx,
928  long long _offset,
929  int _whence ) {
930  irods::error result = SUCCESS();
931 
932  // =-=-=-=-=-=-=-
933  // Check the operation parameters and update the physical path
935  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
936 
937  // =-=-=-=-=-=-=-
938  // get ref to fco
939  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
940 
941  // =-=-=-=-=-=-=-
942  // make the call to lseek
943  long long status = lseek( fco->file_descriptor(), _offset, _whence );
944 
945  // =-=-=-=-=-=-=-
946  // return an error if necessary
947  long long err_status = UNIX_FILE_LSEEK_ERR - errno;
948  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Lseek error for \"%s\", errno = \"%s\", status = %ld.",
949  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
950  result.code( status );
951  }
952  }
953 
954  return result;
955 
956 } // unix_file_lseek_plugin
957 
958 // =-=-=-=-=-=-=-
959 // interface for POSIX mkdir
961  irods::plugin_context& _ctx ) {
962  irods::error result = SUCCESS();
963 
964  // =-=-=-=-=-=-=-
965  // NOTE :: this function assumes the object's physical path is correct and
966  // should not have the vault path prepended - hcj
967 
969  if ( ( result = ASSERT_PASS( ret, "resource context is invalid." ) ).ok() ) {
970 
971  // =-=-=-=-=-=-=-
972  // cast down the chain to our understood object type
973  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
974 
975  // =-=-=-=-=-=-=-
976  // make the call to mkdir & umask
977  mode_t myMask = umask( ( mode_t ) 0000 );
978  int status = mkdir( fco->physical_path().c_str(), fco->mode() );
979 
980  // =-=-=-=-=-=-=-
981  // reset the old mask
982  umask( ( mode_t ) myMask );
983 
984  // =-=-=-=-=-=-=-
985  // return an error if necessary
986  result.code( status );
987  int err_status = UNIX_FILE_MKDIR_ERR - errno;
988  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Mkdir error for \"%s\", errno = \"%s\", status = %d.",
989  fco->physical_path().c_str(), strerror( errno ), err_status ) ).ok() ) {
990  result.code( status );
991  }
992  }
993  return result;
994 
995 } // unix_file_mkdir_plugin
996 
997 // =-=-=-=-=-=-=-
998 // interface for POSIX rmdir
1000  irods::plugin_context& _ctx ) {
1001  irods::error result = SUCCESS();
1002 
1003  // =-=-=-=-=-=-=-
1004  // Check the operation parameters and update the physical path
1006  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1007 
1008  // =-=-=-=-=-=-=-
1009  // cast down the chain to our understood object type
1010  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1011 
1012  // =-=-=-=-=-=-=-
1013  // make the call to rmdir
1014  int status = rmdir( fco->physical_path().c_str() );
1015 
1016  // =-=-=-=-=-=-=-
1017  // return an error if necessary
1018  int err_status = UNIX_FILE_RMDIR_ERR - errno;
1019  result = ASSERT_ERROR( status >= 0, err_status, "Rmdir error for \"%s\", errno = \"%s\", status = %d.",
1020  fco->physical_path().c_str(), strerror( errno ), err_status );
1021  }
1022 
1023  return result;
1024 
1025 } // unix_file_rmdir_plugin
1026 
1027 // =-=-=-=-=-=-=-
1028 // interface for POSIX opendir
1030  irods::plugin_context& _ctx ) {
1031  irods::error result = SUCCESS();
1032 
1033  // =-=-=-=-=-=-=-
1034  // Check the operation parameters and update the physical path
1035  irods::error ret = unix_check_params_and_path< irods::collection_object >( _ctx );
1036  if ( !ret.ok() ) {
1037  return PASSMSG( "Invalid parameters or physical path.", ret );
1038  }
1039 
1040  // =-=-=-=-=-=-=-
1041  // cast down the chain to our understood object type
1042  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1043 
1044  // =-=-=-=-=-=-=-
1045  // make the call to opendir
1046  DIR* dir_ptr = opendir( fco->physical_path().c_str() );
1047  int errsav = errno;
1048 
1049  // =-=-=-=-=-=-=-
1050  // trap error case with bad fd
1051  if ( NULL == dir_ptr ) {
1052  int status = UNIX_FILE_CREATE_ERR - errsav;
1053  std::stringstream msg;
1054  msg << "Open error for \"";
1055  msg << fco->physical_path();
1056  msg << "\", errno = \"";
1057  msg << strerror( errsav );
1058  msg << "\", status = \"";
1059  msg << status;
1060  msg << "\".";
1061  result = ERROR( status, msg.str() );
1062  }
1063  else {
1064  // =-=-=-=-=-=-=-
1065  // cache dir_ptr in the out-variable
1066  fco->directory_pointer( dir_ptr );
1067  }
1068 
1069 
1070  return result;
1071 
1072 } // unix_file_opendir_plugin
1073 
1074 // =-=-=-=-=-=-=-
1075 // interface for POSIX closedir
1077  irods::plugin_context& _ctx ) {
1078  irods::error result = SUCCESS();
1079 
1080  // =-=-=-=-=-=-=-
1081  // Check the operation parameters and update the physical path
1082  irods::error ret = unix_check_params_and_path< irods::collection_object >( _ctx );
1083  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1084 
1085  // =-=-=-=-=-=-=-
1086  // cast down the chain to our understood object type
1087  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1088 
1089  // =-=-=-=-=-=-=-
1090  // make the call to opendir
1091  int status = closedir( fco->directory_pointer() );
1092 
1093  // =-=-=-=-=-=-=-
1094  // return an error if necessary
1095  int err_status = UNIX_FILE_CLOSEDIR_ERR - errno;
1096  result = ASSERT_ERROR( status >= 0, err_status, "Closedir error for \"%s\", errno = \"%s\", status = %d.",
1097  fco->physical_path().c_str(), strerror( errno ), err_status );
1098  }
1099 
1100  return result;
1101 
1102 } // unix_file_closedir_plugin
1103 
1104 // =-=-=-=-=-=-=-
1105 // interface for POSIX readdir
1107  irods::plugin_context& _ctx,
1108  struct rodsDirent** _dirent_ptr ) {
1109  irods::error result = SUCCESS();
1110 
1111  // =-=-=-=-=-=-=-
1112  // Check the operation parameters and update the physical path
1113  irods::error ret = unix_check_params_and_path< irods::collection_object >( _ctx );
1114  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1115 
1116  // =-=-=-=-=-=-=-
1117  // cast down the chain to our understood object type
1118  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1119 
1120  // =-=-=-=-=-=-=-
1121  // zero out errno?
1122  errno = 0;
1123 
1124  // =-=-=-=-=-=-=-
1125  // make the call to readdir
1126  struct dirent * tmp_dirent = readdir( fco->directory_pointer() );
1127 
1128  // =-=-=-=-=-=-=-
1129  // handle error cases
1130  if ( ( result = ASSERT_ERROR( tmp_dirent != NULL, -1, "End of directory list reached." ) ).ok() ) {
1131 
1132  // =-=-=-=-=-=-=-
1133  // alloc dirent as necessary
1134  if ( !( *_dirent_ptr ) ) {
1135  ( *_dirent_ptr ) = ( rodsDirent_t* ) malloc( sizeof( rodsDirent_t ) );
1136  }
1137 
1138  // =-=-=-=-=-=-=-
1139  // convert standard dirent to rods dirent struct
1140  int status = direntToRodsDirent( ( *_dirent_ptr ), tmp_dirent );
1141  if ( status < 0 ) {
1142  irods::log( ERROR( status, "direntToRodsDirent failed." ) );
1143  }
1144 
1145 
1146 #if defined(solaris_platform)
1147  rstrcpy( ( *_dirent_ptr )->d_name, tmp_dirent->d_name, MAX_NAME_LEN );
1148 #endif
1149  }
1150  else {
1151  // =-=-=-=-=-=-=-
1152  // cache status in out variable
1153  int status = UNIX_FILE_READDIR_ERR - errno;
1154  if ( ( result = ASSERT_ERROR( errno == 0, status, "Readdir error, status = %d, errno= \"%s\".",
1155  status, strerror( errno ) ) ).ok() ) {
1156  result.code( -1 );
1157  }
1158  }
1159  }
1160 
1161  return result;
1162 
1163 } // unix_file_readdir_plugin
1164 
1165 // =-=-=-=-=-=-=-
1166 // interface for POSIX readdir
1168  irods::plugin_context& _ctx,
1169  const char* _new_file_name ) {
1170  irods::error result = SUCCESS();
1171 
1172  // =-=-=-=-=-=-=-
1173  // Check the operation parameters and update the physical path
1175  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1176 
1177  // =-=-=-=-=-=-=-
1178  // manufacture a new path from the new file name
1179  std::string new_full_path;
1180  ret = unix_generate_full_path( _ctx.prop_map(), _new_file_name, new_full_path );
1181  if ( ( result = ASSERT_PASS( ret, "Unable to generate full path for destination file: \"%s\".",
1182  _new_file_name ) ).ok() ) {
1183 
1184  // =-=-=-=-=-=-=-
1185  // cast down the hierarchy to the desired object
1186  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1187 
1188  // =-=-=-=-=-=-=-
1189  // get the default directory mode
1190  mode_t mode = 0750;
1191  ret = _ctx.prop_map().get<mode_t>(
1193  mode );
1194  if ( !ret.ok() ) {
1195  return PASS( ret );
1196 
1197  }
1198 
1199  // =-=-=-=-=-=-=-
1200  // make the directories in the path to the new file
1201  std::string new_path = new_full_path;
1202  std::size_t last_slash = new_path.find_last_of( '/' );
1203  new_path.erase( last_slash );
1204  ret = unix_file_mkdir_r( new_path.c_str(), mode );
1205  if ( ( result = ASSERT_PASS( ret, "Mkdir error for \"%s\".", new_path.c_str() ) ).ok() ) {
1206 
1207  }
1208 
1209  // =-=-=-=-=-=-=-
1210  // make the call to rename
1211  int status = rename( fco->physical_path().c_str(), new_full_path.c_str() );
1212 
1213  // issue 4326 - plugins must set the physical path to the new path
1214  fco->physical_path(new_full_path);
1215 
1216  // =-=-=-=-=-=-=-
1217  // handle error cases
1218  int err_status = UNIX_FILE_RENAME_ERR - errno;
1219  if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Rename error for \"%s\" to \"%s\", errno = \"%s\", status = %d.",
1220  fco->physical_path().c_str(), new_full_path.c_str(), strerror( errno ), err_status ) ).ok() ) {
1221  result.code( status );
1222  }
1223  }
1224  }
1225 
1226  return result;
1227 
1228 } // unix_file_rename_plugin
1229 
1230 // =-=-=-=-=-=-=-
1231 // interface for POSIX truncate
1233  irods::plugin_context& _ctx ) {
1234  irods::error result = SUCCESS();
1235 
1236  // =-=-=-=-=-=-=-
1237  // Check the operation parameters and update the physical path
1238  irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx );
1239  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1240 
1241  // =-=-=-=-=-=-=-
1242  // cast down the chain to our understood object type
1243  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1244 
1245  // =-=-=-=-=-=-=-
1246  // make the call to rename
1247  int status = truncate( file_obj->physical_path().c_str(), file_obj->size() );
1248 
1249  // =-=-=-=-=-=-=-
1250  // handle any error cases
1251  int err_status = UNIX_FILE_TRUNCATE_ERR - errno;
1252  result = ASSERT_ERROR( status >= 0, err_status, "Truncate error for: \"%s\", errno = \"%s\", status = %d.",
1253  file_obj->physical_path().c_str(), strerror( errno ), err_status );
1254  }
1255 
1256  return result;
1257 
1258 } // unix_file_truncate_plugin
1259 
1260 
1261 // =-=-=-=-=-=-=-
1262 // unixStageToCache - This routine is for testing the TEST_STAGE_FILE_TYPE.
1263 // Just copy the file from filename to cacheFilename. optionalInfo info
1264 // is not used.
1266  irods::plugin_context& _ctx,
1267  const char* _cache_file_name ) {
1268  irods::error result = SUCCESS();
1269 
1270  // =-=-=-=-=-=-=-
1271  // Check the operation parameters and update the physical path
1273  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1274 
1275  // =-=-=-=-=-=-=-
1276  // cast down the hierarchy to the desired object
1277  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1278 
1279  ret = unix_file_copy( fco->mode(), fco->physical_path().c_str(), _cache_file_name );
1280  result = ASSERT_PASS( ret, "Failed" );
1281  }
1282  return result;
1283 } // unix_file_stagetocache
1284 
1285 // =-=-=-=-=-=-=-
1286 // unixSyncToArch - This routine is for testing the TEST_STAGE_FILE_TYPE.
1287 // Just copy the file from cacheFilename to filename. optionalInfo info
1288 // is not used.
1290  irods::plugin_context& _ctx,
1291  const char* _cache_file_name ) {
1292  irods::error result = SUCCESS();
1293 
1294  // =-=-=-=-=-=-=-
1295  // Check the operation parameters and update the physical path
1297  if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) {
1298 
1299  // =-=-=-=-=-=-=-
1300  // cast down the hierarchy to the desired object
1301  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1302 
1303  ret = unix_file_copy( fco->mode(), _cache_file_name, fco->physical_path().c_str() );
1304  result = ASSERT_PASS( ret, "Failed" );
1305  }
1306 
1307  return result;
1308 
1309 } // unix_file_sync_to_arch
1310 
1311 // =-=-=-=-=-=-=-
1312 // redirect_create - code to determine redirection for create operation
1314  irods::plugin_context& _ctx,
1315  const std::string& _resc_name,
1316  const std::string& _curr_host,
1317  float& _out_vote ) {
1318  irods::error result = SUCCESS();
1319 
1320  // =-=-=-=-=-=-=-
1321  // determine if the resource is down
1322  int resc_status = 0;
1323  irods::error get_ret = _ctx.prop_map().get< int >( irods::RESOURCE_STATUS, resc_status );
1324  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"status\" property." ) ).ok() ) {
1325 
1326  // =-=-=-=-=-=-=-
1327  // if the status is down, vote no.
1328  if ( INT_RESC_STATUS_DOWN == resc_status ) {
1329  _out_vote = 0.0;
1330  result.code( SYS_RESC_IS_DOWN );
1331  // result = PASS( result );
1332  }
1333  else {
1334  // vote no if the file size exceeds the high water mark
1335  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1336  rodsLong_t file_size = fco->size();
1337  if( replica_exceeds_resource_free_space( _ctx, file_size ) ) {
1338  _out_vote = 0.0;
1339  return CODE(USER_FILE_TOO_LARGE);
1340  }
1341 
1343 
1344  // =-=-=-=-=-=-=-
1345  // get the resource host for comparison to curr host
1346  std::string host_name;
1347  get_ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_LOCATION, host_name );
1348  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"location\" property." ) ).ok() ) {
1349 
1350  // =-=-=-=-=-=-=-
1351  // vote higher if we are on the same host
1352  if ( _curr_host == host_name ) {
1353  _out_vote = 1.0;
1354  }
1355  else {
1356  _out_vote = 0.5;
1357  }
1358  }
1359 
1360  rodsLog(
1361  LOG_DEBUG,
1362  "create :: resc name [%s] curr host [%s] resc host [%s] vote [%f]",
1363  _resc_name.c_str(),
1364  _curr_host.c_str(),
1365  host_name.c_str(),
1366  _out_vote );
1367 
1368  }
1369  }
1370  return result;
1371 
1372 } // unix_resolve_hierarchy_create
1373 
1374 // =-=-=-=-=-=-=-
1375 // redirect_open - code to determine redirection for open operation
1377  irods::plugin_property_map& _prop_map,
1378  irods::file_object_ptr _file_obj,
1379  const std::string& _resc_name,
1380  const std::string& _curr_host,
1381  float& _out_vote ) {
1382  irods::error result = SUCCESS();
1383 
1384  // =-=-=-=-=-=-=-
1385  // initially set a good default
1386  _out_vote = 0.0;
1387 
1388  // =-=-=-=-=-=-=-
1389  // determine if the resource is down
1390  int resc_status = 0;
1391  irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status );
1392  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"status\" property." ) ).ok() ) {
1393 
1394  // =-=-=-=-=-=-=-
1395  // if the status is down, vote no.
1396  if ( INT_RESC_STATUS_DOWN != resc_status ) {
1397 
1398  // =-=-=-=-=-=-=-
1399  // get the resource host for comparison to curr host
1400  std::string host_name;
1401  get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name );
1402  if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"location\" property." ) ).ok() ) {
1403 
1404  // =-=-=-=-=-=-=-
1405  // set a flag to test if were at the curr host, if so we vote higher
1406  bool curr_host = ( _curr_host == host_name );
1407 
1408  // =-=-=-=-=-=-=-
1409  // make some flags to clarify decision making
1410  bool need_repl = ( _file_obj->repl_requested() > -1 );
1411 
1412  // =-=-=-=-=-=-=-
1413  // set up variables for iteration
1414  irods::error final_ret = SUCCESS();
1415  std::vector< irods::physical_object > objs = _file_obj->replicas();
1416  std::vector< irods::physical_object >::iterator itr = objs.begin();
1417 
1418  // =-=-=-=-=-=-=-
1419  // check to see if the replica is in this resource, if one is requested
1420  for ( ; itr != objs.end(); ++itr ) {
1421  // =-=-=-=-=-=-=-
1422  // run the hier string through the parser and get the last
1423  // entry.
1424  std::string last_resc;
1426  parser.set_string( itr->resc_hier() );
1427  parser.last_resc( last_resc );
1428 
1429  // =-=-=-=-=-=-=-
1430  // more flags to simplify decision making
1431  bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() );
1432  bool resc_us = ( _resc_name == last_resc );
1433  bool is_dirty = ( itr->is_dirty() != 1 );
1434 
1435  // =-=-=-=-=-=-=-
1436  // success - correct resource and don't need a specific
1437  // replication, or the repl nums match
1438  if ( resc_us ) {
1439  // =-=-=-=-=-=-=-
1440  // if a specific replica is requested then we
1441  // ignore all other criteria
1442  if ( need_repl ) {
1443  if ( repl_us ) {
1444  _out_vote = 1.0;
1445  }
1446  else {
1447  // =-=-=-=-=-=-=-
1448  // repl requested and we are not it, vote
1449  // very low
1450  _out_vote = 0.25;
1451  }
1452  }
1453  else {
1454  // =-=-=-=-=-=-=-
1455  // if no repl is requested consider dirty flag
1456  if ( is_dirty ) {
1457  // =-=-=-=-=-=-=-
1458  // repl is dirty, vote very low
1459  _out_vote = 0.25;
1460  }
1461  else {
1462  // =-=-=-=-=-=-=-
1463  // if our repl is not dirty then a local copy
1464  // wins, otherwise vote middle of the road
1465  if ( curr_host ) {
1466  _out_vote = 1.0;
1467  }
1468  else {
1469  _out_vote = 0.5;
1470  }
1471  }
1472  }
1473 
1474  rodsLog(
1475  LOG_DEBUG,
1476  "open :: resc name [%s] curr host [%s] resc host [%s] vote [%f]",
1477  _resc_name.c_str(),
1478  _curr_host.c_str(),
1479  host_name.c_str(),
1480  _out_vote );
1481 
1482  break;
1483 
1484  } // if resc_us
1485 
1486  } // for itr
1487  }
1488  }
1489  else {
1490  result.code( SYS_RESC_IS_DOWN );
1491  result = PASS( result );
1492  }
1493  }
1494 
1495  return result;
1496 
1497 } // unix_resolve_hierarchy_open
1498 
1499 // =-=-=-=-=-=-=-
1500 // used to allow the resource to determine which host
1501 // should provide the requested operation
1503  irods::plugin_context& _ctx,
1504  const std::string* _opr,
1505  const std::string* _curr_host,
1506  irods::hierarchy_parser* _out_parser,
1507  float* _out_vote ) {
1508  irods::error result = SUCCESS();
1509 
1510  // =-=-=-=-=-=-=-
1511  // check the context validity
1512  irods::error ret = _ctx.valid< irods::file_object >();
1513  if ( ( result = ASSERT_PASS( ret, "Invalid resource context." ) ).ok() ) {
1514 
1515  // =-=-=-=-=-=-=-
1516  // check incoming parameters
1517  if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM, "Invalid input parameter." ) ).ok() ) {
1518  // =-=-=-=-=-=-=-
1519  // cast down the chain to our understood object type
1520  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1521 
1522  // =-=-=-=-=-=-=-
1523  // check that additional info made it
1524  rodsLog(LOG_DEBUG, "%s: %s = [%s]", __FUNCTION__, RECURSIVE_OPR__KW, getValByKey(&file_obj->cond_input(), RECURSIVE_OPR__KW));
1525 
1526  // =-=-=-=-=-=-=-
1527  // get the name of this resource
1528  std::string resc_name;
1529  ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name );
1530  if ( ( result = ASSERT_PASS( ret, "Failed in get property for name." ) ).ok() ) {
1531 
1532  // =-=-=-=-=-=-=-
1533  // test the operation to determine which choices to make
1534  if ( irods::OPEN_OPERATION == ( *_opr ) ||
1535  irods::WRITE_OPERATION == ( *_opr ) ||
1536  irods::UNLINK_OPERATION == ( *_opr )) {
1537  // =-=-=-=-=-=-=-
1538  // call redirect determination for 'get' operation
1539  ret = unix_resolve_hierarchy_open( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) );
1540  result = ASSERT_PASS( ret, "Failed redirecting for open." );
1541 
1542  }
1543  else if ( irods::CREATE_OPERATION == ( *_opr ) ) {
1544  // =-=-=-=-=-=-=-
1545  // call redirect determination for 'create' operation
1546  ret = unix_resolve_hierarchy_create( _ctx, resc_name, ( *_curr_host ), ( *_out_vote ) );
1547  result = ASSERT_PASS( ret, "Failed redirecting for create." );
1548  }
1549 
1550  else {
1551  // =-=-=-=-=-=-=-
1552  // must have been passed a bad operation
1553  result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported." );
1554  }
1555 
1556  // add ourselves to the hierarchy if we have any vote
1557  if( *_out_vote > 0 && result.ok() ) {
1558  _out_parser->add_child( resc_name );
1559  }
1560  }
1561  }
1562  }
1563 
1564  return result;
1565 
1566 } // unix_file_resolve_hierarchy
1567 
1568 // =-=-=-=-=-=-=-
1569 // unix_file_rebalance - code which would rebalance the subtree
1571  irods::plugin_context& _ctx ) {
1572  return SUCCESS();
1573 
1574 } // unix_file_rebalance
1575 
1576 // =-=-=-=-=-=-=-
1577 // 3. create derived class to handle unix file system resources
1578 // necessary to do custom parsing of the context string to place
1579 // any useful values into the property map for reference in later
1580 // operations. semicolon is the preferred delimiter
1582  // =-=-=-=-=-=-=-
1583  // 3a. create a class to provide maintenance operations, this is only for example
1584  // and will not be called.
1586  public:
1587  maintenance_operation( const std::string& _n ) : name_( _n ) {
1588  }
1589 
1591  name_ = _rhs.name_;
1592  }
1593 
1595  name_ = _rhs.name_;
1596  return *this;
1597  }
1598 
1600  rodsLog( LOG_NOTICE, "unixfilesystem_resource::post_disconnect_maintenance_operation - [%s]",
1601  name_.c_str() );
1602  return SUCCESS();
1603  }
1604 
1605  private:
1606  std::string name_;
1607 
1608  }; // class maintenance_operation
1609 
1610  public:
1612  const std::string& _inst_name,
1613  const std::string& _context ) :
1614  irods::resource(
1615  _inst_name,
1616  _context ) {
1617  properties_.set<mode_t>( DEFAULT_VAULT_DIR_MODE, 0750 );
1618  // =-=-=-=-=-=-=-
1619  // parse context string into property pairs assuming a ; as a separator
1620  std::vector< std::string > props;
1621  irods::kvp_map_t kvp;
1623  _context,
1624  kvp );
1625 
1626  // =-=-=-=-=-=-=-
1627  // copy the properties from the context to the prop map
1628  irods::kvp_map_t::iterator itr = kvp.begin();
1629  for( ; itr != kvp.end(); ++itr ) {
1630  properties_.set< std::string >(
1631  itr->first,
1632  itr->second );
1633  } // for itr
1634 
1635  } // ctor
1636 
1638  _b = false;
1639  return SUCCESS();
1640  }
1641 
1642  // =-=-=-=-=-=-=-
1643  // 3b. pass along a functor for maintenance work after
1644  // the client disconnects, uncomment the first two lines for effect.
1646  irods::error result = SUCCESS();
1647  return ERROR( -1, "nop" );
1648  }
1649 }; // class unixfilesystem_resource
1650 
1651 // =-=-=-=-=-=-=-
1652 // 4. create the plugin factory function which will return a dynamically
1653 // instantiated object of the previously defined derived resource. use
1654 // the add_operation member to associate a 'call name' to the interfaces
1655 // defined above. for resource plugins these call names are standardized
1656 // as used by the irods facing interface defined in
1657 // server/drivers/src/fileDriver.c
1658 extern "C"
1659 irods::resource* plugin_factory( const std::string& _inst_name, const std::string& _context ) {
1660 
1661  // =-=-=-=-=-=-=-
1662  // 4a. create unixfilesystem_resource
1663  unixfilesystem_resource* resc = new unixfilesystem_resource( _inst_name, _context );
1664 
1665  // =-=-=-=-=-=-=-
1666  // 4b. map function names to operations. this map will be used to load
1667  // the symbols from the shared object in the delay_load stage of
1668  // plugin loading.
1669  using namespace irods;
1670  using namespace std;
1671  resc->add_operation(
1673  function<error(plugin_context&)>(
1674  unix_file_create ) );
1675 
1676  resc->add_operation(
1678  function<error(plugin_context&)>(
1679  unix_file_open ) );
1680 
1681  resc->add_operation<void*,int>(
1683  std::function<
1684  error(irods::plugin_context&,void*,int)>(
1685  unix_file_read ) );
1686 
1687  resc->add_operation<void*,int>(
1689  function<error(plugin_context&,void*,int)>(
1690  unix_file_write ) );
1691 
1692  resc->add_operation(
1694  function<error(plugin_context&)>(
1695  unix_file_close ) );
1696 
1697  resc->add_operation(
1699  function<error(plugin_context&)>(
1700  unix_file_unlink ) );
1701 
1702  resc->add_operation<struct stat*>(
1704  function<error(plugin_context&, struct stat*)>(
1705  unix_file_stat ) );
1706 
1707  resc->add_operation(
1709  function<error(plugin_context&)>(
1710  unix_file_mkdir ) );
1711 
1712  resc->add_operation(
1714  function<error(plugin_context&)>(
1715  unix_file_opendir ) );
1716 
1717  resc->add_operation<struct rodsDirent**>(
1719  function<error(plugin_context&,struct rodsDirent**)>(
1720  unix_file_readdir ) );
1721 
1722  resc->add_operation<const char*>(
1724  function<error(plugin_context&, const char*)>(
1725  unix_file_rename ) );
1726 
1727  resc->add_operation(
1729  function<error(plugin_context&)>(
1731 
1732  resc->add_operation<long long, int>(
1734  function<error(plugin_context&, long long, int)>(
1735  unix_file_lseek ) );
1736 
1737  resc->add_operation(
1739  function<error(plugin_context&)>(
1740  unix_file_rmdir ) );
1741 
1742  resc->add_operation(
1744  function<error(plugin_context&)>(
1745  unix_file_closedir ) );
1746 
1747  resc->add_operation<const char*>(
1749  function<error(plugin_context&, const char*)>(
1751 
1752  resc->add_operation<const char*>(
1754  function<error(plugin_context&, const char*)>(
1756 
1757  resc->add_operation(
1759  function<error(plugin_context&)>(
1761 
1762  resc->add_operation(
1764  function<error(plugin_context&)>(
1766 
1767  resc->add_operation(
1769  function<error(plugin_context&)>(
1770  unix_file_modified ) );
1771 
1772  resc->add_operation<const std::string*>(
1774  function<error(plugin_context&, const std::string*)>(
1775  unix_file_notify ) );
1776 
1777  resc->add_operation(
1779  function<error(plugin_context&)>(
1780  unix_file_truncate ) );
1781 
1782  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1784  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
1786 
1787  resc->add_operation(
1789  function<error(plugin_context&)>(
1790  unix_file_rebalance ) );
1791 
1792  // =-=-=-=-=-=-=-
1793  // set some properties necessary for backporting to iRODS legacy code
1794  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
1795  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
1796 
1797  // =-=-=-=-=-=-=-
1798  // 4c. return the pointer through the generic interface of an
1799  // irods::resource pointer
1800  return dynamic_cast<irods::resource*>( resc );
1801 
1802 } // plugin_factory
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
getValByKey
char * getValByKey(const keyValPair_t *condInput, const char *keyWord)
Definition: rcMisc.cpp:675
unix_file_rename
irods::error unix_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: libunixfilesystem.cpp:1167
UNIX_FILE_GET_FS_FREESPACE_ERR
@ UNIX_FILE_GET_FS_FREESPACE_ERR
Definition: rodsErrorTable.h:316
UNIX_FILE_WRITE_ERR
@ UNIX_FILE_WRITE_ERR
Definition: rodsErrorTable.h:303
UNIX_FILE_LSEEK_ERR
@ UNIX_FILE_LSEEK_ERR
Definition: rodsErrorTable.h:308
rcComm_t
Definition: rcConnect.h:95
NULL
#define NULL
Definition: rodsDef.h:70
irods_physical_object.hpp
irods::RESOURCE_LOCATION
const std::string RESOURCE_LOCATION("resource_property_location")
unixfilesystem_resource::maintenance_operation::name_
std::string name_
Definition: libunixfilesystem.cpp:1606
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: libunixfilesystem.cpp:1659
irods::lookup_table< boost::any >
unix_file_notify
irods::error unix_file_notify(irods::plugin_context &_ctx, const std::string *)
Definition: libunixfilesystem.cpp:339
unix_file_open
irods::error unix_file_open(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:644
irods::RESOURCE_NAME
const std::string RESOURCE_NAME("resource_property_name")
irods_server_properties.hpp
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
unixfilesystem_resource::unixfilesystem_resource
unixfilesystem_resource(const std::string &_inst_name, const std::string &_context)
Definition: libunixfilesystem.cpp:1611
msParam.h
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
irods::CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS
const std::string CFG_TRANS_BUFFER_SIZE_FOR_PARA_TRANS("transfer_buffer_size_for_parallel_transfer_in_megabytes")
irods::resource
Definition: irods_resource_plugin.hpp:25
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
HIGH_WATER_MARK
const std::string HIGH_WATER_MARK("high_water_mark")
unix_file_getfs_freespace
irods::error unix_file_getfs_freespace(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:353
irods::RESOURCE_OP_MODIFIED
const std::string RESOURCE_OP_MODIFIED("resource_modified")
irods_file_object.hpp
irods::RESOURCE_OP_CLOSEDIR
const std::string RESOURCE_OP_CLOSEDIR("resource_closedir")
irods_stacktrace.hpp
irods::pdmo_type
std::function< irods::error(rcComm_t *) > pdmo_type
Definition: irods_plugin_base.hpp:29
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
unix_file_rmdir
irods::error unix_file_rmdir(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:999
irods::data_object_ptr
boost::shared_ptr< data_object > data_object_ptr
Definition: irods_data_object.hpp:17
irods_collection_object.hpp
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
generalAdmin.h
unixfilesystem_resource::maintenance_operation::operator()
irods::error operator()(rcComm_t *)
Definition: libunixfilesystem.cpp:1599
irods::RESOURCE_OP_READDIR
const std::string RESOURCE_OP_READDIR("resource_readdir")
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
unix_file_truncate
irods::error unix_file_truncate(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:1232
irods::collection_object_ptr
boost::shared_ptr< collection_object > collection_object_ptr
Definition: irods_collection_object.hpp:85
rcConnect.h
UNIX_FILE_CLOSE_ERR
@ UNIX_FILE_CLOSE_ERR
Definition: rodsErrorTable.h:304
unix_file_stat
irods::error unix_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: libunixfilesystem.cpp:891
unix_generate_full_path
irods::error unix_generate_full_path(irods::plugin_property_map &_prop_map, const std::string &_phy_path, std::string &_ret_string)
Definition: libunixfilesystem.cpp:164
unixfilesystem_resource::maintenance_operation
Definition: libunixfilesystem.cpp:1585
irods::RESOURCE_OP_READ
const std::string RESOURCE_OP_READ("resource_read")
irods::RESOURCE_OP_FREESPACE
const std::string RESOURCE_OP_FREESPACE("resource_freespace")
irods::RESOURCE_PATH
const std::string RESOURCE_PATH("resource_property_path")
irods::RESOURCE_OP_LSEEK
const std::string RESOURCE_OP_LSEEK("resource_lseek")
unix_file_lseek
irods::error unix_file_lseek(irods::plugin_context &_ctx, long long _offset, int _whence)
Definition: libunixfilesystem.cpp:926
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
UNIX_FILE_READDIR_ERR
@ UNIX_FILE_READDIR_ERR
Definition: rodsErrorTable.h:314
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
DEFAULT_VAULT_DIR_MODE
const std::string DEFAULT_VAULT_DIR_MODE("default_vault_directory_mode_kw")
irods::plugin_context
Definition: irods_plugin_context.hpp:18
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
irods::lookup_table::get
error get(const std::string &_key, ValueType &_val)
Definition: irods_lookup_table.hpp:71
irods_resource_redirect.hpp
irods::resource::resource
resource(const std::string &_inst, const std::string &_ctx)
Definition: irods_resource_plugin.hpp:29
irods::RESOURCE_STATUS
const std::string RESOURCE_STATUS("resource_property_status")
irods::plugin_base::set_property
error set_property(const std::string &_key, const T &_val)
Definition: irods_plugin_base.hpp:304
RECURSIVE_OPR__KW
#define RECURSIVE_OPR__KW
Definition: rodsKeyWdDef.h:66
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
unixfilesystem_resource
Definition: libunixfilesystem.cpp:1581
ASSERT_ERROR
#define ASSERT_ERROR(expr_, code_, format_,...)
Definition: irods_error.hpp:123
irods_resource_plugin.hpp
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
INVALID_OPERATION
@ INVALID_OPERATION
Definition: rodsErrorTable.h:760
stat_vault_path
irods::error stat_vault_path(const std::string &_path, struct statfs &_sb)
Definition: libunixfilesystem.cpp:416
irods::RESOURCE_OP_TRUNCATE
const std::string RESOURCE_OP_TRUNCATE("resource_truncate")
irods_string_tokenize.hpp
irods::RESOURCE_OP_RENAME
const std::string RESOURCE_OP_RENAME("resource_rename")
irods::OPEN_OPERATION
const std::string OPEN_OPERATION("OPEN")
unix_file_copy
static irods::error unix_file_copy(int mode, const char *srcFileName, const char *destFileName)
Definition: libunixfilesystem.cpp:89
UNIX_FILE_OPEN_ERR
@ UNIX_FILE_OPEN_ERR
Definition: rodsErrorTable.h:300
irods::error::code
long long code() const
Definition: irods_error.cpp:194
unix_file_close
irods::error unix_file_close(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:820
irods.pypyodbc.long
long
Definition: pypyodbc.py:43
unix_file_mkdir
irods::error unix_file_mkdir(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:960
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
SYS_COPY_LEN_ERR
@ SYS_COPY_LEN_ERR
Definition: rodsErrorTable.h:95
LOG_DEBUG
#define LOG_DEBUG
Definition: rodsLog.h:23
irods::plugin_base::properties_
plugin_property_map properties_
Definition: irods_plugin_base.hpp:332
irods::hierarchy_parser::add_child
error add_child(const std::string &_resc)
Definition: irods_hierarchy_parser.cpp:88
unix_file_unlink
irods::error unix_file_unlink(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:855
irods::RESOURCE_OP_CREATE
const std::string RESOURCE_OP_CREATE("resource_create")
irods
Definition: apiHandler.hpp:35
UNIX_FILE_RENAME_ERR
@ UNIX_FILE_RENAME_ERR
Definition: rodsErrorTable.h:318
unix_file_sync_to_arch
irods::error unix_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libunixfilesystem.cpp:1289
UNIX_FILE_TRUNCATE_ERR
@ UNIX_FILE_TRUNCATE_ERR
Definition: rodsErrorTable.h:319
irods::RESOURCE_OP_NOTIFY
const std::string RESOURCE_OP_NOTIFY("resource_notify")
unixfilesystem_resource::maintenance_operation::maintenance_operation
maintenance_operation(const std::string &_n)
Definition: libunixfilesystem.cpp:1587
USER_NO_SUPPORT_ERR
@ USER_NO_SUPPORT_ERR
Definition: rodsErrorTable.h:240
irods::RESOURCE_CREATE_PATH
const std::string RESOURCE_CREATE_PATH("resource_property_create_path")
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
irods::RESOURCE_OP_WRITE
const std::string RESOURCE_OP_WRITE("resource_write")
USER_FILE_TOO_LARGE
@ USER_FILE_TOO_LARGE
Definition: rodsErrorTable.h:242
unixfilesystem_resource::maintenance_operation::operator=
maintenance_operation & operator=(const maintenance_operation &_rhs)
Definition: libunixfilesystem.cpp:1594
UNIX_FILE_UNLINK_ERR
@ UNIX_FILE_UNLINK_ERR
Definition: rodsErrorTable.h:305
unix_resolve_hierarchy_create
irods::error unix_resolve_hierarchy_create(irods::plugin_context &_ctx, const std::string &_resc_name, const std::string &_curr_host, float &_out_vote)
Definition: libunixfilesystem.cpp:1313
unix_file_create
irods::error unix_file_create(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:538
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
KEY_NOT_FOUND
@ KEY_NOT_FOUND
Definition: rodsErrorTable.h:749
unix_file_readdir
irods::error unix_file_readdir(irods::plugin_context &_ctx, struct rodsDirent **_dirent_ptr)
Definition: libunixfilesystem.cpp:1106
irods::collection_object
Definition: irods_collection_object.hpp:14
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
irods::RESOURCE_FREESPACE
const std::string RESOURCE_FREESPACE("resource_property_freespace")
unix_file_opendir
irods::error unix_file_opendir(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:1029
unix_file_resolve_hierarchy
irods::error unix_file_resolve_hierarchy(irods::plugin_context &_ctx, const std::string *_opr, const std::string *_curr_host, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: libunixfilesystem.cpp:1502
irods::RESOURCE_OP_CLOSE
const std::string RESOURCE_OP_CLOSE("resource_close")
irods::log
void log(const error &)
Definition: irods_log.cpp:13
rodsDirent
Definition: rodsType.h:70
KEY_VALUE_PASSTHROUGH_KW
#define KEY_VALUE_PASSTHROUGH_KW
Definition: rodsKeyWdDef.h:284
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
unixfilesystem_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: libunixfilesystem.cpp:1645
irods::RESOURCE_OP_RMDIR
const std::string RESOURCE_OP_RMDIR("resource_rmdir")
MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES
const std::string MINIMUM_FREE_SPACE_FOR_CREATE_IN_BYTES("minimum_free_space_for_create_in_bytes")
unix_file_closedir
irods::error unix_file_closedir(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:1076
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::RESOURCE_OP_UNREGISTERED
const std::string RESOURCE_OP_UNREGISTERED("resource_unregistered")
irods::error
Definition: irods_error.hpp:23
miscServerFunct.hpp
INT_RESC_STATUS_DOWN
#define INT_RESC_STATUS_DOWN
Definition: rodsDef.h:282
SYS_RESC_IS_DOWN
@ SYS_RESC_IS_DOWN
Definition: rodsErrorTable.h:170
warn_if_deprecated_context_string_set
void warn_if_deprecated_context_string_set(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:451
irods::RESOURCE_OP_REGISTERED
const std::string RESOURCE_OP_REGISTERED("resource_registered")
UNIX_FILE_READ_ERR
@ UNIX_FILE_READ_ERR
Definition: rodsErrorTable.h:302
irods_hierarchy_parser.hpp
irods::parse_kvp_string
error parse_kvp_string(const std::string &_str, kvp_map_t &_kvp, const std::string &_association=KVP_DEF_ASSOCIATION, const std::string &_delimeter=KVP_DEF_DELIMITER)
Definition: irods_kvp_string_parser.cpp:69
unix_check_path
irods::error unix_check_path(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:192
unixfilesystem_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_b)
Definition: libunixfilesystem.cpp:1637
irods::file_object
Definition: irods_file_object.hpp:19
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
unix_file_stage_to_cache
irods::error unix_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libunixfilesystem.cpp:1265
irods::RESOURCE_OP_OPENDIR
const std::string RESOURCE_OP_OPENDIR("resource_opendir")
unix_file_modified
irods::error unix_file_modified(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:325
unix_file_write
irods::error unix_file_write(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libunixfilesystem.cpp:781
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
UNIX_FILE_CREATE_ERR
@ UNIX_FILE_CREATE_ERR
Definition: rodsErrorTable.h:301
direntToRodsDirent
int direntToRodsDirent(rodsDirent_t *rodsDirent, struct dirent *fileDirent)
Definition: rcMisc.cpp:330
error
int error
Definition: filesystem.cpp:101
irods::file_object_ptr
boost::shared_ptr< file_object > file_object_ptr
Definition: irods_file_object.hpp:145
irods::WRITE_OPERATION
const std::string WRITE_OPERATION("WRITE")
unixfilesystem_resource::maintenance_operation::maintenance_operation
maintenance_operation(const maintenance_operation &_rhs)
Definition: libunixfilesystem.cpp:1590
irods::plugin_base::add_operation
error add_operation(const std::string &_op, std::function< error(plugin_context &)> _f)
Definition: irods_plugin_base.hpp:122
UNIX_FILE_RMDIR_ERR
@ UNIX_FILE_RMDIR_ERR
Definition: rodsErrorTable.h:311
irods::plugin_context::fco
virtual first_class_object_ptr fco()
Definition: irods_plugin_context.hpp:102
irods::RESOURCE_OP_SYNCTOARCH
const std::string RESOURCE_OP_SYNCTOARCH("resource_synctoarch")
irods_kvp_string_parser.hpp
irods::exception
Definition: irods_exception.hpp:15
UNIX_FILE_CLOSEDIR_ERR
@ UNIX_FILE_CLOSEDIR_ERR
Definition: rodsErrorTable.h:313
REQUIRED_FREE_INODES_FOR_CREATE
const std::string REQUIRED_FREE_INODES_FOR_CREATE("required_free_inodes_for_create")
unix_resolve_hierarchy_open
irods::error unix_resolve_hierarchy_open(irods::plugin_property_map &_prop_map, irods::file_object_ptr _file_obj, const std::string &_resc_name, const std::string &_curr_host, float &_out_vote)
Definition: libunixfilesystem.cpp:1376
unix_check_params_and_path
irods::error unix_check_params_and_path(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:218
unix_file_registered
irods::error unix_file_registered(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:297
irods::experimental::filesystem::client::rename
auto rename(rcComm_t &_comm, const path &_from, const path &_to) -> void
Definition: filesystem.cpp:805
replica_exceeds_resource_free_space
static bool replica_exceeds_resource_free_space(irods::plugin_context &_ctx, rodsLong_t _file_size)
Definition: libunixfilesystem.cpp:470
UNIX_FILE_STAT_ERR
@ UNIX_FILE_STAT_ERR
Definition: rodsErrorTable.h:306
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
mode
int mode
Definition: filesystem.cpp:104
rstrcpy
char * rstrcpy(char *dest, const char *src, int maxLen)
Definition: stringOpr.cpp:51
irods::lookup_table::set
error set(const std::string &_key, const ValueType &_val)
Definition: irods_lookup_table.hpp:83
unix_file_rebalance
irods::error unix_file_rebalance(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:1570
irods::kvp_map_t
std::map< std::string, std::string > kvp_map_t
Definition: irods_kvp_string_parser.hpp:30
CODE
#define CODE(code_)
Definition: irods_error.hpp:120
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
irods::RESOURCE_OP_OPEN
const std::string RESOURCE_OP_OPEN("resource_open")
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
unix_file_mkdir_r
irods::error unix_file_mkdir_r(const std::string &path, mode_t mode)
Definition: libunixfilesystem.cpp:256
unix_file_unregistered
irods::error unix_file_unregistered(irods::plugin_context &_ctx)
Definition: libunixfilesystem.cpp:311
unix_file_read
irods::error unix_file_read(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libunixfilesystem.cpp:742
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
UNIX_FILE_MKDIR_ERR
@ UNIX_FILE_MKDIR_ERR
Definition: rodsErrorTable.h:310
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32