00001
00002
00003
00004
00005
00006
00007
00008 #include "dataObjCreate.h"
00009 #include "dataObjCreateAndStat.h"
00010 #include "dataObjOpen.h"
00011 #include "fileCreate.h"
00012 #include "subStructFileCreate.h"
00013 #include "rodsLog.h"
00014 #include "objMetaOpr.h"
00015 #include "resource.h"
00016 #include "specColl.h"
00017 #include "dataObjOpr.h"
00018 #include "physPath.h"
00019 #include "dataObjUnlink.h"
00020 #include "dataObjLock.h"
00021 #include "regDataObj.h"
00022 #include "rcGlobalExtern.h"
00023 #include "reGlobalsExtern.h"
00024 #include "reDefines.h"
00025 #include "getRemoteZoneResc.h"
00026 #include "getRescQuota.h"
00027 #include "icatHighLevelRoutines.h"
00028
00029 #include "eirods_hierarchy_parser.h"
00030
00031
00032
00033
00034 #include "eirods_resource_backport.h"
00035 #include "eirods_resource_redirect.h"
00036 #include "eirods_hierarchy_parser.h"
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 int
00048 rsDataObjCreate (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00049 {
00050 int l1descInx;
00051 int status;
00052 rodsObjStat_t *rodsObjStatOut = NULL;
00053 int remoteFlag;
00054 rodsServerHost_t *rodsServerHost;
00055 specCollCache_t *specCollCache = NULL;
00056 char *lockType = NULL;
00057 int lockFd = -1;
00058
00059 resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache,
00060 &dataObjInp->condInput);
00061 remoteFlag = getAndConnRemoteZone (rsComm, dataObjInp, &rodsServerHost,
00062 REMOTE_CREATE);
00063 if (remoteFlag < 0) {
00064 return (remoteFlag);
00065 } else if (remoteFlag == REMOTE_HOST) {
00066 openStat_t *openStat = NULL;
00067 addKeyVal (&dataObjInp->condInput, CROSS_ZONE_CREATE_KW, "");
00068 status = rcDataObjCreateAndStat( rodsServerHost->conn, dataObjInp, &openStat );
00069
00070
00071 rmKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW );
00072 if (status < 0)
00073 return status;
00074 l1descInx = allocAndSetL1descForZoneOpr( status, dataObjInp,rodsServerHost, openStat );
00075
00076 if (openStat != NULL)
00077 free (openStat);
00078 return (l1descInx);
00079 }
00080
00081
00082
00083
00084
00085 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00086 if( NULL == resc_hier ) {
00087 std::string hier;
00088 eirods::error ret = eirods::resolve_resource_hierarchy( eirods::EIRODS_CREATE_OPERATION, rsComm,
00089 dataObjInp, hier );
00090 if( !ret.ok() ) {
00091 std::stringstream msg;
00092 msg << __FUNCTION__;
00093 msg << " :: failed in eirods::resolve_resource_hierarchy for [";
00094 msg << dataObjInp->objPath << "]";
00095 eirods::log( PASSMSG( msg.str(), ret ) );
00096 return ret.code();
00097 }
00098
00099
00100
00101
00102 addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00103
00104 }
00105
00106
00107
00108 lockType = getValByKey( &dataObjInp->condInput, LOCK_TYPE_KW );
00109 if (lockType != NULL) {
00110 lockFd = rsDataObjLock (rsComm, dataObjInp);
00111 if (lockFd >= 0) {
00112
00113 rmKeyVal (&dataObjInp->condInput, LOCK_TYPE_KW);
00114 } else {
00115 rodsLogError (LOG_ERROR, lockFd,
00116 "rsDataObjCreate: rsDataObjLock error for %s. lockType = %s",
00117 dataObjInp->objPath, lockType);
00118 return lockFd;
00119 }
00120 }
00121
00122
00123
00124 addKeyVal (&dataObjInp->condInput, SEL_OBJ_TYPE_KW, "dataObj");
00125
00126 status = rsObjStat (rsComm, dataObjInp, &rodsObjStatOut);
00127
00128 if(rodsObjStatOut != NULL && rodsObjStatOut->objType == COLL_OBJ_T) {
00129 if (lockFd >= 0) rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00130 return (USER_INPUT_PATH_ERR);
00131 }
00132
00133 if( rodsObjStatOut != NULL &&
00134 rodsObjStatOut->specColl != NULL &&
00135 rodsObjStatOut->specColl->collClass == LINKED_COLL ) {
00136
00137 if( lockFd >= 0 ) {
00138 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00139 }
00140
00141 return SYS_COLL_LINK_PATH_ERR;
00142 }
00143
00144
00145 if ( rodsObjStatOut == NULL ||
00146 ( rodsObjStatOut->objType == UNKNOWN_OBJ_T &&
00147 rodsObjStatOut->specColl == NULL ) ) {
00148
00149
00150
00151
00152 l1descInx = _rsDataObjCreate (rsComm, dataObjInp);
00153
00154 } else if( rodsObjStatOut->specColl != NULL &&
00155 rodsObjStatOut->objType == UNKNOWN_OBJ_T) {
00156
00157
00158
00159 l1descInx = specCollSubCreate (rsComm, dataObjInp);
00160 } else {
00161
00162
00163 if (getValByKey (&dataObjInp->condInput, FORCE_FLAG_KW) != NULL) {
00164
00165 dataObjInp->openFlags |= O_TRUNC | O_RDWR;
00166 l1descInx = _rsDataObjOpen (rsComm, dataObjInp);
00167 } else {
00168 l1descInx = OVERWRITE_WITHOUT_FORCE_FLAG;
00169 }
00170 }
00171
00172 if( rodsObjStatOut != NULL ) {
00173 freeRodsObjStat (rodsObjStatOut);
00174 }
00175
00176
00177
00178 if (lockFd >= 0) {
00179 if (l1descInx >= 0) {
00180 L1desc[l1descInx].lockFd = lockFd;
00181 } else {
00182 rsDataObjUnlock (rsComm, dataObjInp, lockFd);
00183 }
00184 }
00185
00186
00187 return (l1descInx);
00188 }
00189
00190 int
00191 _rsDataObjCreate (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00192 {
00193
00194 int status;
00195 rescGrpInfo_t* myRescGrpInfo = 0;
00196 int l1descInx;
00197
00198
00199 status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo );
00200 if( status < 0 ) {
00201 rodsLog( LOG_ERROR, "_rsDataObjCreate : failed in call to getRescGrpForCreate. status = %d", status );
00202 return status;
00203 }
00204
00205 #if 1 // JMC - legacy resource
00206 status = l1descInx = _rsDataObjCreateWithRescInfo( rsComm, dataObjInp, myRescGrpInfo->rescInfo, myRescGrpInfo->rescGroupName );
00207 #else // JMC - legacy resource
00208 rescCnt = getRescCnt (myRescGrpInfo);
00209
00210 copiesNeeded = getCopiesFromCond (&dataObjInp->condInput);
00211
00212
00213 tmpRescGrpInfo = myRescGrpInfo;
00214 while (tmpRescGrpInfo != NULL) {
00215 tmpRescInfo = tmpRescGrpInfo->rescInfo;
00216 status = l1descInx = _rsDataObjCreateWithRescInfo( rsComm, dataObjInp,
00217 tmpRescInfo, myRescGrpInfo->rescGroupName );
00218
00219 if (status < 0) {
00220 failedCount++;
00221 if (copiesNeeded == ALL_COPIES || (rescCnt - failedCount < copiesNeeded)) {
00222
00223 freeAllRescGrpInfo (myRescGrpInfo);
00224 return (status);
00225 }
00226 } else {
00227
00228 if (copiesNeeded == ALL_COPIES || copiesNeeded > 1) {
00229 if (tmpRescGrpInfo->next != NULL) {
00230 L1desc[l1descInx].moreRescGrpInfo = tmpRescGrpInfo->next;
00231
00232 L1desc[l1descInx].copiesNeeded = copiesNeeded;
00233 }
00234 }
00235 L1desc[l1descInx].openType = CREATE_TYPE;
00236 freeAllRescGrpInfo (myRescGrpInfo);
00237
00238
00239 return (l1descInx);
00240 }
00241 tmpRescGrpInfo = tmpRescGrpInfo->next;
00242 }
00243
00244 #endif // JMC - remove resource.c
00245
00246
00247
00248
00249
00250
00251
00252 if( status >= 0 ) {
00253 return (status);
00254 } else {
00255 rodsLog (LOG_NOTICE,
00256 "rsDataObjCreate: Internal error");
00257 return (SYS_INTERNAL_NULL_INPUT_ERR);
00258 }
00259 }
00260
00261 int
00262 specCollSubCreate (rsComm_t *rsComm, dataObjInp_t *dataObjInp)
00263 {
00264 int status;
00265 int l1descInx;
00266 dataObjInfo_t *dataObjInfo = NULL;
00267
00268 status = resolvePathInSpecColl (rsComm, dataObjInp->objPath,
00269 WRITE_COLL_PERM, 0, &dataObjInfo);
00270 if( dataObjInfo == NULL ) {
00271 rodsLog( LOG_ERROR, "specCollSubCreate :: dataObjInp is null" );
00272 return status;
00273 }
00274 if (status >= 0) {
00275 rodsLog (LOG_ERROR,
00276 "specCollSubCreate: phyPath %s already exist",
00277 dataObjInfo->filePath);
00278 freeDataObjInfo (dataObjInfo);
00279 return (SYS_COPY_ALREADY_IN_RESC);
00280 } else if (status != SYS_SPEC_COLL_OBJ_NOT_EXIST) {
00281 return (status);
00282 }
00283
00284 l1descInx = allocL1desc ();
00285
00286 if (l1descInx < 0) return l1descInx;
00287
00288 dataObjInfo->replStatus = NEWLY_CREATED_COPY;
00289 fillL1desc (l1descInx, dataObjInp, dataObjInfo, NEWLY_CREATED_COPY,
00290 dataObjInp->dataSize);
00291
00292 if (getValByKey (&dataObjInp->condInput, NO_OPEN_FLAG_KW) == NULL) {
00293 status = dataCreate (rsComm, l1descInx);
00294 if (status < 0) {
00295 freeL1desc (l1descInx);
00296 return (status);
00297 }
00298 }
00299
00300 return l1descInx;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 int
00310 _rsDataObjCreateWithRescInfo (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00311 rescInfo_t *rescInfo, char *rescGroupName)
00312 {
00313 dataObjInfo_t *dataObjInfo;
00314 int l1descInx;
00315 int status;
00316
00317 l1descInx = allocL1desc ();
00318 if (l1descInx < 0) return l1descInx;
00319
00320 dataObjInfo = (dataObjInfo_t*)malloc(sizeof (dataObjInfo_t));
00321 initDataObjInfoWithInp (dataObjInfo, dataObjInp);
00322
00323
00324
00325 #if 0 // JMC - remove legacy resources
00326 if (getRescClass (rescInfo) == COMPOUND_CL) {
00327 rescInfo_t *cacheResc = NULL;
00328 char myRescGroupName[NAME_LEN];
00329
00330 rstrcpy (myRescGroupName, rescGroupName, NAME_LEN);
00331 status = getCacheRescInGrp (rsComm, myRescGroupName, rescInfo, &cacheResc);
00332
00333 if (status < 0 || cacheResc == NULL ) {
00334 rodsLog (LOG_ERROR,
00335 "DataObjCreateWithResInfo:getCacheRescInGrp %s err for %s stat=%d",
00336 rescGroupName, dataObjInfo->objPath, status);
00337 free (dataObjInfo);
00338 freeL1desc (l1descInx);
00339 return status;
00340 }
00341
00342 L1desc[l1descInx].replRescInfo = rescInfo;
00343 dataObjInfo->rescInfo = cacheResc;
00344 rstrcpy (dataObjInfo->rescName, cacheResc->rescName, NAME_LEN);
00345 rstrcpy (dataObjInfo->rescGroupName, myRescGroupName, NAME_LEN);
00346 if (getValByKey (&dataObjInp->condInput, PURGE_CACHE_KW) != NULL) {
00347 L1desc[l1descInx].purgeCacheFlag = 1;
00348 }
00349
00350 } else {
00351 #endif
00352 dataObjInfo->rescInfo = rescInfo;
00353 rstrcpy (dataObjInfo->rescName, rescInfo->rescName, NAME_LEN);
00354 rstrcpy (dataObjInfo->rescGroupName, rescGroupName, NAME_LEN);
00355
00356 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00357 if( resc_hier ) {
00358 rstrcpy( dataObjInfo->rescHier, resc_hier, MAX_NAME_LEN);
00359
00360 } else {
00361 rstrcpy(dataObjInfo->rescHier, rescInfo->rescName, MAX_NAME_LEN);
00362
00363 }
00364
00365 #if 0 // JMC - remove legacy resources
00366
00367
00368 if( getValByKey (&dataObjInp->condInput, PURGE_CACHE_KW) != NULL &&
00369 getRescClass (rescInfo) == CACHE_CL) {
00370 rescInfo_t *compResc = NULL;
00371 if( getRescInGrpByClass (rsComm, rescGroupName, COMPOUND_CL,
00372 &compResc, NULL) >= 0) {
00373 L1desc[l1descInx].replRescInfo = compResc;
00374 L1desc[l1descInx].purgeCacheFlag = 1;
00375 }
00376 }
00377 }
00378 #endif // JMC - remove legacy resources
00379
00380 dataObjInfo->replStatus = NEWLY_CREATED_COPY;
00381 fillL1desc( l1descInx, dataObjInp, dataObjInfo, NEWLY_CREATED_COPY,
00382 dataObjInp->dataSize );
00383
00384 status = getFilePathName (rsComm, dataObjInfo, L1desc[l1descInx].dataObjInp);
00385
00386 if (status < 0) {
00387 freeL1desc (l1descInx);
00388 return (status);
00389 }
00390
00391
00392
00393
00394 if (getValByKey (&dataObjInp->condInput, NO_OPEN_FLAG_KW) != NULL) {
00395
00396
00397 status = 0;
00398 } else {
00399
00400 status = dataObjCreateAndReg( rsComm, l1descInx );
00401 }
00402
00403 if (status < 0) {
00404 freeL1desc (l1descInx);
00405 return (status);
00406 } else {
00407 return (l1descInx);
00408 }
00409 }
00410
00411
00412
00413
00414
00415 int
00416 dataObjCreateAndReg (rsComm_t *rsComm, int l1descInx)
00417 {
00418
00419 dataObjInfo_t *myDataObjInfo = L1desc[l1descInx].dataObjInfo;
00420 int status;
00421
00422 status = dataCreate (rsComm, l1descInx);
00423
00424 if (status < 0) {
00425 return (status);
00426 }
00427
00428
00429 status = svrRegDataObj (rsComm, myDataObjInfo);
00430 if (status < 0) {
00431 l3Unlink (rsComm, myDataObjInfo);
00432 rodsLog (LOG_NOTICE,
00433 "dataObjCreateAndReg: rsRegDataObj for %s failed, status = %d",
00434 myDataObjInfo->objPath, status);
00435 return (status);
00436 } else {
00437 myDataObjInfo->replNum = status;
00438 return (0);
00439 }
00440 }
00441
00442
00443
00444
00445
00446 int
00447 dataCreate (rsComm_t *rsComm, int l1descInx)
00448 {
00449 dataObjInfo_t *myDataObjInfo = L1desc[l1descInx].dataObjInfo;
00450 int status;
00451
00452
00453
00454 status = l3Create (rsComm, l1descInx);
00455
00456 if (status <= 0) {
00457 rodsLog (LOG_NOTICE,
00458 "dataCreate: l3Create of %s failed, status = %d",
00459 myDataObjInfo->filePath, status);
00460 return (status);
00461 } else {
00462 L1desc[l1descInx].l3descInx = status;
00463 }
00464
00465 return (0);
00466 }
00467
00468 int
00469 l3Create (rsComm_t *rsComm, int l1descInx)
00470 {
00471 dataObjInfo_t *dataObjInfo;
00472 int l3descInx;
00473
00474 dataObjInfo = L1desc[l1descInx].dataObjInfo;
00475
00476
00477
00478 std::string location;
00479 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00480 if( !ret.ok() ) {
00481 eirods::log( PASSMSG( "l3Create - failed in get_loc_for_hier_String", ret ) );
00482 return -1;
00483 }
00484
00485
00486 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00487 subFile_t subFile;
00488 memset (&subFile, 0, sizeof (subFile));
00489 rstrcpy (subFile.subFilePath, dataObjInfo->subPath, MAX_NAME_LEN );
00490 rstrcpy (subFile.addr.hostAddr, location.c_str(), NAME_LEN );
00491
00492 subFile.specColl = dataObjInfo->specColl;
00493 subFile.mode = getFileMode (L1desc[l1descInx].dataObjInp);
00494 l3descInx = rsSubStructFileCreate (rsComm, &subFile);
00495 } else {
00496
00497 l3descInx = l3CreateByObjInfo (rsComm, L1desc[l1descInx].dataObjInp,
00498 L1desc[l1descInx].dataObjInfo);
00499 }
00500
00501 return (l3descInx);
00502 }
00503
00504 int
00505 l3CreateByObjInfo (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00506 dataObjInfo_t *dataObjInfo)
00507 {
00508 int l3descInx;
00509
00510 #if 0 // JMC legacy resource
00511
00512
00513
00514
00515
00516 #endif // JMC legacy resource
00517 int retryCnt = 0;
00518 int chkType = 0;
00519
00520
00521
00522 std::string location;
00523 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00524 if( !ret.ok() ) {
00525 eirods::log( PASSMSG( "l3CreateByObjInfo - failed in get_loc_for_hier_String", ret ) );
00526 return -1;
00527 }
00528
00529
00530 fileCreateInp_t fileCreateInp;
00531 memset (&fileCreateInp, 0, sizeof (fileCreateInp));
00532 rstrcpy( fileCreateInp.resc_name_, location.c_str(), MAX_NAME_LEN );
00533 rstrcpy( fileCreateInp.resc_hier_, dataObjInfo->rescHier, MAX_NAME_LEN );
00534 rstrcpy( fileCreateInp.objPath, dataObjInfo->objPath, MAX_NAME_LEN );
00535 fileCreateInp.fileType = static_cast< fileDriverType_t >( -1 );
00536 rstrcpy( fileCreateInp.addr.hostAddr, location.c_str(), NAME_LEN );
00537
00538 rstrcpy (fileCreateInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN);
00539 fileCreateInp.mode = getFileMode (dataObjInp);
00540
00541
00542 chkType = getchkPathPerm (rsComm, dataObjInp, dataObjInfo);
00543 if (chkType == DISALLOW_PATH_REG) {
00544 return PATH_REG_NOT_ALLOWED;
00545 } else if (chkType == NO_CHK_PATH_PERM) {
00546 fileCreateInp.otherFlags |= NO_CHK_PERM_FLAG;
00547 }
00548 fileCreateInp.in_pdmo = dataObjInfo->in_pdmo;
00549
00550
00551 std::string prev_resc_hier = fileCreateInp.resc_hier_;
00552 l3descInx = rsFileCreate (rsComm, &fileCreateInp);
00553
00554
00555 rstrcpy(dataObjInfo->rescHier, fileCreateInp.resc_hier_, MAX_NAME_LEN);
00556 rstrcpy(dataObjInfo->filePath, fileCreateInp.fileName, MAX_NAME_LEN);
00557
00558
00559 while( l3descInx <= 2 && retryCnt < 100 &&
00560 getErrno (l3descInx) == EEXIST ) {
00561 if (resolveDupFilePath (rsComm, dataObjInfo, dataObjInp) < 0) {
00562 break;
00563 }
00564 rstrcpy (fileCreateInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN);
00565 l3descInx = rsFileCreate (rsComm, &fileCreateInp);
00566
00567 rstrcpy(dataObjInfo->rescHier, fileCreateInp.resc_hier_, MAX_NAME_LEN);
00568 rstrcpy(dataObjInfo->filePath, fileCreateInp.fileName, MAX_NAME_LEN);
00569 retryCnt ++;
00570 }
00571 #if 0 // JMC legacy resource
00572 break;
00573
00574 default:
00575 rodsLog (LOG_NOTICE,
00576 "l3Create: rescCat type %d is not recognized",
00577 RescTypeDef[rescTypeInx].rescCat);
00578 l3descInx = SYS_INVALID_RESC_TYPE;
00579 break;
00580
00581 #endif // JMC legacy resource
00582 return (l3descInx);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592 int getRescGrpForCreate( rsComm_t *rsComm, dataObjInp_t *dataObjInp, rescGrpInfo_t** myRescGrpInfo ) {
00593 int status;
00594 ruleExecInfo_t rei;
00595
00596
00597 initReiWithDataObjInp( &rei, rsComm, dataObjInp );
00598
00599 if (dataObjInp->oprType == REPLICATE_OPR) {
00600 status = applyRule ("acSetRescSchemeForRepl", NULL, &rei, NO_SAVE_REI);
00601
00602 } else {
00603 status = applyRule ("acSetRescSchemeForCreate", NULL, &rei, NO_SAVE_REI);
00604
00605 }
00606
00607 if( status < 0 ) {
00608 if (rei.status < 0) {
00609 status = rei.status;
00610 }
00611
00612 rodsLog( LOG_NOTICE,"getRescGrpForCreate:acSetRescSchemeForCreate error for %s,status=%d",
00613 dataObjInp->objPath, status);
00614
00615 return (status);
00616 }
00617
00618 if( rei.rgi == NULL ) {
00619
00620
00621
00622 (*myRescGrpInfo) = new rescGrpInfo_t;
00623 (*myRescGrpInfo)->cacheNext = 0;
00624 (*myRescGrpInfo)->next = 0;
00625 (*myRescGrpInfo)->rescInfo = new rescInfo_t;
00626
00627
00628 eirods::error set_err = eirods::set_default_resource( rsComm, "", "", &dataObjInp->condInput, *(*myRescGrpInfo) );
00629 if( !set_err.ok() ) {
00630 eirods::log( PASS( false, -1, "getRescGrpForCreate - failed.", set_err ) );
00631
00632 return SYS_INVALID_RESC_INPUT;
00633 }
00634
00635 } else {
00636 *myRescGrpInfo = rei.rgi;
00637 }
00638
00639 status = setRescQuota( rsComm, dataObjInp->objPath, myRescGrpInfo, dataObjInp->dataSize );
00640
00641 if( status == SYS_RESC_QUOTA_EXCEEDED ) {
00642 return SYS_RESC_QUOTA_EXCEEDED;
00643 }
00644
00645 #if 0 // JMC - legacy resource
00646 if( strstr( rei.statusStr, "random" ) == NULL ) {
00647
00648 sortRescByLocation (myRescGrpInfo);
00649 return 0;
00650
00651 } else {
00652 return 1;
00653 }
00654 #else
00655 return 0;
00656 #endif
00657 }
00658