00001
00002
00003
00004
00005
00006 #include "dataObjPut.h"
00007 #include "rodsLog.h"
00008 #include "dataPut.h"
00009 #include "filePut.h"
00010 #include "objMetaOpr.h"
00011 #include "physPath.h"
00012 #include "specColl.h"
00013 #include "dataObjOpen.h"
00014 #include "dataObjCreate.h"
00015 #include "regDataObj.h"
00016 #include "dataObjUnlink.h"
00017 #include "rsGlobalExtern.h"
00018 #include "rcGlobalExtern.h"
00019 #include "rsApiHandler.h"
00020 #include "subStructFilePut.h"
00021 #include "dataObjRepl.h"
00022 #include "getRemoteZoneResc.h"
00023
00024
00025 int
00026 rsDataObjPut (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00027 bytesBuf_t *dataObjInpBBuf, portalOprOut_t **portalOprOut)
00028 {
00029 int status;
00030 int status2;
00031 int remoteFlag;
00032 rodsServerHost_t *rodsServerHost;
00033 specCollCache_t *specCollCache = NULL;
00034
00035 resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache,
00036 &dataObjInp->condInput);
00037 #if 0
00038 status = resolvePathInSpecColl (rsComm, dataObjInp->objPath,
00039 READ_COLL_PERM, 0, &dataObjInfo);
00040
00041 if (dataObjInfo != NULL) {
00042 if (dataObjInfo->specColl != NULL &&
00043 dataObjInfo->specColl->collClass == LINKED_COLL) {
00044 rstrcpy (dataObjInp->objPath, dataObjInfo->objPath,
00045 MAX_NAME_LEN);
00046 }
00047 freeAllDataObjInfo (dataObjInfo);
00048 }
00049 #endif
00050
00051 remoteFlag = getAndConnRemoteZone (rsComm, dataObjInp, &rodsServerHost,
00052 REMOTE_CREATE);
00053
00054 if (remoteFlag < 0) {
00055 return (remoteFlag);
00056 } else if (remoteFlag == LOCAL_HOST) {
00057
00058
00059 status2 = applyRuleForPostProcForWrite(rsComm, dataObjInpBBuf,
00060 dataObjInp->objPath);
00061 if (status2 < 0)
00062 return(status2);
00063
00064
00065
00066 dataObjInp->openFlags = O_RDWR;
00067 status = _rsDataObjPut (rsComm, dataObjInp, dataObjInpBBuf,
00068 portalOprOut, BRANCH_MSG);
00069 } else {
00070 int l1descInx;
00071 status = _rcDataObjPut (rodsServerHost->conn, dataObjInp,
00072 dataObjInpBBuf, portalOprOut);
00073 if (status < 0 ||
00074 getValByKey (&dataObjInp->condInput, DATA_INCLUDED_KW) != NULL) {
00075 return (status);
00076 } else {
00077
00078
00079
00080
00081 l1descInx = allocAndSetL1descForZoneOpr (
00082 (*portalOprOut)->l1descInx, dataObjInp, rodsServerHost, NULL);
00083 if (l1descInx < 0) return l1descInx;
00084 (*portalOprOut)->l1descInx = l1descInx;
00085 return status;
00086 }
00087 }
00088
00089 return (status);
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 int
00102 _rsDataObjPut (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00103 bytesBuf_t *dataObjInpBBuf, portalOprOut_t **portalOprOut, int handlerFlag)
00104 {
00105 int status;
00106 int l1descInx;
00107 int retval;
00108 openedDataObjInp_t dataObjCloseInp;
00109 int allFlag;
00110 transferStat_t *transStat = NULL;
00111 dataObjInp_t replDataObjInp;
00112
00113 if (getValByKey (&dataObjInp->condInput, ALL_KW) != NULL) {
00114 allFlag = 1;
00115 } else {
00116 allFlag = 0;
00117 }
00118
00119 if (getValByKey (&dataObjInp->condInput, DATA_INCLUDED_KW) != NULL) {
00120
00121 status = l3DataPutSingleBuf (rsComm, dataObjInp, dataObjInpBBuf);
00122 if (status >= 0 && allFlag == 1) {
00123
00124 addKeyVal (&dataObjInp->condInput, UPDATE_REPL_KW, "");
00125 status = rsDataObjRepl (rsComm, dataObjInp, &transStat);
00126 if (transStat!= NULL) free (transStat);
00127 }
00128 if (status >= 0) {
00129 int status2;
00130
00131
00132 status2 = applyRuleForPostProcForWrite(rsComm, dataObjInpBBuf,
00133 dataObjInp->objPath);
00134 if (status2 >= 0) {
00135 status = 0;
00136 } else {
00137 status = status2;
00138 }
00139
00140
00141 }
00142 return (status);
00143 }
00144
00145
00146
00147 dataObjInp->openFlags |= O_RDWR;
00148
00149 l1descInx = rsDataObjCreate (rsComm, dataObjInp);
00150
00151 if (l1descInx < 0)
00152 return l1descInx;
00153
00154 L1desc[l1descInx].oprType = PUT_OPR;
00155 L1desc[l1descInx].dataSize = dataObjInp->dataSize;
00156
00157 if (getStructFileType (L1desc[l1descInx].dataObjInfo->specColl) >= 0) {
00158 *portalOprOut = (portalOprOut_t *) malloc (sizeof (portalOprOut_t));
00159 bzero (*portalOprOut, sizeof (portalOprOut_t));
00160 (*portalOprOut)->l1descInx = l1descInx;
00161 return l1descInx;
00162 }
00163
00164
00165 status = preProcParaPut (rsComm, l1descInx, portalOprOut);
00166
00167 if (status < 0) {
00168 memset (&dataObjCloseInp, 0, sizeof (dataObjCloseInp));
00169 dataObjCloseInp.l1descInx = l1descInx;
00170 L1desc[l1descInx].oprStatus = status;
00171 rsDataObjClose (rsComm, &dataObjCloseInp);
00172 return (status);
00173 }
00174
00175 if (allFlag == 1) {
00176
00177 memset (&replDataObjInp, 0, sizeof (replDataObjInp));
00178 rstrcpy (replDataObjInp.objPath, dataObjInp->objPath, MAX_NAME_LEN);
00179 addKeyVal (&replDataObjInp.condInput, UPDATE_REPL_KW, "");
00180 addKeyVal (&replDataObjInp.condInput, ALL_KW, "");
00181 }
00182
00183
00184
00185 retval = sendAndRecvBranchMsg (rsComm, rsComm->apiInx, status,
00186 (void *) *portalOprOut, NULL);
00187
00188 if (retval < 0) {
00189 memset (&dataObjCloseInp, 0, sizeof (dataObjCloseInp));
00190 dataObjCloseInp.l1descInx = l1descInx;
00191 L1desc[l1descInx].oprStatus = retval;
00192 rsDataObjClose (rsComm, &dataObjCloseInp);
00193 if (allFlag == 1) clearKeyVal (&replDataObjInp.condInput);
00194 } else if (allFlag == 1) {
00195 status = rsDataObjRepl (rsComm, &replDataObjInp, &transStat);
00196 if (transStat!= NULL) free (transStat);
00197 clearKeyVal (&replDataObjInp.condInput);
00198 }
00199
00200 if (handlerFlag & INTERNAL_SVR_CALL) {
00201
00202 return (retval);
00203 } else {
00204
00205 return (SYS_NO_HANDLER_REPLY_MSG);
00206 }
00207 }
00208
00209
00210
00211
00212
00213 int
00214 preProcParaPut (rsComm_t *rsComm, int l1descInx,
00215 portalOprOut_t **portalOprOut)
00216 {
00217 int l3descInx;
00218 int status;
00219 dataOprInp_t dataOprInp;
00220
00221 l3descInx = L1desc[l1descInx].l3descInx;
00222
00223 initDataOprInp (&dataOprInp, l1descInx, PUT_OPR);
00224
00225 if (L1desc[l1descInx].dataObjInfo != NULL &&
00226 L1desc[l1descInx].dataObjInfo->rescInfo != NULL) {
00227 addKeyVal (&dataOprInp.condInput, RESC_NAME_KW,
00228 L1desc[l1descInx].dataObjInfo->rescInfo->rescName);
00229 }
00230 if (L1desc[l1descInx].remoteZoneHost != NULL) {
00231 status = remoteDataPut (rsComm, &dataOprInp, portalOprOut,
00232 L1desc[l1descInx].remoteZoneHost);
00233 } else {
00234 status = rsDataPut (rsComm, &dataOprInp, portalOprOut);
00235 }
00236
00237 if (status >= 0) {
00238 (*portalOprOut)->l1descInx = l1descInx;
00239 L1desc[l1descInx].bytesWritten = dataOprInp.dataSize;
00240 }
00241 clearKeyVal (&dataOprInp.condInput);
00242 return (status);
00243 }
00244
00245 int
00246 l3DataPutSingleBuf (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00247 bytesBuf_t *dataObjInpBBuf)
00248 {
00249 int bytesWritten;
00250 int l1descInx;
00251 dataObjInfo_t *myDataObjInfo;
00252 char rescGroupName[NAME_LEN];
00253 rescInfo_t *rescInfo;
00254 rescGrpInfo_t *myRescGrpInfo = NULL;
00255 rescGrpInfo_t *tmpRescGrpInfo;
00256 rescInfo_t *tmpRescInfo;
00257 int status;
00258 openedDataObjInp_t dataObjCloseInp;
00259
00260
00261 addKeyVal (&dataObjInp->condInput, NO_OPEN_FLAG_KW, "");
00262 l1descInx = rsDataObjCreate (rsComm, dataObjInp);
00263
00264 if (l1descInx <= 2) {
00265 if (l1descInx >= 0) {
00266 rodsLog (LOG_ERROR,
00267 "l3DataPutSingleBuf: rsDataObjCreate of %s error, status = %d",
00268 dataObjInp->objPath, l1descInx);
00269 return SYS_FILE_DESC_OUT_OF_RANGE;
00270 } else {
00271 return l1descInx;
00272 }
00273 }
00274 bytesWritten = _l3DataPutSingleBuf (rsComm, l1descInx, dataObjInp,
00275 dataObjInpBBuf);
00276
00277 if (bytesWritten < 0) {
00278 myDataObjInfo = L1desc[l1descInx].dataObjInfo;
00279 if (getStructFileType (myDataObjInfo->specColl) < 0 &&
00280 strlen (myDataObjInfo->rescGroupName) > 0 &&
00281 (L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY) == 0) {
00282
00283
00284
00285
00286 rstrcpy (rescGroupName, myDataObjInfo->rescGroupName, NAME_LEN);
00287 rescInfo = myDataObjInfo->rescInfo;
00288 } else {
00289 rescGroupName[0] = '\0';
00290 rescInfo = NULL;
00291 }
00292 }
00293 memset (&dataObjCloseInp, 0, sizeof (dataObjCloseInp));
00294 dataObjCloseInp.l1descInx = l1descInx;
00295 L1desc[l1descInx].oprStatus = bytesWritten;
00296 status = rsDataObjClose (rsComm, &dataObjCloseInp);
00297 if (status < 0) {
00298 rodsLog (LOG_NOTICE,
00299 "l3DataPutSingleBuf: rsDataObjClose of %d error, status = %d",
00300 l1descInx, status);
00301 }
00302
00303 if (bytesWritten >= 0) {
00304 return status;
00305 } else if (strlen (rescGroupName) == 0) {
00306 return bytesWritten;
00307 }
00308
00309
00310
00311 status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo);
00312 if (status < 0) return bytesWritten;
00313 tmpRescGrpInfo = myRescGrpInfo;
00314 while (tmpRescGrpInfo != NULL) {
00315 tmpRescInfo = tmpRescGrpInfo->rescInfo;
00316 if (rescInfo == tmpRescInfo) {
00317
00318 tmpRescGrpInfo = tmpRescGrpInfo->next;
00319 continue;
00320 }
00321 l1descInx = _rsDataObjCreateWithRescInfo (rsComm,
00322 dataObjInp, tmpRescInfo, myRescGrpInfo->rescGroupName);
00323 if (l1descInx <= 2) {
00324 if (l1descInx >= 0) {
00325 rodsLog (LOG_ERROR,
00326 "l3DataPutSingleBuf:_rsDataObjCreateWithRI %s err,stat = %d",
00327 dataObjInp->objPath, l1descInx);
00328 }
00329 } else {
00330 bytesWritten = _l3DataPutSingleBuf (rsComm, l1descInx, dataObjInp,
00331 dataObjInpBBuf);
00332 dataObjCloseInp.l1descInx = l1descInx;
00333 L1desc[l1descInx].oprStatus = bytesWritten;
00334 status = rsDataObjClose (rsComm, &dataObjCloseInp);
00335 if (status < 0) {
00336 rodsLog (LOG_NOTICE,
00337 "l3DataPutSingleBuf: rsDataObjClose of %d error, status = %d",
00338 l1descInx, status);
00339 }
00340 if (bytesWritten >= 0) {
00341 bytesWritten = status;
00342 break;
00343 }
00344 }
00345 tmpRescGrpInfo = tmpRescGrpInfo->next;
00346 }
00347 freeAllRescGrpInfo (myRescGrpInfo);
00348 return bytesWritten;
00349 }
00350
00351 int
00352 _l3DataPutSingleBuf (rsComm_t *rsComm, int l1descInx, dataObjInp_t *dataObjInp,
00353 bytesBuf_t *dataObjInpBBuf)
00354 {
00355 int status = 0;
00356 int bytesWritten;
00357 dataObjInfo_t *myDataObjInfo;
00358
00359 myDataObjInfo = L1desc[l1descInx].dataObjInfo;
00360
00361 bytesWritten = l3FilePutSingleBuf (rsComm, l1descInx, dataObjInpBBuf);
00362
00363 if (bytesWritten >= 0) {
00364 if (L1desc[l1descInx].replStatus == NEWLY_CREATED_COPY &&
00365 myDataObjInfo->specColl == NULL &&
00366 L1desc[l1descInx].remoteZoneHost == NULL) {
00367
00368
00369
00370
00371 status = svrRegDataObj (rsComm, myDataObjInfo);
00372 if (status < 0) {
00373 rodsLog (LOG_NOTICE,
00374 "l3DataPutSingleBuf: rsRegDataObj for %s failed, status = %d",
00375 myDataObjInfo->objPath, status);
00376 if (status != CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME)
00377 l3Unlink (rsComm, myDataObjInfo);
00378 return (status);
00379 } else {
00380 myDataObjInfo->replNum = status;
00381 }
00382 }
00383
00384 if (bytesWritten == 0 && myDataObjInfo->dataSize > 0) {
00385
00386 L1desc[l1descInx].bytesWritten = 1;
00387 } else {
00388 L1desc[l1descInx].bytesWritten = bytesWritten;
00389 }
00390 }
00391 L1desc[l1descInx].dataSize = dataObjInp->dataSize;
00392
00393 return (bytesWritten);
00394 }
00395
00396 int
00397 l3FilePutSingleBuf (rsComm_t *rsComm, int l1descInx, bytesBuf_t *dataObjInpBBuf)
00398 {
00399 dataObjInfo_t *dataObjInfo;
00400 int rescTypeInx;
00401 fileOpenInp_t filePutInp;
00402 int bytesWritten;
00403 dataObjInp_t *dataObjInp;
00404 int retryCnt = 0;
00405 int chkType = 0;
00406
00407 dataObjInfo = L1desc[l1descInx].dataObjInfo;
00408
00409 dataObjInp = L1desc[l1descInx].dataObjInp;
00410
00411 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00412 subFile_t subFile;
00413 memset (&subFile, 0, sizeof (subFile));
00414 rstrcpy (subFile.subFilePath, dataObjInfo->subPath,
00415 MAX_NAME_LEN);
00416 rstrcpy (subFile.addr.hostAddr, dataObjInfo->rescInfo->rescLoc,
00417 NAME_LEN);
00418 subFile.specColl = dataObjInfo->specColl;
00419 subFile.mode = getFileMode (dataObjInp);
00420 subFile.flags = O_WRONLY | dataObjInp->openFlags;
00421 #if 0
00422 if (getValByKey (&dataObjInp->condInput, FORCE_FLAG_KW) != NULL) {
00423 #else
00424 if ((L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY) != 0) {
00425 #endif
00426 subFile.flags |= FORCE_FLAG;
00427 }
00428 bytesWritten = rsSubStructFilePut (rsComm, &subFile, dataObjInpBBuf);
00429 return (bytesWritten);
00430 }
00431
00432 rescTypeInx = dataObjInfo->rescInfo->rescTypeInx;
00433
00434 switch (RescTypeDef[rescTypeInx].rescCat) {
00435 case FILE_CAT:
00436 memset (&filePutInp, 0, sizeof (filePutInp));
00437 #if 0
00438 if (getValByKey (&dataObjInp->condInput, FORCE_FLAG_KW) != NULL) {
00439 #else
00440 if ((L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY) != 0) {
00441 #endif
00442 filePutInp.otherFlags |= FORCE_FLAG;
00443 }
00444 filePutInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
00445 rstrcpy (filePutInp.addr.hostAddr, dataObjInfo->rescInfo->rescLoc,
00446 NAME_LEN);
00447 rstrcpy (filePutInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN);
00448 filePutInp.mode = getFileMode (dataObjInp);
00449 filePutInp.flags = O_WRONLY | dataObjInp->openFlags;
00450
00451
00452 chkType = getchkPathPerm (rsComm, L1desc[l1descInx].dataObjInp,L1desc[l1descInx].dataObjInfo);
00453
00454 if(chkType == DISALLOW_PATH_REG) {
00455 return PATH_REG_NOT_ALLOWED;
00456 } else if (chkType == NO_CHK_PATH_PERM) {
00457
00458 filePutInp.otherFlags |= NO_CHK_PERM_FLAG;
00459 }
00460 bytesWritten = rsFilePut (rsComm, &filePutInp, dataObjInpBBuf);
00461
00462 while (bytesWritten < 0 && retryCnt < 10 &&
00463 (filePutInp.otherFlags & FORCE_FLAG) == 0 &&
00464 getErrno (bytesWritten) == EEXIST) {
00465 if (resolveDupFilePath (rsComm, dataObjInfo, dataObjInp) < 0) {
00466 break;
00467 }
00468 rstrcpy (filePutInp.fileName, dataObjInfo->filePath,
00469 MAX_NAME_LEN);
00470 bytesWritten = rsFilePut (rsComm, &filePutInp, dataObjInpBBuf);
00471 retryCnt ++;
00472 }
00473
00474 break;
00475 default:
00476 rodsLog (LOG_NOTICE,
00477 "l3Open: rescCat type %d is not recognized",
00478 RescTypeDef[rescTypeInx].rescCat);
00479 bytesWritten = SYS_INVALID_RESC_TYPE;
00480 break;
00481 }
00482 return (bytesWritten);
00483 }
00484