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