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)  

irods_resource_redirect.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=
2 // irods includes
3 #include "miscServerFunct.hpp"
4 #include "objInfo.h"
5 #include "dataObjCreate.h"
6 #include "specColl.hpp"
7 #include "collection.hpp"
8 #include "dataObjOpr.hpp"
9 #include "getRescQuota.h"
10 #include "rsDataObjCreate.hpp"
11 #include "rsGetRescQuota.hpp"
12 
13 // =-=-=-=-=-=-=
17 
18 
19 namespace irods {
23  static
25  rsComm_t* _comm,
26  const std::string& _oper,
27  const std::string& _resc_name,
28  file_object_ptr _file_obj,
29  std::string& _out_hier,
30  float& _out_vote ) {
31  // =-=-=-=-=-=-=-
32  // request the resource by name
34  error err = resc_mgr.resolve( _resc_name, resc );
35  if ( !err.ok() ) {
36  return PASSMSG( "failed in resc_mgr.resolve", err );
37 
38  }
39 
40  // =-=-=-=-=-=-=-
41  // if the resource has a parent, bail as this is a grave, terrible error.
42  resource_ptr parent;
43  error p_err = resc->get_parent( parent );
44  if ( p_err.ok() ) {
45  return ERROR(
47  "attempt to directly address a child resource" );
48  }
49 
50  // =-=-=-=-=-=-=-
51  // get current hostname, which is also done by init local server host
52  char host_name_str[ MAX_NAME_LEN ];
53  if ( gethostname( host_name_str, MAX_NAME_LEN ) < 0 ) {
54  return ERROR( SYS_GET_HOSTNAME_ERR, "failed in gethostname" );
55 
56  }
57  std::string host_name( host_name_str );
58 
59  // =-=-=-=-=-=-=-
60  // query the resc given the operation for a hier string which
61  // will determine the host
63  float vote = 0.0;
64  first_class_object_ptr ptr = boost::dynamic_pointer_cast< first_class_object >( _file_obj );
65  err = resc->call< const std::string*, const std::string*, hierarchy_parser*, float* >(
66  _comm, RESOURCE_OP_RESOLVE_RESC_HIER, ptr, &_oper, &host_name, &parser, &vote );
67  if ( !err.ok() || 0.0 == vote ) {
68  std::stringstream msg;
69  msg << "failed in call to redirect";
70  msg << " host [" << host_name << "] ";
71  msg << " hier [" << _out_hier << "]";
72  err.status( false );
73  if ( err.code() == 0 ) {
74  err.code( HIERARCHY_ERROR );
75  }
76  return PASSMSG( msg.str(), err );
77  }
78 
79  // =-=-=-=-=-=-=-
80  // extract the hier string from the parser, politely.
81  parser.str( _out_hier );
82  _out_vote = vote;
83 
84  return SUCCESS();
85 
86  } // request_vote_for_file_object
87 
91  static
93  rsComm_t* _comm,
94  irods::file_object_ptr _file_obj,
95  const std::string& _oper,
96  std::string& _out_hier ) {
97  // =-=-=-=-=-=-=-
98  // build a list of root hiers for all
99  // the repls we have in the list
100  std::map< std::string, float > root_map;
101 
102  // =-=-=-=-=-=-=-
103  // grind through the list, get the root of the hiers and
104  // place it into the map
105  std::vector< physical_object > repls = _file_obj->replicas();
106  for ( size_t i = 0; i < repls.size(); ++i ) {
107  // =-=-=-=-=-=-=-
108  // extract the root resource from the hierarchy
110  parser.set_string( repls[ i ].resc_hier() );
111 
112  std::string root_resc;
113  parser.first_resc( root_resc );
114  root_map[ root_resc ] = 0.0;
115 
116  } // for i
117 
118  // =-=-=-=-=-=-=-
119  // grind through the map and get a vote for each root
120  // cache that and keep track of the max
121  std::string max_hier;
122  float max_vote = -1.0;
123  std::map< std::string, float >::iterator itr = root_map.begin();
124  for ( ; itr != root_map.end(); ++itr ) {
125  // =-=-=-=-=-=-=-
126  // request the vote
127  float vote = 0.0;
128  std::string voted_hier;
130  _comm,
131  _oper.c_str(),
132  itr->first,
133  _file_obj,
134  voted_hier,
135  vote );
136  if ( ret.ok() ) {
137  // =-=-=-=-=-=-=-
138  // assign the vote to the root
139  itr->second = vote;
140 
141  // =-=-=-=-=-=-=-
142  // keep track of max vote, hier and resc name
143  if ( vote > max_vote ) {
144  max_vote = vote;
145  max_hier = voted_hier;
146  }
147  }
148 
149  } // for itr
150 
151  // =-=-=-=-=-=-=-
152  // if we have a max vote of 0.0 then
153  // this is an error
154  double diff = ( max_vote - 0.00000001 );
155  if ( diff <= 0.0 ) {
156  return ERROR(
158  "no valid resource found for data object" );
159  }
160 
161  // =-=-=-=-=-=-=-
162  // set out variables
163  _out_hier = max_hier;
164 
165  return SUCCESS();
166 
167  } // resolve_hier_for_open_or_write_without_keyword
168 
172  static
174  rsComm_t* _comm,
175  irods::file_object_ptr _file_obj,
176  const char* _key_word,
177  const std::string& _oper,
178  std::string& _out_hier ) {
179  // =-=-=-=-=-=-=-
180  // regardless we need to resolve the appropriate resource
181  // to do the voting so search the repls for the proper resc
182  std::vector< physical_object > repls = _file_obj->replicas();
183 
184  bool kw_match_found = false;
185  if ( _key_word ) {
186  // =-=-=-=-=-=-=-
187  // we have a kw present, compare against all the repls for a match
188  for ( size_t i = 0; i < repls.size(); ++i ) {
189  // =-=-=-=-=-=-=-
190  // extract the root resource from the hierarchy
191  std::string root_resc;
193  parser.set_string( repls[ i ].resc_hier() );
194  parser.first_resc( root_resc );
195 
196  // =-=-=-=-=-=-=-
197  // if we have a match then set open & break, otherwise continue
198  if ( root_resc == _key_word ) {
199  _file_obj->resc_hier( repls[ i ].resc_hier() );
200  kw_match_found = true;
201  break;
202  }
203 
204  } // for i
205 
206  // =-=-=-=-=-=-=-
207  // if a match is found, resolve it and get the hier string
208  if ( kw_match_found ) {
209  float vote = 0.0;
211  _comm,
212  _oper.c_str(),
213  _key_word,
214  _file_obj,
215  _out_hier,
216  vote );
217  if ( 0.0 == vote ) {
218  if ( ret.code() == 0 ) {
219  ret.code( -1 );
220  }
221  ret.status( false );
222  }
223 
224  return PASS( ret );
225 
226  } // if kw_match_found
227 
228  // =-=-=-=-=-=-=-
229  // NOTE:: if a kw match is not found is this an
230  // error or is falling through acceptable
231  }
232 
233  // =-=-=-=-=-=-=-
234  // either no kw match or no kw, so pick one...
236  _comm,
237  _file_obj,
238  _oper,
239  _out_hier );
240 
241  } // resolve_hier_for_open_or_write
242 
246  static
248  rsComm_t* _comm,
249  irods::file_object_ptr _file_obj,
250  const char* _key_word,
251  dataObjInp_t* _data_obj_inp,
252  std::string& _out_hier ) {
253  // =-=-=-=-=-=-=-
254  // handle the create operation
255  // check for incoming requested destination resource first
256  std::string resc_name;
257  if ( !_key_word ) {
258  // =-=-=-=-=-=-=-
259  // this is a 'create' operation and no resource is specified,
260  // query the server for the default or other resource to use
261  int status = getRescForCreate( _comm, _data_obj_inp, resc_name );
262  if ( status < 0 || resc_name.empty() ) {
263  // =-=-=-=-=-=-=-
264  return ERROR( status, "failed in getRescForCreate" );
265  }
266  }
267  else {
268  resc_name = _key_word;
269 
270  }
271 
272  // =-=-=-=-=-=-=-
273  // set the resc hier given the root resc name
274  _file_obj->resc_hier( resc_name );
275 
276  // =-=-=-=-=-=-=-
277  // get a vote and hier for the create
278  float vote = 0.0;
280  _comm,
282  resc_name,
283  _file_obj,
284  _out_hier,
285  vote );
286  if ( 0.0 == vote ) {
287  if ( ret.code() == 0 ) {
288  ret.code( HIERARCHY_ERROR );
289  }
290  ret.status( false );
291  }
292 
293  return PASS( ret );
294 
295  } // resolve_hier_for_create
296 
300  static
302  rsComm_t* _comm,
303  irods::file_object_ptr _file_obj,
304  const char* _key_word,
305  dataObjInp_t* _data_obj_inp,
306  std::string& _out_hier ) {
307  // =-=-=-=-=-=-=-
308  // regardless we need to resolve the appropriate resource
309  // to do the voting so search the repls for the proper resc
310  std::vector< physical_object > repls = _file_obj->replicas();
311  bool kw_match_found = false;
312  if ( _key_word ) {
313  // =-=-=-=-=-=-=-
314  // we have a kw present, compare against all the repls for a match
315  for ( size_t i = 0; i < repls.size(); ++i ) {
316  // =-=-=-=-=-=-=-
317  // extract the root resource from the hierarchy
318  std::string root_resc;
320  parser.set_string( repls[ i ].resc_hier() );
321  parser.first_resc( root_resc );
322 
323  // =-=-=-=-=-=-=-
324  // if we have a match then set open & break, otherwise continue
325  if ( root_resc == _key_word ) {
326  _file_obj->resc_hier( repls[ i ].resc_hier() );
327  kw_match_found = true;
328  break;
329  }
330 
331  } // for i
332 
333  // =-=-=-=-=-=-=-
334  // if a match is found, resolve it and get the hier string
335  if ( kw_match_found ) {
336  float vote = 0.0;
338  _comm,
340  _key_word,
341  _file_obj,
342  _out_hier,
343  vote );
344  if ( 0.0 == vote ) {
345  if ( ret.code() == 0 ) {
346  ret.code( -1 );
347  }
348  ret.status( false );
349  }
350 
351  return PASS( ret );
352 
353  } // if kw_match_found
354 
355  // =-=-=-=-=-=-=-
356  // NOTE:: if a kw match is not found is this an
357  // error or is falling through acceptable
358  }
359 
360  // =-=-=-=-=-=-=-
361  // either no kw match or no kw, so pick one...
363  _comm,
364  _file_obj,
365  _key_word,
366  _data_obj_inp,
367  _out_hier );
368 
369  } // resolve_hier_for_create_or_open
370 
375  const std::string& _oper,
376  file_object_ptr& _fobj,
377  dataObjInp_t* _data_obj_inp ) {
378 
379  char* dst_resc_kw = getValByKey( &_data_obj_inp->condInput, DEST_RESC_NAME_KW );
380  char* force_flag_kw = getValByKey( &_data_obj_inp->condInput, FORCE_FLAG_KW );
381  std::vector<physical_object> repls = _fobj->replicas();
382  if ( PUT_OPR != _data_obj_inp->oprType ||
383  repls.empty() ||
384  !dst_resc_kw ||
385  !force_flag_kw ||
386  strlen( dst_resc_kw ) == 0 ||
387  !( OPEN_OPERATION == _oper ||
388  WRITE_OPERATION == _oper ) ) {
389  return SUCCESS();
390  }
391 
392  bool hier_match_flg = false;
393  for ( size_t i = 0; i < repls.size(); ++i ) {
394  // =-=-=-=-=-=-=-
395  // extract the root resource from the hierarchy
397  parser.set_string( repls[ i ].resc_hier() );
398 
399  std::string root_resc;
400  parser.first_resc( root_resc );
401  if ( root_resc == dst_resc_kw ) {
402  hier_match_flg = true;
403  break;
404  }
405 
406  } // for i
407 
408  if ( !hier_match_flg ) {
409  std::stringstream msg;
410  msg << "cannot force put ["
411  << _data_obj_inp->objPath
412  << "] to a different resource ["
413  << dst_resc_kw
414  << "]";
415  return ERROR(
417  msg.str() );
418  }
419 
420  return SUCCESS();
421 
422  } // determine_force_write_to_new_resource
423 
424  // iterate over the linked list and look for a given resource hierarchy
426  const std::string& _hier,
427  dataObjInfo_t* _data_obj_info_head) {
428 
429  dataObjInfo_t* data_obj_info = _data_obj_info_head;
430 
431  while (data_obj_info) {
432  if (!strcmp(_hier.c_str(), data_obj_info->rescHier)) {
433  return true;
434  }
435  data_obj_info = data_obj_info->next;
436  }
437  return false;
438  }
439 
441  rsComm_t* _comm,
442  dataObjInp_t* _obj_inp,
443  std::string& _resc_name ) {
444 
445  /* query rcat for resource info and sort it */
446  ruleExecInfo_t rei;
447  initReiWithDataObjInp( &rei, _comm, _obj_inp );
448 
449  int status = 0;
450  if ( _obj_inp->oprType == REPLICATE_OPR ) {
451  status = applyRule( "acSetRescSchemeForRepl", NULL, &rei, NO_SAVE_REI );
452  }
453  else {
454  status = applyRule( "acSetRescSchemeForCreate", NULL, &rei, NO_SAVE_REI );
455  }
457  free(rei.condInputData);
458 
459  if ( status < 0 ) {
460  if ( rei.status < 0 ) {
461  status = rei.status;
462  }
463 
464  rodsLog(
465  LOG_NOTICE,
466  "getRescForCreate:acSetRescSchemeForCreate error for %s,status=%d",
467  _obj_inp->objPath,
468  status );
469 
470  return status;
471  }
472 
473  // get resource name
474  if ( !strlen( rei.rescName ) ) {
476  _comm,
477  "", "",
478  &_obj_inp->condInput,
479  _resc_name );
480  if ( !set_err.ok() ) {
481  irods::log( PASS( set_err ) );
482  return SYS_INVALID_RESC_INPUT;
483  }
484  }
485  else {
486  _resc_name = rei.rescName;
487  }
488 
490  _comm,
491  _obj_inp->objPath,
492  _resc_name.c_str(),
493  _obj_inp->dataSize );
496  }
497 
498 
499  return 0;
500  }
501 
506  const std::string& _oper,
507  rsComm_t* _comm,
508  dataObjInp_t* _data_obj_inp,
509  std::string& _out_hier,
510  dataObjInfo_t** _data_obj_info ) {
511  // =-=-=-=-=-=-=-
512  // validate incoming parameters
513  if ( !_comm ) {
514  return ERROR(
516  "null comm pointer" );
517  }
518  else if ( !_data_obj_inp ) {
519  return ERROR(
521  "null data obj inp pointer" );
522  }
523 
524  // =-=-=-=-=-=-=-
525  // cache the operation, as we may need to modify it
526  std::string oper = _oper;
527 
528  // =-=-=-=-=-=-=-
529  // if this is a put operation then we do not have a first class object
530  file_object_ptr file_obj(
531  new file_object( ) );
532 
533 
534  // =-=-=-=-=-=-=-
535  // if this is a special collection then we need to get the hier
536  // pass that along and bail as it is not a data object, or if
537  // it is just a not-so-special collection then we continue with
538  // processing the operation, as this may be a create op
539  rodsObjStat_t *rodsObjStatOut = NULL;
540  int spec_stat = collStat( _comm, _data_obj_inp, &rodsObjStatOut );
541  file_obj->logical_path( _data_obj_inp->objPath );
542  if ( spec_stat >= 0 ) {
543  if ( rodsObjStatOut->specColl != NULL ) {
544  _out_hier = rodsObjStatOut->specColl->rescHier;
545  freeRodsObjStat( rodsObjStatOut );
546  return SUCCESS();
547  }
548 
549  }
550  freeRodsObjStat( rodsObjStatOut );
551 
552  // =-=-=-=-=-=-=-
553  // extract the resc name keyword from the conditional input
554  char* back_up_resc_name = getValByKey( &_data_obj_inp->condInput, BACKUP_RESC_NAME_KW );
555  char* dest_resc_name = getValByKey( &_data_obj_inp->condInput, DEST_RESC_NAME_KW );
556  char* default_resc_name = getValByKey( &_data_obj_inp->condInput, DEF_RESC_NAME_KW );
557  char* resc_name = getValByKey( &_data_obj_inp->condInput, RESC_NAME_KW );
558 
559  // =-=-=-=-=-=-=-
560  // assign the keyword in an order, if it applies
561  char* key_word = 0;
562  if ( resc_name ) {
563  key_word = resc_name;
564  }
565  else if ( dest_resc_name ) {
566  key_word = dest_resc_name;
567  }
568  else if ( back_up_resc_name ) {
569  key_word = back_up_resc_name;
570  }
571 
572 
573  // =-=-=-=-=-=-=-
574  // call factory for given dataObjInp, get a file_object
575  error fac_err = file_object_factory( _comm, _data_obj_inp, file_obj, _data_obj_info );
576 
577  // =-=-=-=-=-=-=-
578  // determine if this is an invalid write
580  oper,
581  file_obj,
582  _data_obj_inp );
583  if ( !ret.ok() ) {
584  return PASS( ret );
585 
586  }
587 
588  // =-=-=-=-=-=-=-
589  // perform an open operation if create is not specified ( thats all we have for now )
590  if ( OPEN_OPERATION == oper ||
591  WRITE_OPERATION == oper ||
592  UNLINK_OPERATION == oper ) {
593  // =-=-=-=-=-=-=-
594  // reality check: if the key_word is set, verify that the resource
595  // actually exists before moving forward.
596  if ( key_word ) {
597  resource_ptr resc;
598  error ret = resc_mgr.resolve( key_word, resc );
599  if ( !ret.ok() ) {
600  return PASS( ret );
601  }
602  }
603 
604  // =-=-=-=-=-=-=-
605  // factory has already been called, test for
606  // success before proceeding
607  if ( !fac_err.ok() ) {
608  std::stringstream msg;
609  msg << "resolve_resource_hierarchy :: failed in file_object_factory";
610  return PASSMSG( msg.str(), fac_err );
611  }
612 
613  // =-=-=-=-=-=-=-
614  // consider force flag - we need to consider the default
615  // resc if -f is specified
616  char* force_flag = getValByKey( &_data_obj_inp->condInput, FORCE_FLAG_KW );
617  if ( force_flag &&
618  !key_word ) {
619  key_word = default_resc_name;
620  }
621 
622  // =-=-=-=-=-=-=-
623  // attempt to resolve for an open
624  _out_hier = "";
626  _comm,
627  file_obj,
628  key_word,
629  oper,
630  _out_hier );
631 
632  // make sure the desired hierarchy is in the linked list
633  // otherwise get data object info list again,
634  // in case object was just staged to cache by above function
635  if (_data_obj_info && !is_hier_in_obj_info_list(_out_hier, *_data_obj_info)) {
636 
637  // free current list
638  freeAllDataObjInfo(*_data_obj_info);
639  *_data_obj_info = NULL;
640 
641  // get updated list
643  _comm,
644  _data_obj_inp,
645  _data_obj_info);
646 
647  // error checks
648  if ( status < 0 ) {
649  status = getDataObjInfo( _comm, _data_obj_inp, _data_obj_info, 0, 0 );
650  }
651  if ( 0 == *_data_obj_info || status < 0 ) {
652  if ( *_data_obj_info ) {
653  freeAllDataObjInfo( *_data_obj_info );
654  }
655  std::stringstream msg;
656  msg << "Failed to retrieve data object info list for ["
657  << _data_obj_inp->objPath
658  << "]";
659  return ERROR( HIERARCHY_ERROR, msg.str() );
660  }
661 
662  // check that we have found the correct hierarchy this time
663  if (!is_hier_in_obj_info_list(_out_hier, *_data_obj_info)) {
664  std::stringstream msg;
665  msg << "Failed to find resource hierarchy ["
666  << _out_hier
667  << "for ["
668  << _data_obj_inp->objPath
669  << "]";
670  return ERROR( HIERARCHY_ERROR, msg.str() );
671  }
672  }
675 
676 
677  return ret;
678 
679  }
680  else if ( CREATE_OPERATION == oper ) {
681  std::string create_resc_name;
682  // =-=-=-=-=-=-=-
683  // include the default resc name if it applies
684  if ( !key_word && default_resc_name ) {
685  create_resc_name = default_resc_name;
686 
687  }
688  else if( key_word ) {
689  create_resc_name = key_word;
690  }
692  _comm,
693  _data_obj_inp,
694  create_resc_name );
695  if( status < 0 ) {
696  return ERROR(
697  status,
698  "apply_policy_for_create_operation failed");
699  }
700 
701  // =-=-=-=-=-=-=-
702  // if we have valid data objects then this could
703  // be actually an open rather than a pure create
704  error ret = SUCCESS();
705  if ( fac_err.ok() ) {
707  _comm,
708  file_obj,
709  create_resc_name.c_str(),
710  _data_obj_inp,
711  _out_hier );
712 
713  }
714  else {
715  // =-=-=-=-=-=-=-
716  // attempt to resolve for a create
718  _comm,
719  file_obj,
720  create_resc_name.c_str(),
721  _data_obj_inp,
722  _out_hier );
723  }
724 
725  // make sure the desired hierarchy is in the linked list
726  // otherwise get data object info list again,
727  // in case object was just staged to cache by above function
728  if (_data_obj_info && !is_hier_in_obj_info_list(_out_hier, *_data_obj_info)) {
729 
730  // free current list
731  freeAllDataObjInfo(*_data_obj_info);
732  *_data_obj_info = NULL;
733 
734  // get updated list
736  _comm,
737  _data_obj_inp,
738  _data_obj_info);
739 
740  // error checks
741  if ( status < 0 ) {
742  status = getDataObjInfo( _comm, _data_obj_inp, _data_obj_info, 0, 0 );
743  }
744  if ( 0 == *_data_obj_info || status < 0 ) {
745  if ( *_data_obj_info ) {
746  freeAllDataObjInfo( *_data_obj_info );
747  }
748  std::stringstream msg;
749  msg << "Failed to retrieve data object info list for ["
750  << _data_obj_inp->objPath
751  << "]";
752  return ERROR( HIERARCHY_ERROR, msg.str() );
753  }
754 
755  // check that we have found the correct hierarchy this time
756  if (!is_hier_in_obj_info_list(_out_hier, *_data_obj_info)) {
757  std::stringstream msg;
758  msg << "Failed to find resource hierarchy ["
759  << _out_hier
760  << "for ["
761  << _data_obj_inp->objPath
762  << "]";
763  return ERROR( HIERARCHY_ERROR, msg.str() );
764  }
765  }
768 
769  return ret;
770 
771  } // else
772 
773  // =-=-=-=-=-=-=-
774  // should not get here
775  std::stringstream msg;
776  msg << "operation not supported ["
777  << oper
778  << "]";
779  return ERROR( -1, msg.str() );
780 
781  } // resolve_resource_hierarchy
782 
783 // =-=-=-=-=-=-=-
784 // @brief function to query resource for chosen server to which to redirect
785 // for a given operation
786  error resource_redirect( const std::string& _oper,
787  rsComm_t* _comm,
788  dataObjInp_t* _data_obj_inp,
789  std::string& _out_hier,
790  rodsServerHost_t*& _out_host,
791  int& _out_flag,
792  dataObjInfo_t** _data_obj_info ) {
793  // =-=-=-=-=-=-=-
794  // default to local host if there is a failure
795  _out_flag = LOCAL_HOST;
796 
797  // =-=-=-=-=-=-=-
798  // resolve the resource hierarchy for this given operation and dataObjInp
799  std::string resc_hier;
801  _oper,
802  _comm,
803  _data_obj_inp,
804  resc_hier,
805  _data_obj_info );
806  if ( !res_err.ok() ) {
807  std::stringstream msg;
808  msg << "resource_redirect - failed to resolve resource hierarchy for [";
809  msg << _data_obj_inp->objPath;
810  msg << "]";
811  return PASSMSG( msg.str(), res_err );
812 
813  }
814 
815  // =-=-=-=-=-=-=-
816  // we may have an empty hier due to special collections and other
817  // unfortunate cases which we cannot control, check the hier string
818  // and if it is empty return success ( for now )
819  if ( resc_hier.empty() ) {
820  return SUCCESS();
821  }
822 
823  // =-=-=-=-=-=-=-
824  // parse out the leaf resource id for redirection
825  rodsLong_t resc_id = 0;
826  irods::error ret = resc_mgr.hier_to_leaf_id(resc_hier,resc_id);
827  if( !ret.ok() ) {
828  return PASS(ret);
829  }
830 
831  // =-=-=-=-=-=-=-
832  // get the host property from the last resc and get the
833  // host name from that host
834  rodsServerHost_t* last_resc_host = NULL;
835  error err = get_resource_property< rodsServerHost_t* >(
836  resc_id,
838  last_resc_host );
839  if ( !err.ok() || NULL == last_resc_host ) {
840  std::stringstream msg;
841  msg << "resource_redirect :: failed in get_resource_property call ";
842  msg << "for [" << resc_hier << "]";
843  return PASSMSG( msg.str(), err );
844  }
845 
846 
847  // =-=-=-=-=-=-=-
848  // get current hostname, which is also done by init local server host
849  char host_name_char[ MAX_NAME_LEN ];
850  if ( gethostname( host_name_char, MAX_NAME_LEN ) < 0 ) {
851  return ERROR( SYS_GET_HOSTNAME_ERR, "failed in gethostname" );
852 
853  }
854 
855  std::string host_name( host_name_char );
856 
857  // =-=-=-=-=-=-=
858  // iterate over the list of hostName_t* and see if any match our
859  // host name. if we do, then were local
860  bool match_flg = false;
861  hostName_t* tmp_host = last_resc_host->hostName;
862  while ( tmp_host ) {
863  std::string name( tmp_host->name );
864  if ( name.find( host_name ) != std::string::npos ) {
865  match_flg = true;
866  break;
867 
868  }
869 
870  tmp_host = tmp_host->next;
871 
872  } // while tmp_host
873 
874  // =-=-=-=-=-=-=-
875  // are we really, really local?
876  if ( match_flg ) {
877  _out_hier = resc_hier;
878  _out_flag = LOCAL_HOST;
879  _out_host = 0;
880  return SUCCESS();
881  }
882 
883  // =-=-=-=-=-=-=-
884  // it was not a local resource so then do a svr to svr connection
885  int conn_err = svrToSvrConnect( _comm, last_resc_host );
886  if ( conn_err < 0 ) {
887  return ERROR( conn_err, "failed in svrToSvrConnect" );
888  }
889 
890 
891  // =-=-=-=-=-=-=-
892  // return with a hier string and new connection as remote host
893  _out_hier = resc_hier;
894  _out_host = last_resc_host;
895  _out_flag = REMOTE_HOST;
896 
897  return SUCCESS();
898 
899  } // resource_redirect
900 
901 }; // namespace irods
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
DataObjInp::objPath
char objPath[(1024+64)]
Definition: dataObjInpOut.h:66
RESC_NAME_KW
#define RESC_NAME_KW
Definition: rodsKeyWdDef.h:19
NULL
#define NULL
Definition: rodsDef.h:70
irods::determine_force_write_to_new_resource
error determine_force_write_to_new_resource(const std::string &_oper, file_object_ptr &_fobj, dataObjInp_t *_data_obj_inp)
Definition: irods_resource_redirect.cpp:374
rsComm_t
Definition: rcConnect.h:145
irods::resolve_hier_for_create_or_open
static error resolve_hier_for_create_or_open(rsComm_t *_comm, irods::file_object_ptr _file_obj, const char *_key_word, dataObjInp_t *_data_obj_inp, std::string &_out_hier)
Definition: irods_resource_redirect.cpp:301
SYS_INVALID_RESC_INPUT
@ SYS_INVALID_RESC_INPUT
Definition: rodsErrorTable.h:100
specColl.hpp
rsGetRescQuota.hpp
rsDataObjCreate.hpp
DIRECT_CHILD_ACCESS
@ DIRECT_CHILD_ACCESS
Definition: rodsErrorTable.h:765
RuleExecInfo::status
int status
Definition: irods_re_structs.hpp:19
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
DataObjInp::dataSize
rodsLong_t dataSize
Definition: dataObjInpOut.h:70
irods::resolve_resource_hierarchy
error resolve_resource_hierarchy(const std::string &, rsComm_t *, dataObjInp_t *, std::string &, dataObjInfo_t **_data_obj_info=0)
Definition: irods_resource_redirect.cpp:505
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
NO_SAVE_REI
#define NO_SAVE_REI
Definition: rodsDef.h:103
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
REMOTE_HOST
#define REMOTE_HOST
Definition: rodsConnect.h:45
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
PUT_OPR
#define PUT_OPR
Definition: dataObjInpOut.h:167
DataObjInfo::rescHier
char rescHier[(1024+64)]
Definition: objInfo.h:132
LOCAL_HOST
#define LOCAL_HOST
Definition: rodsConnect.h:44
irods::set_default_resource
error set_default_resource(rsComm_t *, const std::string &, const std::string &, keyValPair_t *, std::string &)
Definition: irods_resource_backport.cpp:298
setRescQuota
int setRescQuota(rsComm_t *comm_handle, const char *obj_path, const char *resc_name, rodsLong_t data_size)
Definition: rsGetRescQuota.cpp:213
collStat
int collStat(rsComm_t *rsComm, dataObjInp_t *dataObjInp, rodsObjStat_t **rodsObjStatOut)
Definition: collection.cpp:271
irods_resource_backport.hpp
irods::resource_redirect
error resource_redirect(const std::string &, rsComm_t *, dataObjInp_t *, std::string &, rodsServerHost_t *&, int &, dataObjInfo_t **_data_obj_info=0)
Definition: irods_resource_redirect.cpp:786
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
generate_iadmin_commands_for_41_to_42_upgrade.name
name
Definition: generate_iadmin_commands_for_41_to_42_upgrade.py:23
dataObjCreate.h
irods_resource_redirect.hpp
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
DataObjInfo::next
struct DataObjInfo * next
Definition: objInfo.h:163
initReiWithDataObjInp
int initReiWithDataObjInp(ruleExecInfo_t *rei, rsComm_t *rsComm, dataObjInp_t *dataObjIn)
Definition: irods_re_structs.cpp:164
freeRodsObjStat
int freeRodsObjStat(rodsObjStat_t *rodsObjStat)
Definition: rcMisc.cpp:3537
BACKUP_RESC_NAME_KW
#define BACKUP_RESC_NAME_KW
Definition: rodsKeyWdDef.h:22
DEST_RESC_NAME_KW
#define DEST_RESC_NAME_KW
Definition: rodsKeyWdDef.h:20
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
RuleExecInfo::condInputData
keyValPair_t * condInputData
Definition: irods_re_structs.hpp:34
hostName::next
struct hostName * next
Definition: rodsConnect.h:39
irods::OPEN_OPERATION
const std::string OPEN_OPERATION("OPEN")
irods::error::code
long long code() const
Definition: irods_error.cpp:194
irods::first_class_object_ptr
boost::shared_ptr< first_class_object > first_class_object_ptr
Definition: irods_first_class_object.hpp:47
irods::file_object_factory
error file_object_factory(rsComm_t *, dataObjInp_t *, file_object_ptr, dataObjInfo_t **)
Definition: irods_file_object.cpp:271
hostName
Definition: rodsConnect.h:37
freeAllDataObjInfo
int freeAllDataObjInfo(dataObjInfo_t *dataObjInfoHead)
Definition: rcMisc.cpp:561
getDataObjInfoIncSpecColl
int getDataObjInfoIncSpecColl(rsComm_t *rsComm, dataObjInp_t *dataObjInp, dataObjInfo_t **dataObjInfo)
Definition: dataObjOpr.cpp:1767
irods
Definition: apiHandler.hpp:35
hostName::name
char * name
Definition: rodsConnect.h:38
SYS_RESC_QUOTA_EXCEEDED
@ SYS_RESC_QUOTA_EXCEEDED
Definition: rodsErrorTable.h:175
DataObjInp
Definition: dataObjInpOut.h:65
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
getRescQuota.h
irods::resource_manager::resolve
error resolve(std::string, resource_ptr &)
Definition: irods_resource_manager.cpp:51
svrToSvrConnect
int svrToSvrConnect(rsComm_t *rsComm, rodsServerHost_t *rodsServerHost)
Definition: miscServerFunct.cpp:106
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
SpecColl::rescHier
char rescHier[(1024+64)]
Definition: objInfo.h:84
collection.hpp
irods::log
void log(const error &)
Definition: irods_log.cpp:13
DEF_RESC_NAME_KW
#define DEF_RESC_NAME_KW
Definition: rodsKeyWdDef.h:21
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
getDataObjInfo
int getDataObjInfo(rsComm_t *rsComm, dataObjInp_t *dataObjInp, dataObjInfo_t **dataObjInfoHead, char *accessPerm, int ignoreCondInput)
Definition: dataObjOpr.cpp:87
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
SYS_GET_HOSTNAME_ERR
@ SYS_GET_HOSTNAME_ERR
Definition: rodsErrorTable.h:85
irods::error
Definition: irods_error.hpp:23
irods::request_vote_for_file_object
static error request_vote_for_file_object(rsComm_t *_comm, const std::string &_oper, const std::string &_resc_name, file_object_ptr _file_obj, std::string &_out_hier, float &_out_vote)
Definition: irods_resource_redirect.cpp:24
miscServerFunct.hpp
HIERARCHY_ERROR
@ HIERARCHY_ERROR
Definition: rodsErrorTable.h:752
irods::is_hier_in_obj_info_list
bool is_hier_in_obj_info_list(const std::string &, dataObjInfo_t *)
Definition: irods_resource_redirect.cpp:425
REPLICATE_OPR
#define REPLICATE_OPR
Definition: dataObjInpOut.h:172
irods_hierarchy_parser.hpp
getRescForCreate
int getRescForCreate(rsComm_t *rsComm, dataObjInp_t *dataObjInp, std::string &_resc_name)
Definition: rsDataObjCreate.cpp:604
FORCE_FLAG_KW
#define FORCE_FLAG_KW
Definition: rodsKeyWdDef.h:13
objInfo.h
irods::resource_manager::hier_to_leaf_id
error hier_to_leaf_id(const std::string &, rodsLong_t &)
Definition: irods_resource_manager.cpp:1082
irods::file_object
Definition: irods_file_object.hpp:19
rodsServerHost
Definition: rodsConnect.h:62
DataObjInp::oprType
int oprType
Definition: dataObjInpOut.h:72
RuleExecInfo::rescName
char rescName[64]
Definition: irods_re_structs.hpp:29
irods::file_object_ptr
boost::shared_ptr< file_object > file_object_ptr
Definition: irods_file_object.hpp:145
RuleExecInfo
Definition: irods_re_structs.hpp:18
irods::WRITE_OPERATION
const std::string WRITE_OPERATION("WRITE")
applyRule
int applyRule(char *inAction, msParamArray_t *inMsParamArray, ruleExecInfo_t *rei, int reiSaveFlag)
Definition: irods_re_structs.cpp:65
irods::error::status
bool status() const
Definition: irods_error.cpp:187
irods::resolve_hier_for_create
static error resolve_hier_for_create(rsComm_t *_comm, irods::file_object_ptr _file_obj, const char *_key_word, dataObjInp_t *_data_obj_inp, std::string &_out_hier)
Definition: irods_resource_redirect.cpp:247
rodsObjStat
Definition: objStat.h:8
rodsObjStat::specColl
specColl_t * specColl
Definition: objStat.h:18
irods::resolve_hier_for_open_or_write
static error resolve_hier_for_open_or_write(rsComm_t *_comm, irods::file_object_ptr _file_obj, const char *_key_word, const std::string &_oper, std::string &_out_hier)
Definition: irods_resource_redirect.cpp:173
rodsServerHost::hostName
hostName_t * hostName
Definition: rodsConnect.h:63
irods::apply_policy_for_create_operation
int apply_policy_for_create_operation(rsComm_t *_comm, dataObjInp_t *_obj_inp, std::string &_resc_name)
Definition: irods_resource_redirect.cpp:440
dataObjOpr.hpp
DataObjInp::condInput
keyValPair_t condInput
Definition: dataObjInpOut.h:74
irods::resolve_hier_for_open_or_write_without_keyword
static error resolve_hier_for_open_or_write_without_keyword(rsComm_t *_comm, irods::file_object_ptr _file_obj, const std::string &_oper, std::string &_out_hier)
Definition: irods_resource_redirect.cpp:92
clearKeyVal
int clearKeyVal(keyValPair_t *condInput)
Definition: rcMisc.cpp:1047
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
DataObjInfo
Definition: objInfo.h:129
irods::RESOURCE_HOST
const std::string RESOURCE_HOST("resource_property_host")
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
irods::UNLINK_OPERATION
const std::string UNLINK_OPERATION("UNLINK")
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32