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