int getRescForGetInColl( rsComm_t *rsComm, collInp_t *collInp, hostSearchStat_t *hostSearchStat ) { collEnt_t *collEnt; int handleInx; int status; if ( collInp == NULL || hostSearchStat == NULL ) { return USER__NULL_INPUT_ERR; } handleInx = rsOpenCollection( rsComm, collInp ); if ( handleInx < 0 ) { return handleInx; } while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( collEnt->objType == DATA_OBJ_T ) { dataObjInp_t dataObjInp; bzero( &dataObjInp, sizeof( dataObjInp ) ); snprintf( dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collEnt->collName, collEnt->dataName ); status = getRescForGetInDataObj( rsComm, &dataObjInp, hostSearchStat ); if ( status < 0 ) { rodsLog( LOG_NOTICE, "getRescForGetInColl: getRescForGetInDataObj %s err, stat=%d", dataObjInp.objPath, status ); } } else if ( collEnt->objType == COLL_OBJ_T ) { collInp_t myCollInp; bzero( &myCollInp, sizeof( myCollInp ) ); rstrcpy( myCollInp.collName, collEnt->collName, MAX_NAME_LEN ); status = getRescForGetInColl( rsComm, &myCollInp, hostSearchStat ); if ( status < 0 ) { rodsLog( LOG_NOTICE, "getRescForGetInColl: getRescForGetInColl %s err, stat=%d", collEnt->collName, status ); } } free( collEnt ); /* just free collEnt but not content */ if ( hostSearchStat->totalCount >= MAX_HOST_TO_SEARCH ) { /* done */ rsCloseCollection( rsComm, &handleInx ); return 0; } } rsCloseCollection( rsComm, &handleInx ); return 0; }
int isCollEmpty( rsComm_t *rsComm, char *collection ) { collInp_t openCollInp; collEnt_t *collEnt; int handleInx; int entCnt = 0; if ( rsComm == NULL || collection == NULL ) { rodsLog( LOG_ERROR, "isCollEmpty: Input rsComm or collection is NULL" ); return True; } memset( &openCollInp, 0, sizeof( openCollInp ) ); rstrcpy( openCollInp.collName, collection, MAX_NAME_LEN ); /* cannot query recur because collection is sorted in wrong order */ openCollInp.flags = 0; handleInx = rsOpenCollection( rsComm, &openCollInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "isCollEmpty: rsOpenCollection of %s error. status = %d", openCollInp.collName, handleInx ); return True; } while ( rsReadCollection( rsComm, &handleInx, &collEnt ) >= 0 ) { entCnt++; free( collEnt ); /* just free collEnt but not content */ } rsCloseCollection( rsComm, &handleInx ); if ( entCnt > 0 ) { return False; } else { return True; } }
int rsCollRepl (rsComm_t *rsComm, collInp_t *collReplInp, collOprStat_t **collOprStat) { int status; dataObjInp_t dataObjInp; collEnt_t *collEnt; int handleInx; transferStat_t myTransStat; int totalFileCnt; int fileCntPerStatOut; int savedStatus = 0; int remoteFlag; rodsServerHost_t *rodsServerHost; /* try to connect to dest resc */ bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, collReplInp->collName, MAX_NAME_LEN); remoteFlag = getAndConnRemoteZone (rsComm, &dataObjInp, &rodsServerHost, REMOTE_CREATE); if (remoteFlag < 0) { return (remoteFlag); } else if (remoteFlag == REMOTE_HOST) { int retval; retval = _rcCollRepl (rodsServerHost->conn, collReplInp, collOprStat); if (retval < 0) return retval; status = svrSendZoneCollOprStat (rsComm, rodsServerHost->conn, *collOprStat, retval); return status; } fileCntPerStatOut = FILE_CNT_PER_STAT_OUT; if (collOprStat != NULL) *collOprStat = NULL; collReplInp->flags = RECUR_QUERY_FG; handleInx = rsOpenCollection (rsComm, collReplInp); if (handleInx < 0) { rodsLog (LOG_ERROR, "rsCollRepl: rsOpenCollection of %s error. status = %d", collReplInp->collName, handleInx); return (handleInx); } if (collOprStat != NULL) { *collOprStat = (collOprStat_t*)malloc (sizeof (collOprStat_t)); memset (*collOprStat, 0, sizeof (collOprStat_t)); } if (CollHandle[handleInx].rodsObjStat->specColl != NULL) { rodsLog (LOG_ERROR, "rsCollRepl: unable to replicate mounted collection %s", collReplInp->collName); rsCloseCollection (rsComm, &handleInx); return (0); } while ((status = rsReadCollection (rsComm, &handleInx, &collEnt)) >= 0) { if (collEnt->objType == DATA_OBJ_T) { if (totalFileCnt == 0) totalFileCnt = CollHandle[handleInx].dataObjSqlResult.totalRowCount; bzero (&dataObjInp, sizeof (dataObjInp)); snprintf (dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collEnt->collName, collEnt->dataName); dataObjInp.condInput = collReplInp->condInput; memset (&myTransStat, 0, sizeof (myTransStat)); status = _rsDataObjRepl (rsComm, &dataObjInp, &myTransStat, NULL); if (status == SYS_COPY_ALREADY_IN_RESC) { savedStatus = status; status = 0; } if (status < 0) { rodsLogError (LOG_ERROR, status, "rsCollRepl: rsDataObjRepl failed for %s. status = %d", dataObjInp.objPath, status); savedStatus = status; break; } else { if (collOprStat != NULL) { (*collOprStat)->bytesWritten += myTransStat.bytesWritten; (*collOprStat)->filesCnt ++; } } if (collOprStat != NULL && (*collOprStat)->filesCnt >= fileCntPerStatOut) { rstrcpy ((*collOprStat)->lastObjPath, dataObjInp.objPath, MAX_NAME_LEN); (*collOprStat)->totalFileCnt = totalFileCnt; status = svrSendCollOprStat (rsComm, *collOprStat); if (status < 0) { rodsLogError (LOG_ERROR, status, "rsCollRepl: svrSendCollOprStat failed for %s. status = %d", dataObjInp.objPath, status); *collOprStat = NULL; savedStatus = status; break; } *collOprStat = (collOprStat_t*)malloc (sizeof (collOprStat_t)); memset (*collOprStat, 0, sizeof (collOprStat_t)); } } free (collEnt); /* just free collEnt but not content */ } rsCloseCollection (rsComm, &handleInx); return (savedStatus); }
int _rsPhyBundleColl( rsComm_t* rsComm, structFileExtAndRegInp_t* phyBundleCollInp, const char *_resc_name ) { collInp_t collInp; bzero( &collInp, sizeof( collInp ) ); rstrcpy( collInp.collName, phyBundleCollInp->collection, MAX_NAME_LEN ); collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG; char* srcRescName = getValByKey( &phyBundleCollInp->condInput, RESC_NAME_KW ); if ( srcRescName != NULL ) { collInp.flags |= INCLUDE_CONDINPUT_IN_QUERY; addKeyVal( &collInp.condInput, RESC_NAME_KW, srcRescName ); } int handleInx = rsOpenCollection( rsComm, &collInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "_rsPhyBundleColl: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx ); return handleInx; } if ( CollHandle[handleInx].rodsObjStat->specColl != NULL ) { rodsLog( LOG_ERROR, "_rsPhyBundleColl: unable to bundle special collection %s", collInp.collName ); rsCloseCollection( rsComm, &handleInx ); return 0; } /* create the bundle file */ char* dataType = getValByKey( &phyBundleCollInp->condInput, DATA_TYPE_KW ); // JMC - backport 4658 char* rescHier = getValByKey( &phyBundleCollInp->condInput, RESC_HIER_STR_KW ); dataObjInp_t dataObjInp; int l1descInx = createPhyBundleDataObj( rsComm, phyBundleCollInp->collection, _resc_name, rescHier, &dataObjInp, dataType ); // JMC - backport 4658 if ( l1descInx < 0 ) { return l1descInx; } // =-=-=-=-=-=-=- // JMC - backport 4528 int chksumFlag = -1; if ( getValByKey( &phyBundleCollInp->condInput, VERIFY_CHKSUM_KW ) != NULL ) { L1desc[l1descInx].chksumFlag = VERIFY_CHKSUM; chksumFlag = 1; } else { chksumFlag = 0; } // =-=-=-=-=-=-=- // JMC - backport 4771 int maxSubFileCnt = -1; // JMC - backport 4528, 4771 if ( getValByKey( &phyBundleCollInp->condInput, MAX_SUB_FILE_KW ) != NULL ) { maxSubFileCnt = atoi( getValByKey( &phyBundleCollInp->condInput, MAX_SUB_FILE_KW ) ); } else { maxSubFileCnt = MAX_SUB_FILE_CNT; } rodsLong_t maxBunSize; if ( getValByKey( &phyBundleCollInp->condInput, MAX_BUNDLE_SIZE_KW ) != NULL ) { maxBunSize = atoi( getValByKey( &phyBundleCollInp->condInput, MAX_BUNDLE_SIZE_KW ) ) * OneGig; } else { maxBunSize = MAX_BUNDLE_SIZE * OneGig; } // =-=-=-=-=-=-=- char phyBunDir[MAX_NAME_LEN]; createPhyBundleDir( rsComm, L1desc[l1descInx].dataObjInfo->filePath, phyBunDir, L1desc[l1descInx].dataObjInfo->rescHier ); curSubFileCond_t curSubFileCond; bunReplCacheHeader_t bunReplCacheHeader; bzero( &bunReplCacheHeader, sizeof( bunReplCacheHeader ) ); bzero( &curSubFileCond, sizeof( curSubFileCond ) ); int status = -1; int savedStatus = 0; collEnt_t* collEnt = NULL; while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( collEnt->objType == DATA_OBJ_T ) { if ( curSubFileCond.collName[0] == '\0' ) { /* a new dataObj. */ rstrcpy( curSubFileCond.collName, collEnt->collName, MAX_NAME_LEN ); rstrcpy( curSubFileCond.dataName, collEnt->dataName, MAX_NAME_LEN ); curSubFileCond.dataId = strtoll( collEnt->dataId, 0, 0 ); } else if ( strcmp( curSubFileCond.collName, collEnt->collName ) != 0 || strcmp( curSubFileCond.dataName, collEnt->dataName ) != 0 ) { /* a new file, need to handle the old one */ if ( bunReplCacheHeader.numSubFiles >= maxSubFileCnt || // JMC - backport 4771 bunReplCacheHeader.totSubFileSize + collEnt->dataSize > maxBunSize ) { /* bundle is full */ status = bundleAndRegSubFiles( rsComm, l1descInx, phyBunDir, phyBundleCollInp->collection, &bunReplCacheHeader, chksumFlag ); // JMC - backport 4528 if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsPhyBundleColl:bunAndRegSubFiles err for %s,stst=%d", phyBundleCollInp->collection, status ); savedStatus = status; } else { /* create a new bundle file */ l1descInx = createPhyBundleDataObj( rsComm, phyBundleCollInp->collection, _resc_name, rescHier, &dataObjInp, dataType ); // JMC - backport 4658 if ( l1descInx < 0 ) { rodsLog( LOG_ERROR, "_rsPhyBundleColl:createPhyBundleDataObj err for %s,stat=%d", phyBundleCollInp->collection, l1descInx ); freeCollEnt( collEnt ); return l1descInx; } createPhyBundleDir( rsComm, L1desc[l1descInx].dataObjInfo->filePath, phyBunDir, L1desc[l1descInx].dataObjInfo->rescHier ); /* need to reset subPhyPath since phyBunDir has * changed */ /* At this point subPhyPath[0] == 0 if it has gone * through replAndAddSubFileToDir below. != 0 if it has * not and already a good cache copy */ if ( curSubFileCond.subPhyPath[0] != '\0' ) setSubPhyPath( phyBunDir, curSubFileCond.dataId, curSubFileCond.subPhyPath ); } } /* end of new bundle file */ status = replAndAddSubFileToDir( rsComm, &curSubFileCond, _resc_name, phyBunDir, &bunReplCacheHeader ); if ( status < 0 ) { savedStatus = status; rodsLog( LOG_ERROR, "_rsPhyBundleColl:replAndAddSubFileToDir err for %s,sta=%d", curSubFileCond.subPhyPath, status ); } curSubFileCond.bundled = 0; curSubFileCond.subPhyPath[0] = curSubFileCond.cachePhyPath[0] = '\0'; rstrcpy( curSubFileCond.collName, collEnt->collName, MAX_NAME_LEN ); rstrcpy( curSubFileCond.dataName, collEnt->dataName, MAX_NAME_LEN ); curSubFileCond.dataId = strtoll( collEnt->dataId, 0, 0 ); } /* end of name compare */ if ( curSubFileCond.bundled > 0 ) { /* already bundled. skip */ } else if ( isDataObjBundled( collEnt ) ) { /* already bundled, skip */ curSubFileCond.bundled = 1; curSubFileCond.subPhyPath[0] = '\0'; curSubFileCond.cachePhyPath[0] = '\0'; /* XXXX there was a bug that if dataSize == 0, replStatus is 0. * This bug has been fixed since 3.1 */ } else if ( ( collEnt->replStatus > 0 || curSubFileCond.subPhyPath[0] == '\0' ) && // JMC - backport 4755 strcmp( collEnt->resource, _resc_name ) == 0 ) { /* have a good copy in cache resource */ setSubPhyPath( phyBunDir, curSubFileCond.dataId, curSubFileCond.subPhyPath ); rstrcpy( curSubFileCond.cachePhyPath, collEnt->phyPath, MAX_NAME_LEN ); curSubFileCond.cacheReplNum = collEnt->replNum; curSubFileCond.subFileSize = collEnt->dataSize; } } // if data obj free( collEnt ); /* just free collEnt but not content */ } // while /* handle any remaining */ status = replAndAddSubFileToDir( rsComm, &curSubFileCond, _resc_name, phyBunDir, &bunReplCacheHeader ); if ( status < 0 ) { savedStatus = status; rodsLog( LOG_ERROR, "_rsPhyBundleColl:replAndAddSubFileToDir err for %s,stat=%d", curSubFileCond.subPhyPath, status ); } status = bundleAndRegSubFiles( rsComm, l1descInx, phyBunDir, phyBundleCollInp->collection, &bunReplCacheHeader, chksumFlag ); // JMC - backport 4528 if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsPhyBundleColl:bunAndRegSubFiles err for %s,stat=%d", phyBundleCollInp->collection, status ); } clearKeyVal( &collInp.condInput ); rsCloseCollection( rsComm, &handleInx ); if ( status >= 0 && savedStatus < 0 ) { return savedStatus; } else { return status; } }
int _rsStructFileBundle( rsComm_t* rsComm, structFileExtAndRegInp_t* structFileBundleInp ) { int status; int handleInx; char phyBunDir[MAX_NAME_LEN]; char tmpPath[MAX_NAME_LEN]; int l1descInx; char* dataType = 0; // JMC - backport 4664 openedDataObjInp_t dataObjCloseInp; // =-=-=-=-=-=-=- // create an empty data obj dataObjInp_t dataObjInp; memset( &dataObjInp, 0, sizeof( dataObjInp ) ); dataObjInp.openFlags = O_WRONLY; // =-=-=-=-=-=-=- // get the data type of the structured file dataType = getValByKey( &structFileBundleInp->condInput, DATA_TYPE_KW ); // =-=-=-=-=-=-=- // ensure that the file name will end in .zip, if necessary if ( dataType != NULL && strstr( dataType, ZIP_DT_STR ) != NULL ) { int len = strlen( structFileBundleInp->objPath ); if ( strcmp( &structFileBundleInp->objPath[len - 4], ".zip" ) != 0 ) { strcat( structFileBundleInp->objPath, ".zip" ); } } // =-=-=-=-=-=-=- // capture the object path in the data obj struct rstrcpy( dataObjInp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN ); // =-=-=-=-=-=-=- // replicate the condInput. may have resource input replKeyVal( &structFileBundleInp->condInput, &dataObjInp.condInput ); // =-=-=-=-=-=-=- // open the file if we are in an add operation, otherwise create the new file if ( ( structFileBundleInp->oprType & ADD_TO_TAR_OPR ) != 0 ) { // JMC - backport 4643 l1descInx = rsDataObjOpen( rsComm, &dataObjInp ); } else { l1descInx = rsDataObjCreate( rsComm, &dataObjInp ); } // =-=-=-=-=-=-=- // error check create / open if ( l1descInx < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsDataObjCreate of %s error. status = %d", dataObjInp.objPath, l1descInx ); return l1descInx; } // =-=-=-=-=-=-=- // FIXME :: Why, when we replicate them above? clearKeyVal( &dataObjInp.condInput ); // JMC - backport 4637 // ???? l3Close (rsComm, l1descInx); // =-=-=-=-=-=-=- // zip does not like a zero length file as target //L1desc[ l1descInx ].l3descInx = 0; //if( dataType != NULL && strstr( dataType, ZIP_DT_STR ) != NULL ) { // if( ( structFileBundleInp->oprType & ADD_TO_TAR_OPR) == 0 ) { // JMC - backport 4643 // l3Unlink( rsComm, L1desc[l1descInx].dataObjInfo ); // } //} // =-=-=-=-=-=-=- // check object permissions / stat chkObjPermAndStat_t chkObjPermAndStatInp; memset( &chkObjPermAndStatInp, 0, sizeof( chkObjPermAndStatInp ) ); rstrcpy( chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN ); chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR; addKeyVal( &chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName ); // =-=-=-=-=-=-=- // get the resc hier string std::string resc_hier; char* resc_hier_ptr = getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW ); if ( !resc_hier_ptr ) { rodsLog( LOG_NOTICE, "_rsStructFileBundle :: RESC_HIER_STR_KW is NULL" ); } else { addKeyVal( &chkObjPermAndStatInp.condInput, RESC_HIER_STR_KW, resc_hier_ptr ); resc_hier = resc_hier_ptr; } status = rsChkObjPermAndStat( rsComm, &chkObjPermAndStatInp ); if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d", chkObjPermAndStatInp.objPath, status ); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose( rsComm, &dataObjCloseInp ); return status; } clearKeyVal( &chkObjPermAndStatInp.condInput ); // =-=-=-=-=-=-=- // create the special hidden directory where the bundling happens createPhyBundleDir( rsComm, L1desc[ l1descInx ].dataObjInfo->filePath, phyBunDir, L1desc[ l1descInx ].dataObjInfo->rescHier ); // =-=-=-=-=-=-=- // build a collection open input structure collInp_t collInp; bzero( &collInp, sizeof( collInp ) ); collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY; rstrcpy( collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN ); addKeyVal( &collInp.condInput, RESC_NAME_KW, L1desc[ l1descInx ].dataObjInfo->rescName ); rodsLog( LOG_DEBUG, "rsStructFileBundle: calling rsOpenCollection for [%s]", structFileBundleInp->collection ); // =-=-=-=-=-=-=- // open the collection from which we will bundle handleInx = rsOpenCollection( rsComm, &collInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx ); rmdir( phyBunDir ); return handleInx; } // =-=-=-=-=-=-=- // preserve the collection path? int collLen = 0; if ( ( structFileBundleInp->oprType & PRESERVE_COLL_PATH ) != 0 ) { // =-=-=-=-=-=-=- // preserve the last entry of the coll path char* tmpPtr = collInp.collName; int tmpLen = 0; collLen = 0; // =-=-=-=-=-=-=- // find length to the last '/' while ( *tmpPtr != '\0' ) { if ( *tmpPtr == '/' ) { collLen = tmpLen; } tmpLen++; tmpPtr++; } } else { collLen = strlen( collInp.collName ); } // =-=-=-=-=-=-=- // preserve the collection path? collEnt_t* collEnt = NULL; while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( NULL == collEnt ) { rodsLog( LOG_ERROR, "rsStructFileBundle: collEnt is NULL" ); continue; } // =-=-=-=-=-=-=- // entry is a data object if ( collEnt->objType == DATA_OBJ_T ) { // =-=-=-=-=-=-=- // filter out any possible replicas that are not on this resource if ( resc_hier != collEnt->resc_hier ) { rodsLog( LOG_DEBUG, "_rsStructFileBundle - skipping [%s] on resc [%s]", collEnt->phyPath, collEnt->resc_hier ); free( collEnt ); collEnt = NULL; continue; } if ( collEnt->collName[collLen] == '\0' ) { snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName ); } else { snprintf( tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName ); status = mkDirForFilePath( rsComm, strlen( phyBunDir ), tmpPath, collEnt->resc_hier, getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkDirForFilePath failed in _rsStructFileBundle with status %d", status ); free( collEnt ); return status; } } // =-=-=-=-=-=-=- // add a link status = link( collEnt->phyPath, tmpPath ); if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d", collEnt->phyPath, tmpPath, errno ); rmLinkedFilesInUnixDir( phyBunDir ); rmdir( phyBunDir ); free( collEnt ); return UNIX_FILE_LINK_ERR - errno; } else { rodsLog( LOG_DEBUG, "_rsStructFileBundle - LINK [%s] on resc [%s]", collEnt->phyPath, collEnt->resc_hier ); } } else { // =-=-=-=-=-=-=- // entry is a collection if ( ( int ) strlen( collEnt->collName ) + 1 <= collLen ) { free( collEnt ); collEnt = NULL; continue; } snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->collName + collLen ); status = mkFileDirR( rsComm, strlen( phyBunDir ), tmpPath, resc_hier.c_str(), getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkFileDirR failed in _rsStructFileBundle with status %d", status ); free( collEnt ); return status; } } // else free( collEnt ); collEnt = NULL; } // while // =-=-=-=-=-=-=- // clean up key vals and close the collection clearKeyVal( &collInp.condInput ); rsCloseCollection( rsComm, &handleInx ); // =-=-=-=-=-=-=- // call the helper function to do the actual bundling status = phyBundle( rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir, collInp.collName, structFileBundleInp->oprType ); // JMC - backport 4643 int savedStatus = 0; if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d", L1desc[ l1descInx ].dataObjInfo->objPath, status ); L1desc[ l1descInx ].bytesWritten = 0; savedStatus = status; } else { // mark it was written so the size would be adjusted L1desc[ l1descInx ].bytesWritten = 1; } // =-=-=-=-=-=-=- // clean up after the bundle directory rmLinkedFilesInUnixDir( phyBunDir ); rmdir( phyBunDir ); dataObjCloseInp.l1descInx = l1descInx; status = rsDataObjClose( rsComm, &dataObjCloseInp ); if ( status >= 0 ) { return savedStatus; } return status; }
int chkCollForBundleOpr( rsComm_t *rsComm, chkObjPermAndStat_t *chkObjPermAndStatInp ) { #ifdef RODS_CAT int status; collInp_t openCollInp; collEnt_t *collEnt = NULL; collEnt_t *curCollEnt = NULL; int handleInx; int curCopyGood = False; char *resource; char *resc_hier; rodsLong_t myId; char myPath[MAX_NAME_LEN]; if ( ( resource = getValByKey( &chkObjPermAndStatInp->condInput, RESC_NAME_KW ) ) == NULL ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr: RESC_NAME_KW not specified for %s", chkObjPermAndStatInp->objPath ); return SYS_INVALID_RESC_INPUT; } if ( ( resc_hier = getValByKey( &chkObjPermAndStatInp->condInput, RESC_HIER_STR_KW ) ) == NULL ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr: RESC_HIER_STR_KW not specified for %s", chkObjPermAndStatInp->objPath ); return SYS_INVALID_RESC_INPUT; } memset( &openCollInp, 0, sizeof( openCollInp ) ); rstrcpy( openCollInp.collName, chkObjPermAndStatInp->objPath, MAX_NAME_LEN ); openCollInp.flags = RECUR_QUERY_FG | LONG_METADATA_FG | NO_TRIM_REPL_FG; handleInx = rsOpenCollection( rsComm, &openCollInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr: rsOpenCollection of %s error. status = %d", openCollInp.collName, handleInx ); return handleInx; } while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( collEnt->specColl.collClass != NO_SPEC_COLL ) { if ( strcmp( resource, collEnt->specColl.resource ) != 0 ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr: specColl resc %s does not match %s", collEnt->specColl.resource, resource ); rsCloseCollection( rsComm, &handleInx ); return SYS_COPY_NOT_EXIST_IN_RESC; } /* check permission */ myId = chlCheckAndGetObjectID( rsComm, "-c", collEnt->specColl.collection, ACCESS_READ_OBJECT ); if ( myId < 0 ) { status = myId; rodsLog( LOG_ERROR, "chkCollForBundleOpr: no accPerm to specColl %s. status = %d", collEnt->specColl.collection, status ); rsCloseCollection( rsComm, &handleInx ); return status; } free( collEnt ); collEnt = NULL; continue; } if ( collEnt->objType == DATA_OBJ_T ) { if ( curCollEnt == NULL ) { curCollEnt = collEnt; saveCollEntForChkColl( collEnt ); if ( collEnt->replStatus > 0 && strcmp( resource, collEnt->resource ) == 0 && strcmp( resc_hier, collEnt->resc_hier ) == 0 ) { curCopyGood = True; } } else { if ( strcmp( curCollEnt->dataName, collEnt->dataName ) == 0 && strcmp( curCollEnt->collName, collEnt->collName ) == 0 ) { if ( collEnt->replStatus > 0 && strcmp( resource, collEnt->resource ) == 0 && strcmp( resc_hier, collEnt->resc_hier ) == 0 ) { /* a good copy */ freeCollEntForChkColl( curCollEnt ); curCopyGood = True; curCollEnt = collEnt; saveCollEntForChkColl( collEnt ); } } else { /* encounter a new data obj */ snprintf( myPath, MAX_NAME_LEN, "%s/%s", curCollEnt->collName, curCollEnt->dataName ); if ( curCopyGood == False ) { status = replDataObjForBundle( rsComm, curCollEnt->collName, curCollEnt->dataName, resource, curCollEnt->resc_hier, resc_hier, 0, NULL ); if ( status < 0 ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr: %s no good copy in %s [%d]", myPath, resource, status ); rsCloseCollection( rsComm, &handleInx ); freeCollEntForChkColl( curCollEnt ); return SYS_COPY_NOT_EXIST_IN_RESC; } } else { } freeCollEntForChkColl( curCollEnt ); curCopyGood = False; curCollEnt = NULL; /* we have a good copy. Check the permission */ myId = chlCheckAndGetObjectID( rsComm, "-d", myPath, ACCESS_READ_OBJECT ); if ( myId < 0 && myId != CAT_UNKNOWN_FILE ) { /* could return CAT_UNKNOWN_FILE if mounted files */ status = myId; rodsLog( LOG_ERROR, "chkCollForBundleOpr: no accPerm to %s. status = %d", myPath, status ); rsCloseCollection( rsComm, &handleInx ); return status; } else { /* copy is OK */ curCollEnt = collEnt; saveCollEntForChkColl( collEnt ); collEnt = NULL; if ( curCollEnt->replStatus > 0 && strcmp( resource, curCollEnt->resource ) == 0 && strcmp( resc_hier, curCollEnt->resc_hier ) == 0 ) { /* a good copy */ curCopyGood = True; } } } } } else { free( collEnt ); } } /* handle what's left */ if ( curCollEnt != NULL ) { if ( curCopyGood == False ) { status = replDataObjForBundle( rsComm, curCollEnt->collName, curCollEnt->dataName, resource, curCollEnt->resc_hier, resc_hier, 0, NULL ); if ( status < 0 ) { rodsLog( LOG_ERROR, "chkCollForBundleOpr:%s does not have a good copy in %s", chkObjPermAndStatInp->objPath, resource ); status = SYS_COPY_NOT_EXIST_IN_RESC; } } else { freeCollEntForChkColl( curCollEnt ); } } else { status = 0; } rsCloseCollection( rsComm, &handleInx ); return 0; #else return SYS_NO_RCAT_SERVER_ERR; #endif }
int _rsPhyRmColl( rsComm_t *rsComm, collInp_t *rmCollInp, dataObjInfo_t *dataObjInfo, collOprStat_t **collOprStat ) { char *tmpValue; int status; collInp_t openCollInp; collEnt_t *collEnt; int handleInx; dataObjInp_t dataObjInp; collInp_t tmpCollInp; int rmtrashFlag = 0; int savedStatus = 0; int fileCntPerStatOut = FILE_CNT_PER_STAT_OUT; int entCnt = 0; ruleExecInfo_t rei; collInfo_t collInfo; memset( &openCollInp, 0, sizeof( openCollInp ) ); rstrcpy( openCollInp.collName, rmCollInp->collName, MAX_NAME_LEN ); /* cannot query recur because collection is sorted in wrong order */ openCollInp.flags = 0; handleInx = rsOpenCollection( rsComm, &openCollInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "_rsPhyRmColl: rsOpenCollection of %s error. status = %d", openCollInp.collName, handleInx ); return handleInx; } memset( &dataObjInp, 0, sizeof( dataObjInp ) ); memset( &tmpCollInp, 0, sizeof( tmpCollInp ) ); /* catch the UNREG_OPR */ dataObjInp.oprType = tmpCollInp.oprType = rmCollInp->oprType; if ( ( tmpValue = getValByKey( &rmCollInp->condInput, AGE_KW ) ) != NULL ) { if ( CollHandle[handleInx].rodsObjStat != NULL ) { /* when a collection is moved, the modfiyTime of the object in * the collectin does not change. So, we'll depend on the * modfiyTime of the collection */ int ageLimit = atoi( tmpValue ) * 60; int modifyTime = atoi( CollHandle[handleInx].rodsObjStat->modifyTime ); if ( ( time( 0 ) - modifyTime ) < ageLimit ) { rsCloseCollection( rsComm, &handleInx ); return 0; } } addKeyVal( &dataObjInp.condInput, AGE_KW, tmpValue ); addKeyVal( &tmpCollInp.condInput, AGE_KW, tmpValue ); } addKeyVal( &dataObjInp.condInput, FORCE_FLAG_KW, "" ); addKeyVal( &tmpCollInp.condInput, FORCE_FLAG_KW, "" ); if ( ( tmpValue = getValByKey( &rmCollInp->condInput, AGE_KW ) ) != NULL ) { addKeyVal( &dataObjInp.condInput, AGE_KW, tmpValue ); addKeyVal( &tmpCollInp.condInput, AGE_KW, tmpValue ); } if ( collOprStat != NULL && *collOprStat == NULL ) { *collOprStat = ( collOprStat_t* )malloc( sizeof( collOprStat_t ) ); memset( *collOprStat, 0, sizeof( collOprStat_t ) ); } if ( getValByKey( &rmCollInp->condInput, ADMIN_RMTRASH_KW ) != NULL ) { if ( isTrashPath( rmCollInp->collName ) == False ) { return SYS_INVALID_FILE_PATH; } if ( rsComm->clientUser.authInfo.authFlag != LOCAL_PRIV_USER_AUTH ) { return CAT_INSUFFICIENT_PRIVILEGE_LEVEL; } addKeyVal( &tmpCollInp.condInput, ADMIN_RMTRASH_KW, "" ); addKeyVal( &dataObjInp.condInput, ADMIN_RMTRASH_KW, "" ); rmtrashFlag = 2; } else if ( getValByKey( &rmCollInp->condInput, RMTRASH_KW ) != NULL ) { if ( isTrashPath( rmCollInp->collName ) == False ) { return SYS_INVALID_FILE_PATH; } addKeyVal( &tmpCollInp.condInput, RMTRASH_KW, "" ); addKeyVal( &dataObjInp.condInput, RMTRASH_KW, "" ); rmtrashFlag = 1; } // =-=-=-=-=-=-=- // JMC - backport 4552 if ( getValByKey( &rmCollInp->condInput, EMPTY_BUNDLE_ONLY_KW ) != NULL ) { addKeyVal( &tmpCollInp.condInput, EMPTY_BUNDLE_ONLY_KW, "" ); addKeyVal( &dataObjInp.condInput, EMPTY_BUNDLE_ONLY_KW, "" ); } // =-=-=-=-=-=-=- while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( entCnt == 0 ) { entCnt ++; /* cannot rm non-empty home collection */ if ( isHomeColl( rmCollInp->collName ) ) { return CANT_RM_NON_EMPTY_HOME_COLL; } } if ( collEnt->objType == DATA_OBJ_T ) { snprintf( dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collEnt->collName, collEnt->dataName ); status = rsDataObjUnlink( rsComm, &dataObjInp ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsPhyRmColl:rsDataObjUnlink failed for %s. stat = %d", dataObjInp.objPath, status ); /* need to set global error here */ savedStatus = status; } else if ( collOprStat != NULL ) { ( *collOprStat )->filesCnt ++; if ( ( *collOprStat )->filesCnt >= fileCntPerStatOut ) { rstrcpy( ( *collOprStat )->lastObjPath, dataObjInp.objPath, MAX_NAME_LEN ); status = svrSendCollOprStat( rsComm, *collOprStat ); if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "_rsPhyRmColl: svrSendCollOprStat failed for %s. status = %d", rmCollInp->collName, status ); *collOprStat = NULL; savedStatus = status; break; } *collOprStat = ( collOprStat_t* )malloc( sizeof( collOprStat_t ) ); memset( *collOprStat, 0, sizeof( collOprStat_t ) ); } } } else if ( collEnt->objType == COLL_OBJ_T ) { if ( strcmp( collEnt->collName, rmCollInp->collName ) == 0 ) { continue; /* duplicate */ } rstrcpy( tmpCollInp.collName, collEnt->collName, MAX_NAME_LEN ); if ( collEnt->specColl.collClass != NO_SPEC_COLL ) { if ( strcmp( collEnt->collName, collEnt->specColl.collection ) == 0 ) { continue; /* no mount point */ } } initReiWithCollInp( &rei, rsComm, &tmpCollInp, &collInfo ); status = applyRule( "acPreprocForRmColl", NULL, &rei, NO_SAVE_REI ); if ( status < 0 ) { if ( rei.status < 0 ) { status = rei.status; } rodsLog( LOG_ERROR, "_rsPhyRmColl:acPreprocForRmColl error for %s,stat=%d", tmpCollInp.collName, status ); return status; } status = _rsRmCollRecur( rsComm, &tmpCollInp, collOprStat ); rei.status = status; rei.status = applyRule( "acPostProcForRmColl", NULL, &rei, NO_SAVE_REI ); if ( rei.status < 0 ) { rodsLog( LOG_ERROR, "_rsRmColl:acPostProcForRmColl error for %s,stat=%d", tmpCollInp.collName, status ); } } if ( status < 0 ) { savedStatus = status; } free( collEnt ); /* just free collEnt but not content */ } rsCloseCollection( rsComm, &handleInx ); if ( ( rmtrashFlag > 0 && ( isTrashHome( rmCollInp->collName ) > 0 || // JMC - backport 4561 isOrphanPath( rmCollInp->collName ) == is_ORPHAN_HOME ) ) || ( isBundlePath( rmCollInp->collName ) == True && getValByKey( &rmCollInp->condInput, EMPTY_BUNDLE_ONLY_KW ) != NULL ) ) { /* don't rm user's home trash coll or orphan collection */ status = 0; } else { if ( dataObjInfo != NULL && dataObjInfo->specColl != NULL ) { if ( dataObjInfo->specColl->collClass == LINKED_COLL ) { rstrcpy( rmCollInp->collName, dataObjInfo->objPath, MAX_NAME_LEN ); status = svrUnregColl( rsComm, rmCollInp ); } else { status = l3Rmdir( rsComm, dataObjInfo ); } } else { status = svrUnregColl( rsComm, rmCollInp ); if ( status < 0 ) { savedStatus = status; } } } clearKeyVal( &tmpCollInp.condInput ); clearKeyVal( &dataObjInp.condInput ); return savedStatus; }
int _rsStructFileBundle (rsComm_t *rsComm, structFileExtAndRegInp_t *structFileBundleInp) { int status; dataObjInp_t dataObjInp; openedDataObjInp_t dataObjCloseInp; collInp_t collInp; collEnt_t *collEnt = NULL; int handleInx; int collLen; char phyBunDir[MAX_NAME_LEN]; char tmpPath[MAX_NAME_LEN]; chkObjPermAndStat_t chkObjPermAndStatInp; int l1descInx; int savedStatus = 0; char *dataType; /* open the structured file */ memset (&dataObjInp, 0, sizeof (dataObjInp)); dataType = getValByKey (&structFileBundleInp->condInput, DATA_TYPE_KW); if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL) { /* zipFile type. must end with .zip */ int len = strlen (structFileBundleInp->objPath); if (strcmp (&structFileBundleInp->objPath[len - 4], ".zip") != 0) { strcat (structFileBundleInp->objPath, ".zip"); } } rstrcpy (dataObjInp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN); /* replicate the condInput. may have resource input */ replKeyVal (&structFileBundleInp->condInput, &dataObjInp.condInput); dataObjInp.openFlags = O_WRONLY; if ((structFileBundleInp->oprType & ADD_TO_TAR_OPR) != 0) { l1descInx = rsDataObjOpen (rsComm, &dataObjInp); } else { l1descInx = rsDataObjCreate (rsComm, &dataObjInp); } if (l1descInx < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsDataObjCreate of %s error. status = %d", dataObjInp.objPath, l1descInx); return (l1descInx); } clearKeyVal (&dataObjInp.condInput); l3Close (rsComm, l1descInx); L1desc[l1descInx].l3descInx = 0; /* zip does not like a zero length file as target */ if ((structFileBundleInp->oprType & ADD_TO_TAR_OPR) == 0) l3Unlink (rsComm, L1desc[l1descInx].dataObjInfo); memset (&chkObjPermAndStatInp, 0, sizeof (chkObjPermAndStatInp)); rstrcpy (chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN); chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR; addKeyVal (&chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName); status = rsChkObjPermAndStat (rsComm, &chkObjPermAndStatInp); clearKeyVal (&chkObjPermAndStatInp.condInput); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d", chkObjPermAndStatInp.objPath, status); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose (rsComm, &dataObjCloseInp); return (status); } createPhyBundleDir (rsComm, L1desc[l1descInx].dataObjInfo->filePath, phyBunDir); bzero (&collInp, sizeof (collInp)); rstrcpy (collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN); collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY; addKeyVal (&collInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName); handleInx = rsOpenCollection (rsComm, &collInp); if (handleInx < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx); rmdir (phyBunDir); return (handleInx); } if ((structFileBundleInp->oprType & PRESERVE_COLL_PATH) != 0) { /* preserver the last entry of the coll path */ char *tmpPtr = collInp.collName; int tmpLen = 0; collLen = 0; /* find length to the last '/' */ while (*tmpPtr != '\0') { if (*tmpPtr == '/') collLen = tmpLen; tmpLen++; tmpPtr++; } } else { collLen = strlen (collInp.collName); } while ((status = rsReadCollection (rsComm, &handleInx, &collEnt)) >= 0) { if (collEnt->objType == DATA_OBJ_T) { if (collEnt->collName[collLen] == '\0') { snprintf (tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName); } else { snprintf (tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName); mkDirForFilePath (UNIX_FILE_TYPE, rsComm, phyBunDir, tmpPath, getDefDirMode ()); } /* add a link */ status = link (collEnt->phyPath, tmpPath); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d", collEnt->phyPath, tmpPath, errno); rmLinkedFilesInUnixDir (phyBunDir); rmdir (phyBunDir); return (UNIX_FILE_LINK_ERR - errno); } } else { /* a collection */ if ((int) strlen (collEnt->collName) + 1 <= collLen) { free (collEnt); continue; } snprintf (tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->collName + collLen); mkdirR (phyBunDir, tmpPath, getDefDirMode ()); } if (collEnt != NULL) { free (collEnt); collEnt = NULL; } } clearKeyVal (&collInp.condInput); rsCloseCollection (rsComm, &handleInx); status = phyBundle (rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir, collInp.collName, structFileBundleInp->oprType); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d", L1desc[l1descInx].dataObjInfo->objPath, status); L1desc[l1descInx].bytesWritten = 0; savedStatus = status; } else { /* mark it was written so the size would be adjusted */ L1desc[l1descInx].bytesWritten = 1; } rmLinkedFilesInUnixDir (phyBunDir); rmdir (phyBunDir); dataObjCloseInp.l1descInx = l1descInx; status = rsDataObjClose (rsComm, &dataObjCloseInp); if (status >= 0) return savedStatus; else return (status); }
int rsNcGetAggInfo (rsComm_t *rsComm, ncOpenInp_t *ncOpenInp, ncAggInfo_t **ncAggInfo) { specCollCache_t *specCollCache = NULL; collInp_t collInp; int handleInx; collEnt_t *collEnt; int status = 0; int status2 = 0; int savedStatus = 0; ncOpenInp_t childNcOpenInp; ncAggElement_t *ncAggElement = NULL; bytesBuf_t *packedBBuf = NULL; bzero (&collInp, sizeof (collInp)); rstrcpy (collInp.collName, ncOpenInp->objPath, MAX_NAME_LEN); resolveLinkedPath (rsComm, collInp.collName, &specCollCache, &ncOpenInp->condInput); collInp.flags = VERY_LONG_METADATA_FG; handleInx = rsOpenCollection (rsComm, &collInp); if (handleInx < 0) { rodsLog (LOG_ERROR, "rsNcGetAggInfo: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx); return (handleInx); } bzero (&childNcOpenInp, sizeof (childNcOpenInp)); *ncAggInfo = (ncAggInfo_t *) calloc (1, sizeof (ncAggInfo_t)); rstrcpy ((*ncAggInfo)->ncObjectName, ncOpenInp->objPath, MAX_NAME_LEN); while ((status2 = rsReadCollection (rsComm, &handleInx, &collEnt)) >= 0) { if (collEnt->objType != DATA_OBJ_T) { free (collEnt); continue; } else if (strcmp (collEnt->dataType, "netcdf") != 0) { if (strcmp (collEnt->dataName, NC_AGG_INFO_FILE_NAME) != 0) { rodsLog (LOG_NOTICE, "rsNcGetAggInfo: dataType of %s in %s is not 'netcdf' type", collEnt->dataName, collInp.collName); savedStatus = NETCDF_INVALID_DATA_TYPE; } free (collEnt); continue; } snprintf (childNcOpenInp.objPath, MAX_NAME_LEN, "%s/%s", collInp.collName, collEnt->dataName); status = rsNcGetAggElement (rsComm, &childNcOpenInp, &ncAggElement); if (status < 0) { rodsLogError (LOG_ERROR, status, "rsNcGetAggInfo: rsNcGetAggElement of %s error.", childNcOpenInp.objPath); free (collEnt); break; } else { status = addNcAggElement (ncAggElement, *ncAggInfo); free (ncAggElement); if (status < 0) { free (collEnt); break; } } free (collEnt); } rsCloseCollection (rsComm, &handleInx); if (status2 < 0 && status2 != CAT_NO_ROWS_FOUND && status >= 0) { status = status2; } if (status >= 0 && (ncOpenInp->mode & NC_WRITE) != 0) { dataObjInp_t dataObjInp; portalOprOut_t *portalOprOut = NULL; status = packStruct ((void *) *ncAggInfo, &packedBBuf, "NcAggInfo_PI", RodsPackTable, 0, XML_PROT); if (status < 0) { rodsLogError (LOG_ERROR, status, "rsNcGetAggInfo: packStruct error for %s", childNcOpenInp.objPath); return status; } /* write it */ bzero (&dataObjInp, sizeof (dataObjInp)); replKeyVal (&ncOpenInp->condInput, &dataObjInp.condInput); snprintf (dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collInp.collName, NC_AGG_INFO_FILE_NAME); dataObjInp.dataSize = packedBBuf->len; dataObjInp.oprType = PUT_OPR; addKeyVal (&dataObjInp.condInput, DATA_INCLUDED_KW, ""); addKeyVal (&dataObjInp.condInput, FORCE_FLAG_KW, ""); status = rsDataObjPut (rsComm, &dataObjInp, packedBBuf, &portalOprOut); clearBBuf (packedBBuf); clearKeyVal (&dataObjInp.condInput); if (portalOprOut != NULL) free (portalOprOut); if (status < 0) { rodsLogError (LOG_ERROR, status, "rsNcGetAggInfo: rsDataObjPut error for %s", dataObjInp.objPath); } } if (status < 0) { return status; } else { return savedStatus; } }