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( err ) );
00075 return err.code();
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 << "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( "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 char* rescHier = getValByKey (&phyBundleCollInp->condInput, RESC_HIER_STR_KW);
00172 dataObjInp_t dataObjInp;
00173 int l1descInx = createPhyBundleDataObj (rsComm, phyBundleCollInp->collection,
00174 rescGrpInfo, rescHier, &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 = bundleAndRegSubFiles (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 rescHier, &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 = bundleAndRegSubFiles (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 bundleAndRegSubFiles (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 "bundleAndRegSubFiles: 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 rstrcpy (regReplicaInp.destDataObjInfo->rescHier,
00439 L1desc[l1descInx].dataObjInfo->rescHier, MAX_NAME_LEN);
00440
00441
00442 if (chksumFlag != 0) {
00443 bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp));
00444 bzero (®Param, sizeof (regParam));
00445 modDataObjMetaInp.dataObjInfo = regReplicaInp.destDataObjInfo;
00446 modDataObjMetaInp.regParam = ®Param;
00447 }
00448
00449
00450
00451
00452 rsDataObjClose (rsComm, &dataObjCloseInp);
00453 while (tmpBunReplCache != NULL) {
00454 char subPhyPath[MAX_NAME_LEN];
00455
00456 nextBunReplCache = tmpBunReplCache->next;
00457
00458 snprintf (subPhyPath, MAX_NAME_LEN, "%s/%lld", phyBunDir,
00459 tmpBunReplCache->dataId);
00460
00461
00462 if (chksumFlag != 0) {
00463 status = fileChksum (UNIX_FILE_TYPE, rsComm, regReplicaInp.destDataObjInfo->filePath,
00464 subPhyPath, regReplicaInp.destDataObjInfo->rescHier, tmpBunReplCache->chksumStr);
00465 if (status < 0) {
00466 savedStatus = status;
00467 rodsLogError (LOG_ERROR, status,"bundleAndRegSubFiles: fileChksum error for %s",tmpBunReplCache->objPath);
00468 }
00469 }
00470
00471 unlink (subPhyPath);
00472
00473 rstrcpy (regReplicaInp.srcDataObjInfo->objPath,
00474 tmpBunReplCache->objPath, MAX_NAME_LEN);
00475 regReplicaInp.srcDataObjInfo->dataId =
00476 regReplicaInp.destDataObjInfo->dataId =
00477 tmpBunReplCache->dataId;
00478 regReplicaInp.srcDataObjInfo->replNum = tmpBunReplCache->srcReplNum;
00479 status = rsRegReplica (rsComm, ®ReplicaInp);
00480 if (status < 0) {
00481 savedStatus = status;
00482 rodsLog (LOG_ERROR,
00483 "bundleAndRegSubFiles: rsRegReplica error for %s. stat = %d",
00484 tmpBunReplCache->objPath, status);
00485 }
00486
00487
00488 if (chksumFlag != 0) {
00489 addKeyVal (®Param, CHKSUM_KW, tmpBunReplCache->chksumStr);
00490 status = rsModDataObjMeta (rsComm, &modDataObjMetaInp);
00491 clearKeyVal (®Param);
00492 if (status < 0) {
00493 savedStatus = status;
00494 rodsLogError (LOG_ERROR, status, "bundleAndRegSubFiles: rsModDataObjMeta error for %s.", tmpBunReplCache->objPath);
00495 }
00496 }
00497
00498 free (tmpBunReplCache);
00499 tmpBunReplCache = nextBunReplCache;
00500 }
00501 clearKeyVal (®ReplicaInp.condInput);
00502 free (regReplicaInp.srcDataObjInfo);
00503 free (regReplicaInp.destDataObjInfo);
00504 bzero (bunReplCacheHeader, sizeof (bunReplCacheHeader_t));
00505 rmdir (phyBunDir);
00506
00507 if (status >= 0 && savedStatus < 0) {
00508 return savedStatus;
00509 } else {
00510 return status;
00511 }
00512 }
00513
00514
00515
00516
00517 int
00518 phyBundle (rsComm_t *rsComm, dataObjInfo_t *dataObjInfo, char *phyBunDir,
00519 char *collection, int oprType )
00520 {
00521 structFileOprInp_t structFileOprInp;
00522 int status = 0;
00523 char *dataType;
00524 int myOprType = oprType;
00525
00526 dataType = dataObjInfo->dataType;
00527 #if 0 // this is now handled by libarchive which can add to existing archives without
00528
00529 if ((oprType & ADD_TO_TAR_OPR) != 0) {
00530
00531 if( dataType != NULL &&
00532 ( strstr( dataType, GZIP_TAR_DT_STR ) != NULL ||
00533 strstr (dataType, BZIP2_TAR_DT_STR) != NULL)) {
00534
00535
00536 status = unbunPhyBunFile (rsComm, dataObjInfo->objPath,
00537 dataObjInfo->rescInfo, dataObjInfo->filePath, phyBunDir,
00538 dataType, PRESERVE_DIR_CONT);
00539 if (status < 0) return status;
00540
00541 myOprType = myOprType ^ ADD_TO_TAR_OPR;
00542 }
00543 }
00544 #endif
00545
00546 bzero (&structFileOprInp, sizeof (structFileOprInp));
00547 addKeyVal( &structFileOprInp.condInput, RESC_HIER_STR_KW, dataObjInfo->rescHier );
00548
00549 structFileOprInp.specColl = (specColl_t*)malloc (sizeof (specColl_t));
00550 memset (structFileOprInp.specColl, 0, sizeof (specColl_t));
00551 structFileOprInp.specColl->type = TAR_STRUCT_FILE_T;
00552
00553
00554 rstrcpy (structFileOprInp.specColl->collection,collection, MAX_NAME_LEN);
00555 rstrcpy (structFileOprInp.specColl->objPath,dataObjInfo->objPath, MAX_NAME_LEN);
00556 structFileOprInp.specColl->collClass = STRUCT_FILE_COLL;
00557 rstrcpy (structFileOprInp.specColl->resource, dataObjInfo->rescName,NAME_LEN);
00558 rstrcpy (structFileOprInp.specColl->phyPath,dataObjInfo->filePath, MAX_NAME_LEN);
00559 addKeyVal( &structFileOprInp.condInput, RESC_HIER_STR_KW, dataObjInfo->rescHier );
00560
00561 rstrcpy (structFileOprInp.specColl->cacheDir, phyBunDir, MAX_NAME_LEN);
00562 structFileOprInp.specColl->cacheDirty = 1;
00563
00564 structFileOprInp.oprType = NO_REG_COLL_INFO | myOprType;
00565 if( dataType != NULL &&
00566 ( strstr( dataType, GZIP_TAR_DT_STR) != NULL ||
00567 strstr( dataType, BZIP2_TAR_DT_STR) != NULL ||
00568 strstr( dataType, ZIP_DT_STR) != NULL ) ) {
00569 addKeyVal (&structFileOprInp.condInput, DATA_TYPE_KW, dataType);
00570 }
00571
00572 status = rsStructFileSync (rsComm, &structFileOprInp);
00573
00574 free (structFileOprInp.specColl);
00575
00576 if ((oprType & ADD_TO_TAR_OPR) != 0 && (myOprType & ADD_TO_TAR_OPR) == 0) {
00577 rmUnlinkedFilesInUnixDir (phyBunDir);
00578 }
00579
00580 if (status < 0) {
00581 rodsLog (LOG_ERROR,
00582 "phyBundle: rsStructFileSync of %s error. stat = %d",
00583 dataObjInfo->objPath, status);
00584 }
00585
00586 return status;
00587 }
00588
00589 int
00590 addSubFileToDir (curSubFileCond_t *curSubFileCond,
00591 bunReplCacheHeader_t *bunReplCacheHeader)
00592 {
00593 int status;
00594 bunReplCache_t *bunReplCache;
00595
00596
00597 status = link (curSubFileCond->cachePhyPath, curSubFileCond->subPhyPath);
00598 if (status < 0) {
00599 rodsLog (LOG_ERROR,
00600 "addSubFileToDir: link error %s to %s. errno = %d",
00601 curSubFileCond->cachePhyPath, curSubFileCond->subPhyPath, errno);
00602 return (UNIX_FILE_LINK_ERR - errno);
00603 }
00604 bunReplCache = (bunReplCache_t*)malloc (sizeof (bunReplCache_t));
00605 bzero (bunReplCache, sizeof (bunReplCache_t));
00606 bunReplCache->dataId = curSubFileCond->dataId;
00607 snprintf (bunReplCache->objPath, MAX_NAME_LEN, "%s/%s",
00608 curSubFileCond->collName, curSubFileCond->dataName);
00609 bunReplCache->srcReplNum = curSubFileCond->cacheReplNum;
00610 bunReplCache->next = bunReplCacheHeader->bunReplCacheHead;
00611 bunReplCacheHeader->bunReplCacheHead = bunReplCache;
00612 bunReplCacheHeader->numSubFiles++;
00613 bunReplCacheHeader->totSubFileSize += curSubFileCond->subFileSize;
00614
00615 return 0;
00616 }
00617
00618 int
00619 setSubPhyPath (char *phyBunDir, rodsLong_t dataId, char *subPhyPath)
00620 {
00621 snprintf (subPhyPath, MAX_NAME_LEN, "%s/%lld", phyBunDir, dataId);
00622 return 0;
00623 }
00624
00625 int
00626 isDataObjBundled (rsComm_t *rsComm, collEnt_t *collEnt)
00627 {
00628 if (strcmp (collEnt->resource, BUNDLE_RESC) == 0) {
00629 if (collEnt->replStatus > 0) {
00630 return 1;
00631 } else {
00632
00633 return 0;
00634 }
00635 } else {
00636 return 0;
00637 }
00638 }
00639
00640 int
00641 replDataObjForBundle (rsComm_t *rsComm, char *collName, char *dataName,
00642 char *rescName, char* rescHier, char* dstRescHier,
00643 int adminFlag, dataObjInfo_t *outCacheObjInfo)
00644 {
00645 transferStat_t transStat;
00646 dataObjInp_t dataObjInp;
00647 int status;
00648
00649 if (outCacheObjInfo != NULL)
00650 memset (outCacheObjInfo, 0, sizeof (dataObjInfo_t));
00651 memset (&dataObjInp, 0, sizeof (dataObjInp_t));
00652 memset (&transStat, 0, sizeof (transStat));
00653
00654 snprintf (dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collName, dataName);
00655 addKeyVal (&dataObjInp.condInput, BACKUP_RESC_NAME_KW, rescName);
00656 if( rescHier ) {
00657 addKeyVal (&dataObjInp.condInput, RESC_HIER_STR_KW, rescHier);
00658 }
00659 if( dstRescHier ) {
00660 addKeyVal (&dataObjInp.condInput, DEST_RESC_HIER_STR_KW, dstRescHier);
00661 }
00662 if (adminFlag > 0)
00663 addKeyVal (&dataObjInp.condInput, IRODS_ADMIN_KW, "");
00664
00665 status = _rsDataObjRepl (rsComm, &dataObjInp, &transStat,
00666 outCacheObjInfo);
00667 clearKeyVal (&dataObjInp.condInput);
00668 return status;
00669 }
00670
00671 int
00672 createPhyBundleDir (rsComm_t *rsComm, char *bunFilePath,
00673 char *outPhyBundleDir)
00674 {
00675
00676 snprintf (outPhyBundleDir, MAX_NAME_LEN, "%s.dir", bunFilePath);
00677 mkdirR ("/", outPhyBundleDir, getDefDirMode ());
00678 return (0);
00679 }
00680
00681 int
00682 createPhyBundleDataObj (rsComm_t *rsComm, char *collection,
00683 rescGrpInfo_t *rescGrpInfo, const char* rescHier, dataObjInp_t *dataObjInp,
00684 char* dataType )
00685 {
00686 int myRanNum;
00687 int l1descInx;
00688 int status;
00689 int rescTypeInx = rescGrpInfo->rescInfo->rescTypeInx;
00690
00691
00692
00693 std::string type;
00694 eirods::error err = eirods::get_resource_property< std::string >( rescGrpInfo->rescInfo->rescName, "type", type );
00695 if( !err.ok() ) {
00696 eirods::log( PASS( err ) );
00697 }
00698
00699 #if 0 // JMC legacy resources
00700 if( std::string("unix file system") != type ) {
00701 rodsLog (LOG_ERROR,
00702 "createPhyBundleFile: resource %s appears to be of type %s rather than UNIX_FILE_TYPE",
00703 rescGrpInfo->rescInfo->rescName, type.c_str());
00704 return SYS_INVALID_RESC_TYPE;
00705 }
00706 else if (getRescClass (rescGrpInfo->rescInfo) != CACHE_CL) {
00707 return SYS_NO_CACHE_RESC_IN_GRP;
00708 }
00709
00710 #endif // JMC legacy resources
00711
00712 do {
00713 int loopCnt = 0;
00714 bzero (dataObjInp, sizeof (dataObjInp_t));
00715 while (1) {
00716 myRanNum = random ();
00717 status = rsMkBundlePath (rsComm, collection, dataObjInp->objPath,
00718 myRanNum);
00719 if (status < 0) {
00720 rodsLog (LOG_ERROR,
00721 "createPhyBundleFile: getPhyBundlePath err for %s.stat = %d",
00722 collection, status);
00723 return status;
00724 }
00725
00726 if (isData (rsComm, dataObjInp->objPath, NULL) >= 0) {
00727 if (loopCnt >= 100) {
00728 break;
00729 } else {
00730 loopCnt++;
00731 continue;
00732 }
00733 } else {
00734 break;
00735 }
00736 }
00737
00738 if (dataType != NULL && strstr (dataType, BUNDLE_STR) != NULL) {
00739 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, dataType);
00740 } else {
00741
00742 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, TAR_BUNDLE_DT_STR);
00743 }
00744
00745 if(rescHier != NULL) {
00746 addKeyVal(&dataObjInp->condInput, RESC_HIER_STR_KW, rescHier);
00747 }
00748
00749 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL) {
00750
00751 int len = strlen (dataObjInp->objPath);
00752 if (strcmp (&dataObjInp->objPath[len - 4], ".zip") != 0) {
00753 strcat (dataObjInp->objPath, ".zip");
00754 }
00755 }
00756
00757 l1descInx = _rsDataObjCreateWithRescInfo (rsComm, dataObjInp,
00758 rescGrpInfo->rescInfo, rescGrpInfo->rescGroupName);
00759
00760 clearKeyVal (&dataObjInp->condInput);
00761 } while (l1descInx == OVERWRITE_WITHOUT_FORCE_FLAG);
00762
00763 if (l1descInx >= 0) {
00764 l3Close (rsComm, l1descInx);
00765 L1desc[l1descInx].l3descInx = 0;
00766 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL)
00767 l3Unlink (rsComm, L1desc[l1descInx].dataObjInfo);
00768 }
00769
00770 return l1descInx;
00771 }
00772
00773
00774
00775
00776
00777
00778 int
00779 rsMkBundlePath (rsComm_t *rsComm, char *collection, char *bundlePath,
00780 int myRanNum)
00781 {
00782 int status;
00783 char *tmpStr;
00784 char startBundlePath[MAX_NAME_LEN];
00785 char destBundleColl[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
00786 char *bundlePathPtr;
00787
00788 bundlePathPtr = bundlePath;
00789 *bundlePathPtr = '/';
00790 bundlePathPtr++;
00791 tmpStr = collection + 1;
00792
00793 while (*tmpStr != '\0') {
00794 *bundlePathPtr = *tmpStr;
00795 bundlePathPtr ++;
00796 if (*tmpStr == '/') {
00797 tmpStr ++;
00798 break;
00799 }
00800 tmpStr ++;
00801 }
00802
00803 if (*tmpStr == '\0') {
00804 rodsLog (LOG_ERROR,
00805 "rsMkBundlePath: input path %s too short", collection);
00806 return (USER_INPUT_PATH_ERR);
00807 }
00808
00809
00810 if (strncmp (tmpStr, "trash/", 6) == 0 ||
00811 strncmp (tmpStr, "bundle/", 7) == 0) {
00812 rodsLog (LOG_ERROR,
00813 "rsMkBundlePath: cannot bundle trash or bundle path %s", collection);
00814 return (USER_INPUT_PATH_ERR);
00815 }
00816
00817
00818
00819 *bundlePathPtr = '\0';
00820 rstrcpy (startBundlePath, bundlePath, MAX_NAME_LEN);
00821
00822 snprintf (bundlePathPtr, MAX_NAME_LEN, "bundle/%s.%d", tmpStr, myRanNum);
00823
00824 if ((status = splitPathByKey (bundlePath, destBundleColl, myFile, '/'))
00825 < 0) {
00826 rodsLog (LOG_ERROR,
00827 "rsMkBundlePath: splitPathByKey error for %s ", bundlePath);
00828 return (USER_INPUT_PATH_ERR);
00829 }
00830
00831 status = rsMkCollR (rsComm, startBundlePath, destBundleColl);
00832
00833 if (status < 0) {
00834 rodsLog (LOG_ERROR,
00835 "rsMkBundlePath: rsMkCollR error for startPath %s, destPath %s ",
00836 startBundlePath, destBundleColl);
00837 }
00838
00839 return (status);
00840 }
00841
00842 int
00843 remotePhyBundleColl (rsComm_t *rsComm,
00844 structFileExtAndRegInp_t *phyBundleCollInp, rodsServerHost_t *rodsServerHost)
00845 {
00846 int status;
00847
00848 if (rodsServerHost == NULL) {
00849 rodsLog (LOG_NOTICE,
00850 "remotePhyBundleColl: Invalid rodsServerHost");
00851 return SYS_INVALID_SERVER_HOST;
00852 }
00853
00854 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00855 return status;
00856 }
00857
00858 status = rcPhyBundleColl (rodsServerHost->conn, phyBundleCollInp);
00859 return status;
00860 }
00861