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