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)  

dataObjOpr.cpp
Go to the documentation of this file.
1 
3 /* dataObjOpr.c - data object operations */
4 
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 #include "rcMisc.h"
8 #include "dataObjOpr.hpp"
9 #include "objMetaOpr.hpp"
10 #include "resource.hpp"
11 #include "collection.hpp"
12 #include "specColl.hpp"
13 #include "physPath.hpp"
14 #include "modDataObjMeta.h"
15 #include "ruleExecSubmit.h"
16 #include "ruleExecDel.h"
17 #include "genQuery.h"
19 #include "miscUtil.h"
20 #include "rsIcatOpr.hpp"
21 #include "getHierarchyForResc.h"
22 #include "dataObjTrim.h"
23 #include "rsGenQuery.hpp"
24 #include "rsDataObjTrim.hpp"
25 #include "rsModDataObjMeta.hpp"
26 
27 // =-=-=-=-=-=-=-
30 #include "irods_log.hpp"
31 #include "irods_stacktrace.hpp"
33 #include "irods_random.hpp"
34 #include "irods_file_object.hpp"
35 
36 #include <algorithm>
37 
38 #include <boost/filesystem/operations.hpp>
39 #include <boost/filesystem/convenience.hpp>
40 #include <boost/lexical_cast.hpp>
41 #include <boost/algorithm/string.hpp>
42 
43 using namespace boost::filesystem;
44 
45 // =-=-=-=-=-=-=-
48  const std::string& _path ) {
49  // =-=-=-=-=-=-=-
50  // set up a default error structure
51  std::stringstream msg;
52  msg << "a valid zone name does not appear at the root of the object path [";
53  msg << _path;
54  msg << "]";
55  irods::error ret_val = ERROR( SYS_INVALID_INPUT_PARAM, msg.str() );
56 
57  // =-=-=-=-=-=-=-
58  // loop over the ZoneInfo linked list and see if the path
59  // has a root object which matches any zone
60  zoneInfo_t* zone_info = ZoneInfoHead;
61  while ( zone_info ) {
62  // =-=-=-=-=-=-=-
63  // build a root zone name
64  std::string zone_name( "/" );
65  zone_name += zone_info->zoneName;
66 
67  // =-=-=-=-=-=-=-
68  // if the zone name appears at the root
69  // then this is a good path
70  size_t pos = _path.find( zone_name );
71  if ( 0 == pos ) {
72  ret_val = SUCCESS();
73  zone_info = 0;
74  }
75  else {
76  zone_info = zone_info->next;
77 
78  }
79 
80  } // while
81 
82  return ret_val;
83 
84 } // validate_logical_path
85 
86 int
88  rsComm_t* rsComm,
89  dataObjInp_t* dataObjInp,
90  dataObjInfo_t** dataObjInfoHead,
91  char* accessPerm,
92  int ignoreCondInput ) {
93  genQueryInp_t genQueryInp;
94  genQueryOut_t *genQueryOut = NULL;
95  int i, status;
96  dataObjInfo_t *dataObjInfo;
97  char *tmpStr;
98  sqlResult_t *dataId, *collId, *replNum, *version, *dataType, *dataSize,
99  *hierString, *filePath, *dataOwnerName, *dataOwnerZone,
100  *replStatus, *statusString, *chksum, *dataExpiry, *dataMapId,
101  *dataComments, *dataCreate, *dataModify, *dataMode, *dataName, *collName;
102  char *tmpDataId, *tmpCollId, *tmpReplNum, *tmpVersion, *tmpDataType,
103  *tmpDataSize, *tmpFilePath,
104  *tmpDataOwnerName, *tmpDataOwnerZone, *tmpReplStatus, *tmpStatusString,
105  *tmpChksum, *tmpDataExpiry, *tmpDataMapId, *tmpDataComments,
106  *tmpDataCreate, *tmpDataModify, *tmpDataMode, *tmpDataName, *tmpCollName,
107  *tmpHierString;
108 
109  char accStr[LONG_NAME_LEN];
110  int qcondCnt;
111  int writeFlag;
112 
113  *dataObjInfoHead = NULL;
114 
115  qcondCnt = initDataObjInfoQuery( dataObjInp, &genQueryInp,
116  ignoreCondInput );
117 
118  if ( qcondCnt < 0 ) {
119  return qcondCnt;
120  }
121 
122  addInxIval( &genQueryInp.selectInp, COL_D_DATA_ID, 1 );
123  addInxIval( &genQueryInp.selectInp, COL_DATA_NAME, 1 );
124  addInxIval( &genQueryInp.selectInp, COL_COLL_NAME, 1 );
125  addInxIval( &genQueryInp.selectInp, COL_D_COLL_ID, 1 );
126  addInxIval( &genQueryInp.selectInp, COL_DATA_REPL_NUM, 1 );
127  addInxIval( &genQueryInp.selectInp, COL_DATA_VERSION, 1 );
128  addInxIval( &genQueryInp.selectInp, COL_DATA_TYPE_NAME, 1 );
129  addInxIval( &genQueryInp.selectInp, COL_DATA_SIZE, 1 );
130  addInxIval( &genQueryInp.selectInp, COL_D_DATA_PATH, 1 );
131  addInxIval( &genQueryInp.selectInp, COL_D_OWNER_NAME, 1 );
132  addInxIval( &genQueryInp.selectInp, COL_D_OWNER_ZONE, 1 );
133  addInxIval( &genQueryInp.selectInp, COL_D_REPL_STATUS, 1 );
134  addInxIval( &genQueryInp.selectInp, COL_D_DATA_STATUS, 1 );
135  addInxIval( &genQueryInp.selectInp, COL_D_DATA_CHECKSUM, 1 );
136  addInxIval( &genQueryInp.selectInp, COL_D_EXPIRY, 1 );
137  addInxIval( &genQueryInp.selectInp, COL_D_MAP_ID, 1 );
138  addInxIval( &genQueryInp.selectInp, COL_D_COMMENTS, 1 );
139  addInxIval( &genQueryInp.selectInp, COL_D_CREATE_TIME, 1 );
140  addInxIval( &genQueryInp.selectInp, COL_D_MODIFY_TIME, 1 );
141  addInxIval( &genQueryInp.selectInp, COL_DATA_MODE, 1 );
142  addInxIval( &genQueryInp.selectInp, COL_D_RESC_HIER, 1 );
143 
144  if ( accessPerm != NULL ) {
145  snprintf( accStr, LONG_NAME_LEN, "%s", rsComm->clientUser.userName );
146  addKeyVal( &genQueryInp.condInput, USER_NAME_CLIENT_KW, accStr );
147 
148  snprintf( accStr, LONG_NAME_LEN, "%s", rsComm->clientUser.rodsZone );
149  addKeyVal( &genQueryInp.condInput, RODS_ZONE_CLIENT_KW, accStr );
150 
151  snprintf( accStr, LONG_NAME_LEN, "%s", accessPerm );
152  addKeyVal( &genQueryInp.condInput, ACCESS_PERMISSION_KW, accStr );
153  }
154  if ( ( tmpStr = getValByKey( &dataObjInp->condInput, TICKET_KW ) ) != NULL ) {
155  addKeyVal( &genQueryInp.condInput, TICKET_KW, tmpStr );
156  }
157 
158  genQueryInp.maxRows = MAX_SQL_ROWS;
159 
160  status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut );
161 
162  if ( status < 0 ) {
163  if ( status != CAT_NO_ROWS_FOUND ) {
165  "getDataObjInfo: rsGenQuery error, status = %d",
166  status );
167  }
168 
169  genQueryInp.continueInx = genQueryOut->continueInx;
170  genQueryInp.maxRows = 0;
171  freeGenQueryOut( &genQueryOut );
172  rsGenQuery( rsComm, &genQueryInp, &genQueryOut );
173 
174  freeGenQueryOut( &genQueryOut );
175  clearGenQueryInp( &genQueryInp );
176 
177  return status;
178  }
179 
180  clearGenQueryInp( &genQueryInp );
181 
182  if ( genQueryOut == NULL ) {
184  "getDataObjInfo: NULL genQueryOut" );
186  }
187 
188  if ( ( dataOwnerName =
189  getSqlResultByInx( genQueryOut, COL_D_OWNER_NAME ) ) == NULL ) {
191  "getDataObjInfo: getSqlResultByInx for COL_D_OWNER_NAME failed" );
192  return UNMATCHED_KEY_OR_INDEX;
193  }
194 
195  if ( ( dataName =
196  getSqlResultByInx( genQueryOut, COL_DATA_NAME ) ) == NULL ) {
198  "getDataObjInfo: getSqlResultByInx for COL_DATA_NAME failed" );
199  return UNMATCHED_KEY_OR_INDEX;
200  }
201 
202  if ( ( collName =
203  getSqlResultByInx( genQueryOut, COL_COLL_NAME ) ) == NULL ) {
205  "getDataObjInfo: getSqlResultByInx for COL_COLL_NAME failed" );
206  return UNMATCHED_KEY_OR_INDEX;
207  }
208 
209  if ( ( dataId = getSqlResultByInx( genQueryOut, COL_D_DATA_ID ) ) == NULL ) {
211  "getDataObjInfo: getSqlResultByInx for COL_D_DATA_ID failed" );
212  return UNMATCHED_KEY_OR_INDEX;
213  }
214 
215  if ( ( collId = getSqlResultByInx( genQueryOut, COL_D_COLL_ID ) ) == NULL ) {
217  "getDataObjInfo: getSqlResultByInx for COL_D_COLL_ID failed" );
218  return UNMATCHED_KEY_OR_INDEX;
219  }
220 
221  if ( ( replNum = getSqlResultByInx( genQueryOut, COL_DATA_REPL_NUM ) ) ==
222  NULL ) {
224  "getDataObjInfo: getSqlResultByInx for COL_DATA_REPL_NUM failed" );
225  return UNMATCHED_KEY_OR_INDEX;
226  }
227 
228  if ( ( version = getSqlResultByInx( genQueryOut, COL_DATA_VERSION ) ) ==
229  NULL ) {
231  "getDataObjInfo: getSqlResultByInx for COL_DATA_VERSION failed" );
232  return UNMATCHED_KEY_OR_INDEX;
233  }
234 
235  if ( ( dataType = getSqlResultByInx( genQueryOut, COL_DATA_TYPE_NAME ) ) ==
236  NULL ) {
238  "getDataObjInfo: getSqlResultByInx for COL_DATA_TYPE_NAME failed" );
239  return UNMATCHED_KEY_OR_INDEX;
240  }
241 
242  if ( ( dataSize = getSqlResultByInx( genQueryOut, COL_DATA_SIZE ) ) == NULL ) {
244  "getDataObjInfo: getSqlResultByInx for COL_DATA_SIZE failed" );
245  return UNMATCHED_KEY_OR_INDEX;
246  }
247 
248  if ( ( hierString = getSqlResultByInx( genQueryOut, COL_D_RESC_HIER ) ) ==
249  NULL ) {
251  "getDataObjInfo: getSqlResultByInx for COL_D_RESC_HIER failed" );
252  return UNMATCHED_KEY_OR_INDEX;
253  }
254 
255  if ( ( filePath = getSqlResultByInx( genQueryOut, COL_D_DATA_PATH ) ) ==
256  NULL ) {
258  "getDataObjInfo: getSqlResultByInx for COL_D_DATA_PATH failed" );
259  return UNMATCHED_KEY_OR_INDEX;
260  }
261 
262  if ( ( dataOwnerZone =
263  getSqlResultByInx( genQueryOut, COL_D_OWNER_ZONE ) ) == NULL ) {
265  "getDataObjInfo: getSqlResultByInx for COL_D_OWNER_ZONE failed" );
266  return UNMATCHED_KEY_OR_INDEX;
267  }
268 
269  if ( ( replStatus =
270  getSqlResultByInx( genQueryOut, COL_D_REPL_STATUS ) ) == NULL ) {
272  "getDataObjInfo: getSqlResultByInx for COL_D_REPL_STATUS failed" );
273  return UNMATCHED_KEY_OR_INDEX;
274  }
275 
276  if ( ( statusString =
277  getSqlResultByInx( genQueryOut, COL_D_DATA_STATUS ) ) == NULL ) {
279  "getDataObjInfo: getSqlResultByInx for COL_D_DATA_STATUS failed" );
280  return UNMATCHED_KEY_OR_INDEX;
281  }
282 
283  if ( ( chksum =
284  getSqlResultByInx( genQueryOut, COL_D_DATA_CHECKSUM ) ) == NULL ) {
286  "getDataObjInfo: getSqlResultByInx for COL_D_DATA_CHECKSUM failed" );
287  return UNMATCHED_KEY_OR_INDEX;
288  }
289 
290  if ( ( dataExpiry =
291  getSqlResultByInx( genQueryOut, COL_D_EXPIRY ) ) == NULL ) {
293  "getDataObjInfo: getSqlResultByInx for COL_D_EXPIRY failed" );
294  return UNMATCHED_KEY_OR_INDEX;
295  }
296 
297  if ( ( dataMapId =
298  getSqlResultByInx( genQueryOut, COL_D_MAP_ID ) ) == NULL ) {
300  "getDataObjInfo: getSqlResultByInx for COL_D_MAP_ID failed" );
301  return UNMATCHED_KEY_OR_INDEX;
302  }
303 
304  if ( ( dataComments =
305  getSqlResultByInx( genQueryOut, COL_D_COMMENTS ) ) == NULL ) {
307  "getDataObjInfo: getSqlResultByInx for COL_D_COMMENTS failed" );
308  return UNMATCHED_KEY_OR_INDEX;
309  }
310 
311  if ( ( dataCreate =
312  getSqlResultByInx( genQueryOut, COL_D_CREATE_TIME ) ) == NULL ) {
314  "getDataObjInfo: getSqlResultByInx for COL_D_CREATE_TIME failed" );
315  return UNMATCHED_KEY_OR_INDEX;
316  }
317 
318  if ( ( dataModify =
319  getSqlResultByInx( genQueryOut, COL_D_MODIFY_TIME ) ) == NULL ) {
321  "getDataObjInfo: getSqlResultByInx for COL_D_MODIFY_TIME failed" );
322  return UNMATCHED_KEY_OR_INDEX;
323  }
324 
325  if ( ( dataMode =
326  getSqlResultByInx( genQueryOut, COL_DATA_MODE ) ) == NULL ) {
328  "getDataObjInfo: getSqlResultByInx for COL_DATA_MODE failed" );
329  return UNMATCHED_KEY_OR_INDEX;
330  }
331 
332  writeFlag = getWriteFlag( dataObjInp->openFlags );
333 
334  for ( i = 0; i < genQueryOut->rowCnt; i++ ) {
335  dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) );
336  memset( dataObjInfo, 0, sizeof( dataObjInfo_t ) );
337 
338  tmpDataId = &dataId->value[dataId->len * i];
339  tmpCollId = &collId->value[collId->len * i];
340  tmpReplNum = &replNum->value[replNum->len * i];
341  tmpVersion = &version->value[version->len * i];
342  tmpDataType = &dataType->value[dataType->len * i];
343  tmpDataSize = &dataSize->value[dataSize->len * i];
344  tmpHierString = &hierString->value[hierString->len * i];
345 
346  tmpFilePath = &filePath->value[filePath->len * i];
347  tmpDataOwnerName = &dataOwnerName->value[dataOwnerName->len * i];
348  tmpDataOwnerZone = &dataOwnerZone->value[dataOwnerZone->len * i];
349  tmpReplStatus = &replStatus->value[replStatus->len * i];
350  tmpStatusString = &statusString->value[statusString->len * i];
351  tmpChksum = &chksum->value[chksum->len * i];
352  tmpDataExpiry = &dataExpiry->value[dataExpiry->len * i];
353  tmpDataMapId = &dataMapId->value[dataMapId->len * i];
354  tmpDataComments = &dataComments->value[dataComments->len * i];
355  tmpDataCreate = &dataCreate->value[dataCreate->len * i];
356  tmpDataModify = &dataModify->value[dataModify->len * i];
357  tmpDataMode = &dataMode->value[dataMode->len * i];
358  tmpDataName = &dataName->value[dataName->len * i];
359  tmpCollName = &collName->value[collName->len * i];
360 
361  snprintf( dataObjInfo->objPath, MAX_NAME_LEN, "%s/%s", tmpCollName, tmpDataName );
362  rstrcpy( dataObjInfo->rescHier, tmpHierString, MAX_NAME_LEN );
363  irods::error ret = resc_mgr.hier_to_leaf_id( tmpHierString, dataObjInfo->rescId );
364  if( !ret.ok() ) {
365  irods::log(PASS(ret));
366  return ret.code();
367  }
368  std::string hier( tmpHierString );
369 
371  parser.set_string( tmpHierString );
372  std::string leaf;
373  parser.last_resc( leaf );
374  rstrcpy( dataObjInfo->rescName, leaf.c_str(), NAME_LEN );
375 
376  rstrcpy( dataObjInfo->dataType, tmpDataType, NAME_LEN );
377  dataObjInfo->dataSize = strtoll( tmpDataSize, 0, 0 );
378  rstrcpy( dataObjInfo->chksum, tmpChksum, NAME_LEN );
379  rstrcpy( dataObjInfo->version, tmpVersion, NAME_LEN );
380  rstrcpy( dataObjInfo->filePath, tmpFilePath, MAX_NAME_LEN );
381  rstrcpy( dataObjInfo->dataOwnerName, tmpDataOwnerName, NAME_LEN );
382  rstrcpy( dataObjInfo->dataOwnerZone, tmpDataOwnerZone, NAME_LEN );
383  dataObjInfo->replNum = atoi( tmpReplNum );
384  dataObjInfo->replStatus = atoi( tmpReplStatus );
385  rstrcpy( dataObjInfo->statusString, tmpStatusString, NAME_LEN );
386  dataObjInfo->dataId = strtoll( tmpDataId, 0, 0 );
387  dataObjInfo->collId = strtoll( tmpCollId, 0, 0 );
388  dataObjInfo->dataMapId = atoi( tmpDataMapId );
389  rstrcpy( dataObjInfo->dataComments, tmpDataComments, LONG_NAME_LEN );
390  rstrcpy( dataObjInfo->dataExpiry, tmpDataExpiry, TIME_LEN );
391  rstrcpy( dataObjInfo->dataCreate, tmpDataCreate, TIME_LEN );
392  rstrcpy( dataObjInfo->dataModify, tmpDataModify, TIME_LEN );
393  rstrcpy( dataObjInfo->dataMode, tmpDataMode, SHORT_STR_LEN );
394  dataObjInfo->writeFlag = writeFlag;
395 
396  dataObjInfo->next = 0;
397 
398  queDataObjInfo( dataObjInfoHead, dataObjInfo, 1, 0 );
399 
400  } // for i
401 
402  freeGenQueryOut( &genQueryOut );
403 
404  return qcondCnt;
405 }
406 
407 int
409  dataObjInfo_t **dataObjInfoHead,
410  dataObjInfo_t **currentArchInfo,
411  dataObjInfo_t **currentCacheInfo,
412  dataObjInfo_t **oldArchInfo,
413  dataObjInfo_t **oldCacheInfo,
414  dataObjInfo_t **downCurrentInfo,
415  dataObjInfo_t **downOldInfo,
416  const char* resc_hier ) {
417  dataObjInfo_t *tmpDataObjInfo, *nextDataObjInfo;
418  // int rescClassInx;
419  int topFlag;
420  dataObjInfo_t *currentBundleInfo = NULL;
421  dataObjInfo_t *oldBundleInfo = NULL;
422 
423  *currentArchInfo = *currentCacheInfo = *oldArchInfo = *oldCacheInfo = NULL;
424  *downCurrentInfo = *downOldInfo = NULL;
425 
426  tmpDataObjInfo = *dataObjInfoHead;
427 
428  while ( tmpDataObjInfo != NULL ) {
429 
430  nextDataObjInfo = tmpDataObjInfo->next;
431  tmpDataObjInfo->next = NULL;
432 
433 
434  if ( !strlen( tmpDataObjInfo->rescName ) ) {
435  topFlag = 0;
436 
437  }
438  else if ( !irods::is_resc_live( tmpDataObjInfo->rescId ).ok() ) {
439  /* the resource is down */
440  if ( tmpDataObjInfo->replStatus > 0 ) {
441  queDataObjInfo( downCurrentInfo, tmpDataObjInfo, 1, 1 );
442  }
443  else {
444  queDataObjInfo( downOldInfo, tmpDataObjInfo, 1, 1 );
445  }
446 
447  tmpDataObjInfo = nextDataObjInfo;
448 
449  continue;
450  }
451  else {
453  irods::get_resource_property< rodsServerHost_t* >( tmpDataObjInfo->rescId, irods::RESOURCE_HOST, rodsServerHost );
454 
456  topFlag = 0;
457  }
458  else {
459  /* queue local host at the head */
460  topFlag = 1;
461  }
462  }
463 
464  std::string class_type;
465  irods::error prop_err = irods::get_resource_property<std::string>(
466  tmpDataObjInfo->rescId,
468  class_type );
469 
470  bool hier_match = false;
471  if ( resc_hier != NULL && ( strcmp( resc_hier, tmpDataObjInfo->rescHier ) == 0 ) ) {
472  hier_match = true;
473  }
474 
475  // =-=-=-=-=-=-=-
476  // if the resc hierarchy is defined match it
477  // honor the original queue structure given repl status
478  if ( resc_hier != NULL && hier_match ) {
479  //queDataObjInfo(currentCacheInfo, tmpDataObjInfo, 1, topFlag);
480  // =-=-=-=-=-=-=-
481  // even if the repl is dirty we will want to select it here as
482  // the resources make these decisions
483  //if( tmpDataObjInfo->replStatus > 0 ) {
484  queDataObjInfo( currentCacheInfo, tmpDataObjInfo, 1, 1 );
485  //} else {
486  // queDataObjInfo( oldCacheInfo, tmpDataObjInfo, 1, topFlag );
487  //}
488  }
489  else if ( resc_hier != NULL && !hier_match ) {
490  if ( tmpDataObjInfo->replStatus > 0 ) {
491  queDataObjInfo( currentCacheInfo, tmpDataObjInfo, 1, 0 );
492  }
493  else {
494  queDataObjInfo( oldCacheInfo, tmpDataObjInfo, 1, 1 );
495  }
496  }
497  else if ( tmpDataObjInfo->replStatus > 0 ) {
498 
499  if ( "archive" == class_type ) {
500  queDataObjInfo( currentArchInfo, tmpDataObjInfo, 1, topFlag );
501  }
502  else if ( "compound" == class_type ) {
503  rodsLog( LOG_ERROR, "sortObj :: class_type == compound" );
504  }
505  else if ( "bundle" == class_type ) {
506  queDataObjInfo( &currentBundleInfo, tmpDataObjInfo, 1, topFlag );
507  }
508  else {
509  queDataObjInfo( currentCacheInfo, tmpDataObjInfo, 1, topFlag );
510  }
511  }
512  else {
513  if ( "archive" == class_type ) {
514  queDataObjInfo( oldArchInfo, tmpDataObjInfo, 1, topFlag );
515  }
516  else if ( "compound" == class_type ) {
517  rodsLog( LOG_ERROR, "sortObj :: class_type == compound" );
518  }
519  else if ( "bundle" == class_type ) {
520  queDataObjInfo( &oldBundleInfo, tmpDataObjInfo, 1, topFlag );
521  }
522  else {
523  queDataObjInfo( oldCacheInfo, tmpDataObjInfo, 1, topFlag );
524  }
525  }
526  tmpDataObjInfo = nextDataObjInfo;
527 
528  } // while
529 
530  /* combine ArchInfo and CompInfo. COMPOUND_CL before BUNDLE_CL */
531  //queDataObjInfo (oldArchInfo, oldCompInfo, 0, 0);
532  queDataObjInfo( oldArchInfo, oldBundleInfo, 0, 0 );
533  //queDataObjInfo (currentArchInfo, currentCompInfo, 0, 0);
534  queDataObjInfo( currentArchInfo, currentBundleInfo, 0, 0 );
535  return 0;
536 }
537 
538 // determine if a forced open is done to a resource which does not have
539 // an original copy of the data object
540 
541 /* sortObjInfoForOpen - Sort the dataObjInfo in dataObjInfoHead for open.
542  * If RESC_HIER_STR_KW is set matching resc obj is first.
543  * If it is for read (writeFlag == 0), discard old copies, then cache first,
544  * archival second.
545  * If it is for write, (writeFlag > 0), resource in DEST_RESC_NAME_KW first,
546  * then current cache, current archival, old cache and old archival.
547  */
549  dataObjInfo_t** dataObjInfoHead,
550  keyValPair_t* condInput,
551  int writeFlag ) {
552 
553  int result = 0;
554  char* resc_hier = getValByKey( condInput, RESC_HIER_STR_KW );
555  if ( !resc_hier ) {
556  std::stringstream msg;
557  msg << __FUNCTION__;
558  msg << " - No resource hierarchy specified in keywords.";
559  irods::log( ERROR( SYS_INVALID_INPUT_PARAM, msg.str() ) );
560  result = SYS_INVALID_INPUT_PARAM;
561  }
562  else {
563  dataObjInfo_t* found_info = NULL;
564  dataObjInfo_t* prev_info = NULL;
565  for ( dataObjInfo_t* dataObjInfo = *dataObjInfoHead;
566  result >= 0 && found_info == NULL && dataObjInfo != NULL;
567  dataObjInfo = dataObjInfo->next ) {
568  if ( strcmp( resc_hier, dataObjInfo->rescHier ) == 0 ) {
569  found_info = dataObjInfo;
570  }
571  else {
572  prev_info = dataObjInfo;
573  }
574  }
575  if ( found_info == NULL ) {
576  // =-=-=-=-=-=-=-
577  // according to the below read only semantics
578  // any copy in the head is a good copy.
579  if ( 0 != writeFlag ) {
580  std::stringstream msg;
581  msg << __FUNCTION__;
582  msg << " - No data object found matching resource hierarchy: \"";
583  msg << resc_hier;
584  msg << "\"";
585  irods::log( ERROR( HIERARCHY_ERROR, msg.str() ) );
586  result = HIERARCHY_ERROR;
587  }
588  }
589  else {
590  if ( prev_info == NULL ) {
591  // our object is at the head of the list. So delete the rest of the list, if any and we are done.
592  if ( found_info->next != NULL ) {
593  freeAllDataObjInfo( found_info->next );
594  found_info->next = NULL;
595  }
596  }
597  else {
598  // remove our object from the list. delete that list then make our object the head.
599  prev_info->next = found_info->next;
600  found_info->next = NULL;
601  freeAllDataObjInfo( *dataObjInfoHead );
602  *dataObjInfoHead = found_info;
603  }
604  }
605  }
606  return result;
607 
608 }
609 
611  const std::string& resc_hier,
612  const irods::file_object_ptr file_obj,
613  dataObjInfo_t **data_obj_info_head) {
614 
615  // checks
616  if (resc_hier.empty()) {
617  std::stringstream msg;
618  msg << __FUNCTION__;
619  msg << " - Empty input resource hierarchy.";
620  irods::log( ERROR( SYS_INVALID_INPUT_PARAM, msg.str() ) );
622  }
623 
624  // initialize output list
625  *data_obj_info_head = NULL;
626 
627 // check C++11 support
628 #if __cplusplus > 199711L
629  // iterate over replicas
630  for (auto& replica : file_obj->replicas()) {
631 
632 #else
633  // iterate over replicas
634  std::vector< irods::physical_object >::iterator itr;
635  for (itr = file_obj->replicas().begin(); itr != file_obj->replicas().end(); ++itr) {
636  irods::physical_object replica = *itr;
637 #endif
638 
639  // look for replica with matching resource hierarchy
640  if (replica.resc_hier() == resc_hier) {
641 
642  // initialize object info
643  dataObjInfo_t *data_obj_info = (dataObjInfo_t*)malloc(sizeof(dataObjInfo_t));
644  memset(data_obj_info, 0, sizeof(dataObjInfo_t));
645 
646  // copy values from physical object
647  data_obj_info->replStatus = replica.is_dirty();
648  data_obj_info->replNum = replica.repl_num();
649  data_obj_info->dataMapId = replica.map_id();
650  data_obj_info->dataSize = replica.size();
651  data_obj_info->dataId = replica.id();
652  data_obj_info->collId = replica.coll_id();
653  snprintf(data_obj_info->objPath, MAX_NAME_LEN, "%s", replica.name().c_str());
654  snprintf(data_obj_info->version, NAME_LEN, "%s", replica.version().c_str());
655  snprintf(data_obj_info->dataType, NAME_LEN, "%s", replica.type_name().c_str());
656  snprintf(data_obj_info->rescName, NAME_LEN, "%s", replica.resc_name().c_str());
657  snprintf(data_obj_info->filePath, MAX_NAME_LEN, "%s", replica.path().c_str());
658  snprintf(data_obj_info->dataOwnerName, NAME_LEN, "%s", replica.owner_name().c_str());
659  snprintf(data_obj_info->dataOwnerZone, NAME_LEN, "%s", replica.owner_zone().c_str());
660  snprintf(data_obj_info->statusString, NAME_LEN, "%s", replica.status().c_str());
661  snprintf(data_obj_info->chksum, NAME_LEN, "%s", replica.checksum().c_str());
662  snprintf(data_obj_info->dataExpiry, TIME_LEN, "%s", replica.expiry_ts().c_str());
663  snprintf(data_obj_info->dataMode, SHORT_STR_LEN, "%s", replica.mode().c_str());
664  snprintf(data_obj_info->dataComments, LONG_NAME_LEN, "%s", replica.r_comment().c_str());
665  snprintf(data_obj_info->dataCreate, TIME_LEN, "%s", replica.create_ts().c_str());
666  snprintf(data_obj_info->dataModify, TIME_LEN, "%s", replica.modify_ts().c_str());
667  snprintf(data_obj_info->rescHier, MAX_NAME_LEN, "%s", replica.resc_hier().c_str());
668 
669  // make data_obj_info the head of our list
670  *data_obj_info_head = data_obj_info;
671 
672  // done
673  return 0;
674  }
675  } // iterate over replicas
676 
677  // no "good" replica was found
678  std::stringstream msg;
679  msg << __FUNCTION__;
680  msg << " - No replica found with input resource hierarchy: \"";
681  msg << resc_hier;
682  msg << "\"";
683  irods::log( ERROR( HIERARCHY_ERROR, msg.str() ) );
684  return HIERARCHY_ERROR;
685 }
686 
687 int
688 getNumDataObjInfo( dataObjInfo_t *dataObjInfoHead ) {
689  dataObjInfo_t *tmpDataObjInfo;
690  int numInfo = 0;
691 
692  tmpDataObjInfo = dataObjInfoHead;
693  while ( tmpDataObjInfo != NULL ) {
694  numInfo++;
695  tmpDataObjInfo = tmpDataObjInfo->next;
696  }
697  return numInfo;
698 }
699 
700 int
701 sortDataObjInfoRandom( dataObjInfo_t **dataObjInfoHead ) {
702  dataObjInfo_t *myDataObjInfo[50];
703  dataObjInfo_t *tmpDataObjInfo;
704  int i, j, tmpCnt, order;
705  int numInfo = getNumDataObjInfo( *dataObjInfoHead );
706 
707  if ( numInfo <= 1 ) {
708  return 0;
709  }
710 
711  if ( numInfo > 50 ) {
713  "sortDataObjInfoRandom: numInfo %d > 50, setting it to 50", numInfo );
714  numInfo = 50;
715  }
716 
717  memset( myDataObjInfo, 0, numInfo * sizeof( dataObjInfo_t * ) );
718  /* fill the array randomly */
719 
720  tmpCnt = numInfo;
721  tmpDataObjInfo = *dataObjInfoHead;
722  while ( tmpDataObjInfo != NULL ) {
723  if ( tmpCnt > 1 ) {
724  order = irods::getRandom<unsigned int>() % tmpCnt;
725  }
726  else {
727  order = 0;
728  }
729  for ( i = 0, j = 0; i < numInfo; i ++ ) {
730  if ( myDataObjInfo[i] == NULL ) {
731  if ( order <= j ) {
732  myDataObjInfo[i] = tmpDataObjInfo;
733  break;
734  }
735  j ++;
736  }
737  }
738  tmpCnt --;
739  tmpDataObjInfo = tmpDataObjInfo->next;
740  }
741 
742  /* now que the array in order */
743 
744  *dataObjInfoHead = NULL;
745  for ( i = 0; i < numInfo; i ++ ) {
746  queDataObjInfo( dataObjInfoHead, myDataObjInfo[i], 1, 1 );
747  }
748 
749  return 0;
750 }
751 
752 /* requeDataObjInfoByResc - requeue the dataObjInfo in the
753  * dataObjInfoHead by putting dataObjInfo stored in preferredResc
754  * at the top of the queue.
755  * return 0 if dataObjInfo with preferredResc exists.
756  * Otherwise, return -1.
757  */
758 
759 int
761  const char *preferredResc, int writeFlag, int topFlag ) {
762 
763  dataObjInfo_t *tmpDataObjInfo, *prevDataObjInfo;
764  int status = -1;
765 
766  if ( preferredResc == NULL || *dataObjInfoHead == NULL ) {
767  return 0;
768  }
769 
770  tmpDataObjInfo = *dataObjInfoHead;
771  if ( tmpDataObjInfo->next == NULL ) {
772  /* just one */
773  if ( strstr(tmpDataObjInfo->rescHier,preferredResc ) != 0 ) {
774  return 0;
775  }
776  else {
777  return -1;
778  }
779  }
780  prevDataObjInfo = NULL;
781  while ( tmpDataObjInfo != NULL ) {
782  if ( strstr(tmpDataObjInfo->rescHier,preferredResc) != 0 ) {
783  if ( writeFlag > 0 || tmpDataObjInfo->replStatus > 0 ) {
784  if ( prevDataObjInfo != NULL ) {
785  prevDataObjInfo->next = tmpDataObjInfo->next;
786  queDataObjInfo( dataObjInfoHead, tmpDataObjInfo, 1,
787  topFlag );
788  }
789  if ( topFlag > 0 ) {
790  return 0;
791  }
792  else {
793  status = 0;
794  }
795  }
796  }
797 
798  prevDataObjInfo = tmpDataObjInfo;
799  tmpDataObjInfo = tmpDataObjInfo->next;
800  }
801 
802  return status;
803 }
804 
805 int
806 requeDataObjInfoByReplNum( dataObjInfo_t **dataObjInfoHead, int replNum ) {
807  dataObjInfo_t *tmpDataObjInfo, *prevDataObjInfo;
808  int status = -1;
809 
810  if ( dataObjInfoHead == NULL || *dataObjInfoHead == NULL ) {
811  return -1;
812  }
813 
814  tmpDataObjInfo = *dataObjInfoHead;
815  if ( tmpDataObjInfo->next == NULL ) {
816  /* just one */
817  if ( replNum == tmpDataObjInfo->replNum ) {
818  return 0;
819  }
820  else {
821  return -1;
822  }
823  }
824  prevDataObjInfo = NULL;
825  while ( tmpDataObjInfo != NULL ) {
826  if ( replNum == tmpDataObjInfo->replNum ) {
827  if ( prevDataObjInfo != NULL ) {
828  prevDataObjInfo->next = tmpDataObjInfo->next;
829  queDataObjInfo( dataObjInfoHead, tmpDataObjInfo, 1, 1 );
830  }
831  status = 0;
832  break;
833  }
834  prevDataObjInfo = tmpDataObjInfo;
835  tmpDataObjInfo = tmpDataObjInfo->next;
836  }
837 
838  return status;
839 }
840 
842 chkCopyInResc( dataObjInfo_t*& dataObjInfoHead,
843  const std::string& _resc_name, /* default resource returned by rule engine */
844  const char* destRescHier /* from optional condInput */ ) {
845 
846  dataObjInfo_t *tmpDataObjInfo;
847 
848  tmpDataObjInfo = dataObjInfoHead;
849  dataObjInfo_t* prev = NULL;
850 
851 
852  while ( tmpDataObjInfo != NULL ) {
853  // No longer good enough to check if the resource names are the same. We have to verify that the resource hierarchies
854  // match as well. - hcj
855  // XXXX - if ( strcmp( tmpDataObjInfo->rescName, _resc_name.c_str() ) == 0 &&
856  if ( strstr( tmpDataObjInfo->rescHier, _resc_name.c_str() ) != 0 &&
857  ( destRescHier == NULL || strcmp( tmpDataObjInfo->rescHier, destRescHier ) == 0 ) ) {
858  if ( prev != NULL ) {
859  prev->next = tmpDataObjInfo->next;
860  }
861  else {
862  dataObjInfoHead = tmpDataObjInfo->next;
863  }
864  tmpDataObjInfo->next = NULL;
865  return tmpDataObjInfo;
866  }
867 
868  prev = tmpDataObjInfo;
869  tmpDataObjInfo = tmpDataObjInfo->next;
870  }
871 
872  return NULL;
873 }
874 
875 
876 /* matchAndTrimRescGrp - check for matching rescName in dataObjInfoHead
877  * and rescGrpInfoHead. If there is a match, unlink and free the
878  * rescGrpInfo in rescGrpInfoHead so that they wont be replicated
879  * If trimjFlag - set what to trim. Valid input are : TRIM_MATCHED_RESC_INFO,
880  * TRIM_MATCHED_OBJ_INFO and TRIM_UNMATCHED_OBJ_INFO
881  */
882 int
884  const std::string& _resc_name, // replaces rescGrpInfoHead
885  int trimjFlag,
886  dataObjInfo_t **trimmedDataObjInfo ) {
887 
888  dataObjInfo_t *tmpDataObjInfo, *prevDataObjInfo, *nextDataObjInfo;
889 
890  if ( trimmedDataObjInfo != NULL ) {
891  *trimmedDataObjInfo = NULL;
892  }
893 
894  tmpDataObjInfo = *dataObjInfoHead;
895  prevDataObjInfo = NULL;
896 
897  while ( tmpDataObjInfo != NULL ) {
898  nextDataObjInfo = tmpDataObjInfo->next;
899 
900  irods::hierarchy_parser h_parse;
901  h_parse.set_string(tmpDataObjInfo->rescHier);
902  if(h_parse.resc_in_hier(_resc_name)) {
903 
904  if ( trimjFlag & TRIM_MATCHED_OBJ_INFO ) {
905  if ( tmpDataObjInfo == *dataObjInfoHead ) {
906  *dataObjInfoHead = tmpDataObjInfo->next;
907 
908  }
909  else if ( prevDataObjInfo != NULL ) {
910  prevDataObjInfo->next = tmpDataObjInfo->next;
911 
912  }
913 
914  if ( trimmedDataObjInfo != NULL ) {
915  queDataObjInfo( trimmedDataObjInfo, tmpDataObjInfo, 1, 0 );
916 
917  }
918  else {
919  free( tmpDataObjInfo );
920 
921  }
922 
923  }
924  else {
925  prevDataObjInfo = tmpDataObjInfo;
926 
927  }
928 
929  }
930 
931  tmpDataObjInfo = nextDataObjInfo;
932 
933  } // while
934 
935  return 0;
936 }
937 
938 /* sortObjInfoForRepl - sort the data object given in dataObjInfoHead.
939  * Put the current copies in dataObjInfoHead. Delete old copies if
940  * deleteOldFlag allowed or put them in oldDataObjInfoHead for further
941  * process if not allowed.
942  */
943 
944 int
946  dataObjInfo_t** dataObjInfoHead, // RESC_HIER
947  dataObjInfo_t** oldDataObjInfoHead, // DST_RESC_HIER
948  int deleteOldFlag,
949  const char* resc_hier,
950  const char* dst_resc_hier ) {
951  // =-=-=-=-=-=-=-
952  // trap bad pointers
953  if ( !dataObjInfoHead || !*dataObjInfoHead ) {
955  }
956 
957  // =-=-=-=-=-=-=-
958  // short circuit sort for the case where a dst resc hier
959  // is provided which means the choice for to which repl
960  // to update is made already. However, we have to handle
961  // the case where the resc_hier and dst_resc_hier are the same.
962  *oldDataObjInfoHead = NULL;
963  if ( resc_hier && dst_resc_hier && strcmp( dst_resc_hier, resc_hier ) != 0 ) {
964  dataObjInfo_t* tmp_info = *dataObjInfoHead;
965  dataObjInfo_t* prev_info = NULL;
966  while ( tmp_info ) {
967  // =-=-=-=-=-=-=-
968  // compare resc hier strings, if its a match this is our
969  // choice so queue it up on the oldDataObjInfoHead
970  if ( 0 == strcmp( dst_resc_hier, tmp_info->rescHier ) ) {
971  // =-=-=-=-=-=-=-
972  // we need to check the status of the resource
973  // to determine if it is up or down before
974  // queue-ing it up
975  if ( irods::is_hier_live( dst_resc_hier ).ok() /* INT_RESC_STATUS_DOWN != tmp_info->rescInfo->rescStatus */ ) {
976  if ( prev_info == NULL ) {
977  *dataObjInfoHead = tmp_info->next;
978  }
979  else {
980  prev_info->next = tmp_info->next;
981  }
982  tmp_info->next = NULL;
983  queDataObjInfo( oldDataObjInfoHead, tmp_info, 1, 1 );
984  tmp_info = 0;
985  }
986  else {
987  rodsLog(
988  LOG_ERROR,
989  "sortObjInfoForRepl - destination resource is down [%s]",
990  dst_resc_hier );
991  return -1;
992  }
993 
994  }
995  else {
996  prev_info = tmp_info;
997  tmp_info = tmp_info->next;
998 
999  }
1000 
1001  } // while tmp_info
1002 
1003  } // if dst_resc_hier
1004 
1005  dataObjInfo_t *currentArchInfo = 0, *currentCacheInfo = 0, *oldArchInfo = 0,
1006  *oldCacheInfo = 0, *downCurrentInfo = 0, *downOldInfo = 0;
1007 
1008  sortObjInfo( dataObjInfoHead, &currentArchInfo, &currentCacheInfo,
1009  &oldArchInfo, &oldCacheInfo, &downCurrentInfo, &downOldInfo, resc_hier );
1010  freeAllDataObjInfo( downOldInfo );
1011  *dataObjInfoHead = currentCacheInfo;
1012  queDataObjInfo( dataObjInfoHead, currentArchInfo, 0, 0 );
1013  queDataObjInfo( dataObjInfoHead, downCurrentInfo, 0, 0 );
1014  if ( *dataObjInfoHead != NULL ) {
1015  if ( *oldDataObjInfoHead == NULL && deleteOldFlag == 0 ) {
1016  /* multi copy not allowed. have to keep old copy in
1017  * oldDataObjInfoHead for further processing */
1018  *oldDataObjInfoHead = oldCacheInfo;
1019  queDataObjInfo( oldDataObjInfoHead, oldArchInfo, 0, 0 );
1020  }
1021  else {
1022  freeAllDataObjInfo( oldCacheInfo );
1023  freeAllDataObjInfo( oldArchInfo );
1024  }
1025  }
1026  else {
1027  queDataObjInfo( dataObjInfoHead, oldCacheInfo, 0, 0 );
1028  queDataObjInfo( dataObjInfoHead, oldArchInfo, 0, 0 );
1029  }
1030  if ( *dataObjInfoHead == NULL ) {
1031  return SYS_RESC_IS_DOWN;
1032  }
1033  else {
1034  return 0;
1035  }
1036 }
1037 
1038 
1039 /* initDataObjInfoQuery - initialize the genQueryInp based on dataObjInp.
1040  * returns the qcondCnt - count of sqlCondInp based on condition input.
1041  */
1042 
1043 int
1045  int ignoreCondInput ) {
1046  char myColl[MAX_NAME_LEN], myData[MAX_NAME_LEN];
1047  char condStr[MAX_NAME_LEN];
1048  char *tmpStr;
1049  int status;
1050  int qcondCnt = 0;
1051 
1052  memset( genQueryInp, 0, sizeof( genQueryInp_t ) );
1053 
1054  if ( ( tmpStr = getValByKey( &dataObjInp->condInput, QUERY_BY_DATA_ID_KW ) )
1055  == NULL ) {
1056  memset( myColl, 0, MAX_NAME_LEN );
1057  memset( myData, 0, MAX_NAME_LEN );
1058 
1059  if ( ( status = splitPathByKey(
1060  dataObjInp->objPath, myColl, MAX_NAME_LEN, myData, MAX_NAME_LEN, '/' ) ) < 0 ) {
1062  "initDataObjInfoQuery: splitPathByKey for %s error, status = %d",
1063  dataObjInp->objPath, status );
1064  return status;
1065  }
1066  snprintf( condStr, MAX_NAME_LEN, "='%s'", myColl );
1067  addInxVal( &genQueryInp->sqlCondInp, COL_COLL_NAME, condStr );
1068  snprintf( condStr, MAX_NAME_LEN, "='%s'", myData );
1069  addInxVal( &genQueryInp->sqlCondInp, COL_DATA_NAME, condStr );
1070  }
1071  else {
1072  snprintf( condStr, MAX_NAME_LEN, "='%s'", tmpStr );
1073  addInxVal( &genQueryInp->sqlCondInp, COL_D_DATA_ID, condStr );
1074  }
1075 
1076  if ( ignoreCondInput == 0 && ( tmpStr =
1077  getValByKey( &dataObjInp->condInput, REPL_NUM_KW ) ) != NULL ) {
1078  snprintf( condStr, NAME_LEN, "='%s'", tmpStr );
1079  addInxVal( &genQueryInp->sqlCondInp, COL_DATA_REPL_NUM, condStr );
1080  qcondCnt++;
1081  }
1082 
1083  if ( const char * admin = getValByKey( &dataObjInp->condInput, ADMIN_KW ) ) {
1084  addKeyVal( &genQueryInp->condInput, ADMIN_KW, admin );
1085  }
1086 
1087  return qcondCnt;
1088 }
1089 
1090 /* chkOrphanFile - check whether a filePath is a orphan file.
1091  * return - 1 - the file is orphan.
1092  * 0 - 0 the file is not an orphan.
1093  * -ive - query error.
1094  * If it is not orphan and dataObjInfo != NULL, output ObjID,
1095  * replNum and objPath to dataObjInfo.
1096  */
1097 
1098 int
1100  rsComm_t* rsComm,
1101  char* filePath,
1102  const char* rescName,
1103  dataObjInfo_t* dataObjInfo ) {
1104  // =-=-=-=-=-=-=-
1105  // disallow the orphaning of a file by an anonymous user as this
1106  // is a similar issue to the use of strict acls in that an anonymous
1107  // user may inappropriately orphan a file owned by another user
1108  if ( strncmp( ANONYMOUS_USER, rsComm->clientUser.userName, NAME_LEN ) == 0 ) {
1109  return SYS_USER_NO_PERMISSION;
1110  }
1111 
1112  genQueryInp_t genQueryInp;
1113  genQueryOut_t *genQueryOut = NULL;
1114  int status;
1115  char condStr[MAX_NAME_LEN];
1116 
1117  rodsLong_t resc_id;
1118  irods::error ret = resc_mgr.hier_to_leaf_id(rescName,resc_id);
1119  if(!ret.ok()) {
1120  irods::log(PASS(ret));
1121  return ret.code();
1122  }
1123  std::string resc_id_str = boost::lexical_cast<std::string>(resc_id);;
1124 
1125  // resc name should be leaf name, not root name of the hier
1126  std::string resc_hier;
1127  ret = resc_mgr.leaf_id_to_hier(resc_id, resc_hier);
1128  if(!ret.ok()) {
1129  irods::log(PASS(ret));
1130  return ret.code();
1131  }
1132 
1133  memset( &genQueryInp, 0, sizeof( genQueryInp_t ) );
1134 
1135  snprintf( condStr, MAX_NAME_LEN, "='%s'", filePath );
1136  addInxVal( &genQueryInp.sqlCondInp, COL_D_DATA_PATH, condStr );
1137  snprintf( condStr, MAX_NAME_LEN, "='%s'", resc_id_str.c_str() );
1138  addInxVal( &genQueryInp.sqlCondInp, COL_D_RESC_ID, condStr );
1139 
1140  addInxIval( &genQueryInp.selectInp, COL_D_DATA_ID, 1 );
1141  addInxIval( &genQueryInp.selectInp, COL_COLL_NAME, 1 );
1142  addInxIval( &genQueryInp.selectInp, COL_DATA_NAME, 1 );
1143  addInxIval( &genQueryInp.selectInp, COL_DATA_REPL_NUM, 1 );
1144  addInxIval( &genQueryInp.selectInp, COL_D_RESC_ID, 1 );
1145 
1146  genQueryInp.maxRows = MAX_SQL_ROWS;
1147 
1148  // =-=-=-=-=-=-=-
1149  // when strict acls are enabled, this query would have returned that no file exists.
1150  // this would have resulted in an incorrect orphaning of a file which may actually be
1151  // owned by another user. we potentially disable the use of strict acls for this single
1152  // query in order to avoid orphaning another users physical data.
1153  addKeyVal( &genQueryInp.condInput, DISABLE_STRICT_ACL_KW, "disable" );
1154 
1155  std::string svr_sid;
1156  try {
1157  irods::get_server_property<const std::string>(irods::AGENT_CONN_KW);
1158  status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut );
1159  } catch ( const irods::exception& e ) {
1160  if ( e.code() == KEY_NOT_FOUND ) {
1161  try {
1162  irods::set_server_property<std::string>(irods::AGENT_CONN_KW, "StrictACLOverride");
1163  status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut );
1165  } catch (const irods::exception& e ) {
1166  irods::log(e);
1167  return e.code();
1168  }
1169  } else {
1171  return e.code();
1172  }
1173  }
1174 
1175  clearGenQueryInp( &genQueryInp );
1176  if ( status < 0 ) {
1177  if ( status == CAT_NO_ROWS_FOUND ) {
1178  freeGenQueryOut( &genQueryOut );
1179  rsComm->perfStat.orphanCnt ++;
1180  return 1;
1181  }
1182  else {
1183  rodsLog( LOG_ERROR,
1184  "chkOrphanFile: rsGenQuery error for %s, status = %d, rescName %s",
1185  filePath, status, rescName );
1186  /* we have unexpected query error. Assume the file is not
1187  * orphan */
1188  freeGenQueryOut( &genQueryOut );
1189  return status;
1190  }
1191  }
1192  else {
1193  sqlResult_t *dataId, *replNum, *dataName, *collName;
1194  rsComm->perfStat.nonOrphanCnt++;
1195 
1196  if ( ( collName =
1197  getSqlResultByInx( genQueryOut, COL_COLL_NAME ) ) == NULL ) {
1199  "chkOrphanFile: getSqlResultByInx for COL_COLL_NAME failed" );
1200  return UNMATCHED_KEY_OR_INDEX;
1201  }
1202 
1203  if ( ( dataName = getSqlResultByInx( genQueryOut, COL_DATA_NAME ) )
1204  == NULL ) {
1206  "chkOrphanFile: getSqlResultByInx for COL_DATA_NAME failed" );
1207  return UNMATCHED_KEY_OR_INDEX;
1208  }
1209 
1210  if ( ( dataId = getSqlResultByInx( genQueryOut, COL_D_DATA_ID ) ) == NULL ) {
1212  "chkOrphanFile: getSqlResultByInx for COL_D_DATA_ID failed" );
1213  return UNMATCHED_KEY_OR_INDEX;
1214  }
1215 
1216  if ( ( replNum = getSqlResultByInx( genQueryOut, COL_DATA_REPL_NUM ) ) ==
1217  NULL ) {
1219  "chkOrphanFile: getSqlResultByInx for COL_DATA_REPL_NUM failed" );
1220  return UNMATCHED_KEY_OR_INDEX;
1221  }
1222 
1223  if ( dataObjInfo != NULL ) {
1224  dataObjInfo->dataId = strtoll( dataId->value, 0, 0 );
1225  dataObjInfo->replNum = atoi( replNum->value );
1226  snprintf( dataObjInfo->objPath, MAX_NAME_LEN, "%s/%s",
1227  collName->value, dataName->value );
1228  rstrcpy( dataObjInfo->rescHier, resc_hier.c_str(), MAX_NAME_LEN );
1229  }
1230 
1231  freeGenQueryOut( &genQueryOut );
1232 
1233  return 0;
1234  }
1235 }
1236 
1237 
1238 /* chkOrphanDir - check whether a filePath is a orphan directory.
1239  * return - 1 - the dir is orphan.
1240  * 0 - 0 the dir is not an orphan.
1241  * -ive - query error.
1242  */
1243 
1244 int
1245 chkOrphanDir( rsComm_t *rsComm, char *dirPath, const char *rescName ) {
1246  char subfilePath[MAX_NAME_LEN];
1247  int savedStatus = 1;
1248  int status = 0;
1249 
1250  path srcDirPath( dirPath );
1251  if ( !exists( srcDirPath ) || !is_directory( srcDirPath ) ) {
1252  rodsLog( LOG_ERROR,
1253  "chkOrphanDir: opendir error for %s, errno = %d",
1254  dirPath, errno );
1255  return UNIX_FILE_OPENDIR_ERR - errno;
1256  }
1257  directory_iterator end_itr; // default construction yields past-the-end
1258  for ( directory_iterator itr( srcDirPath ); itr != end_itr; ++itr ) {
1259  path p = itr->path();
1260  snprintf( subfilePath, MAX_NAME_LEN, "%s",
1261  p.c_str() );
1262  if ( !exists( p ) ) {
1263  rodsLog( LOG_ERROR,
1264  "chkOrphanDir: stat error for %s, errno = %d",
1265  subfilePath, errno );
1266  savedStatus = UNIX_FILE_STAT_ERR - errno;
1267  continue;
1268  }
1269  if ( is_directory( p ) ) {
1270  status = chkOrphanDir( rsComm, subfilePath, rescName );
1271  }
1272  else if ( is_regular_file( p ) ) {
1273  status = chkOrphanFile( rsComm, subfilePath, rescName, NULL );
1274  }
1275  if ( status == 0 ) {
1276  /* not orphan */
1277  return status;
1278  }
1279  else if ( status < 0 ) {
1280  savedStatus = status;
1281  }
1282  }
1283  return savedStatus;
1284 }
1285 
1286 
1287 /* resolveSingleReplCopy - given the dataObjInfoHead (up-to-date copies)
1288  * and oldDataObjInfoHead (stale copies) and the destRescGrpInfo,
1289  * sort through the single copy requirement for repl.
1290  * If there is a good copy in every resc in the rescGroup, return
1291  * HAVE_GOOD_COPY. Otherwise, trim the resc in the rescGroup so only the one
1292  * with no copies are left. The copies required to be overwritten are
1293  * placed in destDataObjInfo. The old dataObjInfo that do not need to
1294  * be overwritten are placed in oldDataObjInfoHead which may be needed
1295  * for compound resource staging.
1296  * A returned value of CAT_NO_ROWS_FOUND mean there is condition in
1297  * condInput but none in dataObjInfoHead or oldDataObjInfoHead match
1298  * the condition. i.e., no source for the replication
1299  */
1300 int
1302  dataObjInfo_t **oldDataObjInfoHead,
1303  const std::string& _resc_name, // replaces destRescGrpInfo
1304  dataObjInfo_t **destDataObjInfo,
1305  keyValPair_t *condInput ) {
1306  int status = 0;
1307  dataObjInfo_t *matchedDataObjInfo = NULL;
1308  dataObjInfo_t *matchedOldDataObjInfo = NULL;
1309 
1310  /* see if dataObjInfoHead and oldDataObjInfoHead matches the condInput */
1311  status = matchDataObjInfoByCondInput( dataObjInfoHead, oldDataObjInfoHead,
1312  condInput, &matchedDataObjInfo, &matchedOldDataObjInfo );
1313  if ( status < 0 ) {
1314  return status;
1315  }
1316 
1317  if ( matchedDataObjInfo != NULL ) {
1318  /* que the matched one on top */
1319  queDataObjInfo( dataObjInfoHead, matchedDataObjInfo, 0, 1 );
1320  queDataObjInfo( oldDataObjInfoHead, matchedOldDataObjInfo, 0, 1 );
1321  }
1322  else if ( matchedOldDataObjInfo != NULL ) {
1323  /* The source of replication is an old copy. Queue dataObjInfoHead
1324  * to oldDataObjInfoHead */
1325  queDataObjInfo( oldDataObjInfoHead, *dataObjInfoHead, 0, 1 );
1326  *dataObjInfoHead = matchedOldDataObjInfo;
1327  }
1328 
1329 
1330  /* single target resource */
1331  char* destRescHier = getValByKey( condInput, DEST_RESC_HIER_STR_KW );
1332  if ( ( *destDataObjInfo = chkCopyInResc( *dataObjInfoHead,
1333  _resc_name,
1334  destRescHier ) ) != NULL ) {
1335  /* have a good copy already */
1336  *destDataObjInfo = NULL; // JMC - backport 4594
1337  return HAVE_GOOD_COPY;
1338  }
1339 
1340  /* handle the old dataObj */
1341  if ( getValByKey( condInput, ALL_KW ) != NULL ) {
1342  dataObjInfo_t *trimmedDataObjInfo = NULL;
1343  /* replicate to all resc. trim the resc that has a match and
1344  * the DataObjInfo that does not have a match */
1345  matchAndTrimRescGrp( oldDataObjInfoHead, _resc_name,
1346  TRIM_MATCHED_RESC_INFO | TRIM_UNMATCHED_OBJ_INFO, &trimmedDataObjInfo );
1347  *destDataObjInfo = *oldDataObjInfoHead;
1348  *oldDataObjInfoHead = trimmedDataObjInfo;
1349  }
1350  else {
1351  char* destRescHier = getValByKey( condInput, DEST_RESC_HIER_STR_KW );
1352  *destDataObjInfo = chkCopyInResc( *oldDataObjInfoHead, _resc_name, destRescHier );
1353  if ( *destDataObjInfo != NULL ) {
1354  /* see if there is any resc that is not used */
1355  matchAndTrimRescGrp( oldDataObjInfoHead, _resc_name,
1357  dequeDataObjInfo( oldDataObjInfoHead, *destDataObjInfo );
1358  }
1359  }
1360  return NO_GOOD_COPY;
1361 }
1362 
1363 int
1365  dataObjInfo_t **oldDataObjInfoHead,
1366  const std::string& _resc_name,
1367  keyValPair_t *condInput,
1368  int multiCopyFlag ) {
1369  int status;
1370  dataObjInfo_t *matchedDataObjInfo = NULL;
1371  dataObjInfo_t *matchedOldDataObjInfo = NULL;
1372 
1373  status = matchDataObjInfoByCondInput( dataObjInfoHead, oldDataObjInfoHead,
1374  condInput, &matchedDataObjInfo, &matchedOldDataObjInfo );
1375  if ( status < 0 ) {
1376  return status;
1377  }
1378 
1379  if ( matchedDataObjInfo != NULL ) {
1380  /* put the matched in oldDataObjInfoHead. should not be anything in
1381  * oldDataObjInfoHead */
1382  *oldDataObjInfoHead = *dataObjInfoHead;
1383  *dataObjInfoHead = matchedDataObjInfo;
1384  }
1385 
1386  if ( multiCopyFlag ) {
1387  matchAndTrimRescGrp( dataObjInfoHead, _resc_name,
1389  matchAndTrimRescGrp( oldDataObjInfoHead, _resc_name,
1391  }
1392  else {
1393  matchAndTrimRescGrp( dataObjInfoHead, _resc_name, TRIM_MATCHED_OBJ_INFO, NULL );
1394  }
1395 
1396  if ( _resc_name.empty() ) {
1397  if ( *dataObjInfoHead == NULL ) {
1398  return CAT_NO_ROWS_FOUND;
1399  }
1400  else {
1401  /* have a good copy in all resc in resc group */
1402  rodsLog( LOG_ERROR,
1403  "resolveInfoForPhymv: %s already have copy in the resc",
1404  ( *dataObjInfoHead )->objPath );
1405  return SYS_COPY_ALREADY_IN_RESC;
1406  }
1407  }
1408  else {
1409  return 0;
1410  }
1411 }
1412 
1413 /* matchDataObjInfoByCondInput - given dataObjInfoHead and oldDataObjInfoHead
1414  * put all DataObjInfo that match condInput into matchedDataObjInfo and
1415  * matchedOldDataObjInfo. The unmatch one stay in dataObjInfoHead and
1416  * oldDataObjInfoHead.
1417  * A CAT_NO_ROWS_FOUND means there is condition in CondInput, but none
1418  * in dataObjInfoHead or oldDataObjInfoHead matches the condition
1419  */
1421  dataObjInfo_t **oldDataObjInfoHead, keyValPair_t *condInput,
1422  dataObjInfo_t **matchedDataObjInfo, dataObjInfo_t **matchedOldDataObjInfo )
1423 
1424 {
1425 
1426  int replNumCond;
1427  int replNum = 0;
1428  int rescCond;
1429  bool destHierCond = false;
1430  char *tmpStr, *rescName = NULL;
1431  char* rescHier = NULL;
1432  char* destRescHier = NULL;
1433  dataObjInfo_t *prevDataObjInfo, *nextDataObjInfo, *tmpDataObjInfo;
1434 
1435  if ( dataObjInfoHead == NULL || *dataObjInfoHead == NULL ||
1436  oldDataObjInfoHead == NULL || matchedDataObjInfo == NULL ||
1437  matchedOldDataObjInfo == NULL ) {
1438  rodsLog( LOG_ERROR,
1439  "requeDataObjInfoByCondInput: NULL dataObjInfo input" );
1440  return USER__NULL_INPUT_ERR;
1441  }
1442 
1443  if ( ( tmpStr = getValByKey( condInput, REPL_NUM_KW ) ) != NULL ) {
1444  replNum = atoi( tmpStr );
1445  replNumCond = 1;
1446  }
1447  else {
1448  replNumCond = 0;
1449  }
1450 
1451  destRescHier = getValByKey( condInput, DEST_RESC_HIER_STR_KW );
1452  rescHier = getValByKey( condInput, RESC_HIER_STR_KW );
1453  if ( destRescHier != NULL && rescHier != NULL ) {
1454  destHierCond = true;
1455  }
1456 
1457  // We only use the resource name if the resource hierarchy is not set
1458  if ( !destHierCond && ( rescName = getValByKey( condInput, RESC_NAME_KW ) ) != NULL ) {
1459  rescCond = 1;
1460  }
1461  else {
1462  rescCond = 0;
1463  }
1464 
1465  if ( replNumCond + rescCond == 0 && !destHierCond ) {
1466  return 0;
1467  }
1468  *matchedDataObjInfo = NULL;
1469  *matchedOldDataObjInfo = NULL;
1470 
1471  tmpDataObjInfo = *dataObjInfoHead;
1472  prevDataObjInfo = NULL;
1473  while ( tmpDataObjInfo != NULL ) {
1474  nextDataObjInfo = tmpDataObjInfo->next;
1475  if ( replNumCond == 1 && replNum == tmpDataObjInfo->replNum ) {
1476 
1477 
1478  if ( prevDataObjInfo != NULL ) {
1479  prevDataObjInfo->next = tmpDataObjInfo->next;
1480  }
1481  else {
1482  *dataObjInfoHead = ( *dataObjInfoHead )->next;
1483  }
1484  queDataObjInfo( matchedDataObjInfo, tmpDataObjInfo, 1, 0 );
1485  }
1486  else if ( destHierCond &&
1487  ( strcmp( rescHier, tmpDataObjInfo->rescHier ) == 0 ||
1488  strcmp( destRescHier, tmpDataObjInfo->rescHier ) == 0 ) ) {
1489  if ( prevDataObjInfo != NULL ) {
1490  prevDataObjInfo->next = tmpDataObjInfo->next;
1491  }
1492  else {
1493  *dataObjInfoHead = ( *dataObjInfoHead )->next;
1494  }
1495  queDataObjInfo( matchedDataObjInfo, tmpDataObjInfo, 1, 0 );
1496  }
1497  else if ( rescCond == 1 &&
1498  ( strstr( tmpDataObjInfo->rescHier, rescName ) != 0 ) ) {
1499  if ( prevDataObjInfo != NULL ) {
1500  prevDataObjInfo->next = tmpDataObjInfo->next;
1501  }
1502  else {
1503  *dataObjInfoHead = ( *dataObjInfoHead )->next;
1504  }
1505  /* que single to the bottom */
1506  queDataObjInfo( matchedDataObjInfo, tmpDataObjInfo, 1, 0 );
1507  }
1508  else {
1509  prevDataObjInfo = tmpDataObjInfo;
1510  }
1511  tmpDataObjInfo = nextDataObjInfo;
1512  }
1513 
1514  tmpDataObjInfo = *oldDataObjInfoHead;
1515  prevDataObjInfo = NULL;
1516  while ( tmpDataObjInfo != NULL ) {
1517  nextDataObjInfo = tmpDataObjInfo->next;
1518  if ( replNumCond == 1 && replNum == tmpDataObjInfo->replNum ) {
1519  if ( prevDataObjInfo != NULL ) {
1520  prevDataObjInfo->next = tmpDataObjInfo->next;
1521  }
1522  else {
1523  *oldDataObjInfoHead = ( *oldDataObjInfoHead )->next;
1524  }
1525  queDataObjInfo( matchedOldDataObjInfo, tmpDataObjInfo, 1, 0 );
1526  }
1527  else if ( destHierCond &&
1528  ( strcmp( rescHier, tmpDataObjInfo->rescHier ) == 0 ||
1529  strcmp( destRescHier, tmpDataObjInfo->rescHier ) == 0 ) ) {
1530  if ( prevDataObjInfo != NULL ) {
1531  prevDataObjInfo->next = tmpDataObjInfo->next;
1532  }
1533  else {
1534  *oldDataObjInfoHead = ( *oldDataObjInfoHead )->next;
1535  }
1536  queDataObjInfo( matchedOldDataObjInfo, tmpDataObjInfo, 1, 0 );
1537  }
1538  else if ( rescCond == 1 &&
1539  ( strstr( tmpDataObjInfo->rescHier, rescName ) != 0 ) ) {
1540  if ( prevDataObjInfo != NULL ) {
1541  prevDataObjInfo->next = tmpDataObjInfo->next;
1542  }
1543  else {
1544  *oldDataObjInfoHead = ( *oldDataObjInfoHead )->next;
1545  }
1546  queDataObjInfo( matchedOldDataObjInfo, tmpDataObjInfo, 1, 0 );
1547  }
1548  else {
1549  prevDataObjInfo = tmpDataObjInfo;
1550  }
1551  tmpDataObjInfo = nextDataObjInfo;
1552  }
1553 
1554  if ( *matchedDataObjInfo == NULL && *matchedOldDataObjInfo == NULL ) {
1555  return CAT_NO_ROWS_FOUND;
1556  }
1557  else {
1558  return replNumCond + rescCond;
1559  }
1560 }
1561 
1562 int
1564  keyValPair_t *condInput ) {
1565  const auto* repl_number_string = getValByKey(condInput, REPL_NUM_KW);
1566  int repl_number = -1;
1567 
1568  if (repl_number_string) {
1569  try {
1570  repl_number = std::stoi(repl_number_string);
1571 
1572  if (!contains_replica(*dataObjInfoHead, repl_number)) {
1574  }
1575  }
1576  catch (const std::invalid_argument& e) {
1578  }
1579  catch (const std::out_of_range& e) {
1581  }
1582  }
1583 
1584  int i, status;
1585  dataObjInfo_t *matchedDataObjInfo = NULL;
1586  dataObjInfo_t *matchedOldDataObjInfo = NULL;
1587  dataObjInfo_t *oldDataObjInfoHead = NULL;
1588  dataObjInfo_t *tmpDataObjInfo, *prevDataObjInfo;
1589  int matchedInfoCnt, unmatchedInfoCnt, matchedOldInfoCnt,
1590  unmatchedOldInfoCnt;
1591  int minCnt;
1592  char *tmpStr;
1593  int condFlag;
1594  int toTrim;
1595 
1596  //char* resc_hier = getValByKey( condInput, RESC_HIER_STR_KW );
1597  //char* dst_resc_hier = getValByKey( condInput, DEST_RESC_HIER_STR_KW );
1598  sortObjInfoForRepl( dataObjInfoHead, &oldDataObjInfoHead, 0, NULL, NULL );
1599 
1600  status = matchDataObjInfoByCondInput( dataObjInfoHead, &oldDataObjInfoHead,
1601  condInput, &matchedDataObjInfo, &matchedOldDataObjInfo );
1602  if ( status < 0 ) {
1603  freeAllDataObjInfo( *dataObjInfoHead );
1604  freeAllDataObjInfo( oldDataObjInfoHead );
1605  *dataObjInfoHead = NULL;
1606  if ( status == CAT_NO_ROWS_FOUND ) {
1607  return 0;
1608  }
1609  else {
1610  rodsLog( LOG_NOTICE, "%s - Failed during matching of data objects.", __FUNCTION__ );
1611  return status;
1612  }
1613  }
1614  condFlag = status; /* cond exist if condFlag > 0 */
1615 
1616  if ( matchedDataObjInfo == NULL && matchedOldDataObjInfo == NULL ) {
1617  if ( condFlag == 0 ) {
1618  /* at least have some good copies */
1619  /* see if we can trim some old copies */
1620  matchedOldDataObjInfo = oldDataObjInfoHead;
1621  oldDataObjInfoHead = NULL;
1622  /* also trim good copy too since there is no condition 12/1/09 */
1623  matchedDataObjInfo = *dataObjInfoHead;
1624  *dataObjInfoHead = NULL;
1625  }
1626  else {
1627  /* don't trim anything */
1628  freeAllDataObjInfo( *dataObjInfoHead );
1629  *dataObjInfoHead = nullptr; // JMC cppcheck - nullptr
1630  freeAllDataObjInfo( oldDataObjInfoHead );
1631  return 0;
1632  }
1633  }
1634 
1635  matchedInfoCnt = getDataObjInfoCnt( matchedDataObjInfo );
1636  unmatchedInfoCnt = getDataObjInfoCnt( *dataObjInfoHead );
1637  unmatchedOldInfoCnt = getDataObjInfoCnt( oldDataObjInfoHead );
1638  /* free the unmatched one first */
1639 
1640  freeAllDataObjInfo( *dataObjInfoHead );
1641  freeAllDataObjInfo( oldDataObjInfoHead );
1642  *dataObjInfoHead = oldDataObjInfoHead = nullptr;
1643 
1644  const auto total_good_repls = matchedInfoCnt + unmatchedInfoCnt;
1645 
1646  if ((tmpStr = getValByKey(condInput, COPIES_KW))) {
1647  try {
1648  minCnt = std::stoi(tmpStr);
1649  }
1650  catch (const std::invalid_argument& e) {
1651  minCnt = DEF_MIN_COPY_CNT;
1652  }
1653  catch (const std::out_of_range& e) {
1654  minCnt = DEF_MIN_COPY_CNT;
1655  }
1656 
1657  if (minCnt <= 0) {
1658  minCnt = DEF_MIN_COPY_CNT;
1659  }
1660  else if (minCnt > total_good_repls) {
1661  minCnt = total_good_repls;
1662  }
1663  }
1664  else {
1665  minCnt = DEF_MIN_COPY_CNT;
1666  }
1667 
1668  // the TOTAL number of good replicas that COULD be trimmed.
1669  toTrim = total_good_repls - minCnt;
1670 
1671  if ( toTrim > matchedInfoCnt ) { /* cannot trim more than match */
1672  toTrim = matchedInfoCnt;
1673  }
1674 
1675  if (repl_number > -1) {
1676  // if the number of good replicas is already down to the minimum and the
1677  // client requested that a good replica be trimmed, doing that would violate
1678  // the minimum replicas requirement.
1679  if (total_good_repls == minCnt && contains_replica(matchedDataObjInfo, repl_number)) {
1680  return USER_INCOMPATIBLE_PARAMS;
1681  }
1682  }
1683 
1684  if ( toTrim >= 0 ) {
1685  /* trim all old */
1686  *dataObjInfoHead = matchedOldDataObjInfo;
1687 
1688  /* take some off the bottom - since cache are queued at top. Want
1689  * to trim them first */
1690  for ( i = 0; i < matchedInfoCnt - toTrim; i++ ) {
1691  prevDataObjInfo = NULL;
1692  tmpDataObjInfo = matchedDataObjInfo;
1693  while ( tmpDataObjInfo != NULL ) {
1694  if ( tmpDataObjInfo->next == NULL ) {
1695  if ( prevDataObjInfo == NULL ) {
1696 
1697  matchedDataObjInfo = NULL;
1698  }
1699  else {
1700  prevDataObjInfo->next = NULL;
1701  }
1702  freeDataObjInfo( tmpDataObjInfo );
1703  break;
1704  }
1705  prevDataObjInfo = tmpDataObjInfo;
1706  tmpDataObjInfo = tmpDataObjInfo->next;
1707  }
1708  }
1709  queDataObjInfo( dataObjInfoHead, matchedDataObjInfo, 0, 1 );
1710  }
1711  else {
1712  /* negative toTrim. see if we can trim some matchedOldDataObjInfo */
1713  freeAllDataObjInfo( matchedDataObjInfo );
1714  matchedOldInfoCnt = getDataObjInfoCnt( matchedOldDataObjInfo );
1715  toTrim = matchedOldInfoCnt + unmatchedOldInfoCnt + toTrim;
1716  if ( toTrim > matchedOldInfoCnt ) {
1717  toTrim = matchedOldInfoCnt;
1718  }
1719 
1720  if ( toTrim <= 0 ) {
1721  freeAllDataObjInfo( matchedOldDataObjInfo );
1722  }
1723  else {
1724  /* take some off the bottom - since cache are queued at top. Want
1725  * to trim them first */
1726  for ( i = 0; i < matchedOldInfoCnt - toTrim; i++ ) {
1727  prevDataObjInfo = NULL;
1728  tmpDataObjInfo = matchedOldDataObjInfo;
1729  while ( tmpDataObjInfo != NULL ) {
1730  if ( tmpDataObjInfo->next == NULL ) {
1731  if ( prevDataObjInfo == NULL ) {
1732  matchedOldDataObjInfo = NULL;
1733  }
1734  else {
1735  prevDataObjInfo->next = NULL;
1736  }
1737  freeDataObjInfo( tmpDataObjInfo );
1738  break;
1739  }
1740  prevDataObjInfo = tmpDataObjInfo;
1741  tmpDataObjInfo = tmpDataObjInfo->next;
1742  }
1743  }
1744  queDataObjInfo( dataObjInfoHead, matchedOldDataObjInfo, 0, 1 );
1745  }
1746  }
1747 
1748  return 0;
1749 }
1750 
1751 int
1753  keyValPair_t *condInput, int writeFlag, int topFlag ) {
1754  char *rescName;
1755  int status = -1;
1756  if ( ( rescName = getValByKey( condInput, DEST_RESC_NAME_KW ) ) != NULL ||
1757  ( rescName = getValByKey( condInput, BACKUP_RESC_NAME_KW ) ) != NULL ||
1758  ( rescName = getValByKey( condInput, DEF_RESC_NAME_KW ) ) != NULL ) {
1759 
1760 
1761  status = requeDataObjInfoByResc( dataObjInfoHead, rescName,
1762  writeFlag, topFlag );
1763  }
1764  return status;
1765 }
1766 int
1768  dataObjInfo_t **dataObjInfo ) {
1769  int status, writeFlag;
1770  specCollPerm_t specCollPerm;
1771  writeFlag = getWriteFlag( dataObjInp->openFlags );
1772  if ( writeFlag > 0 ) {
1773  specCollPerm = WRITE_COLL_PERM;
1774  if ( rsComm->clientUser.authInfo.authFlag <= PUBLIC_USER_AUTH ) {
1776  "getDataObjInfoIncSpecColl:open for write not allowed for user %s",
1777  rsComm->clientUser.userName );
1778  return SYS_NO_API_PRIV;
1779  }
1780  }
1781  else {
1782  specCollPerm = READ_COLL_PERM;
1783  }
1784 
1785  if ( dataObjInp->specColl != NULL &&
1786  dataObjInp->specColl->collClass != NO_SPEC_COLL &&
1787  dataObjInp->specColl->collClass != LINKED_COLL ) {
1788  /* if it is linked, it already has been resolved */
1789  status = resolvePathInSpecColl( rsComm, dataObjInp->objPath,
1790  specCollPerm, 0, dataObjInfo );
1792  dataObjInfo != NULL ) {
1793  freeDataObjInfo( *dataObjInfo );
1794  dataObjInfo = NULL;
1795  }
1796  }
1797  else if ( ( status = resolvePathInSpecColl( rsComm, dataObjInp->objPath,
1798  specCollPerm, 1, dataObjInfo ) ) >= 0 ) {
1799  /* check if specColl in cache. May be able to save one query */
1800  }
1801  else if ( getValByKey( &dataObjInp->condInput,
1802  ADMIN_RMTRASH_KW ) != NULL &&
1804  status = getDataObjInfo( rsComm, dataObjInp, dataObjInfo,
1805  NULL, 0 );
1806  }
1807  else if ( writeFlag > 0 && dataObjInp->oprType != REPLICATE_OPR ) {
1808  status = getDataObjInfo( rsComm, dataObjInp, dataObjInfo,
1809  ACCESS_MODIFY_OBJECT, 0 );
1810  }
1811  else {
1812  status = getDataObjInfo( rsComm, dataObjInp, dataObjInfo,
1813  ACCESS_READ_OBJECT, 0 );
1814  }
1815 
1816  if ( status < 0 && dataObjInp->specColl == NULL ) {
1817  int status2;
1818  status2 = resolvePathInSpecColl( rsComm, dataObjInp->objPath,
1819  specCollPerm, 0, dataObjInfo );
1820  if ( status2 < 0 ) {
1821  if ( status2 == SYS_SPEC_COLL_OBJ_NOT_EXIST &&
1822  dataObjInfo != NULL ) {
1823  freeDataObjInfo( *dataObjInfo );
1824  *dataObjInfo = NULL;
1825  }
1826  }
1827  else {
1828  status = 0;
1829  }
1830  }
1831  if ( status >= 0 &&
1832  NULL != dataObjInfo && NULL != ( *dataObjInfo )->specColl ) {
1833  if ( LINKED_COLL == ( *dataObjInfo )->specColl->collClass ) {
1834  /* already been translated */
1835  rstrcpy( dataObjInp->objPath, ( *dataObjInfo )->objPath,
1836  MAX_NAME_LEN );
1837  free( ( *dataObjInfo )->specColl );
1838  ( *dataObjInfo )->specColl = NULL;
1839  }
1840  else if ( getStructFileType( ( *dataObjInfo )->specColl ) >= 0 ) {
1841  dataObjInp->numThreads = NO_THREADING;
1842  }
1843  }
1844  return status;
1845 }
1846 
1847 int regNewObjSize( rsComm_t *rsComm, char *objPath, int replNum,
1848  rodsLong_t newSize ) {
1849  dataObjInfo_t dataObjInfo;
1850  keyValPair_t regParam;
1851  modDataObjMeta_t modDataObjMetaInp;
1852  char tmpStr[MAX_NAME_LEN];
1853  int status;
1854 
1855  if ( objPath == NULL ) {
1856  return USER__NULL_INPUT_ERR;
1857  }
1858 
1859  memset( &dataObjInfo, 0, sizeof( dataObjInfo ) );
1860  memset( &regParam, 0, sizeof( regParam ) );
1861  memset( &modDataObjMetaInp, 0, sizeof( modDataObjMetaInp ) );
1862 
1863  rstrcpy( dataObjInfo.objPath, objPath, MAX_NAME_LEN );
1864  dataObjInfo.replNum = replNum;
1865  snprintf( tmpStr, MAX_NAME_LEN, "%lld", newSize );
1866  addKeyVal( &regParam, DATA_SIZE_KW, tmpStr );
1867 
1868  modDataObjMetaInp.dataObjInfo = &dataObjInfo;
1869  modDataObjMetaInp.regParam = &regParam;
1870  status = rsModDataObjMeta( rsComm, &modDataObjMetaInp );
1871  if ( status < 0 ) {
1872  rodsLog( LOG_ERROR,
1873  "regNewObjSize: rsModDataObjMeta error for %s, status = %d",
1874  objPath, status );
1875  }
1876 
1877  return status;
1878 }
1879 
1881  rsComm_t* _comm,
1882  const std::string& _resc,
1883  std::string& _hier ) {
1884  // =-=-=-=-=-=-=-
1885  // we need to start with the last resource in the hierarchy
1887  parser.set_string( _resc );
1888 
1889  std::string last_resc;
1890  parser.last_resc( last_resc );
1891 
1892  // =-=-=-=-=-=-=-
1893  // see if it has a parent or a child
1894  irods::resource_ptr resc;
1895  irods::error ret = resc_mgr.resolve( last_resc, resc );
1896  if ( !ret.ok() ) {
1897  return PASS( ret );
1898  }
1899 
1900  // =-=-=-=-=-=-=-
1901  // get parent
1902  irods::resource_ptr parent_resc;
1903  ret = resc->get_parent( parent_resc );
1904  bool has_parent = ret.ok();
1905 
1906  // =-=-=-=-=-=-=-
1907  // get child
1908  bool has_child = ( resc->num_children() > 0 );
1909 
1910  // =-=-=-=-=-=-=-
1911  // if the resc is mid-tier this is a Bad Thing
1912  if ( has_parent && has_child ) {
1913  return ERROR(
1915  "resource is mid-tier" );
1916  }
1917 
1918  // =-=-=-=-=-=-=-
1919  // this is a leaf node situation
1920  else if ( has_parent && !has_child ) {
1921  // =-=-=-=-=-=-=-
1922  // get the path from our parent resource
1923  // to this given leaf resource - this our hier
1925  last_resc,
1926  _hier );
1927  if(!ret.ok()){
1928  return PASS(ret);
1929  }
1930  } else if ( !has_parent && !has_child ) {
1931  _hier = last_resc;
1932 
1933  }
1934 
1935  return SUCCESS();
1936 
1937 } // resolve_hierarchy_for_cond_input
1938 
1941 }
1942 
1945 }
1946 
1948  return {};
1949 }
1950 
1952  return {};
1953 }
1954 
1955 bool contains_replica(const dataObjInfo_t* _objects, const std::string& _resc_name) {
1956  return contains_replica_if(_objects, [&_resc_name](const auto& _node) {
1957  const std::string hier{_node.rescHier};
1958  auto b = boost::make_split_iterator(hier, boost::first_finder(";", boost::is_equal{}));
1959  boost::split_iterator<std::string::const_iterator> e{};
1960 
1961  return std::any_of(b, e, [&_resc_name](const auto& _resource_name) {
1962  return _resource_name == _resc_name;
1963  });
1964  });
1965 }
1966 
1967 bool contains_replica(const dataObjInfo_t* _objects, int _replica_number) {
1968  return contains_replica_if(_objects, [_replica_number](const auto& _node) {
1969  return _node.replNum == _replica_number;
1970  });
1971 }
1972 
COL_DATA_TYPE_NAME
#define COL_DATA_TYPE_NAME
Definition: rodsGenQuery.h:168
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
MAX_SQL_ROWS
#define MAX_SQL_ROWS
Definition: rodsGenQuery.h:16
RESC_NAME_KW
#define RESC_NAME_KW
Definition: rodsKeyWdDef.h:19
irods::resource_manager::get_hier_to_root_for_resc
error get_hier_to_root_for_resc(const std::string &, std::string &)
Definition: irods_resource_manager.cpp:434
irods::physical_object::mode
std::string mode() const
Definition: irods_physical_object.hpp:75
NULL
#define NULL
Definition: rodsDef.h:70
irods::RESOURCE_CLASS
const std::string RESOURCE_CLASS("resource_property_class")
irods::delete_server_property
T delete_server_property(const std::string &_prop)
Definition: irods_server_properties.hpp:138
ACCESS_READ_OBJECT
#define ACCESS_READ_OBJECT
Definition: icatDefines.h:52
rsComm_t
Definition: rcConnect.h:145
COL_DATA_REPL_NUM
#define COL_DATA_REPL_NUM
Definition: rodsGenQuery.h:166
addKeyVal
int addKeyVal(keyValPair_t *condInput, const char *keyWord, const char *value)
Definition: rcMisc.cpp:789
DataObjInfo::version
char version[64]
Definition: objInfo.h:136
irods::physical_object::type_name
std::string type_name() const
Definition: irods_physical_object.hpp:51
irods::physical_object::size
long size() const
Definition: irods_physical_object.hpp:36
COL_D_REPL_STATUS
#define COL_D_REPL_STATUS
Definition: rodsGenQuery.h:175
irods::physical_object::path
std::string path() const
Definition: irods_physical_object.hpp:57
SYS_INTERNAL_NULL_INPUT_ERR
@ SYS_INTERNAL_NULL_INPUT_ERR
Definition: rodsErrorTable.h:92
rodsServerHost::localFlag
int localFlag
Definition: rodsConnect.h:68
GenQueryInp::continueInx
int continueInx
Definition: rodsGenQuery.h:28
DataObjInfo::dataCreate
char dataCreate[32]
Definition: objInfo.h:150
SYS_NO_API_PRIV
@ SYS_NO_API_PRIV
Definition: rodsErrorTable.h:81
DataObjInp::openFlags
int openFlags
Definition: dataObjInpOut.h:68
SYS_USER_NO_PERMISSION
@ SYS_USER_NO_PERMISSION
Definition: rodsErrorTable.h:186
DataObjInfo::dataModify
char dataModify[32]
Definition: objInfo.h:151
irods_server_properties.hpp
specColl.hpp
modDataObjMeta.h
matchAndTrimRescGrp
int matchAndTrimRescGrp(dataObjInfo_t **dataObjInfoHead, const std::string &_resc_name, int trimjFlag, dataObjInfo_t **trimmedDataObjInfo)
Definition: dataObjOpr.cpp:883
COL_D_RESC_HIER
#define COL_D_RESC_HIER
Definition: rodsGenQuery.h:184
sortDataObjInfoRandom
int sortDataObjInfoRandom(dataObjInfo_t **dataObjInfoHead)
Definition: dataObjOpr.cpp:701
UNMATCHED_KEY_OR_INDEX
@ UNMATCHED_KEY_OR_INDEX
Definition: rodsErrorTable.h:244
DataObjInp::specColl
specColl_t * specColl
Definition: dataObjInpOut.h:73
dequeDataObjInfo
int dequeDataObjInfo(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t *dataObjInfo)
Definition: rcMisc.cpp:635
userInfo_t::userName
char userName[64]
Definition: rodsUser.h:66
irods::physical_object::checksum
std::string checksum() const
Definition: irods_physical_object.hpp:69
irods_file_object.hpp
irods_stacktrace.hpp
PASS
#define PASS(prev_error_)
Definition: irods_error.hpp:118
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
irods::AGENT_CONN_KW
const std::string AGENT_CONN_KW("agent_conn")
USER_NAME_CLIENT_KW
#define USER_NAME_CLIENT_KW
Definition: rodsKeyWdDef.h:164
DataObjInfo::dataOwnerZone
char dataOwnerZone[64]
Definition: objInfo.h:139
regNewObjSize
int regNewObjSize(rsComm_t *rsComm, char *objPath, int replNum, rodsLong_t newSize)
Definition: dataObjOpr.cpp:1847
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
resolveSingleReplCopy
int resolveSingleReplCopy(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **oldDataObjInfoHead, const std::string &_resc_name, dataObjInfo_t **destDataObjInfo, keyValPair_t *condInput)
Definition: dataObjOpr.cpp:1301
COL_D_DATA_STATUS
#define COL_D_DATA_STATUS
Definition: rodsGenQuery.h:176
sortObjInfoForRepl
int sortObjInfoForRepl(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **oldDataObjInfoHead, int deleteOldFlag, const char *resc_hier, const char *dst_resc_hier)
Definition: dataObjOpr.cpp:945
SYS_SPEC_COLL_OBJ_NOT_EXIST
@ SYS_SPEC_COLL_OBJ_NOT_EXIST
Definition: rodsErrorTable.h:123
GenQueryInp
Definition: rodsGenQuery.h:24
DataObjInfo::dataType
char dataType[64]
Definition: objInfo.h:133
HAVE_GOOD_COPY
#define HAVE_GOOD_COPY
Definition: dataObjOpr.hpp:24
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
rcMisc.h
ACCESS_PERMISSION_KW
#define ACCESS_PERMISSION_KW
Definition: rodsKeyWdDef.h:185
PUBLIC_USER_AUTH
#define PUBLIC_USER_AUTH
Definition: rodsUser.h:32
irods::is_hier_live
error is_hier_live(const std::string &)
Definition: irods_resource_backport.cpp:234
pid_age.p
p
Definition: pid_age.py:13
freeDataObjInfo
int freeDataObjInfo(dataObjInfo_t *dataObjInfo)
Definition: rcMisc.cpp:544
DataObjInfo::rescId
rodsLong_t rescId
Definition: objInfo.h:164
LONG_NAME_LEN
#define LONG_NAME_LEN
Definition: rodsDef.h:57
irods.pypyodbc.version
string version
Definition: pypyodbc.py:28
getStructFileType
int getStructFileType(specColl_t *specColl)
Definition: objMetaOpr.cpp:386
DataObjInfo::rescHier
char rescHier[(1024+64)]
Definition: objInfo.h:132
DataObjInfo::replStatus
int replStatus
Definition: objInfo.h:141
LOCAL_HOST
#define LOCAL_HOST
Definition: rodsConnect.h:44
contains_replica
bool contains_replica(const dataObjInfo_t *_objects, const std::string &_resc_name)
Definition: dataObjOpr.cpp:1955
irods::physical_object::name
std::string name() const
Definition: irods_physical_object.hpp:45
zoneInfo::zoneName
char zoneName[64]
Definition: rodsConnect.h:75
irods::physical_object::id
long id() const
Definition: irods_physical_object.hpp:39
resolve_hierarchy_for_resc_from_cond_input
irods::error resolve_hierarchy_for_resc_from_cond_input(rsComm_t *_comm, const std::string &_resc, std::string &_hier)
Definition: dataObjOpr.cpp:1880
irods_resource_backport.hpp
WRITE_COLL_PERM
@ WRITE_COLL_PERM
Definition: objInfo.h:99
irods::physical_object::owner_name
std::string owner_name() const
Definition: irods_physical_object.hpp:60
REPL_NUM_KW
#define REPL_NUM_KW
Definition: rodsKeyWdDef.h:30
ALL_KW
#define ALL_KW
Definition: rodsKeyWdDef.h:10
DataObjInfo::collId
rodsLong_t collId
Definition: objInfo.h:144
manual_cleanup.zone_name
zone_name
Definition: manual_cleanup.py:16
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
irods::physical_object::create_ts
std::string create_ts() const
Definition: irods_physical_object.hpp:81
DataObjInfo::filePath
char filePath[(1024+64)]
Definition: objInfo.h:137
DataObjInfo::dataComments
char dataComments[256]
Definition: objInfo.h:147
resolveInfoForPhymv
int resolveInfoForPhymv(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **oldDataObjInfoHead, const std::string &_resc_name, keyValPair_t *condInput, int multiCopyFlag)
Definition: dataObjOpr.cpp:1364
addInxVal
int addInxVal(inxValPair_t *inxValPair, int inx, const char *value)
Definition: rcMisc.cpp:921
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
rescCond
char * rescCond[]
Definition: rcGlobal.cpp:62
ZoneInfoHead
zoneInfo_t * ZoneInfoHead
Definition: irods_server_globals.cpp:23
rsDataObjTrim.hpp
DATA_SIZE_KW
#define DATA_SIZE_KW
Definition: rodsKeyWdDef.h:24
ruleExecDel.h
NO_THREADING
#define NO_THREADING
Definition: rodsDef.h:100
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
COL_D_DATA_CHECKSUM
#define COL_D_DATA_CHECKSUM
Definition: rodsGenQuery.h:177
DataObjInfo::dataId
rodsLong_t dataId
Definition: objInfo.h:143
DataObjInfo::next
struct DataObjInfo * next
Definition: objInfo.h:163
GenQueryInp::selectInp
inxIvalPair_t selectInp
Definition: rodsGenQuery.h:53
GenQueryInp::maxRows
int maxRows
Definition: rodsGenQuery.h:25
COL_D_OWNER_NAME
#define COL_D_OWNER_NAME
Definition: rodsGenQuery.h:173
initDataObjInfoQuery
int initDataObjInfoQuery(dataObjInp_t *dataObjInp, genQueryInp_t *genQueryInp, int ignoreCondInput)
Definition: dataObjOpr.cpp:1044
irods::physical_object::is_dirty
int is_dirty() const
Definition: irods_physical_object.hpp:27
irods::linked_list_iterator
Definition: irods_linked_list_iterator.hpp:19
requeDataObjInfoByDestResc
int requeDataObjInfoByDestResc(dataObjInfo_t **dataObjInfoHead, keyValPair_t *condInput, int writeFlag, int topFlag)
Definition: dataObjOpr.cpp:1752
COL_DATA_NAME
#define COL_DATA_NAME
Definition: rodsGenQuery.h:165
BACKUP_RESC_NAME_KW
#define BACKUP_RESC_NAME_KW
Definition: rodsKeyWdDef.h:22
validate_logical_path
irods::error validate_logical_path(const std::string &_path)
Definition: dataObjOpr.cpp:47
DEST_RESC_NAME_KW
#define DEST_RESC_NAME_KW
Definition: rodsKeyWdDef.h:20
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
getNumDataObjInfo
int getNumDataObjInfo(dataObjInfo_t *dataObjInfoHead)
Definition: dataObjOpr.cpp:688
irods::physical_object::expiry_ts
std::string expiry_ts() const
Definition: irods_physical_object.hpp:72
COPIES_KW
#define COPIES_KW
Definition: rodsKeyWdDef.h:11
irods::error::code
long long code() const
Definition: irods_error.cpp:194
LINKED_COLL
@ LINKED_COLL
Definition: objInfo.h:49
RESC_HIER_STR_KW
#define RESC_HIER_STR_KW
Definition: rodsKeyWdDef.h:225
irods::physical_object::r_comment
std::string r_comment() const
Definition: irods_physical_object.hpp:78
RODS_ZONE_CLIENT_KW
#define RODS_ZONE_CLIENT_KW
Definition: rodsKeyWdDef.h:165
getSqlResultByInx
sqlResult_t * getSqlResultByInx(genQueryOut_t *genQueryOut, int attriInx)
Definition: rcMisc.cpp:1387
chkCopyInResc
dataObjInfo_t * chkCopyInResc(dataObjInfo_t *&dataObjInfoHead, const std::string &_resc_name, const char *destRescHier)
Definition: dataObjOpr.cpp:842
irods::physical_object::repl_num
int repl_num() const
Definition: irods_physical_object.hpp:30
rsComm_t::proxyUser
userInfo_t proxyUser
Definition: rcConnect.h:152
GenQueryOut::continueInx
int continueInx
Definition: rodsGenQuery.h:70
freeAllDataObjInfo
int freeAllDataObjInfo(dataObjInfo_t *dataObjInfoHead)
Definition: rcMisc.cpp:561
DataObjInfo::dataOwnerName
char dataOwnerName[64]
Definition: objInfo.h:138
ruleExecSubmit.h
COL_D_MODIFY_TIME
#define COL_D_MODIFY_TIME
Definition: rodsGenQuery.h:182
irods::hierarchy_parser::resc_in_hier
bool resc_in_hier(const std::string &_resc) const
Definition: irods_hierarchy_parser.cpp:214
ANONYMOUS_USER
#define ANONYMOUS_USER
Definition: rodsDef.h:133
TIME_LEN
#define TIME_LEN
Definition: rodsDef.h:54
GenQueryInp::condInput
keyValPair_t condInput
Definition: rodsGenQuery.h:52
resolveInfoForTrim
int resolveInfoForTrim(dataObjInfo_t **dataObjInfoHead, keyValPair_t *condInput)
Definition: dataObjOpr.cpp:1563
COL_DATA_VERSION
#define COL_DATA_VERSION
Definition: rodsGenQuery.h:167
irods::physical_object::owner_zone
std::string owner_zone() const
Definition: irods_physical_object.hpp:63
COL_D_CREATE_TIME
#define COL_D_CREATE_TIME
Definition: rodsGenQuery.h:181
UNIX_FILE_OPENDIR_ERR
@ UNIX_FILE_OPENDIR_ERR
Definition: rodsErrorTable.h:312
DEF_MIN_COPY_CNT
#define DEF_MIN_COPY_CNT
Definition: rsDataObjTrim.hpp:7
GenQueryInp::sqlCondInp
inxValPair_t sqlCondInp
Definition: rodsGenQuery.h:56
DataObjInp
Definition: dataObjInpOut.h:65
genQuery.h
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
getWriteFlag
int getWriteFlag(int openFlag)
Definition: physPath.cpp:386
irods::resource_manager::resolve
error resolve(std::string, resource_ptr &)
Definition: irods_resource_manager.cpp:51
zoneInfo::next
struct zoneInfo * next
Definition: rodsConnect.h:79
specCollPerm_t
specCollPerm_t
Definition: objInfo.h:96
matchDataObjInfoByCondInput
int matchDataObjInfoByCondInput(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **oldDataObjInfoHead, keyValPair_t *condInput, dataObjInfo_t **matchedDataObjInfo, dataObjInfo_t **matchedOldDataObjInfo)
Definition: dataObjOpr.cpp:1420
addInxIval
int addInxIval(inxIvalPair_t *inxIvalPair, int inx, int value)
Definition: rcMisc.cpp:883
TICKET_KW
#define TICKET_KW
Definition: rodsKeyWdDef.h:109
KEY_NOT_FOUND
@ KEY_NOT_FOUND
Definition: rodsErrorTable.h:749
DataObjInfo::writeFlag
int writeFlag
Definition: objInfo.h:154
ADMIN_KW
#define ADMIN_KW
Definition: rodsKeyWdDef.h:62
irods::physical_object::map_id
long map_id() const
Definition: irods_physical_object.hpp:33
COL_D_EXPIRY
#define COL_D_EXPIRY
Definition: rodsGenQuery.h:178
GenQueryOut
Definition: rodsGenQuery.h:67
irods::physical_object
Definition: irods_physical_object.hpp:10
DataObjInfo::replNum
int replNum
Definition: objInfo.h:140
chkOrphanDir
int chkOrphanDir(rsComm_t *rsComm, char *dirPath, const char *rescName)
Definition: dataObjOpr.cpp:1245
irods::hierarchy_parser::set_string
error set_string(const std::string &_resc_hier)
Definition: irods_hierarchy_parser.cpp:36
LOCAL_PRIV_USER_AUTH
#define LOCAL_PRIV_USER_AUTH
Definition: rodsUser.h:36
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
NO_SPEC_COLL
@ NO_SPEC_COLL
Definition: objInfo.h:46
rsComm_t::perfStat
perfStat_t perfStat
Definition: rcConnect.h:162
userInfo_t::rodsZone
char rodsZone[64]
Definition: rodsUser.h:67
READ_COLL_PERM
@ READ_COLL_PERM
Definition: objInfo.h:98
collection.hpp
splitPathByKey
int splitPathByKey(const char *srcPath, char *dir, size_t maxDirLen, char *file, size_t maxFileLen, char key)
Definition: stringOpr.cpp:222
contains_replica_if
bool contains_replica_if(const dataObjInfo_t *_objects, UnaryPredicate &&_pred)
Definition: dataObjOpr.hpp:135
GenQueryOut::rowCnt
int rowCnt
Definition: rodsGenQuery.h:68
physPath.hpp
irods::log
void log(const error &)
Definition: irods_log.cpp:13
perfStat_t::nonOrphanCnt
int nonOrphanCnt
Definition: rcConnect.h:141
DEF_RESC_NAME_KW
#define DEF_RESC_NAME_KW
Definition: rodsKeyWdDef.h:21
DEST_RESC_HIER_STR_KW
#define DEST_RESC_HIER_STR_KW
Definition: rodsKeyWdDef.h:226
modDataObjMeta_t::regParam
keyValPair_t * regParam
Definition: modDataObjMeta.h:9
begin
irods::linked_list_iterator< dataObjInfo_t > begin(dataObjInfo_t *_objects) noexcept
Definition: dataObjOpr.cpp:1939
rsIcatOpr.hpp
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
rsComm_t::clientUser
userInfo_t clientUser
Definition: rcConnect.h:153
COL_D_COMMENTS
#define COL_D_COMMENTS
Definition: rodsGenQuery.h:180
irods::physical_object::status
std::string status() const
Definition: irods_physical_object.hpp:66
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
QUERY_BY_DATA_ID_KW
#define QUERY_BY_DATA_ID_KW
Definition: rodsKeyWdDef.h:85
resolvePathInSpecColl
int resolvePathInSpecColl(rsComm_t *rsComm, char *objPath, specCollPerm_t specCollPerm, int inCachOnly, dataObjInfo_t **dataObjInfo)
Definition: specColl.cpp:644
sortObjInfoForOpen
int sortObjInfoForOpen(dataObjInfo_t **dataObjInfoHead, keyValPair_t *condInput, int writeFlag)
Definition: dataObjOpr.cpp:548
irods::error
Definition: irods_error.hpp:23
modDataObjMeta_t::dataObjInfo
dataObjInfo_t * dataObjInfo
Definition: modDataObjMeta.h:8
NO_GOOD_COPY
#define NO_GOOD_COPY
Definition: dataObjOpr.hpp:23
HIERARCHY_ERROR
@ HIERARCHY_ERROR
Definition: rodsErrorTable.h:752
irods::resource_manager::leaf_id_to_hier
error leaf_id_to_hier(const rodsLong_t &, std::string &)
Definition: irods_resource_manager.cpp:1119
perfStat_t::orphanCnt
int orphanCnt
Definition: rcConnect.h:140
DataObjInfo::chksum
char chksum[64]
Definition: objInfo.h:135
getDataObjInfoIncSpecColl
int getDataObjInfoIncSpecColl(rsComm_t *rsComm, dataObjInp_t *dataObjInp, dataObjInfo_t **dataObjInfo)
Definition: dataObjOpr.cpp:1767
SYS_RESC_IS_DOWN
@ SYS_RESC_IS_DOWN
Definition: rodsErrorTable.h:170
SqlResult::value
char * value
Definition: rodsGenQuery.h:64
REPLICATE_OPR
#define REPLICATE_OPR
Definition: dataObjInpOut.h:172
USER_INVALID_REPLICA_INPUT
@ USER_INVALID_REPLICA_INPUT
Definition: rodsErrorTable.h:289
irods_hierarchy_parser.hpp
DataObjInfo::dataExpiry
char dataExpiry[32]
Definition: objInfo.h:149
getDataObjInfo
int getDataObjInfo(rsComm_t *rsComm, dataObjInp_t *dataObjInp, dataObjInfo_t **dataObjInfoHead, char *accessPerm, int ignoreCondInput)
Definition: dataObjOpr.cpp:87
TRIM_MATCHED_RESC_INFO
#define TRIM_MATCHED_RESC_INFO
Definition: dataObjOpr.hpp:27
COL_D_OWNER_ZONE
#define COL_D_OWNER_ZONE
Definition: rodsGenQuery.h:174
TRIM_UNMATCHED_OBJ_INFO
#define TRIM_UNMATCHED_OBJ_INFO
Definition: dataObjOpr.hpp:30
irods::resource_manager::hier_to_leaf_id
error hier_to_leaf_id(const std::string &, rodsLong_t &)
Definition: irods_resource_manager.cpp:1082
rodsServerHost
Definition: rodsConnect.h:62
DataObjInfo::rescName
char rescName[64]
Definition: objInfo.h:131
getDataObjInfoCnt
int getDataObjInfoCnt(dataObjInfo_t *dataObjInfoHead)
Definition: rcMisc.cpp:661
TRIM_MATCHED_OBJ_INFO
#define TRIM_MATCHED_OBJ_INFO
Definition: dataObjOpr.hpp:29
DataObjInp::oprType
int oprType
Definition: dataObjInpOut.h:72
CAT_NO_ROWS_FOUND
@ CAT_NO_ROWS_FOUND
Definition: rodsErrorTable.h:423
SqlResult
Definition: rodsGenQuery.h:61
irods.six.b
def b(s)
Definition: six.py:606
DataObjInfo::dataMapId
int dataMapId
Definition: objInfo.h:145
chkOrphanFile
int chkOrphanFile(rsComm_t *rsComm, char *filePath, const char *rescName, dataObjInfo_t *dataObjInfo)
Definition: dataObjOpr.cpp:1099
irods::file_object_ptr
boost::shared_ptr< file_object > file_object_ptr
Definition: irods_file_object.hpp:145
rsModDataObjMeta
int rsModDataObjMeta(rsComm_t *rsComm, modDataObjMeta_t *modDataObjMetaInp)
Definition: rsModDataObjMeta.cpp:23
COL_COLL_NAME
#define COL_COLL_NAME
Definition: rodsGenQuery.h:189
getHierarchyForResc.h
irods::physical_object::modify_ts
std::string modify_ts() const
Definition: irods_physical_object.hpp:84
rsModDataObjMeta.hpp
irods::physical_object::version
std::string version() const
Definition: irods_physical_object.hpp:48
resource.hpp
irods::exception
Definition: irods_exception.hpp:15
SqlResult::len
int len
Definition: rodsGenQuery.h:63
USER_INCOMPATIBLE_PARAMS
@ USER_INCOMPATIBLE_PARAMS
Definition: rodsErrorTable.h:288
icatHighLevelRoutines.hpp
COL_D_MAP_ID
#define COL_D_MAP_ID
Definition: rodsGenQuery.h:179
end
irods::linked_list_iterator< dataObjInfo_t > end(dataObjInfo_t *_objects) noexcept
Definition: dataObjOpr.cpp:1947
irods::physical_object::resc_name
std::string resc_name() const
Definition: irods_physical_object.hpp:54
requeDataObjInfoByReplNum
int requeDataObjInfoByReplNum(dataObjInfo_t **dataObjInfoHead, int replNum)
Definition: dataObjOpr.cpp:806
DataObjInfo::objPath
char objPath[(1024+64)]
Definition: objInfo.h:130
SHORT_STR_LEN
#define SHORT_STR_LEN
Definition: rodsDef.h:67
irods::physical_object::resc_hier
std::string resc_hier() const
Definition: irods_physical_object.hpp:87
COL_D_COLL_ID
#define COL_D_COLL_ID
Definition: rodsGenQuery.h:164
rsGenQuery.hpp
irods_random.hpp
userInfo_t::authInfo
authInfo_t authInfo
Definition: rodsUser.h:70
UNIX_FILE_STAT_ERR
@ UNIX_FILE_STAT_ERR
Definition: rodsErrorTable.h:306
miscUtil.h
REQUE_MATCHED_RESC_INFO
#define REQUE_MATCHED_RESC_INFO
Definition: dataObjOpr.hpp:28
rstrcpy
char * rstrcpy(char *dest, const char *src, int maxLen)
Definition: stringOpr.cpp:51
COL_D_DATA_PATH
#define COL_D_DATA_PATH
Definition: rodsGenQuery.h:172
dataObjOpr.hpp
DataObjInp::condInput
keyValPair_t condInput
Definition: dataObjInpOut.h:74
sortObjInfo
int sortObjInfo(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **currentArchInfo, dataObjInfo_t **currentCacheInfo, dataObjInfo_t **oldArchInfo, dataObjInfo_t **oldCacheInfo, dataObjInfo_t **downCurrentInfo, dataObjInfo_t **downOldInfo, const char *resc_hier)
Definition: dataObjOpr.cpp:408
modDataObjMeta_t
Definition: modDataObjMeta.h:7
zoneInfo
Definition: rodsConnect.h:74
freeGenQueryOut
int freeGenQueryOut(genQueryOut_t **genQueryOut)
Definition: rcMisc.cpp:1133
ACCESS_MODIFY_OBJECT
#define ACCESS_MODIFY_OBJECT
Definition: icatDefines.h:59
SYS_COPY_ALREADY_IN_RESC
@ SYS_COPY_ALREADY_IN_RESC
Definition: rodsErrorTable.h:113
NAME_LEN
#define NAME_LEN
Definition: rodsDef.h:55
KeyValPair
Definition: objInfo.h:120
DataObjInfo::statusString
char statusString[64]
Definition: objInfo.h:142
authInfo_t::authFlag
int authFlag
Definition: rodsUser.h:42
create_and_sort_data_obj_info_for_open
int create_and_sort_data_obj_info_for_open(const std::string &resc_hier, const irods::file_object_ptr file_obj, dataObjInfo_t **data_obj_info_head)
Definition: dataObjOpr.cpp:610
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")
DISABLE_STRICT_ACL_KW
#define DISABLE_STRICT_ACL_KW
Definition: rodsKeyWdDef.h:285
COL_DATA_SIZE
#define COL_DATA_SIZE
Definition: rodsGenQuery.h:169
dataObjTrim.h
DataObjInfo::dataSize
rodsLong_t dataSize
Definition: objInfo.h:134
clearGenQueryInp
void clearGenQueryInp(void *voidInp)
Definition: rcMisc.cpp:1118
rsGenQuery
int rsGenQuery(rsComm_t *rsComm, genQueryInp_t *genQueryInp, genQueryOut_t **genQueryOut)
Definition: rsGenQuery.cpp:604
DataObjInp::numThreads
int numThreads
Definition: dataObjInpOut.h:71
queDataObjInfo
int queDataObjInfo(dataObjInfo_t **dataObjInfoHead, dataObjInfo_t *dataObjInfo, int singleInfoFlag, int topFlag)
Definition: rcMisc.cpp:581
DataObjInfo::dataMode
char dataMode[32]
Definition: objInfo.h:148
irods_log.hpp
irods::physical_object::coll_id
long coll_id() const
Definition: irods_physical_object.hpp:42
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32
ADMIN_RMTRASH_KW
#define ADMIN_RMTRASH_KW
Definition: rodsKeyWdDef.h:63
requeDataObjInfoByResc
int requeDataObjInfoByResc(dataObjInfo_t **dataObjInfoHead, const char *preferredResc, int writeFlag, int topFlag)
Definition: dataObjOpr.cpp:760
objMetaOpr.hpp
SpecColl::collClass
specCollClass_t collClass
Definition: objInfo.h:77
dataCreate
int dataCreate(rsComm_t *rsComm, int l1descInx)
Definition: rsDataObjCreate.cpp:476
irods::is_resc_live
error is_resc_live(rodsLong_t)
Definition: irods_resource_backport.cpp:263
COL_D_RESC_ID
#define COL_D_RESC_ID
Definition: rodsGenQuery.h:185
COL_D_DATA_ID
#define COL_D_DATA_ID
Definition: rodsGenQuery.h:163
USER__NULL_INPUT_ERR
@ USER__NULL_INPUT_ERR
Definition: rodsErrorTable.h:247
COL_DATA_MODE
#define COL_DATA_MODE
Definition: rodsGenQuery.h:183