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 >(
00695 rescGrpInfo->rescInfo->rescName,
00696 eirods::RESOURCE_TYPE,
00697 type );
00698 if( !err.ok() ) {
00699 eirods::log( PASS( err ) );
00700 }
00701
00702 #if 0 // JMC legacy resources
00703 if( std::string("unix file system") != type ) {
00704 rodsLog (LOG_ERROR,
00705 "createPhyBundleFile: resource %s appears to be of type %s rather than UNIX_FILE_TYPE",
00706 rescGrpInfo->rescInfo->rescName, type.c_str());
00707 return SYS_INVALID_RESC_TYPE;
00708 }
00709 else if (getRescClass (rescGrpInfo->rescInfo) != CACHE_CL) {
00710 return SYS_NO_CACHE_RESC_IN_GRP;
00711 }
00712
00713 #endif // JMC legacy resources
00714
00715 do {
00716 int loopCnt = 0;
00717 bzero (dataObjInp, sizeof (dataObjInp_t));
00718 while (1) {
00719 myRanNum = random ();
00720 status = rsMkBundlePath (rsComm, collection, dataObjInp->objPath,
00721 myRanNum);
00722 if (status < 0) {
00723 rodsLog (LOG_ERROR,
00724 "createPhyBundleFile: getPhyBundlePath err for %s.stat = %d",
00725 collection, status);
00726 return status;
00727 }
00728
00729 if (isData (rsComm, dataObjInp->objPath, NULL) >= 0) {
00730 if (loopCnt >= 100) {
00731 break;
00732 } else {
00733 loopCnt++;
00734 continue;
00735 }
00736 } else {
00737 break;
00738 }
00739 }
00740
00741 if (dataType != NULL && strstr (dataType, BUNDLE_STR) != NULL) {
00742 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, dataType);
00743 } else {
00744
00745 addKeyVal (&dataObjInp->condInput, DATA_TYPE_KW, TAR_BUNDLE_DT_STR);
00746 }
00747
00748 if(rescHier != NULL) {
00749 addKeyVal(&dataObjInp->condInput, RESC_HIER_STR_KW, rescHier);
00750 }
00751
00752 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL) {
00753
00754 int len = strlen (dataObjInp->objPath);
00755 if (strcmp (&dataObjInp->objPath[len - 4], ".zip") != 0) {
00756 strcat (dataObjInp->objPath, ".zip");
00757 }
00758 }
00759
00760 l1descInx = _rsDataObjCreateWithRescInfo (rsComm, dataObjInp,
00761 rescGrpInfo->rescInfo, rescGrpInfo->rescGroupName);
00762
00763 clearKeyVal (&dataObjInp->condInput);
00764 } while (l1descInx == OVERWRITE_WITHOUT_FORCE_FLAG);
00765
00766 if (l1descInx >= 0) {
00767 l3Close (rsComm, l1descInx);
00768 L1desc[l1descInx].l3descInx = 0;
00769 if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL)
00770 l3Unlink (rsComm, L1desc[l1descInx].dataObjInfo);
00771 }
00772
00773 return l1descInx;
00774 }
00775
00776
00777
00778
00779
00780
00781 int
00782 rsMkBundlePath (rsComm_t *rsComm, char *collection, char *bundlePath,
00783 int myRanNum)
00784 {
00785 int status;
00786 char *tmpStr;
00787 char startBundlePath[MAX_NAME_LEN];
00788 char destBundleColl[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
00789 char *bundlePathPtr;
00790
00791 bundlePathPtr = bundlePath;
00792 *bundlePathPtr = '/';
00793 bundlePathPtr++;
00794 tmpStr = collection + 1;
00795
00796 while (*tmpStr != '\0') {
00797 *bundlePathPtr = *tmpStr;
00798 bundlePathPtr ++;
00799 if (*tmpStr == '/') {
00800 tmpStr ++;
00801 break;
00802 }
00803 tmpStr ++;
00804 }
00805
00806 if (*tmpStr == '\0') {
00807 rodsLog (LOG_ERROR,
00808 "rsMkBundlePath: input path %s too short", collection);
00809 return (USER_INPUT_PATH_ERR);
00810 }
00811
00812
00813 if (strncmp (tmpStr, "trash/", 6) == 0 ||
00814 strncmp (tmpStr, "bundle/", 7) == 0) {
00815 rodsLog (LOG_ERROR,
00816 "rsMkBundlePath: cannot bundle trash or bundle path %s", collection);
00817 return (USER_INPUT_PATH_ERR);
00818 }
00819
00820
00821
00822 *bundlePathPtr = '\0';
00823 rstrcpy (startBundlePath, bundlePath, MAX_NAME_LEN);
00824
00825 snprintf (bundlePathPtr, MAX_NAME_LEN, "bundle/%s.%d", tmpStr, myRanNum);
00826
00827 if ((status = splitPathByKey (bundlePath, destBundleColl, myFile, '/'))
00828 < 0) {
00829 rodsLog (LOG_ERROR,
00830 "rsMkBundlePath: splitPathByKey error for %s ", bundlePath);
00831 return (USER_INPUT_PATH_ERR);
00832 }
00833
00834 status = rsMkCollR (rsComm, startBundlePath, destBundleColl);
00835
00836 if (status < 0) {
00837 rodsLog (LOG_ERROR,
00838 "rsMkBundlePath: rsMkCollR error for startPath %s, destPath %s ",
00839 startBundlePath, destBundleColl);
00840 }
00841
00842 return (status);
00843 }
00844
00845 int
00846 remotePhyBundleColl (rsComm_t *rsComm,
00847 structFileExtAndRegInp_t *phyBundleCollInp, rodsServerHost_t *rodsServerHost)
00848 {
00849 int status;
00850
00851 if (rodsServerHost == NULL) {
00852 rodsLog (LOG_NOTICE,
00853 "remotePhyBundleColl: Invalid rodsServerHost");
00854 return SYS_INVALID_SERVER_HOST;
00855 }
00856
00857 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00858 return status;
00859 }
00860
00861 status = rcPhyBundleColl (rodsServerHost->conn, phyBundleCollInp);
00862 return status;
00863 }
00864