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