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