/* resolveDataObjReplStatus - a dirty copy may be deleted leaving no * dirty copy. In that case, pick the newest copy and mark it dirty */ int resolveDataObjReplStatus( rsComm_t *rsComm, dataObjInp_t *dataObjUnlinkInp ) { int status; dataObjInfo_t *dataObjInfoHead = NULL; dataObjInfo_t *newestDataObjInfo = NULL; dataObjInfo_t *tmpDataObjInfo; if ( getValByKey( &dataObjUnlinkInp->condInput, RESC_NAME_KW ) == NULL && getValByKey( &dataObjUnlinkInp->condInput, REPL_NUM_KW ) == NULL ) { return 0; } status = getDataObjInfo( rsComm, dataObjUnlinkInp, &dataObjInfoHead, ACCESS_DELETE_OBJECT, 1 ); if ( status < 0 ) { return status; } tmpDataObjInfo = dataObjInfoHead; while ( tmpDataObjInfo != NULL ) { if ( tmpDataObjInfo->replStatus == 0 ) { if ( newestDataObjInfo == NULL ) { newestDataObjInfo = tmpDataObjInfo; } else if ( atoi( tmpDataObjInfo->dataModify ) > atoi( newestDataObjInfo->dataModify ) ) { newestDataObjInfo = tmpDataObjInfo; } } else { newestDataObjInfo = NULL; break; } tmpDataObjInfo = tmpDataObjInfo->next; } /* modify the repl status */ if ( newestDataObjInfo != NULL ) { keyValPair_t regParam; char tmpStr[MAX_NAME_LEN]; modDataObjMeta_t modDataObjMetaInp; memset( ®Param, 0, sizeof( regParam ) ); memset( &modDataObjMetaInp, 0, sizeof( modDataObjMetaInp ) ); snprintf( tmpStr, MAX_NAME_LEN, "%d", NEWLY_CREATED_COPY ); addKeyVal( ®Param, REPL_STATUS_KW, tmpStr ); modDataObjMetaInp.dataObjInfo = newestDataObjInfo; modDataObjMetaInp.regParam = ®Param; status = rsModDataObjMeta( rsComm, &modDataObjMetaInp ); clearKeyVal( ®Param ); } freeAllDataObjInfo( dataObjInfoHead ); return status; }
int bundleAndRegSubFiles( rsComm_t *rsComm, int l1descInx, char *phyBunDir, char *collection, bunReplCacheHeader_t *bunReplCacheHeader, int chksumFlag ) { // JMC - backport 4528 int status; openedDataObjInp_t dataObjCloseInp; bunReplCache_t *tmpBunReplCache, *nextBunReplCache; regReplica_t regReplicaInp; dataObjInp_t dataObjUnlinkInp; keyValPair_t regParam; // JMC - backport 4528 modDataObjMeta_t modDataObjMetaInp; // JMC - backport 4528 int savedStatus = 0; bzero( &dataObjCloseInp, sizeof( dataObjCloseInp ) ); dataObjCloseInp.l1descInx = l1descInx; if ( bunReplCacheHeader->numSubFiles == 0 ) { bzero( &dataObjUnlinkInp, sizeof( dataObjUnlinkInp ) ); rstrcpy( dataObjUnlinkInp.objPath, L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN ); dataObjUnlinkS( rsComm, &dataObjUnlinkInp, L1desc[l1descInx].dataObjInfo ); L1desc[l1descInx].bytesWritten = 0; rsDataObjClose( rsComm, &dataObjCloseInp ); bzero( bunReplCacheHeader, sizeof( bunReplCacheHeader_t ) ); return 0; } status = phyBundle( rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir, collection, CREATE_TAR_OPR ); // JMC - backport 4643 if ( status < 0 ) { rodsLog( LOG_ERROR, "bundleAndRegSubFiles: rsStructFileSync of %s error. stat = %d", L1desc[l1descInx].dataObjInfo->objPath, status ); rmLinkedFilesInUnixDir( phyBunDir ); rmdir( phyBunDir ); rsDataObjClose( rsComm, &dataObjCloseInp ); tmpBunReplCache = bunReplCacheHeader->bunReplCacheHead; while ( tmpBunReplCache != NULL ) { nextBunReplCache = tmpBunReplCache->next; free( tmpBunReplCache ); tmpBunReplCache = nextBunReplCache; // JMC - backport 4579 } bzero( bunReplCacheHeader, sizeof( bunReplCacheHeader_t ) ); return status; } else { /* mark it was written so the size would be adjusted */ L1desc[l1descInx].bytesWritten = 1; } /* now register a replica for each subfile */ tmpBunReplCache = bunReplCacheHeader->bunReplCacheHead; if ( tmpBunReplCache == NULL ) { rmdir( phyBunDir ); bzero( &dataObjUnlinkInp, sizeof( dataObjUnlinkInp ) ); rstrcpy( dataObjUnlinkInp.objPath, L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN ); dataObjUnlinkS( rsComm, &dataObjUnlinkInp, L1desc[l1descInx].dataObjInfo ); L1desc[l1descInx].bytesWritten = 0; rsDataObjClose( rsComm, &dataObjCloseInp ); bzero( bunReplCacheHeader, sizeof( bunReplCacheHeader_t ) ); return 0; } bzero( ®ReplicaInp, sizeof( regReplicaInp ) ); regReplicaInp.srcDataObjInfo = ( dataObjInfo_t* )malloc( sizeof( dataObjInfo_t ) ); regReplicaInp.destDataObjInfo = ( dataObjInfo_t* )malloc( sizeof( dataObjInfo_t ) ); bzero( regReplicaInp.srcDataObjInfo, sizeof( dataObjInfo_t ) ); bzero( regReplicaInp.destDataObjInfo, sizeof( dataObjInfo_t ) ); addKeyVal( ®ReplicaInp.condInput, ADMIN_KW, "" ); rstrcpy( regReplicaInp.destDataObjInfo->rescName, BUNDLE_RESC, NAME_LEN ); rstrcpy( regReplicaInp.destDataObjInfo->filePath, L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN ); rstrcpy( regReplicaInp.destDataObjInfo->rescHier, L1desc[l1descInx].dataObjInfo->rescHier, MAX_NAME_LEN ); // =-=-=-=-=-=-=- // JMC - backport 4528 if ( chksumFlag != 0 ) { bzero( &modDataObjMetaInp, sizeof( modDataObjMetaInp ) ); bzero( ®Param, sizeof( regParam ) ); modDataObjMetaInp.dataObjInfo = regReplicaInp.destDataObjInfo; modDataObjMetaInp.regParam = ®Param; } // =-=-=-=-=-=-=- /* close here because dataObjInfo is still being used */ rsDataObjClose( rsComm, &dataObjCloseInp ); while ( tmpBunReplCache != NULL ) { char subPhyPath[MAX_NAME_LEN]; nextBunReplCache = tmpBunReplCache->next; /* rm the hard link here */ snprintf( subPhyPath, MAX_NAME_LEN, "%s/%lld", phyBunDir, tmpBunReplCache->dataId ); // =-=-=-=-=-=-=- // JMC - backport 4528 if ( chksumFlag != 0 ) { status = fileChksum( rsComm, regReplicaInp.destDataObjInfo->filePath, subPhyPath, regReplicaInp.destDataObjInfo->rescHier, 0, tmpBunReplCache->chksumStr ); if ( status < 0 ) { savedStatus = status; rodsLogError( LOG_ERROR, status, "bundleAndRegSubFiles: fileChksum error for %s", tmpBunReplCache->objPath ); } } // =-=-=-=-=-=-=- unlink( subPhyPath ); /* register the replica */ rstrcpy( regReplicaInp.srcDataObjInfo->objPath, tmpBunReplCache->objPath, MAX_NAME_LEN ); regReplicaInp.srcDataObjInfo->dataId = regReplicaInp.destDataObjInfo->dataId = tmpBunReplCache->dataId; regReplicaInp.srcDataObjInfo->replNum = tmpBunReplCache->srcReplNum; status = rsRegReplica( rsComm, ®ReplicaInp ); if ( status < 0 ) { savedStatus = status; rodsLog( LOG_ERROR, "bundleAndRegSubFiles: rsRegReplica error for %s. stat = %d", tmpBunReplCache->objPath, status ); } // =-=-=-=-=-=-=- // JMC - backport 4528 if ( chksumFlag != 0 ) { addKeyVal( ®Param, CHKSUM_KW, tmpBunReplCache->chksumStr ); // avoid triggering file operations addKeyVal( ®Param, IN_PDMO_KW, "" ); status = rsModDataObjMeta( rsComm, &modDataObjMetaInp ); clearKeyVal( ®Param ); if ( status < 0 ) { savedStatus = status; rodsLogError( LOG_ERROR, status, "bundleAndRegSubFiles: rsModDataObjMeta error for %s.", tmpBunReplCache->objPath ); } } // =-=-=-=-=-=-=- free( tmpBunReplCache ); tmpBunReplCache = nextBunReplCache; } clearKeyVal( ®ReplicaInp.condInput ); free( regReplicaInp.srcDataObjInfo ); free( regReplicaInp.destDataObjInfo ); bzero( bunReplCacheHeader, sizeof( bunReplCacheHeader_t ) ); rmdir( phyBunDir ); if ( status >= 0 && savedStatus < 0 ) { return savedStatus; } else { return status; } }
int chkCollForExtAndReg (rsComm_t *rsComm, char *collection, rodsObjStat_t **rodsObjStatOut) { dataObjInp_t dataObjInp; int status; rodsObjStat_t *myRodsObjStat = NULL; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, collection, MAX_NAME_LEN); #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); #if 0 if (status == CAT_NO_ROWS_FOUND || status == OBJ_PATH_DOES_NOT_EXIST || status == USER_FILE_DOES_NOT_EXIST) { #endif if (status < 0) { status = rsMkCollR (rsComm, "/", collection); if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: rsMkCollR of %s error. status = %d", collection, status); return (status); } else { #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); } } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: collStat of %s error. status = %d", dataObjInp.objPath, status); return (status); } else if (myRodsObjStat->specColl != NULL && myRodsObjStat->specColl->collClass != MOUNTED_COLL) { /* only do mounted coll */ freeRodsObjStat (myRodsObjStat); rodsLog (LOG_ERROR, "chkCollForExtAndReg: %s is a struct file collection", dataObjInp.objPath); return (SYS_STRUCT_FILE_INMOUNTED_COLL); } if (myRodsObjStat->specColl == NULL) { status = checkCollAccessPerm (rsComm, collection, ACCESS_DELETE_OBJECT); } else { status = checkCollAccessPerm (rsComm, myRodsObjStat->specColl->collection, ACCESS_DELETE_OBJECT); } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: no permission to write %s, status = %d", collection, status); freeRodsObjStat (myRodsObjStat); } else { if (rodsObjStatOut != NULL) { *rodsObjStatOut = myRodsObjStat; } else { freeRodsObjStat (myRodsObjStat); } } return (status); } /* regUnbunSubfiles - non bulk version of registering all files in phyBunDir * to the collection. Valid values for flags are: * FORCE_FLAG_FLAG. */ int regUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *collection, char *phyBunDir, int flags, genQueryOut_t *attriArray) { #ifndef USE_BOOST_FS DIR *dirPtr; struct dirent *myDirent; struct stat statbuf; #endif char subfilePath[MAX_NAME_LEN]; char subObjPath[MAX_NAME_LEN]; dataObjInp_t dataObjInp; int status; int savedStatus = 0; rodsLong_t st_size; #ifdef USE_BOOST_FS path srcDirPath (phyBunDir); if (!exists(srcDirPath) || !is_directory(srcDirPath)) { #else dirPtr = opendir (phyBunDir); if (dirPtr == NULL) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: opendir error for %s, errno = %d", phyBunDir, errno); return (UNIX_FILE_OPENDIR_ERR - errno); } bzero (&dataObjInp, sizeof (dataObjInp)); #ifdef USE_BOOST_FS directory_iterator end_itr; // default construction yields past-the-end for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) { path p = itr->path(); snprintf (subfilePath, MAX_NAME_LEN, "%s", p.c_str ()); #else while ((myDirent = readdir (dirPtr)) != NULL) { if (strcmp (myDirent->d_name, ".") == 0 || strcmp (myDirent->d_name, "..") == 0) { continue; } snprintf (subfilePath, MAX_NAME_LEN, "%s/%s", phyBunDir, myDirent->d_name); #endif #ifdef USE_BOOST_FS if (!exists (p)) { #else status = lstat (subfilePath, &statbuf); if (status != 0) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: stat error for %s, errno = %d", subfilePath, errno); savedStatus = UNIX_FILE_STAT_ERR - errno; unlink (subfilePath); continue; } #ifdef USE_BOOST_FS if (is_symlink (p)) { #else if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) { #endif rodsLogError (LOG_ERROR, SYMLINKED_BUNFILE_NOT_ALLOWED, "regUnbunSubfiles: %s is a symlink", subfilePath); savedStatus = SYMLINKED_BUNFILE_NOT_ALLOWED; continue; } #ifdef USE_BOOST_FS path childPath = p.filename(); snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, childPath.c_str()); if (is_directory (p)) { #else snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, myDirent->d_name); if ((statbuf.st_mode & S_IFDIR) != 0) { #endif status = rsMkCollR (rsComm, "/", subObjPath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: rsMkCollR of %s error. status = %d", subObjPath, status); savedStatus = status; continue; } status = regUnbunSubfiles (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, flags, attriArray); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regUnbunSubfiles of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } #ifdef USE_BOOST_FS } else if (is_regular_file (p)) { st_size = file_size (p); #else } else if ((statbuf.st_mode & S_IFREG) != 0) { st_size = statbuf.st_size; #endif status = regSubfile (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, st_size, flags); unlink (subfilePath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regSubfile of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } } } #ifndef USE_BOOST_FS closedir (dirPtr); #endif rmdir (phyBunDir); return savedStatus; } int regSubfile (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *subObjPath, char *subfilePath, rodsLong_t dataSize, int flags) { dataObjInfo_t dataObjInfo; dataObjInp_t dataObjInp; #ifndef USE_BOOST_FS struct stat statbuf; #endif int status; int modFlag = 0; bzero (&dataObjInp, sizeof (dataObjInp)); bzero (&dataObjInfo, sizeof (dataObjInfo)); rstrcpy (dataObjInp.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN); rstrcpy (dataObjInfo.dataType, "generic", NAME_LEN); dataObjInfo.rescInfo = rescInfo; rstrcpy (dataObjInfo.rescGroupName, rescGroupName, NAME_LEN); dataObjInfo.dataSize = dataSize; status = getFilePathName (rsComm, &dataObjInfo, &dataObjInp); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: getFilePathName err for %s. status = %d", dataObjInp.objPath, status); return (status); } #ifdef USE_BOOST_FS path p (dataObjInfo.filePath); if (exists (p)) { if (is_directory (p)) { #else status = stat (dataObjInfo.filePath, &statbuf); if (status == 0 || errno != ENOENT) { if ((statbuf.st_mode & S_IFDIR) != 0) { #endif return SYS_PATH_IS_NOT_A_FILE; } if (chkOrphanFile (rsComm, dataObjInfo.filePath, rescInfo->rescName, &dataObjInfo) > 0) { /* an orphan file. just rename it */ fileRenameInp_t fileRenameInp; bzero (&fileRenameInp, sizeof (fileRenameInp)); rstrcpy (fileRenameInp.oldFileName, dataObjInfo.filePath, MAX_NAME_LEN); status = renameFilePathToNewDir (rsComm, ORPHAN_DIR, &fileRenameInp, rescInfo, 1); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: renameFilePathToNewDir err for %s. status = %d", fileRenameInp.oldFileName, status); return (status); } } else { /* not an orphan file */ if ((flags & FORCE_FLAG_FLAG) != 0 && dataObjInfo.dataId > 0 && strcmp (dataObjInfo.objPath, subObjPath) == 0) { /* overwrite the current file */ modFlag = 1; unlink (dataObjInfo.filePath); } else { status = SYS_COPY_ALREADY_IN_RESC; rodsLog (LOG_ERROR, "regSubFile: phypath %s is already in use. status = %d", dataObjInfo.filePath, status); return (status); } } } /* make the necessary dir */ mkDirForFilePath (UNIX_FILE_TYPE, rsComm, "/", dataObjInfo.filePath, getDefDirMode ()); /* add a link */ #ifndef windows_platform /* Windows does not support link */ status = link (subfilePath, dataObjInfo.filePath); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: link error %s to %s. errno = %d", subfilePath, dataObjInfo.filePath, errno); return (UNIX_FILE_LINK_ERR - errno); } #endif if (modFlag == 0) { status = svrRegDataObj (rsComm, &dataObjInfo); } else { char tmpStr[MAX_NAME_LEN]; modDataObjMeta_t modDataObjMetaInp; keyValPair_t regParam; bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp)); bzero (®Param, sizeof (regParam)); snprintf (tmpStr, MAX_NAME_LEN, "%lld", dataSize); addKeyVal (®Param, DATA_SIZE_KW, tmpStr); addKeyVal (®Param, ALL_REPL_STATUS_KW, tmpStr); snprintf (tmpStr, MAX_NAME_LEN, "%d", (int) time (NULL)); addKeyVal (®Param, DATA_MODIFY_KW, tmpStr); modDataObjMetaInp.dataObjInfo = &dataObjInfo; modDataObjMetaInp.regParam = ®Param; status = rsModDataObjMeta (rsComm, &modDataObjMetaInp); clearKeyVal (®Param); } if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: svrRegDataObj of %s. errno = %d", dataObjInfo.objPath, errno); unlink (dataObjInfo.filePath); } else { ruleExecInfo_t rei; dataObjInp_t dataObjInp; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, dataObjInfo.objPath, MAX_NAME_LEN); initReiWithDataObjInp (&rei, rsComm, &dataObjInp); rei.doi = &dataObjInfo; rei.status = applyRule ("acPostProcForTarFileReg", NULL, &rei, NO_SAVE_REI); if (rei.status < 0) { rodsLogError (LOG_ERROR, rei.status, "regSubFile: acPostProcForTarFileReg error for %s. status = %d", dataObjInfo.objPath); } } return status; }