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)  

libunivmss.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=-
2 // irods includes
3 #include "msParam.h"
4 #include "generalAdmin.h"
5 #include "physPath.hpp"
6 #include "reIn2p3SysRule.hpp"
7 #include "miscServerFunct.hpp"
8 #include "rsExecCmd.hpp"
9 
10 // =-=-=-=-=-=-=-
12 #include "irods_file_object.hpp"
18 #include "irods_stacktrace.hpp"
19 #include "irods_re_structs.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/lexical_cast.hpp>
31 #include <boost/function.hpp>
32 #include <boost/any.hpp>
33 #include <boost/algorithm/string.hpp>
34 
37 template< typename DEST_TYPE >
39  irods::plugin_context& _ctx ) {
40  // =-=-=-=-=-=-=-
41  // ask the context if it is valid
42  irods::error ret = _ctx.valid< DEST_TYPE >();
43  if ( !ret.ok() ) {
44  return PASSMSG( "resource context is invalid", ret );
45 
46  }
47 
48  return SUCCESS();
49 
50 } // univ_mss_check_param
51 
52 
53 #define NB_READ_TOUT_SEC 60 /* 60 sec timeout */
54 #define NB_WRITE_TOUT_SEC 60 /* 60 sec timeout */
55 
56 // =-=-=-=-=-=-=-
58 const std::string SCRIPT_PROP( "script" );
59 
64  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
65 
66 } // univ_mss_file_create
67 
68 // =-=-=-=-=-=-=-
69 // interface for POSIX Open
72  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
73 
74 } // univ_mss_file_open
75 
80  void*,
81  int ) {
82  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
83 
84 } // univ_mss_file_read
85 
90  void*,
91  int ) {
92  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
93 
94 } // univ_mss_file_write
95 
100  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
101 
102 } // univ_mss_file_close
103 
107  irods::plugin_context& _ctx ) {
108  // =-=-=-=-=-=-=-
109  // check context
110  irods::error err = univ_mss_check_param< irods::data_object >( _ctx );
111  if ( !err.ok() ) {
112  std::stringstream msg;
113  msg << __FUNCTION__;
114  msg << " - invalid context";
115  return PASSMSG( msg.str(), err );
116 
117  }
118 
119  // =-=-=-=-=-=-=-
120  // get the script property
121  std::string script;
122  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
123  if ( !err.ok() ) {
124  return PASSMSG( __FUNCTION__, err );
125  }
126 
127  // =-=-=-=-=-=-=-
128  // snag a ref to the fco
129  irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
130  std::string filename = fco->physical_path();
131 
132  execCmd_t execCmdInp;
133  memset( &execCmdInp, 0, sizeof( execCmdInp ) );
134  snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() );
135  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "rm '%s'", filename.c_str() );
136  snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "localhost" );
137 
138  execCmdOut_t *execCmdOut = NULL;
139  int status = _rsExecCmd( &execCmdInp, &execCmdOut );
140  freeCmdExecOut( execCmdOut );
141 
142  if ( status < 0 ) {
143  status = UNIV_MSS_UNLINK_ERR - errno;
144  std::stringstream msg;
145  msg << "univ_mss_file_unlink - failed for [";
146  msg << filename;
147  msg << "]";
148  return ERROR( status, msg.str() );
149  }
150 
151  return CODE( status );
152 
153 } // univ_mss_file_unlink
154 
158  irods::plugin_context& _ctx,
159  struct stat* _statbuf ) {
160  // =-=-=-=-=-=-=-
161  // check context
162  irods::error err = univ_mss_check_param< irods::data_object >( _ctx );
163  if ( !err.ok() ) {
164  std::stringstream msg;
165  msg << __FUNCTION__;
166  msg << " - invalid context";
167  return PASSMSG( msg.str(), err );
168 
169  }
170 
171  // =-=-=-=-=-=-=-
172  // get the script property
173  std::string script;
174  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
175  if ( !err.ok() ) {
176  return PASSMSG( __FUNCTION__, err );
177  }
178 
179  // =-=-=-=-=-=-=-
180  // snag a ref to the fco
181  irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
182  std::string filename = fco->physical_path();
183 
184 
185  int i, status;
186  execCmd_t execCmdInp;
187  char cmdArgv[HUGE_NAME_LEN] = "";
188  const char *delim1 = ":\n";
189  const char *delim2 = "-";
190  const char *delim3 = ".";
191  execCmdOut_t *execCmdOut = NULL;
192  struct tm mytm;
193  time_t myTime;
194 
195  bzero( &execCmdInp, sizeof( execCmdInp ) );
196  rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN );
197  snprintf( cmdArgv, sizeof( cmdArgv ), "stat '%s' ", filename.c_str() );
198  rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN );
199  rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN );
200  status = _rsExecCmd( &execCmdInp, &execCmdOut );
201 
202  if ( status == 0 && NULL != execCmdOut ) { // JMC cppcheck - nullptr
203  if ( execCmdOut->stdoutBuf.buf != NULL ) {
204  const std::string outputStr(static_cast<char*>(execCmdOut->stdoutBuf.buf), execCmdOut->stdoutBuf.len);
205  std::vector<std::string> output_tokens;
206  boost::algorithm::split( output_tokens, outputStr, boost::is_any_of( delim1 ) );
207  _statbuf->st_dev = atoi( output_tokens[0].c_str() );
208  _statbuf->st_ino = atoi( output_tokens[1].c_str() );
209  _statbuf->st_mode = atoi( output_tokens[2].c_str() );
210  _statbuf->st_nlink = atoi( output_tokens[3].c_str() );
211  _statbuf->st_uid = atoi( output_tokens[4].c_str() );
212  _statbuf->st_gid = atoi( output_tokens[5].c_str() );
213  _statbuf->st_rdev = atoi( output_tokens[6].c_str() );
214  _statbuf->st_size = atoll( output_tokens[7].c_str() );
215  _statbuf->st_blksize = atoi( output_tokens[8].c_str() );
216  _statbuf->st_blocks = atoi( output_tokens[9].c_str() );
217  for ( i = 0; i < 3; i++ ) {
218  std::vector<std::string> date_tokens;
219  boost::algorithm::split( date_tokens, output_tokens[10 + i], boost::is_any_of( delim2 ) );
220  mytm.tm_year = atoi( date_tokens[0].c_str() ) - 1900;
221  mytm.tm_mon = atoi( date_tokens[1].c_str() ) - 1;
222  mytm.tm_mday = atoi( date_tokens[2].c_str() );
223  std::vector<std::string> time_tokens;
224  boost::algorithm::split( time_tokens, date_tokens[3], boost::is_any_of( delim3 ) );
225  mytm.tm_hour = atoi( time_tokens[0].c_str() );
226  mytm.tm_min = atoi( time_tokens[1].c_str() );
227  mytm.tm_sec = atoi( time_tokens[2].c_str() );
228  myTime = mktime( &mytm );
229  switch ( i ) {
230  case 0:
231  _statbuf->st_atime = myTime;
232  break;
233  case 1:
234  _statbuf->st_mtime = myTime;
235  break;
236  case 2:
237  _statbuf->st_ctime = myTime;
238  break;
239  }
240  }
241  }
242  }
243  else {
244  status = UNIV_MSS_STAT_ERR - errno;
245  std::stringstream msg;
246  msg << "univ_mss_file_stat - failed for [";
247  msg << filename;
248  msg << "]";
249  freeCmdExecOut( execCmdOut );
250  return ERROR( status, msg.str() );
251 
252  }
253 
254  freeCmdExecOut( execCmdOut );
255  return CODE( status );
256 
257 } // univ_mss_file_stat
258 
263  long long,
264  int ) {
265  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
266 
267 } // univ_mss_file_lseek
268 
272  irods::plugin_context& _ctx ) {
273  // =-=-=-=-=-=-=-
274  // check context
275  irods::error err = univ_mss_check_param< irods::data_object >( _ctx );
276  if ( !err.ok() ) {
277  std::stringstream msg;
278  msg << __FUNCTION__;
279  msg << " - invalid context";
280  return PASSMSG( msg.str(), err );
281 
282  }
283 
284  // =-=-=-=-=-=-=-
285  // get the script property
286  std::string script;
287  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
288  if ( !err.ok() ) {
289  return PASSMSG( __FUNCTION__, err );
290  }
291 
292  // =-=-=-=-=-=-=-
293  // snag a ref to the fco
294  irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
295  std::string filename = fco->physical_path();
296 
297  int mode = fco->mode();
298  int status = 0;
299  execCmd_t execCmdInp;
300 
301  if ( mode != getDefDirMode() ) {
302  mode = getDefFileMode();
303  }
304 
305  bzero( &execCmdInp, sizeof( execCmdInp ) );
306  snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() );
307  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "chmod '%s' %o", filename.c_str(), mode );
308  snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" );
309  execCmdOut_t *execCmdOut = NULL;
310  status = _rsExecCmd( &execCmdInp, &execCmdOut );
311  freeCmdExecOut( execCmdOut );
312 
313  if ( status < 0 ) {
314  status = UNIV_MSS_CHMOD_ERR - errno;
315  std::stringstream msg;
316  msg << "univ_mss_file_chmod - failed for [";
317  msg << filename;
318  msg << "]";
319  return ERROR( status, msg.str() );
320 
321  }
322 
323  return CODE( status );
324 
325 } // univ_mss_file_chmod
326 
330  irods::plugin_context& _ctx ) {
331  // =-=-=-=-=-=-=-
332  // check context
333  irods::error err = univ_mss_check_param< irods::collection_object >( _ctx );
334  if ( !err.ok() ) {
335  std::stringstream msg;
336  msg << __FUNCTION__;
337  msg << " - invalid context";
338  return PASSMSG( msg.str(), err );
339 
340  }
341 
342  // =-=-=-=-=-=-=-
343  // get the script property
344  std::string script;
345  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
346  if ( !err.ok() ) {
347  return PASSMSG( __FUNCTION__, err );
348  }
349 
350  // =-=-=-=-=-=-=-
351  // snag a ref to the fco
352  irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
353  std::string dirname = fco->physical_path();
354 
355  int status = 0;
356  execCmd_t execCmdInp;
357 
358  bzero( &execCmdInp, sizeof( execCmdInp ) );
359  snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() );
360  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "mkdir '%s'", dirname.c_str() );
361  snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" );
362  execCmdOut_t *execCmdOut = NULL;
363  status = _rsExecCmd( &execCmdInp, &execCmdOut );
364  freeCmdExecOut( execCmdOut );
365  if ( status < 0 ) {
366  status = UNIV_MSS_MKDIR_ERR - errno;
367  std::stringstream msg;
368  msg << "univ_mss_file_mkdir - mkdir failed for [";
369  msg << dirname;
370  msg << "]";
371  return ERROR( status, msg.str() );
372  }
373 
374  int mode = getDefDirMode();
375  fco->mode( mode );
376  err = univ_mss_file_chmod( _ctx );
377 
378  return err;
379 
380 } // univ_mss_file_mkdir
381 
386  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
387 
388 } // univ_mss_file_rmdir
389 
394  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
395 
396 } // univ_mss_file_opendir
397 
398 // =-=-=-=-=-=-=-
402  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
403 
404 } // univ_mss_file_closedir
405 
410  struct rodsDirent** ) {
411  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
412 
413 } // univ_mss_file_readdir
414 
418  irods::plugin_context& _ctx,
419  const char* _new_file_name ) {
420  // =-=-=-=-=-=-=-
421  // check context
422  irods::error err = univ_mss_check_param< irods::file_object >( _ctx );
423  if ( !err.ok() ) {
424  std::stringstream msg;
425  msg << __FUNCTION__;
426  msg << " - invalid context";
427  return PASSMSG( msg.str(), err );
428 
429  }
430 
431  // =-=-=-=-=-=-=-
432  // get the script property
433  std::string script;
434  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
435  if ( !err.ok() ) {
436  return PASSMSG( __FUNCTION__, err );
437  }
438 
439  // =-=-=-=-=-=-=-
440  // snag a ref to the fco
441  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
442  std::string filename = fco->physical_path();
443 
444  // =-=-=-=-=-=-=-
445  // first create the directory name
446  char dirname[MAX_NAME_LEN] = "";
447  const char* lastpart = strrchr( _new_file_name, '/' );
448  int lenDir = strlen( _new_file_name ) - strlen( lastpart );
449  strncpy( dirname, _new_file_name, lenDir );
450 
451  // =-=-=-=-=-=-=-
452  // create a context to call the mkdir operation
455  dirname,
456  fco->resc_hier(),
457  fco->mode(), 0 ) );
458  irods::plugin_context context(
459  _ctx.prop_map(),
460  coll_obj, "" );
461 
462  // =-=-=-=-=-=-=-
463  // create the directory on the MSS
464  int status = 0;
465  err = univ_mss_file_mkdir( context );
466 
467  execCmd_t execCmdInp;
468 
469  bzero( &execCmdInp, sizeof( execCmdInp ) );
470  snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() );
471  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "mv '%s' '%s'", filename.c_str(), _new_file_name );
472  snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" );
473  execCmdOut_t *execCmdOut = NULL;
474  status = _rsExecCmd( &execCmdInp, &execCmdOut );
475  freeCmdExecOut( execCmdOut );
476 
477  if ( status < 0 ) {
478  status = UNIV_MSS_RENAME_ERR - errno;
479  std::stringstream msg;
480  msg << "univ_mss_file_rename - failed for [";
481  msg << filename;
482  msg << "]";
483  return ERROR( status, msg.str() );
484 
485  }
486 
487  // issue 4326 - plugins must set the physical path to the new path
488  fco->physical_path(_new_file_name);
489 
490  return CODE( status );
491 
492 } // univ_mss_file_rename
493 
498  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
499 
500 } // univ_mss_file_truncate
501 
506  return ERROR( SYS_NOT_SUPPORTED, __FUNCTION__ );
507 
508 } // univ_mss_file_getfs_freespace
509 
515  irods::plugin_context& _ctx,
516  const char* _cache_file_name ) {
517  // =-=-=-=-=-=-=-
518  // check context
519  irods::error err = univ_mss_check_param< irods::file_object >( _ctx );
520  if ( !err.ok() ) {
521  std::stringstream msg;
522  msg << __FUNCTION__;
523  msg << " - invalid context";
524  return PASSMSG( msg.str(), err );
525 
526  }
527 
528  // =-=-=-=-=-=-=-
529  // snag a ref to the fco
530  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
531  std::string filename = fco->physical_path();
532 
533  // =-=-=-=-=-=-=-
534  // get the script property
535  std::string script;
536  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
537  if ( !err.ok() ) {
538  return PASSMSG( __FUNCTION__, err );
539  }
540 
541  int status = 0;
542 
543  std::stringstream cmdArgv;
544  cmdArgv << "stageToCache '" << filename << "' '" << _cache_file_name << "'";
545 
546  execCmd_t execCmdInp;
547  bzero( &execCmdInp, sizeof( execCmdInp ) );
548  snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() );
549  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "%s", cmdArgv.str().c_str() );
550  snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" );
551 
552  execCmdOut_t *execCmdOut = NULL;
553  status = _rsExecCmd( &execCmdInp, &execCmdOut );
554  freeCmdExecOut( execCmdOut );
555 
556  if ( status < 0 ) {
558  std::stringstream msg;
559  msg << "univ_mss_file_stage_to_cache: staging from [";
560  msg << _cache_file_name;
561  msg << "] to [";
562  msg << filename;
563  msg << "] failed.";
564  return ERROR( status, msg.str() );
565  }
566 
567  return CODE( status );
568 
569 } // univ_mss_file_stage_to_cache
570 
576  irods::plugin_context& _ctx,
577  const char* _cache_file_name ) {
578  // =-=-=-=-=-=-=-
579  // check context
580  irods::error err = univ_mss_check_param< irods::file_object >( _ctx );
581  if ( !err.ok() ) {
582  std::stringstream msg;
583  msg << __FUNCTION__;
584  msg << " - invalid context";
585  return PASSMSG( msg.str(), err );
586 
587  }
588 
589  // =-=-=-=-=-=-=-
590  // snag a ref to the fco
591  irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
592  std::string filename = fco->physical_path();
593 
594  // =-=-=-=-=-=-=-
595  // first create the directory name
596  char dirname[MAX_NAME_LEN] = "";
597  const char* lastpart = strrchr( filename.c_str(), '/' );
598  int lenDir = strlen( filename.c_str() ) - strlen( lastpart );
599  strncpy( dirname, filename.c_str(), lenDir );
600 
601  // =-=-=-=-=-=-=-
602  // create a context to call the mkdir operation
605  dirname,
606  fco->resc_hier(),
607  fco->mode(), 0 ) );
608  irods::plugin_context context(
609  _ctx.prop_map(),
610  coll_obj, "" );
611 
612  // =-=-=-=-=-=-=-
613  // create the directory on the MSS
614  int status = 0;
615  err = univ_mss_file_mkdir( context );
616 
617  execCmdOut_t* execCmdOut = NULL;
618 
619  // =-=-=-=-=-=-=-
620  // get the script property
621  std::string script;
622  err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script );
623  if ( !err.ok() ) {
624  return PASSMSG( __FUNCTION__, err );
625  }
626 
627  execCmd_t execCmdInp;
628  bzero( &execCmdInp, sizeof( execCmdInp ) );
629  rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN );
630  snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "syncToArch %s %s", _cache_file_name, filename.c_str() );
631  rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN );
632  status = _rsExecCmd( &execCmdInp, &execCmdOut );
633  if ( status == 0 ) {
634  err = univ_mss_file_chmod( _ctx );
635  if ( !err.ok() ) {
636  PASSMSG( "univ_mss_file_sync_to_arch - failed.", err );
637  }
638  }
639  else {
641  std::stringstream msg;
642  msg << "univ_mss_file_sync_to_arch: copy of [";
643  msg << _cache_file_name;
644  msg << "] to [";
645  msg << filename;
646  msg << "] failed.";
647  msg << " stdout buff [";
648  msg << execCmdOut->stdoutBuf.buf;
649  msg << "] stderr buff [";
650  msg << execCmdOut->stderrBuf.buf;
651  msg << "] status [";
652  msg << execCmdOut->status << "]";
653  freeCmdExecOut( execCmdOut );
654  return ERROR( status, msg.str() );
655  }
656 
657  return CODE( status );
658 
659 } // univ_mss_file_sync_to_arch
660 
664  irods::plugin_context& _ctx ) {
665  // Check the operation parameters and update the physical path
666  irods::error ret = univ_mss_check_param< irods::file_object >( _ctx );
667  if ( !ret.ok() ) {
668  std::stringstream msg;
669  msg << "Invalid parameters or physical path.";
670  return PASSMSG( msg.str(), ret );
671  }
672  // NOOP
673  return SUCCESS();
674 } // univ_mss_file_registered
675 
679  irods::plugin_context& _ctx ) {
680  // Check the operation parameters and update the physical path
681  irods::error ret = univ_mss_check_param< irods::file_object >( _ctx );
682  if ( !ret.ok() ) {
683  std::stringstream msg;
684  msg << "Invalid parameters or physical path.";
685  return PASSMSG( msg.str(), ret );
686  }
687  // NOOP
688  return SUCCESS();
689 } // univ_mss_file_unregistered
690 
694  irods::plugin_context& _ctx ) {
695  // Check the operation parameters and update the physical path
696  irods::error ret = univ_mss_check_param< irods::file_object >( _ctx );
697  if ( !ret.ok() ) {
698  std::stringstream msg;
699  msg << "Invalid parameters or physical path.";
700  return PASSMSG( msg.str(), ret );
701  }
702  // NOOP
703  return SUCCESS();
704 } // univ_mss_file_modified
705 
706 // =-=-=-=-=-=-=-
707 // redirect_get - code to determine redirection for get operation
709  irods::plugin_property_map& _prop_map,
710  const std::string& _curr_host,
711  float& _out_vote ) {
712  // =-=-=-=-=-=-=-
713  // determine if the resource is down
714  int resc_status = 0;
715  irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status );
716  if ( !get_ret.ok() ) {
717  return PASSMSG( "univ_mss_file_resolve_hierarchy_create - failed to get 'status' property", get_ret );
718  }
719 
720  // =-=-=-=-=-=-=-
721  // if the status is down, vote no.
722  if ( INT_RESC_STATUS_DOWN == resc_status ) {
723  _out_vote = 0.0;
724  return SUCCESS();
725  }
726 
727  // =-=-=-=-=-=-=-
728  // get the resource host for comparison to curr host
729  std::string host_name;
730  get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name );
731  if ( !get_ret.ok() ) {
732  return PASSMSG( "univ_mss_file_resolve_hierarchy_create - failed to get 'location' property", get_ret );
733  }
734 
735  // =-=-=-=-=-=-=-
736  // vote higher if we are on the same host
737  if ( _curr_host == host_name ) {
738  _out_vote = 1.0;
739  }
740  else {
741  _out_vote = 0.5;
742  }
743 
744  return SUCCESS();
745 
746 } // univ_mss_file_resolve_hierarchy_create
747 
748 // =-=-=-=-=-=-=-
749 // redirect_get - code to determine redirection for get operation
751  irods::plugin_property_map& _prop_map,
752  irods::file_object_ptr _file_obj,
753  const std::string& _resc_name,
754  const std::string& _curr_host,
755  float& _out_vote ) {
756  // =-=-=-=-=-=-=-
757  // determine if the resource is down
758  int resc_status = 0;
759  irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status );
760  if ( !get_ret.ok() ) {
761  return PASSMSG( "univ_mss_file_resolve_hierarchy_open - failed to get 'status' property", get_ret );
762  }
763 
764  // =-=-=-=-=-=-=-
765  // if the status is down, vote no.
766  if ( INT_RESC_STATUS_DOWN == resc_status ) {
767  _out_vote = 0.0;
768  return SUCCESS();
769  }
770 
771  // =-=-=-=-=-=-=-
772  // get the resource host for comparison to curr host
773  std::string host_name;
774  get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name );
775  if ( !get_ret.ok() ) {
776  return PASSMSG( "univ_mss_file_resolve_hierarchy_open - failed to get 'location' property", get_ret );
777  }
778 
779  // =-=-=-=-=-=-=-
780  // set a flag to test if were at the curr host, if so we vote higher
781  bool curr_host = ( _curr_host == host_name );
782 
783  // =-=-=-=-=-=-=-
784  // make some flags to clairify decision making
785  bool need_repl = ( _file_obj->repl_requested() > -1 );
786 
787  // =-=-=-=-=-=-=-
788  // set up variables for iteration
789  irods::error final_ret = SUCCESS();
790  std::vector< irods::physical_object > objs = _file_obj->replicas();
791  std::vector< irods::physical_object >::iterator itr = objs.begin();
792 
793  // =-=-=-=-=-=-=-
794  // initially set vote to 0.0
795  _out_vote = 0.0;
796 
797  // =-=-=-=-=-=-=-
798  // check to see if the replica is in this resource, if one is requested
799  for ( ; itr != objs.end(); ++itr ) {
800  // =-=-=-=-=-=-=-
801  // run the hier string through the parser and get the last
802  // entry.
803  std::string last_resc;
805  parser.set_string( itr->resc_hier() );
806  parser.last_resc( last_resc );
807 
808  // =-=-=-=-=-=-=-
809  // more flags to simplify decision making
810  bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() );
811  bool resc_us = ( _resc_name == last_resc );
812 
813  // =-=-=-=-=-=-=-
814  // success - correct resource and dont need a specific
815  // replication, or the repl nums match
816  if ( resc_us ) {
817  if ( !need_repl || ( need_repl && repl_us ) ) {
818  if ( curr_host ) {
819  _out_vote = 1.0;
820  }
821  else {
822  _out_vote = 0.5;
823  }
824  break;
825  }
826 
827  } // if resc_us
828 
829  } // for itr
830 
831  return SUCCESS();
832 
833 } // redirect_get
834 
835 // =-=-=-=-=-=-=-
836 // used to allow the resource to determine which host
837 // should provide the requested operation
839  irods::plugin_context& _ctx,
840  const std::string* _opr,
841  const std::string* _curr_host,
842  irods::hierarchy_parser* _out_parser,
843  float* _out_vote ) {
844  // =-=-=-=-=-=-=-
845  // check the context validity
846  irods::error ret = _ctx.valid< irods::file_object >();
847  if ( !ret.ok() ) {
848  std::stringstream msg;
849  msg << __FUNCTION__ << " - resource context is invalid";
850  return PASSMSG( msg.str(), ret );
851  }
852 
853  // =-=-=-=-=-=-=-
854  // check incoming parameters
855  if ( !_opr ) {
856  return ERROR( -1, "univ_mss_file_resolve_hierarchy- null operation" );
857  }
858  if ( !_curr_host ) {
859  return ERROR( -1, "univ_mss_file_resolve_hierarchy- null operation" );
860  }
861  if ( !_out_parser ) {
862  return ERROR( -1, "univ_mss_file_resolve_hierarchy- null outgoing hier parser" );
863  }
864  if ( !_out_vote ) {
865  return ERROR( -1, "univ_mss_file_resolve_hierarchy- null outgoing vote" );
866  }
867 
868  // =-=-=-=-=-=-=-
869  // cast down the chain to our understood object type
870  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
871 
872  // =-=-=-=-=-=-=-
873  // get the name of this resource
874  std::string resc_name;
875  ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name );
876  if ( !ret.ok() ) {
877  std::stringstream msg;
878  msg << "univ_mss_file_resolve_hierarchy- failed in get property for name";
879  return ERROR( -1, msg.str() );
880  }
881 
882  // =-=-=-=-=-=-=-
883  // add ourselves to the hierarchy parser by default
884  _out_parser->add_child( resc_name );
885 
886  // =-=-=-=-=-=-=-
887  // test the operation to determine which choices to make
888  if ( irods::OPEN_OPERATION == ( *_opr ) || irods::UNLINK_OPERATION == ( *_opr )) {
889  // =-=-=-=-=-=-=-
890  // call redirect determination for 'get' operation
891  return univ_mss_file_resolve_hierarchy_open( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) );
892 
893  }
894  else if ( irods::CREATE_OPERATION == ( *_opr ) ) {
895  // =-=-=-=-=-=-=-
896  // call redirect determination for 'create' operation
897  return univ_mss_file_resolve_hierarchy_create( _ctx.prop_map(), ( *_curr_host ), ( *_out_vote ) );
898  }
899 
900  // =-=-=-=-=-=-=-
901  // must have been passed a bad operation
902  std::stringstream msg;
903  msg << "univ_mss_file_resolve_hierarchy- operation not supported [";
904  msg << ( *_opr ) << "]";
905  return ERROR( -1, msg.str() );
906 
907 } // univ_mss_file_resolve_hierarchy
908 
909 
910 // =-=-=-=-=-=-=-
911 // univ_mss__file_rebalance - code which would rebalance the subtree
913  irods::plugin_context& _ctx ) {
914  return SUCCESS();
915 
916 } // univ_mss_file_rebalance
917 
918 // =-=-=-=-=-=-=-
919 // 3. create derived class to handle universal mss resources
920 // context string will hold the script to be called.
922  public:
923  univ_mss_resource( const std::string& _inst_name,
924  const std::string& _context ) :
925  irods::resource( _inst_name, _context ) {
926 
927  // =-=-=-=-=-=-=-
928  // check the context string for inappropriate path behavior
929  if ( context_.find( "/" ) != std::string::npos ) {
930  std::stringstream msg;
931  msg << "univmss resource :: the path [";
932  msg << context_;
933  msg << "] should be a single file name which should reside in msiExecCmd_bin";
934  rodsLog( LOG_ERROR, "[%s]", msg.str().c_str() );
935  }
936 
937  // =-=-=-=-=-=-=-
938  // assign context string as the univ mss script to call
939  properties_.set< std::string >( SCRIPT_PROP, context_ );
940  }
941 
942  // =-=-=-=-=-=-
943  // override from plugin_base
945  _flg = false;
946  return SUCCESS();
947  }
948 
949  // =-=-=-=-=-=-
950  // override from plugin_base
952  return ERROR( -1, "nop" );
953  }
954 
955 }; // class univ_mss_resource
956 
957 // =-=-=-=-=-=-=-
958 // 4. create the plugin factory function which will return a dynamically
959 // instantiated object of the previously defined derived resource. use
960 // the add_operation member to associate a 'call name' to the interfaces
961 // defined above. for resource plugins these call names are standardized
962 // as used by the irods facing interface defined in
963 // server/drivers/src/fileDriver.c
964 extern "C"
965 irods::resource* plugin_factory( const std::string& _inst_name,
966  const std::string& _context ) {
967  // =-=-=-=-=-=-=-
968  // 4a. create univ_mss_resource object
969  univ_mss_resource* resc = new univ_mss_resource( _inst_name, _context );
970 
971  // =-=-=-=-=-=-=-
972  // 4b. map function names to operations. this map will be used to load
973  // the symbols from the shared object in the delay_load stage of
974  // plugin loading.
975  using namespace irods;
976  using namespace std;
977 
978  resc->add_operation(
980  function<error(plugin_context&)>(
982 
983  resc->add_operation<const char*>(
985  function<error(plugin_context&, const char*)>(
987 
988  resc->add_operation<const char*>(
990  function<error(plugin_context&, const char*)>(
992 
993  resc->add_operation(
995  function<error(plugin_context&)>(
997 
998  resc->add_operation<const char*>(
1000  function<error(plugin_context&, const char*)>(
1002 
1003  resc->add_operation<struct stat*>(
1005  function<error(plugin_context&, struct stat*)>(
1006  univ_mss_file_stat ) );
1007 
1008  resc->add_operation(
1010  function<error(plugin_context&)>(
1012 
1013  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1015  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
1017 
1018  resc->add_operation(
1020  function<error(plugin_context&)>(
1022 
1023  // =-=-=-=-=-=-=-
1024  // set some properties necessary for backporting to iRODS legacy code
1025  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
1026  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
1027 
1028  // =-=-=-=-=-=-=-
1029  // 4c. return the pointer through the generic interface of an
1030  // irods::resource pointer
1031  return dynamic_cast<irods::resource*>( resc );
1032 
1033 } // plugin_factory
UNIV_MSS_SYNCTOARCH_ERR
@ UNIV_MSS_SYNCTOARCH_ERR
Definition: rodsErrorTable.h:324
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
univ_mss_file_unregistered
irods::error univ_mss_file_unregistered(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:678
NULL
#define NULL
Definition: rodsDef.h:70
irods_physical_object.hpp
irods::RESOURCE_LOCATION
const std::string RESOURCE_LOCATION("resource_property_location")
ExecCmd::execAddr
char execAddr[256]
Definition: execCmd.h:13
getDefDirMode
int getDefDirMode()
Definition: physPath.cpp:1070
irods::lookup_table< boost::any >
irods::RESOURCE_NAME
const std::string RESOURCE_NAME("resource_property_name")
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
BytesBuf::buf
void * buf
Definition: rodsDef.h:199
ExecCmdOut
Definition: execCmd.h:20
msParam.h
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
irods::resource
Definition: irods_resource_plugin.hpp:25
univ_mss_file_rename
irods::error univ_mss_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: libunivmss.cpp:417
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
irods_file_object.hpp
irods_stacktrace.hpp
irods::pdmo_type
std::function< irods::error(rcComm_t *) > pdmo_type
Definition: irods_plugin_base.hpp:29
HUGE_NAME_LEN
#define HUGE_NAME_LEN
Definition: rodsDef.h:62
irods::data_object_ptr
boost::shared_ptr< data_object > data_object_ptr
Definition: irods_data_object.hpp:17
irods_collection_object.hpp
univ_mss_file_rebalance
irods::error univ_mss_file_rebalance(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:912
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
generalAdmin.h
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
reIn2p3SysRule.hpp
irods::collection_object_ptr
boost::shared_ptr< collection_object > collection_object_ptr
Definition: irods_collection_object.hpp:85
univ_mss_file_mkdir
irods::error univ_mss_file_mkdir(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:329
univ_mss_file_close
irods::error univ_mss_file_close(irods::plugin_context &)
Definition: libunivmss.cpp:98
UNIV_MSS_UNLINK_ERR
@ UNIV_MSS_UNLINK_ERR
Definition: rodsErrorTable.h:326
LONG_NAME_LEN
#define LONG_NAME_LEN
Definition: rodsDef.h:57
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: libunivmss.cpp:965
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
SCRIPT_PROP
const std::string SCRIPT_PROP("script")
univ_mss_file_getfs_freespace
irods::error univ_mss_file_getfs_freespace(irods::plugin_context &)
Definition: libunivmss.cpp:504
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
irods::plugin_context
Definition: irods_plugin_context.hpp:18
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
UNIV_MSS_STAT_ERR
@ UNIV_MSS_STAT_ERR
Definition: rodsErrorTable.h:329
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
univ_mss_file_resolve_hierarchy_open
irods::error univ_mss_file_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: libunivmss.cpp:750
univ_mss_file_registered
irods::error univ_mss_file_registered(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:663
univ_mss_file_sync_to_arch
irods::error univ_mss_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libunivmss.cpp:575
getDefFileMode
int getDefFileMode()
Definition: physPath.cpp:1057
BytesBuf::len
int len
Definition: rodsDef.h:198
univ_mss_file_chmod
irods::error univ_mss_file_chmod(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:271
irods_resource_plugin.hpp
SYS_NOT_SUPPORTED
@ SYS_NOT_SUPPORTED
Definition: rodsErrorTable.h:133
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
irods::RESOURCE_OP_TRUNCATE
const std::string RESOURCE_OP_TRUNCATE("resource_truncate")
irods_string_tokenize.hpp
univ_mss_file_closedir
irods::error univ_mss_file_closedir(irods::plugin_context &)
Definition: libunivmss.cpp:400
irods::RESOURCE_OP_RENAME
const std::string RESOURCE_OP_RENAME("resource_rename")
freeCmdExecOut
void freeCmdExecOut(execCmdOut_t *ruleExecOut)
Definition: irods_re_structs.cpp:150
irods::OPEN_OPERATION
const std::string OPEN_OPERATION("OPEN")
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
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
ExecCmdOut::status
int status
Definition: execCmd.h:23
irods
Definition: apiHandler.hpp:35
ExecCmdOut::stdoutBuf
bytesBuf_t stdoutBuf
Definition: execCmd.h:21
UNIV_MSS_CHMOD_ERR
@ UNIV_MSS_CHMOD_ERR
Definition: rodsErrorTable.h:328
univ_mss_file_stage_to_cache
irods::error univ_mss_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: libunivmss.cpp:514
univ_mss_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: libunivmss.cpp:951
univ_mss_file_readdir
irods::error univ_mss_file_readdir(irods::plugin_context &, struct rodsDirent **)
Definition: libunivmss.cpp:408
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
univ_mss_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_flg)
Definition: libunivmss.cpp:944
univ_mss_file_create
irods::error univ_mss_file_create(irods::plugin_context &)
Definition: libunivmss.cpp:62
univ_mss_file_resolve_hierarchy_create
irods::error univ_mss_file_resolve_hierarchy_create(irods::plugin_property_map &_prop_map, const std::string &_curr_host, float &_out_vote)
Definition: libunivmss.cpp:708
irods::collection_object
Definition: irods_collection_object.hpp:14
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
physPath.hpp
rodsDirent
Definition: rodsType.h:70
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
UNIV_MSS_RENAME_ERR
@ UNIV_MSS_RENAME_ERR
Definition: rodsErrorTable.h:330
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
irods::error
Definition: irods_error.hpp:23
univ_mss_file_stat
irods::error univ_mss_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: libunivmss.cpp:157
miscServerFunct.hpp
INT_RESC_STATUS_DOWN
#define INT_RESC_STATUS_DOWN
Definition: rodsDef.h:282
univ_mss_check_param
irods::error univ_mss_check_param(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:38
univ_mss_file_lseek
irods::error univ_mss_file_lseek(irods::plugin_context &, long long, int)
Definition: libunivmss.cpp:261
ExecCmd
Definition: execCmd.h:10
irods_hierarchy_parser.hpp
univ_mss_file_opendir
irods::error univ_mss_file_opendir(irods::plugin_context &)
Definition: libunivmss.cpp:392
irods::file_object
Definition: irods_file_object.hpp:19
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
UNIV_MSS_MKDIR_ERR
@ UNIV_MSS_MKDIR_ERR
Definition: rodsErrorTable.h:327
error
int error
Definition: filesystem.cpp:101
univ_mss_file_unlink
irods::error univ_mss_file_unlink(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:106
irods::file_object_ptr
boost::shared_ptr< file_object > file_object_ptr
Definition: irods_file_object.hpp:145
irods_re_structs.hpp
irods::plugin_base::add_operation
error add_operation(const std::string &_op, std::function< error(plugin_context &)> _f)
Definition: irods_plugin_base.hpp:122
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")
univ_mss_file_modified
irods::error univ_mss_file_modified(irods::plugin_context &_ctx)
Definition: libunivmss.cpp:693
univ_mss_file_rmdir
irods::error univ_mss_file_rmdir(irods::plugin_context &)
Definition: libunivmss.cpp:384
univ_mss_file_open
irods::error univ_mss_file_open(irods::plugin_context &)
Definition: libunivmss.cpp:70
irods::plugin_base::context_
std::string context_
Definition: irods_plugin_base.hpp:326
univ_mss_resource::univ_mss_resource
univ_mss_resource(const std::string &_inst_name, const std::string &_context)
Definition: libunivmss.cpp:923
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
univ_mss_file_resolve_hierarchy
irods::error univ_mss_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: libunivmss.cpp:838
univ_mss_file_write
irods::error univ_mss_file_write(irods::plugin_context &, void *, int)
Definition: libunivmss.cpp:88
_rsExecCmd
int _rsExecCmd(execCmd_t *execCmdInp, execCmdOut_t **execCmdOut)
Definition: rsExecCmd.cpp:227
ExecCmd::cmd
char cmd[256]
Definition: execCmd.h:11
CODE
#define CODE(code_)
Definition: irods_error.hpp:120
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
ExecCmd::cmdArgv
char cmdArgv[100000]
Definition: execCmd.h:12
univ_mss_file_read
irods::error univ_mss_file_read(irods::plugin_context &, void *, int)
Definition: libunivmss.cpp:78
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
UNIV_MSS_STAGETOCACHE_ERR
@ UNIV_MSS_STAGETOCACHE_ERR
Definition: rodsErrorTable.h:325
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
univ_mss_file_truncate
irods::error univ_mss_file_truncate(irods::plugin_context &)
Definition: libunivmss.cpp:496
ExecCmdOut::stderrBuf
bytesBuf_t stderrBuf
Definition: execCmd.h:22
rsExecCmd.hpp
univ_mss_resource
Definition: libunivmss.cpp:921