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