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)  

librepl.cpp
Go to the documentation of this file.
1 // Plug-in defining a replicating resource. This resource makes sure that all of its data is replicated to all of its children
3 //
5 
6 // =-=-=-=-=-=-=-
7 // irods includes
9 #include "msParam.h"
10 #include "rodsLog.h"
11 
12 // =-=-=-=-=-=-=-
14 #include "irods_file_object.hpp"
19 #include "irods_plugin_base.hpp"
20 #include "irods_stacktrace.hpp"
21 #include "irods_repl_retry.hpp"
22 #include "irods_repl_types.hpp"
23 #include "irods_object_oper.hpp"
24 #include "irods_replicator.hpp"
28 #include "irods_repl_rebalance.hpp"
30 #include "irods_random.hpp"
31 #include "irods_exception.hpp"
32 #include "rsGenQuery.hpp"
33 
34 // =-=-=-=-=-=-=-
35 // stl includes
36 #include <iostream>
37 #include <sstream>
38 #include <vector>
39 #include <string>
40 #include <map>
41 #include <list>
42 #include <boost/lexical_cast.hpp>
43 
44 // =-=-=-=-=-=-=-
45 // system includes
46 #ifndef _WIN32
47 #include <sys/file.h>
48 #include <sys/param.h>
49 #endif
50 #include <errno.h>
51 #include <sys/stat.h>
52 #include <string.h>
53 #ifndef _WIN32
54 #include <unistd.h>
55 #endif
56 #include <sys/types.h>
57 #if defined(osx_platform)
58 #include <sys/malloc.h>
59 #else
60 #include <malloc.h>
61 #endif
62 #include <fcntl.h>
63 #ifndef _WIN32
64 #include <sys/file.h>
65 #include <unistd.h>
66 #endif
67 #include <dirent.h>
68 
69 #if defined(solaris_platform)
70 #include <sys/statvfs.h>
71 #endif
72 #if defined(linux_platform)
73 #include <sys/vfs.h>
74 #endif
75 #include <sys/stat.h>
76 
77 #include <string.h>
78 
79 
80 const std::string NUM_REPL_KW( "num_repl" );
81 const std::string READ_KW( "read" );
82 const std::string READ_RANDOM_POLICY( "random" );
83 
85 template< typename DEST_TYPE >
87  irods::plugin_context& _ctx ) {
88  irods::error result = SUCCESS();
89  // =-=-=-=-=-=-=-
90  // verify that the resc context is valid
91  irods::error ret = _ctx.valid< DEST_TYPE >();
92  if ( !ret.ok() ) {
93  result = PASSMSG( "resource context is invalid", ret );
94  }
95 
96  return result;
97 }
98 
100 
101 // =-=-=-=-=-=-=-
102 // 2. Define operations which will be called by the file*
103 // calls declared in server/driver/include/fileDriver.h
104 // =-=-=-=-=-=-=-
105 
106 // =-=-=-=-=-=-=-
107 // NOTE :: to access properties in the _prop_map do the
108 // :: following :
109 // :: double my_var = 0.0;
110 // :: irods::error ret = _prop_map.get< double >( "my_key", my_var );
111 // =-=-=-=-=-=-=-
112 
114 // Utility functions
115 
120  const irods::hierarchy_parser& _parser,
121  irods::plugin_context& _ctx,
122  irods::resource_ptr& _ret_resc ) {
123  std::string this_name{};
124  auto ret{_ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, this_name)};
125  if (!ret.ok()) {
126  return PASS(ret);
127  }
128  std::string child{};
129  ret = _parser.next(this_name, child);
130  if (!ret.ok()) {
131  return PASS(ret);
132  }
133  irods::resource_child_map* cmap_ref;
135  _ret_resc = (*cmap_ref)[child].second;
136  return SUCCESS();
137 }
138 
141  const object_list_t& _object_list,
142  const irods::file_object_ptr _object,
143  irods::object_oper& _rtn_oper ) {
144  bool result{};
145  for (auto& oper : _object_list) {
146  if (oper.object() == (*_object.get())) {
147  _rtn_oper = oper;
148  result = true;
149  }
150  }
151  return result;
152 }
153 
156  irods::plugin_context& _ctx,
157  const std::string& _oper ) {
158  irods::error result = SUCCESS();
159  irods::error ret;
160  object_list_t object_list;
161  // The object list is now a queue of operations and their associated objects. Their corresponding replicating operations
162  // will be performed one at a time in the order in which they were put into the queue.
163  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( ( _ctx.fco() ) );
164  ret = _ctx.prop_map().get<object_list_t>( OBJECT_LIST_PROP, object_list );
165  irods::object_oper oper;
166  if ( !ret.ok() && ret.code() != KEY_NOT_FOUND ) {
167  std::stringstream msg;
168  msg << __FUNCTION__;
169  msg << " - Failed to get the object list from the resource.";
170  result = PASSMSG( msg.str(), ret );
171  }
172  else if ( replObjectInList( object_list, file_obj, oper ) ) {
173  // confirm the operations are compatible
174  bool mismatched = false;
175  if ( _oper == irods::CREATE_OPERATION ) {
176  if ( oper.operation() != irods::CREATE_OPERATION ) {
177  mismatched = true;
178  }
179  }
180  else if ( _oper == irods::WRITE_OPERATION ) {
181  // write is allowed after create
182  if ( oper.operation() != irods::CREATE_OPERATION && oper.operation() != irods::WRITE_OPERATION ) {
183  mismatched = true;
184  }
185  }
186 
187  result = ASSERT_ERROR( !mismatched, INVALID_OPERATION,
188  "Existing object operation: \"%s\" does not match current operation: \"%s\".",
189  oper.operation().c_str(), _oper.c_str() );
190  }
191  else {
192  oper.object() = *( file_obj.get() );
193  oper.operation() = _oper;
194  object_list.push_back( oper );
195  ret = _ctx.prop_map().set<object_list_t>( OBJECT_LIST_PROP, object_list );
196  result = ASSERT_PASS( ret, "Failed to set the object list property on the resource." );
197  }
198 
199  if ( !result.ok() ) {
200  irods::log( result );
201  }
202 
203  return result;
204 }
205 
207  irods::plugin_context& _ctx,
208  irods::hierarchy_parser& _out_parser) {
209  // Need to make sure selected hierarchy contains this resource
210  std::string name{};
211  const auto ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, name);
212  if (!ret.ok()) {
213  return PASS(ret);
214  }
215 
216  // Get selected hier from RESC_HIER_STR_KW, set at time of resolution
217  irods::hierarchy_parser selected_parser{};
218  bool resc_hier_in_keyword{};
219  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object>(_ctx.fco());
220  if (file_obj->l1_desc_idx() > 0) {
221  const auto hier_str{getValByKey(&L1desc[file_obj->l1_desc_idx()].dataObjInp->condInput, RESC_HIER_STR_KW)};
222  if (!hier_str) {
224  (boost::format(
225  "[%s] - No hierarchy string found in keywords for file object.") %
226  __FUNCTION__).str().c_str());
227  }
228  selected_parser.set_string(hier_str);
229  resc_hier_in_keyword = selected_parser.resc_in_hier(name);
230  }
231 
232  // Get resc hier from the file object directly if not in RESC_HIER_STR_KW
233  if (!resc_hier_in_keyword) {
234  const auto& selected_hier = file_obj->resc_hier();
235  if (selected_hier.empty()) {
237  (boost::format(
238  "[%s] - file object does not have a resource hierarchy.") %
239  __FUNCTION__).str().c_str());
240  }
241  selected_parser.set_string(selected_hier);
242  if (!selected_parser.resc_in_hier(name)) {
243  return ERROR(HIERARCHY_ERROR,
244  (boost::format(
245  "[%s] - Replicating a file object which does not exist in this hierarchy.") %
246  __FUNCTION__).str().c_str());
247  }
248  }
249 
250  _out_parser = selected_parser;
251  return SUCCESS();
252 }
253 
255  object_list_t object_list_to_repl{};
256  irods::error ret{_ctx.prop_map().get<object_list_t>(OBJECT_LIST_PROP, object_list_to_repl)};
257  if (!ret.ok() && KEY_NOT_FOUND != ret.code()) {
258  return PASS(ret);
259  }
260  if (object_list_to_repl.empty()) {
261  return SUCCESS();
262  }
263 
264  child_list_t child_list{};
265  ret = _ctx.prop_map().get<child_list_t>(CHILD_LIST_PROP, child_list);
266  if (!ret.ok()) {
267  return PASS(ret);
268  }
269  if (child_list.empty()) {
270  return SUCCESS();
271  }
272 
273  // get the root resource name as well as the child hierarchy string
274  irods::hierarchy_parser selected_parser{};
275  ret = get_selected_hierarchy(_ctx, selected_parser);
276  if (!ret.ok()) {
277  return PASS(ret);
278  }
279  std::string child{};
280  ret = selected_parser.str(child);
281  if (!ret.ok()) {
282  return PASSMSG(
283  (boost::format(
284  "[%s] - Failed to get the hierarchy string from the parser.") %
285  __FUNCTION__).str(), ret );
286  }
287  std::string root_resc{};
288  ret = selected_parser.first_resc(root_resc);
289  if (!ret.ok()) {
290  return PASSMSG(
291  (boost::format(
292  "[%s] - Failed to get the root resource from the parser.") %
293  __FUNCTION__).str(), ret );
294  }
295 
296  std::string name{};
297  ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, name);
298  if (!ret.ok()) {
299  return PASS(ret);
300  }
301 
302  irods::create_write_replicator oper_repl{root_resc, name, child};
303  irods::replicator replicator{&oper_repl};
304  ret = replicator.replicate(_ctx, child_list, object_list_to_repl);
305  if (!ret.ok()) {
306  return PASSMSG(
307  (boost::format(
308  "[%s] - Failed to replicate the create/write operation to the siblings.") %
309  __FUNCTION__).str(), ret );
310  }
311 
312  ret = _ctx.prop_map().set<object_list_t>(OBJECT_LIST_PROP, object_list_to_repl);
313  if (!ret.ok()) {
314  return PASS(ret);
315  }
316  return SUCCESS();
317 } // replicate_create_write_operation
318 
320 // Actual operations
321 
322 // Called after a new file is registered with the ICAT
324  irods::plugin_context& _ctx ) {
325  irods::error result = SUCCESS();
326  irods::error ret;
327  ret = replCheckParams< irods::file_object >( _ctx );
328  if ( ( result = ASSERT_PASS( ret, "Error checking passed paramters." ) ).ok() ) {
329 
330  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( _ctx.fco() );
332  parser.set_string( file_obj->resc_hier() );
333  irods::resource_ptr child;
334  ret = replGetNextRescInHier( parser, _ctx, child );
335  if ( ( result = ASSERT_PASS( ret, "Failed to get the next resource in hierarchy." ) ).ok() ) {
336  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_REGISTERED, _ctx.fco() );
337  result = ASSERT_PASS( ret, "Failed while calling child operation." );
338  }
339  }
340  return result;
341 }
342 
343 // Called when a file is unregistered from the ICAT
345  irods::plugin_context& _ctx ) {
346  irods::error result = SUCCESS();
347  irods::error ret;
348  ret = replCheckParams< irods::file_object >( _ctx );
349  if ( !ret.ok() ) {
350  std::stringstream msg;
351  msg << __FUNCTION__;
352  msg << " - Error found checking passed parameters.";
353  result = PASSMSG( msg.str(), ret );
354  }
355  else {
356  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
358  parser.set_string( file_obj->resc_hier() );
359  irods::resource_ptr child;
360  ret = replGetNextRescInHier( parser, _ctx, child );
361  if ( !ret.ok() ) {
362  std::stringstream msg;
363  msg << __FUNCTION__;
364  msg << " - Failed to get the next resource in hierarchy.";
365  result = PASSMSG( msg.str(), ret );
366  }
367  else {
368  ret = child->call( file_obj->comm(), irods::RESOURCE_OP_UNREGISTERED, file_obj ) ;
369  if ( !ret.ok() ) {
370  std::stringstream msg;
371  msg << __FUNCTION__;
372  msg << " - Failed while calling child operation.";
373  result = PASSMSG( msg.str(), ret );
374  }
375  }
376  }
377  return result;
378 }
379 
381  size_t num_repl{};
382  irods::error ret = _ctx.prop_map().get<size_t>(NUM_REPL_KW, num_repl);
383  if(!ret.ok()) {
384  return SUCCESS();
385  }
386 
387  child_list_t new_list{};
388  if(num_repl <= 1) {
389  ret = _ctx.prop_map().set<child_list_t>(CHILD_LIST_PROP, new_list);
390  if(!ret.ok()) {
391  return PASS(ret);
392  }
393  return SUCCESS();
394  }
395 
396  child_list_t child_list{};
397  ret = _ctx.prop_map().get<child_list_t>(CHILD_LIST_PROP, child_list);
398  if(!ret.ok()) {
399  return PASS(ret);
400  }
401 
402  // decrement num_repl by 1 to count first replica
403  num_repl--;
404 
405  if(num_repl < child_list.size()) {
406  bool pick_done{};
407  std::vector<size_t> picked_indicies{};
408  while(!pick_done) {
409  size_t rand_index{irods::getRandom<size_t>() % child_list.size()};
410  if(std::find(
411  picked_indicies.begin(),
412  picked_indicies.end(),
413  rand_index) == picked_indicies.end()) {
414  new_list.push_back(child_list[rand_index]);
415  picked_indicies.push_back(rand_index);
416  if(picked_indicies.size() >= num_repl) {
417  pick_done = true;
418  }
419  }
420  }
421 
422  // if we have an empty new_list, simply keep the old one
423  if(0 == new_list.size()) {
424  return SUCCESS();
425  }
426 
427  ret = _ctx.prop_map().set<child_list_t>(CHILD_LIST_PROP, new_list);
428  if(!ret.ok()) {
429  return PASS(ret);
430  }
431  }
432 
433  return SUCCESS();
434 
435 } // proc_child_list_for_create_policy
436 
438  irods::plugin_context& _ctx,
439  const std::string& operation) {
440  // Get selected hierarchy parser
441  irods::hierarchy_parser selected_parser{};
442  irods::error ret = get_selected_hierarchy(_ctx, selected_parser);
443  if (!ret.ok()) {
444  return PASS(ret);
445  }
446 
447  // Get hierarchy for current resource for use when resolving children
448  std::string name{};
449  ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, name);
450  if (!ret.ok()) {
451  return PASS(ret);
452  }
453  std::string current_resc_hier_str{};
454  ret = selected_parser.str(current_resc_hier_str, name);
455  if (!ret.ok()) {
456  return PASS(ret);
457  }
458 
459  // Get list of children for this resource
460  irods::resource_child_map* cmap_ref;
462  if (cmap_ref->empty()) {
463  rodsLog(LOG_NOTICE, "[%s] - child map empty - nothing to do", __FUNCTION__);
464  return SUCCESS();
465  }
466 
467  // Get current hostname for vote
468  char host_name_str[MAX_NAME_LEN];
469  if (gethostname(host_name_str, MAX_NAME_LEN) < 0) {
470  return ERROR(SYS_GET_HOSTNAME_ERR, "failed in gethostname");
471  }
472  const std::string host_name(host_name_str);
473 
474  // Loop over children and create a list of hierarchies to which objects will be replicated
475  float out_vote{};
476  child_list_t repl_vector{};
477  for (auto& entry : *cmap_ref) {
478  auto child{entry.second.second};
479  std::string child_name{};
480  ret = child->get_property<std::string>(irods::RESOURCE_NAME, child_name);
481  if (!ret.ok()) {
482  return PASS(ret);
483  }
484 
485  // Don't repl to the selected hier
486  if (selected_parser.resc_in_hier(child_name)) {
487  continue;
488  }
489 
490  // Resolve child and add to repl list based on vote
492  parser.set_string(current_resc_hier_str);
493  ret = child->call<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
494  _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), &operation, &host_name, &parser, &out_vote );
495  if (!ret.ok() && CHILD_NOT_FOUND != ret.code()) {
496  return PASSMSG((boost::format(
497  "[%s] - Failed calling redirect on the child \"%s\".") %
498  __FUNCTION__ % entry.first).str(), ret);
499  }
500  else if (out_vote > 0.0) {
501  repl_vector.push_back(parser);
502  }
503  }
504 
505  // add the resulting vector as a property of the resource
506  ret = _ctx.prop_map().set<child_list_t>(CHILD_LIST_PROP, repl_vector);
507  if (!ret.ok()) {
508  return PASS(ret);
509  }
510 
511  // Determine which children of the child list will receive replicas
512  if (irods::CREATE_OPERATION == operation) {
514  if (!ret.ok()) {
515  return PASS(ret);
516  }
517  }
518 
519  return SUCCESS();
520 } // create_replication_list
521 
522 // Called when a files entry is modified in the ICAT
524  // Make sure context is valid
525  irods::error ret{replCheckParams<irods::file_object>(_ctx)};
526  if (!ret.ok()) {
527  return PASS(ret);
528  }
529 
530  // Get next resource on which to call file_modified
531  irods::file_object_ptr file_obj{boost::dynamic_pointer_cast<irods::file_object>(_ctx.fco())};
533  parser.set_string(file_obj->resc_hier());
534  irods::resource_ptr child{};
535  ret = replGetNextRescInHier(parser, _ctx, child);
536  if (!ret.ok()) {
537  return PASS(ret);
538  }
539 
540  // Call file_modified on next resource in hierarchy
541  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() );
542  if (!ret.ok()) {
543  return PASS(ret);
544  }
545 
546  // If this resource is in PDMO subparser, the operation is for someone else
547  std::string name;
548  ret = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, name);
549  if (!ret.ok()) {
550  return PASS(ret);
551  }
552  irods::hierarchy_parser sub_parser{};
553  sub_parser.set_string(file_obj->in_pdmo());
554  if (sub_parser.resc_in_hier(name)) {
555  return SUCCESS();
556  }
557 
558  // Get operation type based on reason for opening the file
559  const auto open_type_str{getValByKey(&file_obj->cond_input(), OPEN_TYPE_KW)};
560  if (nullptr == open_type_str) {
562  (boost::format("[%s] - no OPEN_TYPE_KW value provided") %
563  __FUNCTION__).str());
564  return SUCCESS();
565  }
566 
567  std::string operation{};
568  try {
569  switch(std::stoi(open_type_str)) {
570  case CREATE_TYPE:
571  operation = irods::CREATE_OPERATION;
572  break;
573  case OPEN_FOR_WRITE_TYPE:
574  operation = irods::WRITE_OPERATION;
575  break;
576  default:
577  throw std::invalid_argument(open_type_str);
578  }
579  }
580  catch (const std::invalid_argument&) {
582  (boost::format("[%s] - invalid OPEN_TYPE_KW value provided:[%s]") %
583  __FUNCTION__ % open_type_str).str());
584  }
585 
586  // Create child list and list of operations to replicate - then, replicate
587  ret = create_replication_list(_ctx, operation);
588  if (!ret.ok()) {
589  return PASS(ret);
590  }
591  ret = replUpdateObjectAndOperProperties(_ctx, operation);
592  if (!ret.ok()) {
593  return PASS(ret);
594  }
596  if (!ret.ok()) {
597  return PASSMSG((boost::format(
598  "[%s] - Failed to replicate create/write operation for object: \"%s\".") %
599  __FUNCTION__ % file_obj->logical_path()).str(), ret);
600  }
601 
602  return SUCCESS();
603 } // repl_file_modified
604 
605 // =-=-=-=-=-=-=-
606 // interface for POSIX create
608  irods::plugin_context& _ctx ) {
609  irods::error result = SUCCESS();
610  irods::error ret;
611 
612  // get the list of objects that need to be replicated
613  object_list_t object_list;
614  ret = _ctx.prop_map().get<object_list_t>( OBJECT_LIST_PROP, object_list );
615 
616  ret = replCheckParams< irods::file_object >( _ctx );
617  if ( !ret.ok() ) {
618  result = PASSMSG( "repl_file_create - bad params.", ret );
619  }
620  else {
621  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
623  parser.set_string( file_obj->resc_hier() );
624  irods::resource_ptr child;
625  ret = replGetNextRescInHier( parser, _ctx, child );
626  if ( !ret.ok() ) {
627  std::stringstream msg;
628  msg << __FUNCTION__;
629  msg << " - Failed to get the next resource in hierarchy.";
630  result = PASSMSG( msg.str(), ret );
631  }
632  else {
633  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_CREATE, _ctx.fco() );
634  if ( !ret.ok() ) {
635  std::stringstream msg;
636  msg << __FUNCTION__;
637  msg << " - Failed while calling child operation.";
638  result = PASSMSG( msg.str(), ret );
639  }
640  }
641  }
642  return result;
643 } // repl_file_create
644 
645 // =-=-=-=-=-=-=-
646 // interface for POSIX Open
648  irods::plugin_context& _ctx ) {
649  irods::error result = SUCCESS();
650  irods::error ret;
651 
652  ret = replCheckParams< irods::file_object >( _ctx );
653  if ( !ret.ok() ) {
654  std::stringstream msg;
655  msg << __FUNCTION__;
656  msg << " - bad params.";
657  result = PASSMSG( msg.str(), ret );
658  }
659  else {
660  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( ( _ctx.fco() ) );
662  parser.set_string( file_obj->resc_hier() );
663  irods::resource_ptr child;
664  ret = replGetNextRescInHier( parser, _ctx, child );
665  if ( !ret.ok() ) {
666  std::stringstream msg;
667  msg << __FUNCTION__;
668  msg << " - Failed to get the next resource in hierarchy.";
669  result = PASSMSG( msg.str(), ret );
670  }
671  else {
672  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_OPEN, _ctx.fco() );
673  if ( !ret.ok() ) {
674  std::stringstream msg;
675  msg << __FUNCTION__;
676  msg << " - Failed while calling child operation.";
677  result = PASSMSG( msg.str(), ret );
678  }
679  }
680  }
681  return result;
682 } // repl_file_open
683 
684 // =-=-=-=-=-=-=-
685 // interface for POSIX Read
687  irods::plugin_context& _ctx,
688  void* _buf,
689  int _len ) {
690  irods::error result = SUCCESS();
691  irods::error ret;
692 
693  ret = replCheckParams< irods::file_object >( _ctx );
694  if ( !ret.ok() ) {
695  std::stringstream msg;
696  msg << __FUNCTION__;
697  msg << " - bad params.";
698  result = PASSMSG( msg.str(), ret );
699  }
700  else {
701  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( ( _ctx.fco() ) );
703  parser.set_string( file_obj->resc_hier() );
704  irods::resource_ptr child;
705  ret = replGetNextRescInHier( parser, _ctx, child );
706  if ( !ret.ok() ) {
707  std::stringstream msg;
708  msg << __FUNCTION__;
709  msg << " - Failed to get the next resource in hierarchy.";
710  result = PASSMSG( msg.str(), ret );
711  }
712  else {
713  ret = child->call<void*, int>( _ctx.comm(), irods::RESOURCE_OP_READ, _ctx.fco(), _buf, _len );
714  if ( !ret.ok() ) {
715  std::stringstream msg;
716  msg << __FUNCTION__;
717  msg << " - Failed while calling child operation.";
718  result = PASSMSG( msg.str(), ret );
719  }
720  else {
721  // have to return the actual code because it contains the number of bytes read
722  result = CODE( ret.code() );
723  }
724  }
725  }
726  return result;
727 } // repl_file_read
728 
729 // =-=-=-=-=-=-=-
730 // interface for POSIX Write
732  irods::plugin_context& _ctx,
733  void* _buf,
734  int _len ) {
735  irods::error result = SUCCESS();
736  irods::error ret;
737  // get the list of objects that need to be replicated
738  object_list_t object_list;
739  ret = _ctx.prop_map().get<object_list_t>( OBJECT_LIST_PROP, object_list );
740 
741  ret = replCheckParams< irods::file_object >( _ctx );
742  if ( !ret.ok() ) {
743  std::stringstream msg;
744  msg << __FUNCTION__;
745  msg << " - bad params.";
746  result = PASSMSG( msg.str(), ret );
747  }
748  else {
749  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( ( _ctx.fco() ) );
751  parser.set_string( file_obj->resc_hier() );
752  irods::resource_ptr child;
753  ret = replGetNextRescInHier( parser, _ctx, child );
754  if ( !ret.ok() ) {
755  std::stringstream msg;
756  msg << __FUNCTION__;
757  msg << " - Failed to get the next resource in hierarchy.";
758  result = PASSMSG( msg.str(), ret );
759  }
760  else {
761  ret = child->call<void*, int>( _ctx.comm(), irods::RESOURCE_OP_WRITE, _ctx.fco(), _buf, _len );
762  if ( !ret.ok() ) {
763  std::stringstream msg;
764  msg << __FUNCTION__;
765  msg << " - Failed while calling child operation.";
766  result = PASSMSG( msg.str(), ret );
767  }
768  else {
769  result = CODE( ret.code() );
770 
771  }
772  }
773  }
774  return result;
775 } // repl_file_write
776 
777 // =-=-=-=-=-=-=-
778 // interface for POSIX Close
780  irods::plugin_context& _ctx ) {
781  irods::error result = SUCCESS();
782  irods::error ret;
783  // get the list of objects that need to be replicated
784  object_list_t object_list;
785  ret = _ctx.prop_map().get<object_list_t>( OBJECT_LIST_PROP, object_list );
786 
787  ret = replCheckParams< irods::file_object >( _ctx );
788  if ( ( result = ASSERT_PASS( ret, "Bad params." ) ).ok() ) {
789 
790  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( _ctx.fco() );
792  parser.set_string( file_obj->resc_hier() );
793  irods::resource_ptr child;
794  ret = replGetNextRescInHier( parser, _ctx, child );
795  if ( ( result = ASSERT_PASS( ret, "Failed to get the next resource in hierarchy." ) ).ok() ) {
796 
797  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_CLOSE, _ctx.fco() );
798  result = ASSERT_PASS( ret, "Failed while calling child operation." );
799  }
800  }
801  return result;
802 
803 } // repl_file_close
804 
805 // =-=-=-=-=-=-=-
806 // interface for POSIX Unlink
808  irods::plugin_context& _ctx ) {
809  irods::error result = SUCCESS();
810  irods::error ret;
811 
812  ret = replCheckParams< irods::data_object >( _ctx );
813  if ( !ret.ok() ) {
814  std::stringstream msg;
815  msg << __FUNCTION__;
816  msg << " - bad params.";
817  result = PASSMSG( msg.str(), ret );
818  }
819  else {
820  irods::data_object_ptr data_obj = boost::dynamic_pointer_cast<irods::data_object >( _ctx.fco() );
822  parser.set_string( data_obj->resc_hier() );
823  irods::resource_ptr child;
824  ret = replGetNextRescInHier( parser, _ctx, child );
825  if ( !ret.ok() ) {
826  std::stringstream msg;
827  msg << __FUNCTION__;
828  msg << " - Failed to get the next resource in hierarchy.";
829  result = PASSMSG( msg.str(), ret );
830  }
831  else {
832  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_UNLINK, _ctx.fco() );
833  if ( !ret.ok() ) {
834  std::stringstream msg;
835  msg << __FUNCTION__;
836  msg << " - Failed while calling child operation.";
837  result = PASSMSG( msg.str(), ret );
838  }
839  else {
840  result = CODE( ret.code() );
841 
842  }
843  }
844  }
845  return result;
846 } // repl_file_unlink
847 
848 // =-=-=-=-=-=-=-
849 // interface for POSIX Stat
851  irods::plugin_context& _ctx,
852  struct stat* _statbuf ) {
853  irods::error result = SUCCESS();
854  irods::error ret;
855 
856  ret = replCheckParams< irods::data_object >( _ctx );
857  if ( !ret.ok() ) {
858  std::stringstream msg;
859  msg << __FUNCTION__;
860  msg << " - bad params.";
861  result = PASSMSG( msg.str(), ret );
862  }
863  else {
864  irods::data_object_ptr data_obj = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() );
866  parser.set_string( data_obj->resc_hier() );
867  irods::resource_ptr child;
868  ret = replGetNextRescInHier( parser, _ctx, child );
869  if ( !ret.ok() ) {
870  std::stringstream msg;
871  msg << __FUNCTION__;
872  msg << " - Failed to get the next resource in hierarchy.";
873  result = PASSMSG( msg.str(), ret );
874  }
875  else {
876  ret = child->call<struct stat*>( _ctx.comm(), irods::RESOURCE_OP_STAT, _ctx.fco(), _statbuf );
877  if ( !ret.ok() ) {
878  std::stringstream msg;
879  msg << __FUNCTION__;
880  msg << " - Failed while calling child operation.";
881  result = PASSMSG( msg.str(), ret );
882  }
883  else {
884  result = CODE( ret.code() );
885  }
886  }
887  }
888  return result;
889 } // repl_file_stat
890 
891 // =-=-=-=-=-=-=-
892 // interface for POSIX lseek
894  irods::plugin_context& _ctx,
895  long long _offset,
896  int _whence ) {
897  irods::error result = SUCCESS();
898  irods::error ret;
899 
900  ret = replCheckParams< irods::file_object >( _ctx );
901  if ( !ret.ok() ) {
902  std::stringstream msg;
903  msg << __FUNCTION__;
904  msg << " - bad params.";
905  result = PASSMSG( msg.str(), ret );
906  }
907  else {
908  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
910  parser.set_string( file_obj->resc_hier() );
911  irods::resource_ptr child;
912  ret = replGetNextRescInHier( parser, _ctx, child );
913  if ( !ret.ok() ) {
914  std::stringstream msg;
915  msg << __FUNCTION__;
916  msg << " - Failed to get the next resource in hierarchy.";
917  result = PASSMSG( msg.str(), ret );
918  }
919  else {
920  ret = child->call<long long, int>( _ctx.comm(), irods::RESOURCE_OP_LSEEK, _ctx.fco(), _offset, _whence );
921  if ( !ret.ok() ) {
922  std::stringstream msg;
923  msg << __FUNCTION__;
924  msg << " - Failed while calling child operation.";
925  result = PASSMSG( msg.str(), ret );
926  }
927  else {
928  result = CODE( ret.code() );
929  }
930  }
931  }
932  return result;
933 } // repl_file_lseek
934 
935 // =-=-=-=-=-=-=-
936 // interface for POSIX mkdir
938  irods::plugin_context& _ctx ) {
939  irods::error result = SUCCESS();
940  irods::error ret;
941 
942  ret = replCheckParams< irods::collection_object >( _ctx );
943  if ( !ret.ok() ) {
944  std::stringstream msg;
945  msg << __FUNCTION__;
946  msg << " - bad params.";
947  result = PASSMSG( msg.str(), ret );
948  }
949  else {
950  irods::collection_object_ptr collection_obj = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
952  parser.set_string( collection_obj->resc_hier() );
953  irods::resource_ptr child;
954  ret = replGetNextRescInHier( parser, _ctx, child );
955  if ( !ret.ok() ) {
956  std::stringstream msg;
957  msg << __FUNCTION__;
958  msg << " - Failed to get the next resource in hierarchy.";
959  result = PASSMSG( msg.str(), ret );
960  }
961  else {
962  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_MKDIR, _ctx.fco() );
963  if ( !ret.ok() ) {
964  std::stringstream msg;
965  msg << __FUNCTION__;
966  msg << " - Failed while calling child operation.";
967  result = PASSMSG( msg.str(), ret );
968  }
969  else {
970  result = CODE( ret.code() );
971  }
972  }
973  }
974  return result;
975 } // repl_file_mkdir
976 
977 // =-=-=-=-=-=-=-
978 // interface for POSIX mkdir
980  irods::plugin_context& _ctx ) {
981  irods::error result = SUCCESS();
982  irods::error ret;
983 
984  ret = replCheckParams< irods::collection_object >( _ctx );
985  if ( !ret.ok() ) {
986  std::stringstream msg;
987  msg << __FUNCTION__;
988  msg << " - bad params.";
989  result = PASSMSG( msg.str(), ret );
990  }
991  else {
992  irods::collection_object_ptr file_obj = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
994  parser.set_string( file_obj->resc_hier() );
995  irods::resource_ptr child;
996  ret = replGetNextRescInHier( parser, _ctx, child );
997  if ( !ret.ok() ) {
998  std::stringstream msg;
999  msg << __FUNCTION__;
1000  msg << " - Failed to get the next resource in hierarchy.";
1001  result = PASSMSG( msg.str(), ret );
1002  }
1003  else {
1004  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_RMDIR, _ctx.fco() );
1005  if ( !ret.ok() ) {
1006  std::stringstream msg;
1007  msg << __FUNCTION__;
1008  msg << " - Failed while calling child operation.";
1009  result = PASSMSG( msg.str(), ret );
1010  }
1011  else {
1012  result = CODE( ret.code() );
1013  }
1014  }
1015  }
1016  return result;
1017 } // repl_file_rmdir
1018 
1019 // =-=-=-=-=-=-=-
1020 // interface for POSIX opendir
1022  irods::plugin_context& _ctx ) {
1023  irods::error result = SUCCESS();
1024  irods::error ret;
1025 
1026  ret = replCheckParams< irods::collection_object >( _ctx );
1027  if ( !ret.ok() ) {
1028  std::stringstream msg;
1029  msg << __FUNCTION__;
1030  msg << " - bad params.";
1031  result = PASSMSG( msg.str(), ret );
1032  }
1033  else {
1034  irods::collection_object_ptr collection_obj = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1036  parser.set_string( collection_obj->resc_hier() );
1037  irods::resource_ptr child;
1038  ret = replGetNextRescInHier( parser, _ctx, child );
1039  if ( !ret.ok() ) {
1040  std::stringstream msg;
1041  msg << __FUNCTION__;
1042  msg << " - Failed to get the next resource in hierarchy.";
1043  result = PASSMSG( msg.str(), ret );
1044  }
1045  else {
1046  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_OPENDIR, _ctx.fco() );
1047  if ( !ret.ok() ) {
1048  std::stringstream msg;
1049  msg << __FUNCTION__;
1050  msg << " - Failed while calling child operation.";
1051  result = PASSMSG( msg.str(), ret );
1052  }
1053  else {
1054  result = CODE( ret.code() );
1055  }
1056  }
1057  }
1058  return result;
1059 } // repl_file_opendir
1060 
1061 // =-=-=-=-=-=-=-
1062 // interface for POSIX closedir
1064  irods::plugin_context& _ctx ) {
1065  irods::error result = SUCCESS();
1066  irods::error ret;
1067 
1068  ret = replCheckParams< irods::collection_object >( _ctx );
1069  if ( !ret.ok() ) {
1070  std::stringstream msg;
1071  msg << __FUNCTION__;
1072  msg << " - bad params.";
1073  result = PASSMSG( msg.str(), ret );
1074  }
1075  else {
1076  irods::collection_object_ptr collection_obj = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1078  parser.set_string( collection_obj->resc_hier() );
1079  irods::resource_ptr child;
1080  ret = replGetNextRescInHier( parser, _ctx, child );
1081  if ( !ret.ok() ) {
1082  std::stringstream msg;
1083  msg << __FUNCTION__;
1084  msg << " - Failed to get the next resource in hierarchy.";
1085  result = PASSMSG( msg.str(), ret );
1086  }
1087  else {
1088  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_CLOSEDIR, _ctx.fco() );
1089  if ( !ret.ok() ) {
1090  std::stringstream msg;
1091  msg << __FUNCTION__;
1092  msg << " - Failed while calling child operation.";
1093  result = PASSMSG( msg.str(), ret );
1094  }
1095  else {
1096  result = CODE( ret.code() );
1097  }
1098  }
1099  }
1100  return result;
1101 } // repl_file_closedir
1102 
1103 // =-=-=-=-=-=-=-
1104 // interface for POSIX readdir
1106  irods::plugin_context& _ctx,
1107  struct rodsDirent** _dirent_ptr ) {
1108  irods::error result = SUCCESS();
1109  irods::error ret;
1110 
1111  ret = replCheckParams< irods::collection_object >( _ctx );
1112  if ( !ret.ok() ) {
1113  std::stringstream msg;
1114  msg << __FUNCTION__;
1115  msg << " - bad params.";
1116  result = PASSMSG( msg.str(), ret );
1117  }
1118  else {
1119  irods::collection_object_ptr collection_obj = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() );
1121  parser.set_string( collection_obj->resc_hier() );
1122  irods::resource_ptr child;
1123  ret = replGetNextRescInHier( parser, _ctx, child );
1124  if ( !ret.ok() ) {
1125  std::stringstream msg;
1126  msg << __FUNCTION__;
1127  msg << " - Failed to get the next resource in hierarchy.";
1128  result = PASSMSG( msg.str(), ret );
1129  }
1130  else {
1131  ret = child->call<rodsDirent**>( _ctx.comm(), irods::RESOURCE_OP_READDIR, _ctx.fco(), _dirent_ptr );
1132  if ( !ret.ok() ) {
1133  std::stringstream msg;
1134  msg << __FUNCTION__;
1135  msg << " - Failed while calling child operation.";
1136  result = PASSMSG( msg.str(), ret );
1137  }
1138  else {
1139  result = CODE( ret.code() );
1140  }
1141  }
1142  }
1143  return result;
1144 } // repl_file_readdir
1145 
1146 // =-=-=-=-=-=-=-
1147 // interface for POSIX readdir
1149  irods::plugin_context& _ctx,
1150  const char* _new_file_name ) {
1151  irods::error result = SUCCESS();
1152  irods::error ret;
1153 
1154  ret = replCheckParams< irods::file_object >( _ctx );
1155  if ( !ret.ok() ) {
1156  std::stringstream msg;
1157  msg << __FUNCTION__;
1158  msg << " - bad params.";
1159  result = PASSMSG( msg.str(), ret );
1160  }
1161  else {
1162  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1164  parser.set_string( file_obj->resc_hier() );
1165  irods::resource_ptr child;
1166  ret = replGetNextRescInHier( parser, _ctx, child );
1167  if ( !ret.ok() ) {
1168  std::stringstream msg;
1169  msg << __FUNCTION__;
1170  msg << " - Failed to get the next resource in hierarchy.";
1171  result = PASSMSG( msg.str(), ret );
1172  }
1173  else {
1174  ret = child->call<const char*>( _ctx.comm(), irods::RESOURCE_OP_RENAME, _ctx.fco(), _new_file_name );
1175  if ( !ret.ok() ) {
1176  std::stringstream msg;
1177  msg << __FUNCTION__;
1178  msg << " - Failed while calling child operation.";
1179  result = PASSMSG( msg.str(), ret );
1180  }
1181  else {
1182  result = CODE( ret.code() );
1183  }
1184  }
1185  }
1186  return result;
1187 } // repl_file_rename
1188 
1189 // =-=-=-=-=-=-=-
1190 // interface for POSIX truncate
1192  irods::plugin_context& _ctx ) {
1193  // =-=-=-=-=-=-=-
1194  irods::error result = SUCCESS();
1195  irods::error ret;
1196 
1197  ret = replCheckParams<irods::file_object>( _ctx );
1198  if ( !ret.ok() ) {
1199  std::stringstream msg;
1200  msg << __FUNCTION__;
1201  msg << " - bad params.";
1202  result = PASSMSG( msg.str(), ret );
1203  }
1204  else {
1205  irods::file_object_ptr ptr = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1207  parser.set_string( ptr->resc_hier() );
1208  irods::resource_ptr child;
1209  ret = replGetNextRescInHier( parser, _ctx, child );
1210  if ( !ret.ok() ) {
1211  std::stringstream msg;
1212  msg << __FUNCTION__;
1213  msg << " - Failed to get the next resource in hierarchy.";
1214  result = PASSMSG( msg.str(), ret );
1215  }
1216  else {
1217  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_TRUNCATE, _ctx.fco() );
1218  if ( !ret.ok() ) {
1219  std::stringstream msg;
1220  msg << __FUNCTION__;
1221  msg << " - Failed while calling child operation.";
1222  result = PASSMSG( msg.str(), ret );
1223  }
1224  else {
1225  result = CODE( ret.code() );
1226  }
1227  }
1228  }
1229  return result;
1230 } // repl_file_truncate
1231 
1232 // =-=-=-=-=-=-=-
1233 // interface to determine free space on a device given a path
1235  irods::plugin_context& _ctx ) {
1236  irods::error result = SUCCESS();
1237  irods::error ret;
1238 
1239  ret = replCheckParams< irods::file_object >( _ctx );
1240  if ( !ret.ok() ) {
1241  std::stringstream msg;
1242  msg << __FUNCTION__;
1243  msg << " - bad params.";
1244  result = PASSMSG( msg.str(), ret );
1245  }
1246  else {
1247  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1249  parser.set_string( file_obj->resc_hier() );
1250  irods::resource_ptr child;
1251  ret = replGetNextRescInHier( parser, _ctx, child );
1252  if ( !ret.ok() ) {
1253  std::stringstream msg;
1254  msg << __FUNCTION__;
1255  msg << " - Failed to get the next resource in hierarchy.";
1256  result = PASSMSG( msg.str(), ret );
1257  }
1258  else {
1259  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_FREESPACE, _ctx.fco() );
1260  if ( !ret.ok() ) {
1261  std::stringstream msg;
1262  msg << __FUNCTION__;
1263  msg << " - Failed while calling child operation.";
1264  result = PASSMSG( msg.str(), ret );
1265  }
1266  else {
1267  result = CODE( ret.code() );
1268  }
1269  }
1270  }
1271  return result;
1272 } // repl_file_getfs_freespace
1273 
1274 // =-=-=-=-=-=-=-
1275 // repl_file_stage_to_cache - This routine is for testing the TEST_STAGE_FILE_TYPE.
1276 // Just copy the file from filename to cacheFilename. optionalInfo info
1277 // is not used.
1279  irods::plugin_context& _ctx,
1280  const char* _cache_file_name ) {
1281  irods::error result = SUCCESS();
1282  irods::error ret;
1283 
1284  ret = replCheckParams< irods::file_object >( _ctx );
1285  if ( !ret.ok() ) {
1286  std::stringstream msg;
1287  msg << __FUNCTION__;
1288  msg << " - bad params.";
1289  result = PASSMSG( msg.str(), ret );
1290  }
1291  else {
1292  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1294  parser.set_string( file_obj->resc_hier() );
1295  irods::resource_ptr child;
1296  ret = replGetNextRescInHier( parser, _ctx, child );
1297  if ( !ret.ok() ) {
1298  std::stringstream msg;
1299  msg << __FUNCTION__;
1300  msg << " - Failed to get the next resource in hierarchy.";
1301  result = PASSMSG( msg.str(), ret );
1302  }
1303  else {
1304  ret = child->call< const char* >(
1305  _ctx.comm(),
1307  _ctx.fco(),
1308  _cache_file_name );
1309  if ( !ret.ok() ) {
1310  std::stringstream msg;
1311  msg << __FUNCTION__;
1312  msg << " - Failed while calling child operation.";
1313  result = PASSMSG( msg.str(), ret );
1314  }
1315  }
1316  }
1317  return result;
1318 } // repl_file_stage_to_cache
1319 
1320 // =-=-=-=-=-=-=-
1321 // repl_file_sync_to_arch - This routine is for testing the TEST_STAGE_FILE_TYPE.
1322 // Just copy the file from cacheFilename to filename. optionalInfo info
1323 // is not used.
1325  irods::plugin_context& _ctx,
1326  const char* _cache_file_name ) {
1327  irods::error result = SUCCESS();
1328  irods::error ret;
1329 
1330  ret = replCheckParams< irods::file_object >( _ctx );
1331  if ( !ret.ok() ) {
1332  std::stringstream msg;
1333  msg << __FUNCTION__;
1334  msg << " - bad params.";
1335  result = PASSMSG( msg.str(), ret );
1336  }
1337  else {
1338  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
1340  parser.set_string( file_obj->resc_hier() );
1341  irods::resource_ptr child;
1342  ret = replGetNextRescInHier( parser, _ctx, child );
1343  if ( !ret.ok() ) {
1344  std::stringstream msg;
1345  msg << __FUNCTION__;
1346  msg << " - Failed to get the next resource in hierarchy.";
1347  result = PASSMSG( msg.str(), ret );
1348  }
1349  else {
1350  ret = child->call<const char*>( _ctx.comm(), irods::RESOURCE_OP_SYNCTOARCH, _ctx.fco(), _cache_file_name );
1351  if ( !ret.ok() ) {
1352  std::stringstream msg;
1353  msg << __FUNCTION__;
1354  msg << " - Failed while calling child operation.";
1355  result = PASSMSG( msg.str(), ret );
1356  }
1357  else {
1358  result = CODE( ret.code() );
1359  }
1360  }
1361  }
1362  return result;
1363 } // repl_file_sync_to_arch
1364 
1367  irods::plugin_context& _ctx,
1368  irods::hierarchy_parser& _parser ) {
1369  std::string name;
1370  auto ret{_ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, name)};
1371  if (!ret.ok()) {
1372  return PASS(ret);
1373  }
1374  ret = _parser.add_child(name);
1375  if (!ret.ok()) {
1376  return PASS(ret);
1377  }
1378  return SUCCESS();
1379 } // add_self_to_hierarchy
1380 
1383  irods::plugin_context& _ctx,
1384  const std::string* _operation,
1385  const std::string* _curr_host,
1386  irods::hierarchy_parser& _parser,
1387  redirect_map_t& _redirect_map ) {
1388 
1389  irods::resource_child_map* cmap_ref;
1391 
1392  float out_vote{};
1393  for (auto& entry : *cmap_ref) {
1394  auto parser{_parser};
1395  const auto ret{entry.second.second->call<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1396  _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _operation, _curr_host, &parser, &out_vote)};
1397  if (!ret.ok() && CHILD_NOT_FOUND != ret.code()) {
1398  return PASSMSG((boost::format(
1399  "[%s] - Failed calling redirect on the child \"%s\".") %
1400  __FUNCTION__ % entry.first).str(), ret);
1401  }
1402  else {
1403  _redirect_map.insert(std::pair<float, irods::hierarchy_parser>(out_vote, parser));
1404  }
1405  }
1406  return SUCCESS();
1407 } // resolve_children
1408 
1411  const redirect_map_t& _redirect_map,
1412  irods::hierarchy_parser* _out_parser,
1413  float* _out_vote ) {
1414 
1415  std::vector<std::pair<float, irods::hierarchy_parser>> items;
1416  redirect_map_t::const_iterator itr = _redirect_map.cbegin();
1417  for( ; itr != _redirect_map.cend(); ++itr ) {
1418  if(itr->first > 0) {
1419  items.push_back(std::make_pair(itr->first, itr->second));
1420  }
1421  }
1422 
1423  size_t rand_index = irods::getRandom<size_t>() % items.size();
1424  std::vector<std::pair<float, irods::hierarchy_parser>>::iterator a_itr = items.begin();
1425  std::advance(a_itr, rand_index);
1426  *_out_vote = a_itr->first;
1427  *_out_parser = a_itr->second;
1428 
1429  return SUCCESS();
1430 } // process_redirect_map_for_random_open
1431 
1434  irods::plugin_context& _ctx,
1435  const std::string& _operation,
1436  const redirect_map_t& _redirect_map,
1437  irods::hierarchy_parser* _out_parser,
1438  float* _out_vote ) {
1439  (*_out_vote) = 0.0;
1440  if (_redirect_map.empty()) {
1441  // there are no votes to consider
1442  return SUCCESS();
1443  }
1444 
1445  // Enact read policy if specified
1446  if (irods::OPEN_OPERATION == _operation) {
1447  std::string read_policy{};
1448  auto ret{_ctx.prop_map().get<std::string>(READ_KW, read_policy)};
1449  if (ret.ok() && READ_RANDOM_POLICY == read_policy) {
1450  ret = process_redirect_map_for_random_open(_redirect_map, _out_parser, _out_vote);
1451  if (!ret.ok()) {
1452  return PASS(ret);
1453  }
1454  return SUCCESS();
1455  }
1456  }
1457 
1458  // Select hierarchy and store vote value
1459  const auto& it{_redirect_map.begin()};
1460  const auto& vote{it->first};
1461  const auto& parser{it->second};
1462  *_out_parser = parser;
1463  *_out_vote = vote;
1464  return SUCCESS();
1465 } // select_child
1466 
1469  irods::plugin_context& _ctx,
1470  const std::string* _operation,
1471  const std::string* _curr_host,
1472  irods::hierarchy_parser* _inout_parser,
1473  float* _out_vote ) {
1474  if (nullptr == _operation || nullptr == _curr_host || nullptr == _inout_parser || nullptr == _out_vote) {
1476  (boost::format(
1477  "[%s]: null parameters passed to redirect") %
1478  __FUNCTION__).str().c_str() );
1479  }
1480 
1481  // add ourselves to the hierarchy parser
1482  auto ret{add_self_to_hierarchy(_ctx, *_inout_parser)};
1483  if (!ret.ok()) {
1484  return PASS(ret);
1485  }
1486 
1487  // Resolve each one of our children and put into redirect_map
1488  redirect_map_t redirect_map;
1489  ret = resolve_children(_ctx, _operation, _curr_host, *_inout_parser, redirect_map);
1490  if (!ret.ok()) {
1491  return PASS(ret);
1492  }
1493 
1494  // Select a resolved hierarchy from redirect_map for the operation
1495  ret = select_child(_ctx, *_operation, redirect_map, _inout_parser, _out_vote);
1496  if (!ret.ok()) {
1497  return PASS(ret);
1498  }
1499 
1500  return SUCCESS();
1501 } // repl_file_resolve_hierarchy
1502 
1504  irods::resource_child_map *cmap_ptr;
1506  for (auto& entry : *cmap_ptr) {
1507  irods::error ret = entry.second.second->call(_ctx.comm(), irods::RESOURCE_OP_REBALANCE, _ctx.fco() );
1508  if (!ret.ok()) {
1509  return PASS(ret);
1510  }
1511  }
1512  return SUCCESS();
1513 }
1514 
1515 // throws irods::exception
1517  if (!_ctx.rule_results().empty()) {
1518  irods::kvp_map_t kvp;
1519  irods::error kvp_err = irods::parse_kvp_string(_ctx.rule_results(), kvp);
1520  if (!kvp_err.ok()) {
1521  THROW(kvp_err.code(), kvp_err.result());
1522  }
1523 
1524  const auto it = kvp.find(irods::REPL_LIMIT_KEY);
1525  if (it != kvp.end()) {
1526  try {
1527  return boost::lexical_cast<int>(it->second);
1528  } catch (const boost::bad_lexical_cast&) {
1529  THROW(SYS_INVALID_INPUT_PARAM, boost::format("failed to cast string [%s] to integer") % it->second);
1530  }
1531  }
1532  }
1534 }
1535 
1536 // repl_file_rebalance - code which would rebalance the subtree
1538  irods::plugin_context& _ctx ) {
1540  if (!result.ok()) {
1541  return PASS(result);
1542  }
1543 
1544  // get invocation timestamp
1545  // only replicas at rest prior to this invocation timestamp will be rebalanced
1546  // prevents race condition of new/inflight data being 'over'-rebalanced
1547  char invocation_timestamp[50];
1548  getNowStr(invocation_timestamp);
1549 
1550  std::string resource_name;
1551  result = _ctx.prop_map().get<std::string>(irods::RESOURCE_NAME, resource_name);
1552  if (!result.ok()) {
1553  return PASS(result);
1554  }
1555 
1556  try {
1557  const int batch_size = get_rebalance_batch_size(_ctx);
1558  const std::vector<leaf_bundle_t> leaf_bundles = resc_mgr.gather_leaf_bundles_for_resc(resource_name);
1559  irods::update_out_of_date_replicas(_ctx, leaf_bundles, batch_size, invocation_timestamp, resource_name);
1560  irods::create_missing_replicas(_ctx, leaf_bundles, batch_size, invocation_timestamp, resource_name);
1561  } catch (const irods::exception& e) {
1562  return irods::error(e);
1563  }
1564  return SUCCESS();
1565 }
1566 
1567 // Called when a files entry is modified in the ICAT
1569  irods::plugin_context& _ctx,
1570  const std::string* _opr ) {
1571  irods::error result = SUCCESS();
1572  irods::error ret = replCheckParams< irods::file_object >( _ctx );
1573  if ( !ret.ok() ) {
1574  std::stringstream msg;
1575  msg << __FUNCTION__;
1576  msg << " - bad params.";
1577  result = PASSMSG( msg.str(), ret );
1578  }
1579  else {
1580  irods::file_object_ptr file_obj = boost::dynamic_pointer_cast<irods::file_object >( ( _ctx.fco() ) );
1582  parser.set_string( file_obj->resc_hier() );
1583  irods::resource_ptr child;
1584  ret = replGetNextRescInHier( parser, _ctx, child );
1585  if ( !ret.ok() ) {
1586  std::stringstream msg;
1587  msg << __FUNCTION__;
1588  msg << " - Failed to get the next resource in hierarchy.";
1589  result = PASSMSG( msg.str(), ret );
1590  }
1591  else {
1592  ret = child->call( _ctx.comm(), irods::RESOURCE_OP_NOTIFY, _ctx.fco(), _opr );
1593  if ( !ret.ok() ) {
1594  std::stringstream msg;
1595  msg << __FUNCTION__;
1596  msg << " - Failed while calling child operation.";
1597  result = PASSMSG( msg.str(), ret );
1598  }
1599  }
1600  }
1601  return result;
1602 }
1603 
1604 // =-=-=-=-=-=-=-
1605 // 3. create derived class to handle unix file system resources
1606 // necessary to do custom parsing of the context string to place
1607 // any useful values into the property map for reference in later
1608 // operations. semicolon is the preferred delimiter
1610 
1611  public:
1613  const std::string& _inst_name,
1614  const std::string& _context ) :
1615  irods::resource(
1616  _inst_name,
1617  _context ) {
1618 
1619  if ( _context.empty() ) {
1620  // Retry capability requires default values to be used if not set
1624  return;
1625  }
1626 
1627  irods::kvp_map_t kvp_map;
1628  irods::error ret = irods::parse_kvp_string( _context, kvp_map );
1629  if ( !ret.ok() ) {
1630  irods::log( PASS( ret ) );
1631  }
1632 
1633  if ( kvp_map.find( NUM_REPL_KW ) != kvp_map.end() ) {
1635  (boost::format(
1636  "[%s] - resource [%s] is using deprecated context string [%s]") %
1637  __FUNCTION__ %
1638  _inst_name %
1639  NUM_REPL_KW).str());
1640  try {
1641  int num_repl = boost::lexical_cast< int >( kvp_map[ NUM_REPL_KW ] );
1642  if( num_repl <= 0 ) {
1644  boost::format(
1645  "[%s] - [%s] for resource [%s] is 0" ) %
1646  __FUNCTION__ %
1647  NUM_REPL_KW %
1648  _inst_name) );
1649  }
1650  else {
1651  properties_.set< size_t >( NUM_REPL_KW, static_cast< size_t >( num_repl ) );
1652  }
1653  }
1654  catch ( const boost::bad_lexical_cast& ) {
1656  boost::format(
1657  "[%s] - failed to cast [%s] for resource [%s] to value [%s]") %
1658  __FUNCTION__ %
1659  NUM_REPL_KW %
1660  _inst_name %
1661  kvp_map[ NUM_REPL_KW ] ) );
1662  }
1663  }
1664 
1665  auto retry_attempts = irods::DEFAULT_RETRY_ATTEMPTS;
1666  if ( kvp_map.find( irods::RETRY_ATTEMPTS_KW ) != kvp_map.end() ) {
1667  try {
1668  // boost::lexical_cast does not raise errors on negatives when casting to unsigned
1669  const int int_retry_attempts = boost::lexical_cast< int >( kvp_map[ irods::RETRY_ATTEMPTS_KW ] );
1670  if ( int_retry_attempts < 0 ) {
1672  boost::format(
1673  "[%s] - [%s] for resource [%s] is < 0; using default value [%d]" ) %
1674  __FUNCTION__ %
1675  _inst_name %
1676  irods::RETRY_ATTEMPTS_KW.c_str() %
1678  }
1679  else {
1680  retry_attempts = static_cast< decltype( retry_attempts ) >( int_retry_attempts );
1681  }
1682  }
1683  catch ( const boost::bad_lexical_cast& ) {
1685  boost::format(
1686  "[%s] - failed to cast [%s] for resource [%s] to value [%s]; using default value [%d]") %
1687  __FUNCTION__ %
1689  _inst_name %
1690  kvp_map[ irods::RETRY_ATTEMPTS_KW ] %
1692  }
1693  }
1694  properties_.set< decltype( retry_attempts ) >( irods::RETRY_ATTEMPTS_KW, retry_attempts );
1695 
1696  auto retry_delay_in_seconds = irods::DEFAULT_RETRY_FIRST_DELAY_IN_SECONDS;
1697  if ( kvp_map.find( irods::RETRY_FIRST_DELAY_IN_SECONDS_KW ) != kvp_map.end() ) {
1698  try {
1699  // boost::lexical_cast does not raise errors on negatives when casting to unsigned
1700  const int int_retry_delay = boost::lexical_cast< int >( kvp_map[ irods::RETRY_FIRST_DELAY_IN_SECONDS_KW ] );
1701  if ( int_retry_delay <= 0 ) {
1703  boost::format(
1704  "[%s] - [%s] for resource [%s] is <= 0; using default value [%d]" ) %
1705  __FUNCTION__ %
1706  _inst_name %
1709  }
1710  else {
1711  retry_delay_in_seconds = static_cast< decltype( retry_delay_in_seconds ) >( int_retry_delay );
1712  }
1713  }
1714  catch ( const boost::bad_lexical_cast& ) {
1716  boost::format(
1717  "[%s] - failed to cast [%s] for resource [%s] to value [%s]; using default value [%d]") %
1718  __FUNCTION__ %
1720  _inst_name %
1723  }
1724  }
1725  properties_.set< decltype( retry_delay_in_seconds ) >( irods::RETRY_FIRST_DELAY_IN_SECONDS_KW, retry_delay_in_seconds );
1726 
1727  auto backoff_multiplier = irods::DEFAULT_RETRY_BACKOFF_MULTIPLIER;
1728  if ( kvp_map.find( irods::RETRY_BACKOFF_MULTIPLIER_KW ) != kvp_map.end() ) {
1729  try {
1730  backoff_multiplier = boost::lexical_cast< decltype( backoff_multiplier ) >( kvp_map[ irods::RETRY_BACKOFF_MULTIPLIER_KW ] );
1731  if ( backoff_multiplier < 1 ) {
1733  boost::format(
1734  "[%s] - [%s] for resource [%s] is < 1; using default value [%d]" ) %
1735  __FUNCTION__ %
1736  _inst_name %
1739  backoff_multiplier = irods::DEFAULT_RETRY_BACKOFF_MULTIPLIER;
1740  }
1741  }
1742  catch ( const boost::bad_lexical_cast& ) {
1744  boost::format(
1745  "[%s] - failed to cast [%s] for resource [%s] to value [%s]; using default value [%d]") %
1746  __FUNCTION__ %
1748  _inst_name %
1751  }
1752  }
1753  properties_.set< decltype( backoff_multiplier ) >( irods::RETRY_BACKOFF_MULTIPLIER_KW, backoff_multiplier );
1754 
1755  if ( kvp_map.find( READ_KW ) != kvp_map.end() ) {
1756  properties_.set< std::string >( READ_KW, kvp_map[ READ_KW ] );
1757  }
1758  } // ctor
1759 
1761  irods::pdmo_type& ) {
1762  irods::error result = SUCCESS();
1763  // nothing to do
1764  return result;
1765  }
1766 
1768  bool& _flag ) {
1769  irods::error result = SUCCESS();
1770  _flag = false;
1771  return result;
1772  }
1773 
1774 }; // class repl_resource
1775 
1776 // =-=-=-=-=-=-=-
1777 // 4. create the plugin factory function which will return a dynamically
1778 // instantiated object of the previously defined derived resource. use
1779 // the add_operation member to associate a 'call name' to the interfaces
1780 // defined above. for resource plugins these call names are standardized
1781 // as used by the irods facing interface defined in
1782 // server/drivers/src/fileDriver.c
1783 extern "C"
1784 irods::resource* plugin_factory( const std::string& _inst_name, const std::string& _context ) {
1785 
1786  // =-=-=-=-=-=-=-
1787  // 4a. create repl_resource
1788  repl_resource* resc = new repl_resource( _inst_name, _context );
1789 
1790  // =-=-=-=-=-=-=-
1791  // 4b. map function names to operations. this map will be used to load
1792  // the symbols from the shared object in the delay_load stage of
1793  // plugin loading.
1794  using namespace irods;
1795  using namespace std;
1796  resc->add_operation(
1798  function<error(plugin_context&)>(
1799  repl_file_create ) );
1800 
1801  resc->add_operation(
1803  function<error(plugin_context&)>(
1804  repl_file_open ) );
1805 
1806  resc->add_operation<void*,int>(
1808  std::function<
1809  error(irods::plugin_context&,void*,int)>(
1810  repl_file_read ) );
1811 
1812  resc->add_operation<void*,int>(
1814  function<error(plugin_context&,void*,int)>(
1815  repl_file_write ) );
1816 
1817  resc->add_operation(
1819  function<error(plugin_context&)>(
1820  repl_file_close ) );
1821 
1822  resc->add_operation(
1824  function<error(plugin_context&)>(
1825  repl_file_unlink ) );
1826 
1827  resc->add_operation<struct stat*>(
1829  function<error(plugin_context&, struct stat*)>(
1830  repl_file_stat ) );
1831 
1832  resc->add_operation(
1834  function<error(plugin_context&)>(
1835  repl_file_mkdir ) );
1836 
1837  resc->add_operation(
1839  function<error(plugin_context&)>(
1840  repl_file_opendir ) );
1841 
1842  resc->add_operation<struct rodsDirent**>(
1844  function<error(plugin_context&,struct rodsDirent**)>(
1845  repl_file_readdir ) );
1846 
1847  resc->add_operation<const char*>(
1849  function<error(plugin_context&, const char*)>(
1850  repl_file_rename ) );
1851 
1852  resc->add_operation(
1854  function<error(plugin_context&)>(
1856 
1857  resc->add_operation<long long, int>(
1859  function<error(plugin_context&, long long, int)>(
1860  repl_file_lseek ) );
1861 
1862  resc->add_operation(
1864  function<error(plugin_context&)>(
1865  repl_file_rmdir ) );
1866 
1867  resc->add_operation(
1869  function<error(plugin_context&)>(
1870  repl_file_closedir ) );
1871 
1872  resc->add_operation<const char*>(
1874  function<error(plugin_context&, const char*)>(
1876 
1877  resc->add_operation<const char*>(
1879  function<error(plugin_context&, const char*)>(
1881 
1882  resc->add_operation(
1884  function<error(plugin_context&)>(
1886 
1887  resc->add_operation(
1889  function<error(plugin_context&)>(
1891 
1892  resc->add_operation(
1894  function<error(plugin_context&)>(
1895  repl_file_modified ) );
1896 
1897  resc->add_operation<const std::string*>(
1899  function<error(plugin_context&, const std::string*)>(
1900  repl_file_notify ) );
1901 
1902  resc->add_operation(
1904  function<error(plugin_context&)>(
1905  repl_file_truncate ) );
1906 
1907  resc->add_operation<const std::string*, const std::string*, irods::hierarchy_parser*, float*>(
1909  function<error(plugin_context&,const std::string*, const std::string*, irods::hierarchy_parser*, float*)>(
1911 
1912  resc->add_operation(
1914  function<error(plugin_context&)>(
1915  repl_file_rebalance ) );
1916 
1917  // =-=-=-=-=-=-=-
1918  // set some properties necessary for backporting to iRODS legacy code
1919  resc->set_property< int >( irods::RESOURCE_CHECK_PATH_PERM, 2 );//DO_CHK_PATH_PERM );
1920  resc->set_property< int >( irods::RESOURCE_CREATE_PATH, 1 );//CREATE_PATH );
1921 
1922  // =-=-=-=-=-=-=-
1923  // 4c. return the pointer through the generic interface of an
1924  // irods::resource pointer
1925  return dynamic_cast<irods::resource*>( resc );
1926 
1927 } // 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
repl_file_registered
irods::error repl_file_registered(irods::plugin_context &_ctx)
Definition: librepl.cpp:323
resolve_children
irods::error resolve_children(irods::plugin_context &_ctx, const std::string *_operation, const std::string *_curr_host, irods::hierarchy_parser &_parser, redirect_map_t &_redirect_map)
Definition: librepl.cpp:1382
L1desc
l1desc_t L1desc[1026]
Definition: irods_server_globals.cpp:29
repl_file_open
irods::error repl_file_open(irods::plugin_context &_ctx)
Definition: librepl.cpp:647
READ_RANDOM_POLICY
const std::string READ_RANDOM_POLICY("random")
repl_file_opendir
irods::error repl_file_opendir(irods::plugin_context &_ctx)
Definition: librepl.cpp:1021
SYS_INTERNAL_NULL_INPUT_ERR
@ SYS_INTERNAL_NULL_INPUT_ERR
Definition: rodsErrorTable.h:92
irods::lookup_table< std::pair< std::string, resource_ptr > >
irods::RESOURCE_NAME
const std::string RESOURCE_NAME("resource_property_name")
THROW
#define THROW(_code, _msg)
Definition: irods_exception.hpp:68
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
msParam.h
repl_file_mkdir
irods::error repl_file_mkdir(irods::plugin_context &_ctx)
Definition: librepl.cpp:937
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
irods::resource
Definition: irods_resource_plugin.hpp:25
repl_file_getfs_freespace
irods::error repl_file_getfs_freespace(irods::plugin_context &_ctx)
Definition: librepl.cpp:1234
irods::RESOURCE_CHECK_PATH_PERM
const std::string RESOURCE_CHECK_PATH_PERM("resource_property_check_path_perm")
irods_plugin_base.hpp
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
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
READ_KW
const std::string READ_KW("read")
repl_resource::repl_resource
repl_resource(const std::string &_inst_name, const std::string &_context)
Definition: librepl.cpp:1612
CHILD_LIST_PROP
const std::string CHILD_LIST_PROP
Definition: irods_repl_types.hpp:27
irods::data_object_ptr
boost::shared_ptr< data_object > data_object_ptr
Definition: irods_data_object.hpp:17
DEFAULT_REBALANCE_BATCH_SIZE
const int DEFAULT_REBALANCE_BATCH_SIZE
Definition: librepl.cpp:99
select_child
irods::error select_child(irods::plugin_context &_ctx, const std::string &_operation, const redirect_map_t &_redirect_map, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: librepl.cpp:1433
irods_collection_object.hpp
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
LOG_WARNING
#define LOG_WARNING
Definition: rodsLog.h:38
create_replication_list
irods::error create_replication_list(irods::plugin_context &_ctx, const std::string &operation)
Definition: librepl.cpp:437
repl_file_close
irods::error repl_file_close(irods::plugin_context &_ctx)
Definition: librepl.cpp:779
irods_exception.hpp
irods::RESOURCE_OP_RESOLVE_RESC_HIER
const std::string RESOURCE_OP_RESOLVE_RESC_HIER("resource_resolve_hierarchy")
irods::RESOURCE_OP_READDIR
const std::string RESOURCE_OP_READDIR("resource_readdir")
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
irods::collection_object_ptr
boost::shared_ptr< collection_object > collection_object_ptr
Definition: irods_collection_object.hpp:85
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_backport.hpp
irods::RESOURCE_OP_LSEEK
const std::string RESOURCE_OP_LSEEK("resource_lseek")
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
getNowStr
void getNowStr(char *timeStr)
Definition: rcMisc.cpp:1590
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
irods::RETRY_BACKOFF_MULTIPLIER_KW
const std::string RETRY_BACKOFF_MULTIPLIER_KW
Definition: irods_repl_retry.hpp:16
irods::plugin_context
Definition: irods_plugin_context.hpp:18
repl_file_closedir
irods::error repl_file_closedir(irods::plugin_context &_ctx)
Definition: librepl.cpp:1063
generate_iadmin_commands_for_41_to_42_upgrade.name
name
Definition: generate_iadmin_commands_for_41_to_42_upgrade.py:23
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::plugin_base::set_property
error set_property(const std::string &_key, const T &_val)
Definition: irods_plugin_base.hpp:304
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
irods_object_oper.hpp
NUM_REPL_KW
const std::string NUM_REPL_KW("num_repl")
repl_file_rebalance
irods::error repl_file_rebalance(irods::plugin_context &_ctx)
Definition: librepl.cpp:1537
repl_resource
Definition: librepl.cpp:1609
CREATE_TYPE
#define CREATE_TYPE
Definition: dataObjInpOut.h:193
irods::create_write_replicator
Definition: irods_create_write_replicator.hpp:12
repl_file_truncate
irods::error repl_file_truncate(irods::plugin_context &_ctx)
Definition: librepl.cpp:1191
ASSERT_ERROR
#define ASSERT_ERROR(expr_, code_, format_,...)
Definition: irods_error.hpp:123
irods::REPL_LIMIT_KEY
const std::string REPL_LIMIT_KEY("replication_rebalance_limit")
redirect_map_t
std::multimap< float, irods::hierarchy_parser, child_comp > redirect_map_t
Definition: irods_repl_types.hpp:24
irods_resource_plugin.hpp
get_selected_hierarchy
irods::error get_selected_hierarchy(irods::plugin_context &_ctx, irods::hierarchy_parser &_out_parser)
Definition: librepl.cpp:206
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
INVALID_OPERATION
@ INVALID_OPERATION
Definition: rodsErrorTable.h:760
irods::plugin_context::comm
virtual rsComm_t * comm()
Definition: irods_plugin_context.hpp:95
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")
repl_file_readdir
irods::error repl_file_readdir(irods::plugin_context &_ctx, struct rodsDirent **_dirent_ptr)
Definition: librepl.cpp:1105
irods::create_missing_replicas
void create_missing_replicas(irods::plugin_context &_ctx, const std::vector< leaf_bundle_t > &_leaf_bundles, const int _batch_size, const std::string &_invocation_timestamp, const std::string &_resource_name)
Definition: irods_repl_rebalance.cpp:506
irods::error::code
long long code() const
Definition: irods_error.cpp:194
RESC_HIER_STR_KW
#define RESC_HIER_STR_KW
Definition: rodsKeyWdDef.h:225
irods.pypyodbc.long
long
Definition: pypyodbc.py:43
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
irods::lookup_table::empty
bool empty() const
Definition: irods_lookup_table.hpp:50
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
irods::RESOURCE_OP_CREATE
const std::string RESOURCE_OP_CREATE("resource_create")
irods
Definition: apiHandler.hpp:35
process_redirect_map_for_random_open
irods::error process_redirect_map_for_random_open(const redirect_map_t &_redirect_map, irods::hierarchy_parser *_out_parser, float *_out_vote)
Definition: librepl.cpp:1410
irods::resource_manager::gather_leaf_bundles_for_resc
std::vector< leaf_bundle_t > gather_leaf_bundles_for_resc(const std::string &_resource_name)
Definition: irods_resource_manager.cpp:519
OPEN_TYPE_KW
#define OPEN_TYPE_KW
Definition: rodsKeyWdDef.h:95
irods::RESOURCE_OP_NOTIFY
const std::string RESOURCE_OP_NOTIFY("resource_notify")
irods::RESOURCE_CREATE_PATH
const std::string RESOURCE_CREATE_PATH("resource_property_create_path")
l1desc::dataObjInp
dataObjInp_t * dataObjInp
Definition: objDesc.hpp:41
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")
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: librepl.cpp:1784
repl_file_rmdir
irods::error repl_file_rmdir(irods::plugin_context &_ctx)
Definition: librepl.cpp:979
ASSERT_PASS
#define ASSERT_PASS(prev_error_, format_,...)
Definition: irods_error.hpp:124
KEY_NOT_FOUND
@ KEY_NOT_FOUND
Definition: rodsErrorTable.h:749
repl_file_stat
irods::error repl_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: librepl.cpp:850
irods::update_out_of_date_replicas
void update_out_of_date_replicas(irods::plugin_context &_ctx, const std::vector< leaf_bundle_t > &_leaf_bundles, const int _batch_size, const std::string &_invocation_timestamp, const std::string &_resource_name)
Definition: irods_repl_rebalance.cpp:426
irods::hierarchy_parser::set_string
error set_string(const std::string &_resc_hier)
Definition: irods_hierarchy_parser.cpp:36
irods::DEFAULT_RETRY_ATTEMPTS
const uint32_t DEFAULT_RETRY_ATTEMPTS
Definition: irods_repl_retry.hpp:18
repl_file_modified
irods::error repl_file_modified(irods::plugin_context &_ctx)
Definition: librepl.cpp:523
repl_resource::need_post_disconnect_maintenance_operation
irods::error need_post_disconnect_maintenance_operation(bool &_flag)
Definition: librepl.cpp:1767
OBJECT_LIST_PROP
const std::string OBJECT_LIST_PROP
Definition: irods_repl_types.hpp:28
irods::RESOURCE_OP_CLOSE
const std::string RESOURCE_OP_CLOSE("resource_close")
replCheckParams
irods::error replCheckParams(irods::plugin_context &_ctx)
Definition: librepl.cpp:86
rodsLog.h
OPEN_FOR_WRITE_TYPE
#define OPEN_FOR_WRITE_TYPE
Definition: dataObjInpOut.h:195
irods::log
void log(const error &)
Definition: irods_log.cpp:13
irods::RESC_CHILD_MAP_PROP
const std::string RESC_CHILD_MAP_PROP("resource_child_map_property")
irods::RETRY_FIRST_DELAY_IN_SECONDS_KW
const std::string RETRY_FIRST_DELAY_IN_SECONDS_KW
Definition: irods_repl_retry.hpp:15
rodsDirent
Definition: rodsType.h:70
irods_repl_rebalance.hpp
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
repl_file_stage_to_cache
irods::error repl_file_stage_to_cache(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: librepl.cpp:1278
irods::RESOURCE_OP_RMDIR
const std::string RESOURCE_OP_RMDIR("resource_rmdir")
repl_file_resolve_hierarchy
irods::error repl_file_resolve_hierarchy(irods::plugin_context &_ctx, const std::string *_operation, const std::string *_curr_host, irods::hierarchy_parser *_inout_parser, float *_out_vote)
Definition: librepl.cpp:1468
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
SYS_GET_HOSTNAME_ERR
@ SYS_GET_HOSTNAME_ERR
Definition: rodsErrorTable.h:85
irods::RESOURCE_OP_UNREGISTERED
const std::string RESOURCE_OP_UNREGISTERED("resource_unregistered")
irods::error
Definition: irods_error.hpp:23
repl_file_notify
irods::error repl_file_notify(irods::plugin_context &_ctx, const std::string *_opr)
Definition: librepl.cpp:1568
HIERARCHY_ERROR
@ HIERARCHY_ERROR
Definition: rodsErrorTable.h:752
call_rebalance_on_children
irods::error call_rebalance_on_children(irods::plugin_context &_ctx)
Definition: librepl.cpp:1503
get_rebalance_batch_size
int get_rebalance_batch_size(irods::plugin_context &_ctx)
Definition: librepl.cpp:1516
replicate_create_write_operation
irods::error replicate_create_write_operation(irods::plugin_context &_ctx)
Definition: librepl.cpp:254
irods::RESOURCE_OP_REGISTERED
const std::string RESOURCE_OP_REGISTERED("resource_registered")
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
child_list_t
std::vector< irods::hierarchy_parser > child_list_t
Definition: irods_repl_types.hpp:16
irods::hierarchy_parser::next
error next(const std::string &_current, std::string &_ret_resc) const
Definition: irods_hierarchy_parser.cpp:136
repl_file_write
irods::error repl_file_write(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: librepl.cpp:731
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
irods::DEFAULT_RETRY_BACKOFF_MULTIPLIER
const double DEFAULT_RETRY_BACKOFF_MULTIPLIER
Definition: irods_repl_retry.hpp:20
entry
Definition: ruleAdmin.cpp:22
irods_repl_types.hpp
irods::plugin_context::rule_results
virtual const std::string rule_results()
Definition: irods_plugin_context.hpp:105
irods::RESOURCE_OP_OPENDIR
const std::string RESOURCE_OP_OPENDIR("resource_opendir")
irods::object_oper
Definition: irods_object_oper.hpp:12
irods::RESOURCE_OP_STAGETOCACHE
const std::string RESOURCE_OP_STAGETOCACHE("resource_stagetocache")
irods_replicator.hpp
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
object_list_t
std::list< irods::object_oper > object_list_t
Definition: irods_repl_types.hpp:17
irods::WRITE_OPERATION
const std::string WRITE_OPERATION("WRITE")
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")
irods_kvp_string_parser.hpp
CHILD_NOT_FOUND
@ CHILD_NOT_FOUND
Definition: rodsErrorTable.h:753
irods::exception
Definition: irods_exception.hpp:15
icatHighLevelRoutines.hpp
repl_file_sync_to_arch
irods::error repl_file_sync_to_arch(irods::plugin_context &_ctx, const char *_cache_file_name)
Definition: librepl.cpp:1324
replGetNextRescInHier
irods::error replGetNextRescInHier(const irods::hierarchy_parser &_parser, irods::plugin_context &_ctx, irods::resource_ptr &_ret_resc)
Definition: librepl.cpp:119
rsGenQuery.hpp
irods_random.hpp
repl_file_unlink
irods::error repl_file_unlink(irods::plugin_context &_ctx)
Definition: librepl.cpp:807
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
irods::lookup_table::set
error set(const std::string &_key, const ValueType &_val)
Definition: irods_lookup_table.hpp:83
irods::RETRY_ATTEMPTS_KW
const std::string RETRY_ATTEMPTS_KW
Definition: irods_repl_retry.hpp:14
DataObjInp::condInput
keyValPair_t condInput
Definition: dataObjInpOut.h:74
replUpdateObjectAndOperProperties
irods::error replUpdateObjectAndOperProperties(irods::plugin_context &_ctx, const std::string &_oper)
Definition: librepl.cpp:155
irods::replicator
Definition: irods_replicator.hpp:13
add_self_to_hierarchy
irods::error add_self_to_hierarchy(irods::plugin_context &_ctx, irods::hierarchy_parser &_parser)
Definition: librepl.cpp:1366
irods::replicator::replicate
error replicate(plugin_context &_ctx, const child_list_t &_siblings, object_list_t &_opers)
Definition: irods_replicator.cpp:14
irods::DEFAULT_RETRY_FIRST_DELAY_IN_SECONDS
const uint32_t DEFAULT_RETRY_FIRST_DELAY_IN_SECONDS
Definition: irods_repl_retry.hpp:19
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_repl_retry.hpp
repl_file_rename
irods::error repl_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: librepl.cpp:1148
repl_file_lseek
irods::error repl_file_lseek(irods::plugin_context &_ctx, long long _offset, int _whence)
Definition: librepl.cpp:893
repl_resource::post_disconnect_maintenance_operation
irods::error post_disconnect_maintenance_operation(irods::pdmo_type &)
Definition: librepl.cpp:1760
repl_file_create
irods::error repl_file_create(irods::plugin_context &_ctx)
Definition: librepl.cpp:607
irods::RESOURCE_OP_OPEN
const std::string RESOURCE_OP_OPEN("resource_open")
proc_child_list_for_create_policy
irods::error proc_child_list_for_create_policy(irods::plugin_context &_ctx)
Definition: librepl.cpp:380
irods::CREATE_OPERATION
const std::string CREATE_OPERATION("CREATE")
irods::error::result
std::string result() const
Definition: irods_error.cpp:201
irods_create_write_replicator.hpp
repl_file_read
irods::error repl_file_read(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: librepl.cpp:686
repl_file_unregistered
irods::error repl_file_unregistered(irods::plugin_context &_ctx)
Definition: librepl.cpp:344
replObjectInList
bool replObjectInList(const object_list_t &_object_list, const irods::file_object_ptr _object, irods::object_oper &_rtn_oper)
Definition: librepl.cpp:140