00001
00002
00003
00004
00005
00006
00007
00008 #include "dataObjOpen.h"
00009 #include "dataObjOpenAndStat.h"
00010 #include "rodsLog.h"
00011 #include "objMetaOpr.h"
00012 #include "resource.h"
00013 #include "resource.h"
00014 #include "dataObjOpr.h"
00015 #include "physPath.h"
00016 #include "dataObjCreate.h"
00017 #include "dataObjLock.h"
00018
00019 #include "fileOpen.h"
00020 #include "subStructFileOpen.h"
00021 #include "rsGlobalExtern.h"
00022 #include "rcGlobalExtern.h"
00023 #include "reGlobalsExtern.h"
00024 #include "reDefines.h"
00025 #include "reDefines.h"
00026 #include "getRemoteZoneResc.h"
00027 #include "regReplica.h"
00028 #include "regDataObj.h"
00029 #include "dataObjClose.h"
00030 #include "dataObjRepl.h"
00031
00032
00033
00034 #include "eirods_resource_backport.h"
00035 #include "eirods_resource_redirect.h"
00036 #include "eirods_hierarchy_parser.h"
00037 #include "eirods_stacktrace.h"
00038
00039 int
00040 rsDataObjOpen (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00041 {
00042 int status, l1descInx;
00043 int remoteFlag;
00044 rodsServerHost_t *rodsServerHost;
00045
00046 remoteFlag = getAndConnRemoteZone (rsComm, dataObjInp, &rodsServerHost,
00047 REMOTE_OPEN);
00048 if (remoteFlag < 0) {
00049 return (remoteFlag);
00050 } else if (remoteFlag == REMOTE_HOST) {
00051 openStat_t *openStat = NULL;
00052 status = rcDataObjOpenAndStat (rodsServerHost->conn, dataObjInp,
00053 &openStat);
00054 if (status < 0) return status;
00055 l1descInx = allocAndSetL1descForZoneOpr (status, dataObjInp,
00056 rodsServerHost, openStat);
00057 if (openStat != NULL) free (openStat);
00058 return (l1descInx);
00059 } else {
00060
00061
00062 if( getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ) == NULL ) {
00063 std::string hier;
00064 eirods::error ret = eirods::resolve_resource_hierarchy( eirods::EIRODS_OPEN_OPERATION,
00065 rsComm, dataObjInp, hier );
00066 if( !ret.ok() ) {
00067 std::stringstream msg;
00068 msg << "failed in eirods::resolve_resource_hierarchy for [";
00069 msg << dataObjInp->objPath << "]";
00070 eirods::log( PASSMSG( msg.str(), ret ) );
00071 return ret.code();
00072 }
00073
00074
00075
00076
00077 addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00078
00079 }
00080
00081 l1descInx = _rsDataObjOpen( rsComm, dataObjInp );
00082
00083 }
00084
00085 return (l1descInx);
00086 }
00087
00088
00089
00090
00091
00092 int
00093 _rsDataObjOpen (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00094 {
00095
00096 int status;
00097 dataObjInfo_t *dataObjInfoHead = NULL;
00098 dataObjInfo_t *otherDataObjInfo = NULL;
00099 dataObjInfo_t *nextDataObjInfo = NULL;
00100 dataObjInfo_t *tmpDataObjInfo;
00101 dataObjInfo_t *compDataObjInfo = NULL;
00102 dataObjInfo_t *cacheDataObjInfo = NULL;
00103 rescInfo_t *compRescInfo = NULL;
00104 int l1descInx;
00105 int writeFlag;
00106 int phyOpenFlag = DO_PHYOPEN;
00107 char *lockType = NULL;
00108 int lockFd = -1;
00109
00110 if (getValByKey (&dataObjInp->condInput, NO_OPEN_FLAG_KW) != NULL) {
00111 phyOpenFlag = DO_NOT_PHYOPEN;
00112 } else if (getValByKey (&dataObjInp->condInput, PHYOPEN_BY_SIZE_KW)
00113 != NULL) {
00114 phyOpenFlag = PHYOPEN_BY_SIZE;
00115 }
00116
00117
00118 lockType = getValByKey (&dataObjInp->condInput, LOCK_TYPE_KW);
00119 if (lockType != NULL) {
00120 lockFd = rsDataObjLock (rsComm, dataObjInp);
00121 if (lockFd > 0) {
00122
00123 rmKeyVal (&dataObjInp->condInput, LOCK_TYPE_KW);
00124 } else {
00125 rodsLogError (LOG_ERROR, lockFd,
00126 "_rsDataObjOpen: rsDataObjLock error for %s. lockType = %s",
00127 dataObjInp->objPath, lockType);
00128 return lockFd;
00129 }
00130 }
00131
00132
00133
00134 status = getDataObjInfoIncSpecColl (rsComm, dataObjInp, &dataObjInfoHead);
00135
00136 writeFlag = getWriteFlag (dataObjInp->openFlags);
00137
00138 if (status < 0) {
00139 if (dataObjInp->openFlags & O_CREAT && writeFlag > 0) {
00140 l1descInx = rsDataObjCreate (rsComm, dataObjInp);
00141 status = l1descInx;
00142 }
00143
00144
00145 if (lockFd >= 0) {
00146 if (status > 0) {
00147 L1desc[l1descInx].lockFd = lockFd;
00148 } else {
00149 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00150 }
00151 }
00152 return (status);
00153
00154 } else {
00155
00156 status = sortObjInfoForOpen (rsComm, &dataObjInfoHead, &dataObjInp->condInput, writeFlag);
00157 if (status < 0) {
00158 if (lockFd > 0) {
00159 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00160 }
00161 std::stringstream msg;
00162 msg << __FUNCTION__;
00163 msg << " - Unable to select a data obj info matching the resource hierarchy from the keywords.";
00164 eirods::log(ERROR(status, msg.str()));
00165 return status;
00166 }
00167
00168 status = applyPreprocRuleForOpen (rsComm, dataObjInp, &dataObjInfoHead);
00169 if (status < 0) {
00170 if (lockFd > 0)
00171 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00172 return status;
00173 }
00174 }
00175
00176 if (getStructFileType (dataObjInfoHead->specColl) >= 0) {
00177
00178 } else if (writeFlag > 0) {
00179
00180
00181 status = procDataObjOpenForWrite (rsComm, dataObjInp, &dataObjInfoHead, &cacheDataObjInfo, &compDataObjInfo, &compRescInfo);
00182 }
00183
00184 if (status < 0) {
00185 if (lockFd > 0)
00186 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00187 freeAllDataObjInfo (dataObjInfoHead);
00188 return status;
00189 }
00190
00191 std::string resc_class;
00192 eirods::error prop_err = eirods::get_resource_property<std::string>(
00193 dataObjInfoHead->rescInfo->rescName, "class", resc_class );
00194 if( prop_err.ok() ) {
00195 if( resc_class == "bundle" ) {
00196 status = stageBundledData (rsComm, &dataObjInfoHead);
00197 if (status < 0) {
00198 rodsLog (LOG_ERROR,
00199 "_rsDataObjOpen: stageBundledData of %s failed stat=%d",
00200 dataObjInfoHead->objPath, status);
00201 freeAllDataObjInfo (dataObjInfoHead);
00202 if (lockFd >= 0) rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00203 return status;
00204 }
00205 }
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 tmpDataObjInfo = dataObjInfoHead;
00220
00221 while (tmpDataObjInfo != NULL) {
00222 nextDataObjInfo = tmpDataObjInfo->next;
00223 tmpDataObjInfo->next = NULL;
00224 if ( writeFlag > 0 && cacheDataObjInfo != NULL &&
00225 tmpDataObjInfo != cacheDataObjInfo) {
00226
00227 queDataObjInfo (&otherDataObjInfo, tmpDataObjInfo, 1, 1);
00228 tmpDataObjInfo = nextDataObjInfo;
00229 continue;
00230 }
00231
00232 status = l1descInx = _rsDataObjOpenWithObjInfo (rsComm, dataObjInp,phyOpenFlag, tmpDataObjInfo, cacheDataObjInfo);
00233
00234 if (status >= 0) {
00235 if (compDataObjInfo != NULL) {
00236 L1desc[l1descInx].replDataObjInfo = compDataObjInfo;
00237 } else if (compRescInfo != NULL) {
00238 L1desc[l1descInx].replRescInfo = compRescInfo;
00239 }
00240
00241 queDataObjInfo (&otherDataObjInfo, nextDataObjInfo, 0, 1);
00242 L1desc[l1descInx].otherDataObjInfo = otherDataObjInfo;
00243
00244 if (writeFlag > 0) {
00245 L1desc[l1descInx].openType = OPEN_FOR_WRITE_TYPE;
00246 } else {
00247 L1desc[l1descInx].openType = OPEN_FOR_READ_TYPE;
00248 }
00249
00250
00251 if (lockFd >= 0) {
00252 if (l1descInx >= 0) {
00253 L1desc[l1descInx].lockFd = lockFd;
00254 } else {
00255 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00256 }
00257 }
00258
00259 return (l1descInx);
00260
00261 }
00262
00263 tmpDataObjInfo = nextDataObjInfo;
00264 }
00265
00266 freeAllDataObjInfo (otherDataObjInfo);
00267
00268 return (status);
00269 }
00270
00271
00272
00273
00274
00275
00276
00277 int
00278 _rsDataObjOpenWithObjInfo (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00279 int phyOpenFlag, dataObjInfo_t *dataObjInfo, dataObjInfo_t *cacheDataObjInfo)
00280 {
00281 int replStatus;
00282 int status;
00283 int l1descInx;
00284 l1descInx = allocL1desc ();
00285
00286 if (l1descInx < 0) return l1descInx;
00287
00288 replStatus = dataObjInfo->replStatus | OPEN_EXISTING_COPY;
00289
00290
00291
00292
00293 fillL1desc (l1descInx, dataObjInp, dataObjInfo, replStatus, -1);
00294 if( getValByKey (&dataObjInp->condInput, PURGE_CACHE_KW) != NULL) {
00295 L1desc[l1descInx].purgeCacheFlag = 1;
00296 }
00297
00298 if (phyOpenFlag == DO_NOT_PHYOPEN) {
00299
00300 status = 0;
00301 } else if (phyOpenFlag == PHYOPEN_BY_SIZE) {
00302
00303 if (getValByKey (&dataObjInp->condInput, DATA_INCLUDED_KW) != NULL
00304 && dataObjInfo->dataSize <= MAX_SZ_FOR_SINGLE_BUF) {
00305 status = 0;
00306 } else if (dataObjInfo->dataSize != UNKNOWN_FILE_SZ &&
00307 dataObjInfo->dataSize < MAX_SZ_FOR_SINGLE_BUF) {
00308 status = 0;
00309 } else {
00310 status = dataOpen (rsComm, l1descInx);
00311 }
00312 } else {
00313 status = dataOpen (rsComm, l1descInx);
00314 }
00315
00316 if (status < 0) {
00317 freeL1desc (l1descInx);
00318 return (status);
00319 } else {
00320 return (l1descInx);
00321 }
00322 }
00323
00324 int
00325 dataOpen (rsComm_t *rsComm, int l1descInx)
00326 {
00327 dataObjInfo_t *myDataObjInfo = L1desc[l1descInx].dataObjInfo;
00328 int status;
00329
00330
00331 status = l3Open (rsComm, l1descInx);
00332
00333 if (status <= 0) {
00334 rodsLog (LOG_NOTICE,
00335 "dataOpen: l3Open of %s failed, status = %d",
00336 myDataObjInfo->filePath, status);
00337 return (status);
00338 } else {
00339 L1desc[l1descInx].l3descInx = status;
00340 return (0);
00341 }
00342 }
00343
00344 int
00345 l3Open (rsComm_t *rsComm, int l1descInx)
00346 {
00347 dataObjInfo_t *dataObjInfo;
00348 int l3descInx;
00349 int mode, flags;
00350
00351 dataObjInfo = L1desc[l1descInx].dataObjInfo;
00352
00353 std::string location;
00354 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00355 if( !ret.ok() ) {
00356 eirods::log( PASSMSG( "l3Open - failed in specColl open", ret ) );
00357 return -1;
00358 }
00359
00360 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00361 subFile_t subFile;
00362 memset (&subFile, 0, sizeof (subFile));
00363 rstrcpy (subFile.subFilePath, dataObjInfo->subPath,MAX_NAME_LEN);
00364 rstrcpy (subFile.addr.hostAddr, location.c_str(), NAME_LEN );
00365 subFile.specColl = dataObjInfo->specColl;
00366 subFile.mode = getFileMode (L1desc[l1descInx].dataObjInp);
00367 subFile.flags = getFileFlags (l1descInx);
00368 l3descInx = rsSubStructFileOpen (rsComm, &subFile);
00369 } else {
00370 mode = getFileMode (L1desc[l1descInx].dataObjInp);
00371 flags = getFileFlags (l1descInx);
00372 l3descInx = _l3Open (rsComm, dataObjInfo, mode, flags);
00373 }
00374 return (l3descInx);
00375 }
00376
00377 int
00378 _l3Open (rsComm_t *rsComm, dataObjInfo_t *dataObjInfo, int mode, int flags)
00379 {
00380 int l3descInx;
00381 fileOpenInp_t fileOpenInp;
00382
00383
00384
00385 std::string location;
00386 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00387 if( !ret.ok() ) {
00388 eirods::log( PASSMSG( "l3FilePutSingleBuf - failed in get_loc_for_hier_String", ret ) );
00389 return -1;
00390 }
00391
00392 memset (&fileOpenInp, 0, sizeof (fileOpenInp));
00393 rstrcpy( fileOpenInp.resc_name_, dataObjInfo->rescInfo->rescName, MAX_NAME_LEN );
00394 rstrcpy( fileOpenInp.resc_hier_, dataObjInfo->rescHier, MAX_NAME_LEN );
00395 rstrcpy( fileOpenInp.objPath, dataObjInfo->objPath, MAX_NAME_LEN );
00396 fileOpenInp.fileType = static_cast< fileDriverType_t >( -1 );
00397 rstrcpy (fileOpenInp.addr.hostAddr, location.c_str(), NAME_LEN);
00398 rstrcpy (fileOpenInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN);
00399 fileOpenInp.mode = mode;
00400 fileOpenInp.flags = flags;
00401 rstrcpy(fileOpenInp.in_pdmo, dataObjInfo->in_pdmo, MAX_NAME_LEN);
00402 l3descInx = rsFileOpen (rsComm, &fileOpenInp);
00403
00404 return (l3descInx);
00405 }
00406
00407
00408
00409
00410
00411 int
00412 l3OpenByHost (rsComm_t *rsComm, int rescTypeInx, int l3descInx, int flags)
00413 {
00414 fileOpenInp_t fileOpenInp;
00415 int newL3descInx;
00416
00417 memset (&fileOpenInp, 0, sizeof (fileOpenInp));
00418 fileOpenInp.fileType = static_cast< fileDriverType_t>( -1 );
00419 rstrcpy( fileOpenInp.resc_hier_, FileDesc[l3descInx].rescHier, MAX_NAME_LEN );
00420 rstrcpy (fileOpenInp.fileName, FileDesc[l3descInx].fileName, MAX_NAME_LEN);
00421 rstrcpy(fileOpenInp.objPath, FileDesc[l3descInx].objPath, MAX_NAME_LEN);
00422 fileOpenInp.mode = FileDesc[l3descInx].mode;
00423 fileOpenInp.flags = flags;
00424 newL3descInx = rsFileOpenByHost (rsComm, &fileOpenInp,
00425 FileDesc[l3descInx].rodsServerHost);
00426
00427 return (newL3descInx);
00428 }
00429
00430 int
00431 applyPreprocRuleForOpen (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00432 dataObjInfo_t **dataObjInfoHead)
00433 {
00434 int status;
00435 ruleExecInfo_t rei;
00436
00437 initReiWithDataObjInp (&rei, rsComm, dataObjInp);
00438 rei.doi = *dataObjInfoHead;
00439
00440 status = applyRule ("acPreprocForDataObjOpen", NULL, &rei, NO_SAVE_REI);
00441
00442 if (status < 0) {
00443 if (rei.status < 0) {
00444 status = rei.status;
00445 }
00446 rodsLog (LOG_ERROR,
00447 "applyPreprocRuleForOpen:acPreprocForDataObjOpen error for %s,stat=%d",
00448 dataObjInp->objPath, status);
00449 } else {
00450 *dataObjInfoHead = rei.doi;
00451 }
00452 return (status);
00453 }
00454
00455
00456
00457
00458 int
00459 createEmptyRepl (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00460 dataObjInfo_t **dataObjInfoHead)
00461 {
00462 int status;
00463 char *rescName;
00464 rescInfo_t *rescInfo;
00465 rescGrpInfo_t *tmpRescGrpInfo;
00466 regReplica_t regReplicaInp;
00467 rescGrpInfo_t *myRescGrpInfo = NULL;
00468 keyValPair_t *condInput = &dataObjInp->condInput;
00469 dataObjInfo_t *myDataObjInfo;
00470
00471 if ((rescName = getValByKey (condInput, DEST_RESC_NAME_KW)) == NULL &&
00472 (rescName = getValByKey (condInput, BACKUP_RESC_NAME_KW)) == NULL &&
00473 (rescName = getValByKey (condInput, DEF_RESC_NAME_KW)) == NULL) {
00474 return USER_NO_RESC_INPUT_ERR;
00475 }
00476
00477 status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo);
00478 if (status < 0 || myRescGrpInfo == NULL ) return status;
00479
00480 myDataObjInfo = (dataObjInfo_t*)malloc (sizeof (dataObjInfo_t));
00481 *myDataObjInfo = *(*dataObjInfoHead);
00482 tmpRescGrpInfo = myRescGrpInfo;
00483 while (tmpRescGrpInfo != NULL) {
00484 rescInfo = (*dataObjInfoHead)->rescInfo;
00485
00486 myDataObjInfo->rescInfo = new rescInfo_t;
00487 memcpy( myDataObjInfo->rescInfo, rescInfo, sizeof( rescInfo_t ) );
00488
00489 rstrcpy (myDataObjInfo->rescName, rescInfo->rescName, NAME_LEN);
00490 rstrcpy (myDataObjInfo->rescGroupName, (*dataObjInfoHead)->rescGroupName, NAME_LEN);
00491
00492 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00493 if( resc_hier ) {
00494 rstrcpy (myDataObjInfo->rescHier, resc_hier, MAX_NAME_LEN);
00495 } else {
00496 rodsLog( LOG_NOTICE, "createEmptyRepl :: using rescInfo->rescName for hier" );
00497 rstrcpy (myDataObjInfo->rescHier, rescInfo->rescName, MAX_NAME_LEN);
00498
00499 }
00500
00501
00502 status = getFilePathName (rsComm, myDataObjInfo, dataObjInp);
00503 if (status < 0) {
00504 tmpRescGrpInfo = tmpRescGrpInfo->next;
00505 continue;
00506 }
00507 status = l3CreateByObjInfo (rsComm, dataObjInp, myDataObjInfo);
00508 if (status < 0) {
00509 tmpRescGrpInfo = tmpRescGrpInfo->next;
00510 continue;
00511 }
00512
00513 _l3Close (rsComm, rescInfo->rescTypeInx, status);
00514
00515
00516 memset (®ReplicaInp, 0, sizeof (regReplicaInp));
00517 regReplicaInp.srcDataObjInfo = *dataObjInfoHead;
00518 regReplicaInp.destDataObjInfo = myDataObjInfo;
00519 if (getValByKey (&dataObjInp->condInput, IRODS_ADMIN_KW) != NULL) {
00520 addKeyVal (®ReplicaInp.condInput, IRODS_ADMIN_KW, "");
00521 }
00522 status = rsRegReplica (rsComm, ®ReplicaInp);
00523 clearKeyVal (®ReplicaInp.condInput);
00524
00525 break;
00526 }
00527
00528 freeAllRescGrpInfo (myRescGrpInfo);
00529
00530 if (status < 0) {
00531 free (myDataObjInfo);
00532 } else {
00533
00534 myDataObjInfo->next = *dataObjInfoHead;
00535 *dataObjInfoHead = myDataObjInfo;
00536 }
00537 return status;
00538 }
00539
00540
00541
00542 int
00543 procDataObjOpenForWrite (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00544 dataObjInfo_t **dataObjInfoHead, dataObjInfo_t **cacheDataObjInfo,
00545 dataObjInfo_t **compDataObjInfo, rescInfo_t **compRescInfo)
00546 {
00547 int status = 0;
00548 rescGrpInfo_t *myRescGrpInfo = NULL;
00549
00550
00551 status = requeDataObjInfoByDestResc ( dataObjInfoHead, &dataObjInp->condInput, 1, 1 );
00552
00553
00554 if (status < 0 && (*dataObjInfoHead)->specColl == NULL &&
00555 getValByKey (&dataObjInp->condInput, DEST_RESC_NAME_KW) != NULL) {
00556
00557 status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo);
00558 if (status < 0) return status;
00559
00560
00561 status = createEmptyRepl (rsComm, dataObjInp, dataObjInfoHead);
00562 if (status < 0) {
00563 rodsLogError (LOG_ERROR, status,
00564 "procDataObjForOpenWrite: createEmptyRepl of %s failed",
00565 (*dataObjInfoHead)->objPath);
00566 freeAllRescGrpInfo (myRescGrpInfo);
00567 return status;
00568 }
00569
00570 } else {
00571 status = 0;
00572 }
00573
00574 if (*compDataObjInfo != NULL) {
00575 dequeDataObjInfo (dataObjInfoHead, *compDataObjInfo);
00576 }
00577 freeAllRescGrpInfo (myRescGrpInfo);
00578 return status;
00579 }
00580
00581
00582
00583 eirods::error selectObjInfo(
00584 dataObjInfo_t * _dataObjInfoHead,
00585 keyValPair_t* _condInput,
00586 dataObjInfo_t** _rtn_dataObjInfo)
00587 {
00588 eirods::error result = SUCCESS();
00589 *_rtn_dataObjInfo = NULL;
00590 char* resc_hier = getValByKey(_condInput, RESC_HIER_STR_KW);
00591 if(!resc_hier) {
00592 std::stringstream msg;
00593 msg << __FUNCTION__;
00594 msg << " - No resource hierarchy specified in keywords.";
00595 result = ERROR(SYS_INVALID_INPUT_PARAM, msg.str());
00596 } else {
00597 for(dataObjInfo_t* dataObjInfo = _dataObjInfoHead;
00598 result.ok() && *_rtn_dataObjInfo == NULL && dataObjInfo != NULL;
00599 dataObjInfo = dataObjInfo->next) {
00600 if(strcmp(resc_hier, dataObjInfo->rescHier) == 0) {
00601 *_rtn_dataObjInfo = dataObjInfo;
00602 }
00603 }
00604 if(*_rtn_dataObjInfo == NULL) {
00605 std::stringstream msg;
00606 msg << __FUNCTION__;
00607 msg << " - Failed to find a data obj matching resource hierarchy: \"";
00608 msg << resc_hier;
00609 msg << "\"";
00610 result = ERROR(EIRODS_HIERARCHY_ERROR, msg.str());
00611 }
00612 }
00613 return result;
00614 }