00001
00002
00003
00004
00005
00006
00007
00008 #include "phyBundleColl.h"
00009 #include "objMetaOpr.h"
00010 #include "resource.h"
00011 #include "collection.h"
00012 #include "specColl.h"
00013 #include "physPath.h"
00014 #include "dataObjOpr.h"
00015 #include "miscServerFunct.h"
00016 #include "openCollection.h"
00017 #include "readCollection.h"
00018 #include "closeCollection.h"
00019 #include "dataObjRepl.h"
00020 #include "dataObjUnlink.h"
00021 #include "dataObjCreate.h"
00022 #include "syncMountedColl.h"
00023 #include "regReplica.h"
00024 #include "unbunAndRegPhyBunfile.h"
00025 #include "fileChksum.h"
00026 #include "eirods_stacktrace.h"
00027
00028
00029
00030 #include "eirods_resource_backport.h"
00031 #include "eirods_resource_redirect.h"
00032 #include "eirods_stacktrace.h"
00033
00034
00035 static rodsLong_t OneGig = (1024*1024*1024);
00036
00037 int
00038 rsPhyBundleColl( rsComm_t* rsComm,
00039 structFileExtAndRegInp_t* phyBundleCollInp ) {
00040 int status = -1;
00041 specCollCache_t* specCollCache = 0;
00042 char* destRescName = 0;
00043
00044 resolveLinkedPath (rsComm, phyBundleCollInp->objPath, &specCollCache,
00045 &phyBundleCollInp->condInput);
00046
00047 resolveLinkedPath (rsComm, phyBundleCollInp->collection,
00048 &specCollCache, NULL);
00049
00050 if ((destRescName = getValByKey (&phyBundleCollInp->condInput,
00051 DEST_RESC_NAME_KW)) == NULL) {
00052 return USER_NO_RESC_INPUT_ERR;
00053 }
00054
00055 if (isLocalZone (phyBundleCollInp->collection) == 0) {
00056
00057 return SYS_INVALID_ZONE_NAME;
00058 }
00059
00060 #if 0 // JMC - legacy resource
00061 status = _getRescInfo (rsComm, destRescName, &rescGrpInfo);
00062 if (status < 0 || NULL == rescGrpInfo ) {
00063 rodsLog (LOG_ERROR,
00064 "rsPhyBundleColl: _getRescInfo of %s error for %s. stat = %d",
00065 destRescName, phyBundleCollInp->collection, status);
00066 return status;
00067 }
00068 #endif // JMC - legacy resource
00069
00070 rescGrpInfo_t rescGrpInfo;
00071 rescGrpInfo.rescInfo = 0;
00072 eirods::error err = eirods::get_resc_grp_info( destRescName, rescGrpInfo );
00073 if( !err.ok() ) {
00074 eirods::log( PASS( false, -1, "rsPhyBundleColl - failed.", err ) );
00075 return -1;
00076 }
00077
00078
00079
00080
00081
00082 dataObjInp_t data_inp;
00083 bzero( &data_inp, sizeof( data_inp ) );
00084 rstrcpy( data_inp.objPath, phyBundleCollInp->objPath, MAX_NAME_LEN );
00085 bzero( &data_inp.condInput, sizeof( data_inp.condInput ) );
00086 addKeyVal( &data_inp.condInput, DEST_RESC_NAME_KW, destRescName );
00087
00088 std::string hier;
00089 char* hier_kw = getValByKey( &phyBundleCollInp->condInput, RESC_HIER_STR_KW );
00090 if( hier_kw == NULL ) {
00091 eirods::error ret = eirods::resolve_resource_hierarchy( eirods::EIRODS_CREATE_OPERATION, rsComm,
00092 &data_inp, hier );
00093 if( !ret.ok() ) {
00094 std::stringstream msg;
00095 msg << "rsPhyBundleColl - failed in eirods::resolve_resource_hierarchy for [";
00096 msg << data_inp.objPath << "]";
00097 eirods::log( PASSMSG( msg.str(), ret ) );
00098 return ret.code();
00099 }
00100
00101
00102
00103
00104 addKeyVal( &phyBundleCollInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00105
00106 }
00107
00108
00109
00110 std::string location;
00111 eirods::error ret = eirods::get_loc_for_hier_string( hier, location );
00112 if( !ret.ok() ) {
00113 eirods::log( PASSMSG( "rsPhyBundleColl - failed in get_loc_for_hier_String", ret ) );
00114 return -1;
00115 }
00116
00117
00118
00119 rodsHostAddr_t rescAddr;
00120 bzero (&rescAddr, sizeof (rescAddr));
00121
00122 rstrcpy (rescAddr.hostAddr, location.c_str(), NAME_LEN);
00123 rodsServerHost_t* rodsServerHost = 0;
00124 int remoteFlag = resolveHost (&rescAddr, &rodsServerHost);
00125
00126
00127
00128 if (remoteFlag == LOCAL_HOST) {
00129 status = _rsPhyBundleColl( rsComm, phyBundleCollInp, &rescGrpInfo );
00130 } else if (remoteFlag == REMOTE_HOST) {
00131 status = remotePhyBundleColl( rsComm, phyBundleCollInp, rodsServerHost );
00132 } else if (remoteFlag < 0) {
00133 status = remoteFlag;
00134 }
00135
00136
00137 return status;
00138 }
00139
00140 int
00141 _rsPhyBundleColl( rsComm_t* rsComm,
00142 structFileExtAndRegInp_t* phyBundleCollInp,
00143 rescGrpInfo_t* rescGrpInfo ) {
00144 rescInfo_t* myRescInfo = rescGrpInfo->rescInfo;
00145 char* myRescName = myRescInfo->rescName;
00146
00147 collInp_t collInp;
00148 bzero (&collInp, sizeof (collInp));
00149 rstrcpy (collInp.collName, phyBundleCollInp->collection, MAX_NAME_LEN);
00150 collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG;
00151
00152 int handleInx = rsOpenCollection (rsComm, &collInp);
00153
00154 if (handleInx < 0) {
00155 rodsLog (LOG_ERROR,
00156 "_rsPhyBundleColl: rsOpenCollection of %s error. status = %d",
00157 collInp.collName, handleInx);
00158 return (handleInx);
00159 }
00160
00161 if (CollHandle[handleInx].rodsObjStat->specColl != NULL) {
00162 rodsLog (LOG_ERROR,
00163 "_rsPhyBundleColl: unable to bundle special collection %s",
00164 collInp.collName);
00165 rsCloseCollection (rsComm, &handleInx);
00166 return (0);
00167 }
00168
00169
00170 char* dataType = getValByKey (&phyBundleCollInp->condInput, DATA_TYPE_KW);
00171
00172 dataObjInp_t dataObjInp;
00173 int l1descInx = createPhyBundleDataObj (rsComm, phyBundleCollInp->collection,
00174 rescGrpInfo, &dataObjInp, dataType );
00175
00176 if (l1descInx < 0) {
00177 return l1descInx;
00178 }
00179
00180
00181
00182 int chksumFlag = -1;
00183 if (getValByKey (&phyBundleCollInp->condInput, VERIFY_CHKSUM_KW) != NULL) {
00184 L1desc[l1descInx].chksumFlag = VERIFY_CHKSUM;
00185 chksumFlag = 1;
00186 } else {
00187 chksumFlag = 0;
00188 }
00189
00190
00191 int maxSubFileCnt = -1;
00192 if (getValByKey (&phyBundleCollInp->condInput, MAX_SUB_FILE_KW) != NULL) {
00193 maxSubFileCnt = atoi(getValByKey (&phyBundleCollInp->condInput, MAX_SUB_FILE_KW));
00194 } else {
00195 maxSubFileCnt = MAX_SUB_FILE_CNT;
00196 }
00197
00198
00199 char phyBunDir[MAX_NAME_LEN];
00200 createPhyBundleDir (rsComm, L1desc[l1descInx].dataObjInfo->filePath,
00201 phyBunDir);
00202
00203
00204 curSubFileCond_t curSubFileCond;
00205 bunReplCacheHeader_t bunReplCacheHeader;
00206 bzero (&bunReplCacheHeader, sizeof (bunReplCacheHeader));
00207 bzero (&curSubFileCond, sizeof (curSubFileCond));
00208
00209 int status = -1;
00210 int savedStatus = 0;
00211 collEnt_t* collEnt = 0;
00212 while ((status = rsReadCollection (rsComm, &handleInx, &collEnt)) >= 0) {
00213 if (collEnt->objType == DATA_OBJ_T) {
00214 if (curSubFileCond.collName[0] == '\0') {
00215
00216 rstrcpy (curSubFileCond.collName, collEnt->collName,
00217 MAX_NAME_LEN);
00218 rstrcpy (curSubFileCond.dataName, collEnt->dataName,
00219 MAX_NAME_LEN);
00220 curSubFileCond.dataId = strtoll (collEnt->dataId, 0, 0);
00221 } else if (strcmp (curSubFileCond.collName, collEnt->collName) != 0
00222 || strcmp (curSubFileCond.dataName, collEnt->dataName) != 0) {
00223
00224 if (bunReplCacheHeader.numSubFiles >= maxSubFileCnt ||
00225 bunReplCacheHeader.totSubFileSize + collEnt->dataSize >
00226 MAX_BUNDLE_SIZE * OneGig) {
00227
00228 status = bundlleAndRegSubFiles (rsComm, l1descInx,
00229 phyBunDir, phyBundleCollInp->collection,
00230 &bunReplCacheHeader, chksumFlag);
00231 if (status < 0) {
00232 rodsLog (LOG_ERROR,
00233 "_rsPhyBundleColl:bunAndRegSubFiles err for %s,stst=%d",
00234 phyBundleCollInp->collection, status);
00235 savedStatus = status;
00236 } else {
00237
00238 l1descInx = createPhyBundleDataObj (rsComm,
00239 phyBundleCollInp->collection, rescGrpInfo,
00240 &dataObjInp, dataType);
00241
00242 if (l1descInx < 0) {
00243 rodsLog (LOG_ERROR,
00244 "_rsPhyBundleColl:createPhyBundleDataObj err for %s,stat=%d",
00245 phyBundleCollInp->collection, l1descInx);
00246 return (l1descInx);
00247 }
00248
00249 createPhyBundleDir (rsComm,
00250 L1desc[l1descInx].dataObjInfo->filePath, phyBunDir);
00251
00252
00253
00254
00255
00256 if (curSubFileCond.subPhyPath[0] != '\0')
00257 setSubPhyPath (phyBunDir, curSubFileCond.dataId,
00258 curSubFileCond.subPhyPath);
00259
00260 }
00261 }
00262 status = replAndAddSubFileToDir (rsComm, &curSubFileCond, myRescName, phyBunDir, &bunReplCacheHeader);
00263 if (status < 0) {
00264 savedStatus = status;
00265 rodsLog (LOG_ERROR,
00266 "_rsPhyBundleColl:replAndAddSubFileToDir err for %s,sta=%d",
00267 curSubFileCond.subPhyPath, status);
00268 }
00269 curSubFileCond.bundled = 0;
00270 curSubFileCond.subPhyPath[0] =
00271 curSubFileCond.cachePhyPath[0] = '\0';
00272 rstrcpy (curSubFileCond.collName, collEnt->collName,
00273 MAX_NAME_LEN);
00274 rstrcpy (curSubFileCond.dataName, collEnt->dataName,
00275 MAX_NAME_LEN);
00276 curSubFileCond.dataId = strtoll (collEnt->dataId, 0, 0);
00277 }
00278
00279 if (curSubFileCond.bundled > 0) {
00280
00281 } else if (isDataObjBundled (rsComm, collEnt)) {
00282
00283 curSubFileCond.bundled = 1;
00284 curSubFileCond.subPhyPath[0] = '\0';
00285 curSubFileCond.cachePhyPath[0] = '\0';
00286
00287
00288 } else if( ( collEnt->replStatus > 0 || curSubFileCond.subPhyPath[0] == '\0') &&
00289 strcmp (collEnt->resource, myRescName) == 0) {
00290
00291 setSubPhyPath (phyBunDir, curSubFileCond.dataId, curSubFileCond.subPhyPath);
00292 rstrcpy (curSubFileCond.cachePhyPath, collEnt->phyPath, MAX_NAME_LEN);
00293 curSubFileCond.cacheReplNum = collEnt->replNum;
00294 curSubFileCond.subFileSize = collEnt->dataSize;
00295 }
00296
00297 }
00298
00299 free (collEnt);
00300
00301 }
00302
00303
00304 status = replAndAddSubFileToDir (rsComm, &curSubFileCond,
00305 myRescName, phyBunDir, &bunReplCacheHeader);
00306 if (status < 0) {
00307 savedStatus = status;
00308 rodsLog (LOG_ERROR,
00309 "_rsPhyBundleColl:replAndAddSubFileToDir err for %s,stat=%d",
00310 curSubFileCond.subPhyPath, status);
00311 }
00312
00313 status = bundlleAndRegSubFiles (rsComm, l1descInx, phyBunDir,
00314 phyBundleCollInp->collection, &bunReplCacheHeader, chksumFlag);
00315 if (status < 0) {
00316 rodsLog (LOG_ERROR,
00317 "_rsPhyBundleColl:bunAndRegSubFiles err for %s,stat=%d",
00318 phyBundleCollInp->collection, status);
00319 }
00320 if (status >= 0 && savedStatus < 0) {
00321 return savedStatus;
00322 } else {
00323 return status;
00324 }
00325 }
00326
00327 int
00328 replAndAddSubFileToDir (rsComm_t *rsComm, curSubFileCond_t *curSubFileCond,
00329 char *myRescName, char *phyBunDir, bunReplCacheHeader_t *bunReplCacheHeader)
00330 {
00331 int status;
00332 dataObjInfo_t dataObjInfo;
00333
00334 if (curSubFileCond->bundled == 1) {
00335 return 0;
00336 }
00337
00338 bzero (&dataObjInfo, sizeof (dataObjInfo));
00339
00340 if (curSubFileCond->subPhyPath[0] == '\0') {
00341
00342 status = replDataObjForBundle (rsComm, curSubFileCond->collName,
00343 curSubFileCond->dataName, myRescName,
00344 0, 0, 1, &dataObjInfo);
00345 if (status >= 0) {
00346 setSubPhyPath (phyBunDir, curSubFileCond->dataId,
00347 curSubFileCond->subPhyPath);
00348 rstrcpy (curSubFileCond->cachePhyPath, dataObjInfo.filePath,
00349 MAX_NAME_LEN);
00350 curSubFileCond->cacheReplNum = dataObjInfo.replNum;
00351 curSubFileCond->subFileSize = dataObjInfo.dataSize;
00352 }
00353 }
00354 status = addSubFileToDir (curSubFileCond, bunReplCacheHeader);
00355 if (status < 0) {
00356 rodsLog (LOG_ERROR,
00357 "_rsPhyBundleColl:addSubFileToDir error for %s,stst=%d",
00358 curSubFileCond->subPhyPath, status);
00359 }
00360 return status;
00361 }
00362
00363 int
00364 bundlleAndRegSubFiles (rsComm_t *rsComm, int l1descInx, char *phyBunDir,
00365 char *collection, bunReplCacheHeader_t *bunReplCacheHeader, int chksumFlag)
00366 {
00367 int status;
00368 openedDataObjInp_t dataObjCloseInp;
00369 bunReplCache_t *tmpBunReplCache, *nextBunReplCache;
00370 regReplica_t regReplicaInp;
00371 dataObjInp_t dataObjUnlinkInp;
00372 keyValPair_t regParam;
00373 modDataObjMeta_t modDataObjMetaInp;
00374
00375 int savedStatus = 0;
00376
00377 bzero (&dataObjCloseInp, sizeof (dataObjCloseInp));
00378 dataObjCloseInp.l1descInx = l1descInx;
00379 if (bunReplCacheHeader->numSubFiles == 0) {
00380 bzero (&dataObjUnlinkInp, sizeof (dataObjUnlinkInp));
00381 rstrcpy (dataObjUnlinkInp.objPath,
00382 L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN);
00383 dataObjUnlinkS (rsComm, &dataObjUnlinkInp,
00384 L1desc[l1descInx].dataObjInfo);
00385 L1desc[l1descInx].bytesWritten = 0;
00386 rsDataObjClose (rsComm, &dataObjCloseInp);
00387 bzero (bunReplCacheHeader, sizeof (bunReplCacheHeader_t));
00388 return 0;
00389 }
00390
00391 status = phyBundle (rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir,
00392 collection, CREATE_TAR_OPR);
00393 if (status < 0) {
00394 rodsLog (LOG_ERROR,
00395 "bundlleAndRegSubFiles: rsStructFileSync of %s error. stat = %d",
00396 L1desc[l1descInx].dataObjInfo->objPath, status);
00397 rmLinkedFilesInUnixDir (phyBunDir);
00398 rmdir (phyBunDir);
00399 rsDataObjClose (rsComm, &dataObjCloseInp);
00400 tmpBunReplCache = bunReplCacheHeader->bunReplCacheHead;
00401 while (tmpBunReplCache != NULL) {
00402 nextBunReplCache = tmpBunReplCache->next;
00403 free (tmpBunReplCache);
00404 tmpBunReplCache = nextBunReplCache;
00405 }
00406 bzero (bunReplCacheHeader, sizeof (bunReplCacheHeader_t));
00407 return status;
00408 } else {
00409
00410 L1desc[l1descInx].bytesWritten = 1;
00411 }
00412
00413
00414 tmpBunReplCache = bunReplCacheHeader->bunReplCacheHead;
00415
00416 if (tmpBunReplCache == NULL) {
00417 rmdir (phyBunDir);
00418 bzero (&dataObjUnlinkInp, sizeof (dataObjUnlinkInp));
00419 rstrcpy (dataObjUnlinkInp.objPath,
00420 L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN);
00421 dataObjUnlinkS (rsComm, &dataObjUnlinkInp,
00422 L1desc[l1descInx].dataObjInfo);
00423 L1desc[l1descInx].bytesWritten = 0;
00424 rsDataObjClose (rsComm, &dataObjCloseInp);
00425 bzero (bunReplCacheHeader, sizeof (bunReplCacheHeader_t));
00426 return 0;
00427 }
00428
00429 bzero (®ReplicaInp, sizeof (regReplicaInp));
00430 regReplicaInp.srcDataObjInfo = (dataObjInfo_t*)malloc (sizeof (dataObjInfo_t));
00431 regReplicaInp.destDataObjInfo = (dataObjInfo_t*)malloc (sizeof (dataObjInfo_t));
00432 bzero (regReplicaInp.srcDataObjInfo, sizeof (dataObjInfo_t));
00433 bzero (regReplicaInp.destDataObjInfo, sizeof (dataObjInfo_t));
00434 addKeyVal (®ReplicaInp.condInput, IRODS_ADMIN_KW, "");
00435 rstrcpy (regReplicaInp.destDataObjInfo->rescName, BUNDLE_RESC, NAME_LEN);
00436 rstrcpy (regReplicaInp.destDataObjInfo->filePath,
00437 L1desc[l1descInx].dataObjInfo->objPath, MAX_NAME_LEN);
00438
00439
00440 if (chksumFlag != 0) {
00441 bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp));
00442 bzero (®Param, sizeof (regParam));
00443 modDataObjMetaInp.dataObjInfo = regReplicaInp.destDataObjInfo;
00444 modDataObjMetaInp.regParam = ®Param;
00445 }
00446
00447
00448
00449
00450 rsDataObjClose (rsComm, &dataObjCloseInp);
00451 while (tmpBunReplCache != NULL) {
00452 char subPhyPath[MAX_NAME_LEN];
00453
00454 nextBunReplCache = tmpBunReplCache->next;
00455
00456 snprintf (subPhyPath, MAX_NAME_LEN, "%s/%lld", phyBunDir,
00457 tmpBunReplCache->dataId);
00458
00459
00460 if (chksumFlag != 0) {
00461 status = fileChksum (UNIX_FILE_TYPE, rsComm, regReplicaInp.destDataObjInfo->filePath,
00462 subPhyPath, "", tmpBunReplCache->chksumStr);
00463 if (status < 0) {
00464 savedStatus = status;
00465 rodsLogError (LOG_ERROR, status,"bundlleAndRegSubFiles: fileChksum error for %s",tmpBunReplCache->objPath);
00466 }
00467 }
00468
00469 unlink (subPhyPath);
00470
00471 rstrcpy (regReplicaInp.srcDataObjInfo->objPath,
00472 tmpBunReplCache->objPath, MAX_NAME_LEN);
00473 regReplicaInp.srcDataObjInfo->dataId =
00474 regReplicaInp.destDataObjInfo->dataId =
00475 tmpBunReplCache->dataId;
00476 regReplicaInp.srcDataObjInfo->replNum = tmpBunReplCache->srcReplNum;
00477 status = rsRegReplica (rsComm, ®ReplicaInp);
00478 if (status < 0) {
00479 savedStatus = status;
00480 rodsLog (LOG_ERROR,
00481 "bundlleAndRegSubFiles: rsRegReplica error for %s. stat = %d",
00482 tmpBunReplCache->objPath, status);
00483 }
00484
00485
00486 if (chksumFlag != 0) {
00487 addKeyVal (®Param, CHKSUM_KW, tmpBunReplCache->chksumStr);
00488 status = rsModDataObjMeta (rsComm, &modDataObjMetaInp);
00489 clearKeyVal (®Param);
00490 if (status < 0) {
00491 savedStatus = status;
00492 rodsLogError (LOG_ERROR, status, "bundlleAndRegSubFiles: rsModDataObjMeta error for %s.", tmpBunReplCache->objPath);
00493 }
00494 }
00495
00496 free (tmpBunReplCache);
00497 tmpBunReplCache = nextBunReplCache;
00498 }
00499 clearKeyVal (®ReplicaInp.condInput);
00500 free (regReplicaInp.srcDataObjInfo);
00501 free (regReplicaInp.destDataObjInfo);
00502 bzero (bunReplCacheHeader, sizeof (bunReplCacheHeader_t));
00503 rmdir (phyBunDir);
00504
00505 if (status >= 0 && savedStatus < 0) {
00506 return savedStatus;
00507 } else {
00508 return status;
00509 }
00510 }
00511
00512
00513
00514
00515 int
00516 phyBundle (rsComm_t *rsComm, dataObjInfo_t *dataObjInfo, char *phyBunDir,
00517 char *collection, int oprType )
00518 {
00519 structFileOprInp_t structFileOprInp;
00520 int status = 0;
00521 char *dataType;
00522 int myOprType = oprType;
00523
00524 dataType = dataObjInfo->dataType;
00525 #if 0 // this is now handled by libarchive which can add to existing archives without
00526
00527 if ((oprType & ADD_TO_TAR_OPR) != 0) {
00528
00529 if( dataType != NULL &&
00530 ( strstr( dataType, GZIP_TAR_DT_STR ) != NULL ||
00531 strstr (dataType, BZIP2_TAR_DT_STR) != NULL)) {
00532
00533
00534 status = unbunPhyBunFile (rsComm, dataObjInfo->objPath,
00535 dataObjInfo->rescInfo, dataObjInfo->filePath, phyBunDir,
00536 dataType, PRESERVE_DIR_CONT);
00537 if (status < 0) return status;
00538
00539 myOprType = myOprType ^ ADD_TO_TAR_OPR;
00540 }
00541 }
00542 #endif
00543
00544 bzero (&structFileOprInp, sizeof (structFileOprInp));
00545 addKeyVal( &structFileOprInp.condInput, RESC_HIER_STR_KW, dataObjInfo->rescHier );
00546
00547 structFileOprInp.specColl = (specColl_t*)malloc (sizeof (specColl_t));
00548 memset (structFileOprInp.specColl, 0, sizeof (specColl_t));
00549 structFileOprInp.specColl->type = TAR_STRUCT_FILE_T;
00550
00551
00552 rstrcpy (structFileOprInp.specColl->collection,collection, MAX_NAME_LEN);
00553 rstrcpy (structFileOprInp.specColl->objPath,dataObjInfo->objPath, MAX_NAME_LEN);
00554 structFileOprInp.specColl->collClass = STRUCT_FILE_COLL;
00555 rstrcpy (structFileOprInp.specColl->resource, dataObjInfo->rescName,NAME_LEN);
00556 rstrcpy (structFileOprInp.specColl->phyPath,dataObjInfo->filePath, MAX_NAME_LEN);
00557 addKeyVal( &structFileOprInp.condInput, RESC_HIER_STR_KW, dataObjInfo->rescHier );
00558
00559 rstrcpy (structFileOprInp.specColl->cacheDir, phyBunDir, MAX_NAME_LEN);
00560 structFileOprInp.specColl->cacheDirty = 1;
00561
00562 structFileOprInp.oprType = NO_REG_COLL_INFO | myOprType;
00563 if( dataType != NULL &&
00564 ( strstr( dataType, GZIP_TAR_DT_STR) != NULL ||
00565 strstr( dataType, BZIP2_TAR_DT_STR) != NULL ||
00566 strstr( dataType, ZIP_DT_STR) != NULL ) ) {
00567 addKeyVal (&structFileOprInp.condInput, DATA_TYPE_KW, dataType);
00568 }
00569
00570 status = rsStructFileSync (rsComm, &structFileOprInp);
00571
00572 free (structFileOprInp.specColl);
00573
00574 if ((oprType & ADD_TO_TAR_OPR) != 0 && (myOprType & ADD_TO_TAR_OPR) == 0) {
00575 rmUnlinkedFilesInUnixDir (phyBunDir);
00576 }
00577
00578 if (status < 0) {
00579 rodsLog (LOG_ERROR,
00580 "phyBundle: rsStructFileSync of %s error. stat = %d",
00581 dataObjInfo->objPath, status);
00582 }
00583
00584 return status;
00585 }
00586
00587 int
00588 addSubFileToDir (curSubFileCond_t *curSubFileCond,
00589 bunReplCacheHeader_t *bunReplCacheHeader)
00590 {
00591 int status;
00592 bunReplCache_t *bunReplCache;
00593
00594
00595 status = link (curSubFileCond->cachePhyPath, curSubFileCond->subPhyPath);
00596 if (status < 0) {
00597 rodsLog (LOG_ERROR,
00598 "addSubFileToDir: link error %s to %s. errno = %d",
00599 curSubFileCond->cachePhyPath, curSubFileCond->subPhyPath, errno);
00600 return (UNIX_FILE_LINK_ERR - errno);
00601 }
00602 bunReplCache = (bunReplCache_t*)malloc (sizeof (bunReplCache_t));
00603 bzero (bunReplCache, sizeof (bunReplCache_t));
00604 bunReplCache->dataId = curSubFileCond->dataId;
00605 snprintf (bunReplCache->objPath, MAX_NAME_LEN, "%s/%s",
00606 curSubFileCond->collName, curSubFileCond->dataName);
00607 bunReplCache->srcReplNum = curSubFileCond->cacheReplNum;
00608 bunReplCache->next = bunReplCacheHeader->bunReplCacheHead;
00609 bunReplCacheHeader->bunReplCacheHead = bunReplCache;
00610 bunReplCacheHeader->numSubFiles++;
00611 bunReplCacheHeader->totSubFileSize += curSubFileCond->subFileSize;
00612
00613 return 0;
00614 }
00615
00616 int
00617 setSubPhyPath (char *phyBunDir, rodsLong_t dataId, char *subPhyPath)
00618 {
00619 snprintf (subPhyPath, MAX_NAME_LEN, "%s/%lld", phyBunDir, dataId);
00620 return 0;
00621 }
00622
00623 int
00624 isDataObjBundled (rsComm_t *rsComm, collEnt_t *collEnt)
00625 {
00626 if (strcmp (collEnt->resource, BUNDLE_RESC) == 0) {
00627 if (collEnt->replStatus > 0) {
00628 return 1;
00629 } else {
00630
00631 return 0;
00632 }
00633 } else {
00634 return 0;
00635 }
00636 }
00637
00638 int
00639 replDataObjForBundle (rsComm_t *rsComm, char *collName, char *dataName,
00640 char *rescName, char* rescHier, char* dstRescHier,
00641 int adminFlag, dataObjInfo_t *outCacheObjInfo)
00642 {
00643 transferStat_t transStat;
00644 dataObjInp_t dataObjInp;
00645 int status;
00646
00647 if (outCacheObjInfo != NULL)
00648 memset (outCacheObjInfo, 0, sizeof (dataObjInfo_t));
00649 memset (&dataObjInp, 0, sizeof (dataObjInp_t));
00650 memset (&transStat, 0, sizeof (transStat));
00651
00652 snprintf (dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collName, dataName);
00653 addKeyVal (&dataObjInp.condInput, BACKUP_RESC_NAME_KW, rescName);
00654 if( rescHier ) {
00655 addKeyVal (&dataObjInp.condInput, RESC_HIER_STR_KW, rescHier);
00656 }
00657 if( dstRescHier ) {
00658 addKeyVal (&dataObjInp.condInput, DEST_RESC_HIER_STR_KW, dstRescHier);
00659 }
00660 if (adminFlag > 0)
00661 addKeyVal (&dataObjInp.condInput, IRODS_ADMIN_KW, "");
00662
00663 status = _rsDataObjRepl (rsComm, &dataObjInp, &transStat,
00664 outCacheObjInfo);
00665 clearKeyVal (&dataObjInp.condInput);
00666 return status;
00667 }
00668
00669 int
00670 createPhyBundleDir (rsComm_t *rsComm, char *bunFilePath,
00671 char *outPhyBundleDir)
00672 {
00673
00674 snprintf (outPhyBundleDir, MAX_NAME_LEN, "%s.dir", bunFilePath);
00675 mkdirR ("/", outPhyBundleDir, getDefDirMode ());
00676 return (0);
00677 }
00678
00679 int
00680 createPhyBundleDataObj (rsComm_t *rsComm, char *collection,
00681 rescGrpInfo_t *rescGrpInfo, dataObjInp_t *dataObjInp, char* dataType )
00682 {
00683 int myRanNum;
00684 int l1descInx;
00685 int status;
00686 int rescTypeInx = rescGrpInfo->rescInfo->rescTypeInx;
00687
00688
00689
00690 std::string type;
00691 eirods::error err = eirods::get_resource_property< std::string >( rescGrpInfo->rescInfo->rescName, "type", type );
00692 if( !err.ok() ) {
00693 eirods::log( PASS( false, -1, "createPhyBundleDataObj failed.", err ) );
00694 }
00695
00696 if( "unix file system" != type ) {
00697 rodsLog (LOG_ERROR,
00698 "createPhyBundleFile: resource %s is not UNIX_FILE_TYPE",
00699 rescGrpInfo->rescInfo->rescName);
00700 return SYS_INVALID_RESC_TYPE;
00701 }
00702 #if 0 // JMC legacy resources
00703 else if (getRescClass (rescGrpInfo->rescInfo) != CACHE_CL) {
00704 return SYS_NO_CACHE_RESC_IN_GRP;
00705 }
00706
00707 #endif // JMC legacy resources
00708
00709 do {
00710 int loopCnt = 0;
00711 bzero (dataObjInp, sizeof (dataObjInp_t));
00712 while (1) {
00713 myRanNum = random ();
00714 status = rsMkBundlePath (rsComm, collection, dataObjInp->objPath,
00715 myRanNum);
00716 if (status < 0) {
00717 rodsLog (LOG_ERROR,
00718 "createPhyBundleFile: getPhyBundlePath err for %s.stat = %d",
00719 collection, status);
00720 return status;
00721 }
00722
00723 if (isData (rsComm, dataObjInp->objPath, NULL) >= 0) {
00724 if (loopCnt >= 100) {
00725 break;
00726 } else {
00727 loopCnt++;
00728 continue;
00729 }
00730 } else {
00731 break;
00732 }
00733 }
00734
00735 if (dataType != NULL && strstr (dataType, BUNDLE_STR) != NULL) {
00736 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, dataType);
00737 } else {
00738
00739 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, TAR_BUNDLE_DT_STR);
00740 }
00741
00742 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL) {
00743
00744 int len = strlen (dataObjInp->objPath);
00745 if (strcmp (&dataObjInp->objPath[len - 4], ".zip") != 0) {
00746 strcat (dataObjInp->objPath, ".zip");
00747 }
00748 }
00749
00750 l1descInx = _rsDataObjCreateWithRescInfo (rsComm, dataObjInp,
00751 rescGrpInfo->rescInfo, rescGrpInfo->rescGroupName);
00752
00753 clearKeyVal (&dataObjInp->condInput);
00754 } while (l1descInx == OVERWRITE_WITHOUT_FORCE_FLAG);
00755
00756 if (l1descInx >= 0) {
00757 l3Close (rsComm, l1descInx);
00758 L1desc[l1descInx].l3descInx = 0;
00759 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL)
00760 l3Unlink (rsComm, L1desc[l1descInx].dataObjInfo);
00761 }
00762
00763 return l1descInx;
00764 }
00765
00766
00767
00768
00769
00770
00771 int
00772 rsMkBundlePath (rsComm_t *rsComm, char *collection, char *bundlePath,
00773 int myRanNum)
00774 {
00775 int status;
00776 char *tmpStr;
00777 char startBundlePath[MAX_NAME_LEN];
00778 char destBundleColl[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
00779 char *bundlePathPtr;
00780
00781 bundlePathPtr = bundlePath;
00782 *bundlePathPtr = '/';
00783 bundlePathPtr++;
00784 tmpStr = collection + 1;
00785
00786 while (*tmpStr != '\0') {
00787 *bundlePathPtr = *tmpStr;
00788 bundlePathPtr ++;
00789 if (*tmpStr == '/') {
00790 tmpStr ++;
00791 break;
00792 }
00793 tmpStr ++;
00794 }
00795
00796 if (*tmpStr == '\0') {
00797 rodsLog (LOG_ERROR,
00798 "rsMkBundlePath: input path %s too short", collection);
00799 return (USER_INPUT_PATH_ERR);
00800 }
00801
00802
00803 if (strncmp (tmpStr, "trash/", 6) == 0 ||
00804 strncmp (tmpStr, "bundle/", 7) == 0) {
00805 rodsLog (LOG_ERROR,
00806 "rsMkBundlePath: cannot bundle trash or bundle path %s", collection);
00807 return (USER_INPUT_PATH_ERR);
00808 }
00809
00810
00811
00812 *bundlePathPtr = '\0';
00813 rstrcpy (startBundlePath, bundlePath, MAX_NAME_LEN);
00814
00815 snprintf (bundlePathPtr, MAX_NAME_LEN, "bundle/%s.%d", tmpStr, myRanNum);
00816
00817 if ((status = splitPathByKey (bundlePath, destBundleColl, myFile, '/'))
00818 < 0) {
00819 rodsLog (LOG_ERROR,
00820 "rsMkBundlePath: splitPathByKey error for %s ", bundlePath);
00821 return (USER_INPUT_PATH_ERR);
00822 }
00823
00824 status = rsMkCollR (rsComm, startBundlePath, destBundleColl);
00825
00826 if (status < 0) {
00827 rodsLog (LOG_ERROR,
00828 "rsMkBundlePath: rsMkCollR error for startPath %s, destPath %s ",
00829 startBundlePath, destBundleColl);
00830 }
00831
00832 return (status);
00833 }
00834
00835 int
00836 remotePhyBundleColl (rsComm_t *rsComm,
00837 structFileExtAndRegInp_t *phyBundleCollInp, rodsServerHost_t *rodsServerHost)
00838 {
00839 int status;
00840
00841 if (rodsServerHost == NULL) {
00842 rodsLog (LOG_NOTICE,
00843 "remotePhyBundleColl: Invalid rodsServerHost");
00844 return SYS_INVALID_SERVER_HOST;
00845 }
00846
00847 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00848 return status;
00849 }
00850
00851 status = rcPhyBundleColl (rodsServerHost->conn, phyBundleCollInp);
00852 return status;
00853 }
00854