int rsDataObjCreate( rsComm_t *rsComm, dataObjInp_t *dataObjInp ) { int l1descInx; int status; rodsObjStat_t *rodsObjStatOut = NULL; int remoteFlag; rodsServerHost_t *rodsServerHost; specCollCache_t *specCollCache = NULL; char *lockType = NULL; // JMC - backport 4604 int lockFd = -1; // JMC - backport 4604 resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache, &dataObjInp->condInput ); remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost, REMOTE_CREATE ); if ( remoteFlag < 0 ) { return ( remoteFlag ); } else if ( remoteFlag == REMOTE_HOST ) { openStat_t *openStat = NULL; addKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW, "" ); status = rcDataObjCreateAndStat( rodsServerHost->conn, dataObjInp, &openStat ); /* rm it to avoid confusion */ rmKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW ); if ( status < 0 ) { return status; } l1descInx = allocAndSetL1descForZoneOpr( status, dataObjInp, rodsServerHost, openStat ); if ( openStat != NULL ) { free( openStat ); } return ( l1descInx ); } // =-=-=-=-=-=-=- // working on the "home zone", determine if we need to redirect to a different // server in this zone for this operation. if there is a RESC_HIER_STR_KW then // we know that the redirection decision has already been made char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ); if ( NULL == resc_hier ) { std::string hier; irods::error ret = irods::resolve_resource_hierarchy( irods::CREATE_OPERATION, rsComm, dataObjInp, hier ); if ( !ret.ok() ) { std::stringstream msg; msg << "failed in irods::resolve_resource_hierarchy for ["; msg << dataObjInp->objPath << "]"; irods::log( PASSMSG( msg.str(), ret ) ); return ret.code(); } // =-=-=-=-=-=-=- // we resolved the redirect and have a host, set the hier str for subsequent // api calls, etc. addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() ); } // if keyword // =-=-=-=-=-=-=- // JMC - backport 4604 lockType = getValByKey( &dataObjInp->condInput, LOCK_TYPE_KW ); if ( lockType != NULL ) { lockFd = rsDataObjLock( rsComm, dataObjInp ); if ( lockFd >= 0 ) { /* rm it so it won't be done again causing deadlock */ rmKeyVal( &dataObjInp->condInput, LOCK_TYPE_KW ); } else { rodsLogError( LOG_ERROR, lockFd, "rsDataObjCreate: rsDataObjLock error for %s. lockType = %s", dataObjInp->objPath, lockType ); return lockFd; } } // =-=-=-=-=-=-=- // Gets here means local zone operation stat dataObj addKeyVal( &dataObjInp->condInput, SEL_OBJ_TYPE_KW, "dataObj" ); status = rsObjStat( rsComm, dataObjInp, &rodsObjStatOut ); if ( rodsObjStatOut != NULL && rodsObjStatOut->objType == COLL_OBJ_T ) { if ( lockFd >= 0 ) { rsDataObjUnlock( rsComm, dataObjInp, lockFd ); // JMC - backport 4604 } return ( USER_INPUT_PATH_ERR ); } if ( rodsObjStatOut != NULL && rodsObjStatOut->specColl != NULL && rodsObjStatOut->specColl->collClass == LINKED_COLL ) { /* should not be here because if has been translated */ if ( lockFd >= 0 ) { rsDataObjUnlock( rsComm, dataObjInp, lockFd ); // JMC - backport 4604 } return SYS_COLL_LINK_PATH_ERR; } if ( rodsObjStatOut == NULL || ( rodsObjStatOut->objType == UNKNOWN_OBJ_T && rodsObjStatOut->specColl == NULL ) ) { /* does not exist. have to create one */ /* use L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY instead */ /* newly created. take out FORCE_FLAG since it could be used by put */ /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */ l1descInx = _rsDataObjCreate( rsComm, dataObjInp ); } else if ( rodsObjStatOut->specColl != NULL && rodsObjStatOut->objType == UNKNOWN_OBJ_T ) { /* newly created. take out FORCE_FLAG since it could be used by put */ /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */ l1descInx = specCollSubCreate( rsComm, dataObjInp ); } else { /* dataObj exist */ if ( getValByKey( &dataObjInp->condInput, FORCE_FLAG_KW ) != NULL ) { dataObjInp->openFlags |= O_TRUNC | O_RDWR; // =-=-=-=-=-=-=- // re-determine the resource hierarchy since this is an open instead of a create std::string hier; irods::error ret = irods::resolve_resource_hierarchy( irods::WRITE_OPERATION, rsComm, dataObjInp, hier ); if ( !ret.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " :: failed in irods::resolve_resource_hierarchy for ["; msg << dataObjInp->objPath << "]"; irods::log( PASSMSG( msg.str(), ret ) ); return ret.code(); } // =-=-=-=-=-=-=- // we resolved the redirect and have a host, set the hier str for subsequent // api calls, etc. addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() ); std::string top_resc; irods::hierarchy_parser parser; parser.set_string( hier ); parser.first_resc( top_resc ); addKeyVal( &dataObjInp->condInput, DEST_RESC_NAME_KW, top_resc.c_str() ); l1descInx = _rsDataObjOpen( rsComm, dataObjInp ); } else { l1descInx = OVERWRITE_WITHOUT_FORCE_FLAG; } } if ( rodsObjStatOut != NULL ) { freeRodsObjStat( rodsObjStatOut ); } // =-=-=-=-=-=-=- // JMC - backport 4604 if ( lockFd >= 0 ) { if ( l1descInx >= 0 ) { L1desc[l1descInx].lockFd = lockFd; } else { rsDataObjUnlock( rsComm, dataObjInp, lockFd ); } } // =-=-=-=-=-=-=- return ( l1descInx ); }
int _rsDataObjGet( rsComm_t *rsComm, dataObjInp_t *dataObjInp, portalOprOut_t **portalOprOut, bytesBuf_t *dataObjOutBBuf, int handlerFlag ) { int status; dataObjInfo_t *dataObjInfo; int l1descInx; char *chksumStr = NULL; int retval; openedDataObjInp_t dataObjCloseInp; /* PHYOPEN_BY_SIZE ask it to check whether "dataInclude" should be done */ addKeyVal( &dataObjInp->condInput, PHYOPEN_BY_SIZE_KW, "" ); l1descInx = _rsDataObjOpen( rsComm, dataObjInp ); if ( l1descInx < 0 ) { return l1descInx; } L1desc[l1descInx].oprType = GET_OPR; dataObjInfo = L1desc[l1descInx].dataObjInfo; if ( getStructFileType( dataObjInfo->specColl ) >= 0 && // JMC - backport 4682 L1desc[l1descInx].l3descInx > 0 ) { /* l3descInx == 0 if included */ *portalOprOut = ( portalOprOut_t * ) malloc( sizeof( portalOprOut_t ) ); bzero( *portalOprOut, sizeof( portalOprOut_t ) ); ( *portalOprOut )->l1descInx = l1descInx; return l1descInx; } if ( getValByKey( &dataObjInp->condInput, VERIFY_CHKSUM_KW ) != NULL ) { if ( strlen( dataObjInfo->chksum ) > 0 ) { /* a chksum already exists */ chksumStr = strdup( dataObjInfo->chksum ); } else { status = dataObjChksumAndReg( rsComm, dataObjInfo, &chksumStr ); if ( status < 0 ) { return status; } rstrcpy( dataObjInfo->chksum, chksumStr, NAME_LEN ); } } if ( L1desc[l1descInx].l3descInx <= 2 ) { /* no physical file was opened */ status = l3DataGetSingleBuf( rsComm, l1descInx, dataObjOutBBuf, portalOprOut ); if ( status >= 0 ) { int status2; /** since the object is read here, we apply post procesing RAJA * Dec 2 2010 **/ status2 = applyRuleForPostProcForRead( rsComm, dataObjOutBBuf, dataObjInp->objPath ); if ( status2 >= 0 ) { status = 0; } else { status = status2; } /** since the object is read here, we apply post procesing * RAJA Dec 2 2010 **/ if ( chksumStr != NULL ) { rstrcpy( ( *portalOprOut )->chksum, chksumStr, NAME_LEN ); free( chksumStr ); } } return status; } status = preProcParaGet( rsComm, l1descInx, portalOprOut ); if ( status < 0 ) { memset( &dataObjCloseInp, 0, sizeof( dataObjCloseInp ) ); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose( rsComm, &dataObjCloseInp ); if ( chksumStr != NULL ) { free( chksumStr ); } return status; } status = l1descInx; /* means file not included */ if ( chksumStr != NULL ) { rstrcpy( ( *portalOprOut )->chksum, chksumStr, NAME_LEN ); free( chksumStr ); } /* return portalOprOut to the client and wait for the rcOprComplete * call. That is when the parallel I/O is done */ retval = sendAndRecvBranchMsg( rsComm, rsComm->apiInx, status, ( void * ) * portalOprOut, dataObjOutBBuf ); if ( retval < 0 ) { memset( &dataObjCloseInp, 0, sizeof( dataObjCloseInp ) ); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose( rsComm, &dataObjCloseInp ); } if ( handlerFlag & INTERNAL_SVR_CALL ) { /* internal call. want to know the real status */ return retval; } else { /* already send the client the status */ return SYS_NO_HANDLER_REPLY_MSG; } }
int rsDataObjOpen( rsComm_t *rsComm, dataObjInp_t *dataObjInp ) { int status, l1descInx; int remoteFlag; rodsServerHost_t *rodsServerHost; remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost, REMOTE_OPEN ); if ( remoteFlag < 0 ) { return remoteFlag; } else if ( remoteFlag == REMOTE_HOST ) { openStat_t *openStat = NULL; status = rcDataObjOpenAndStat( rodsServerHost->conn, dataObjInp, &openStat ); if ( status < 0 ) { return status; } l1descInx = allocAndSetL1descForZoneOpr( status, dataObjInp, rodsServerHost, openStat ); if ( openStat != NULL ) { free( openStat ); } return l1descInx; } else { // dataObjInfo_t linked list dataObjInfo_t *dataObjInfoHead = NULL; // resource hierarchy std::string hier; // =-=-=-=-=-=-=- // determine the resource hierarchy if one is not provided if ( getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ) == NULL ) { irods::error ret = irods::resolve_resource_hierarchy( irods::OPEN_OPERATION, rsComm, dataObjInp, hier, &dataObjInfoHead ); if (ret.ok()) { // =-=-=-=-=-=-=- // we resolved the redirect and have a host, set the hier str for subsequent // api calls, etc. addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() ); } } else { // file object for file_object_factory irods::file_object_ptr file_obj( new irods::file_object() ); // get resource hierarchy from condInput hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ); // get replicas vector populated irods::error fac_err = irods::file_object_factory(rsComm, dataObjInp, file_obj, &dataObjInfoHead); }// if ( getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ) == NULL ) l1descInx = _rsDataObjOpen( rsComm, dataObjInp, dataObjInfoHead ); } return l1descInx; }
int rsStructFileExtAndReg (rsComm_t *rsComm, structFileExtAndRegInp_t *structFileExtAndRegInp) { int status; dataObjInp_t dataObjInp; openedDataObjInp_t dataObjCloseInp; dataObjInfo_t *dataObjInfo; int l1descInx; rescInfo_t *rescInfo; char *rescGroupName; int remoteFlag; rodsServerHost_t *rodsServerHost; char phyBunDir[MAX_NAME_LEN], *tmpStr; int flags = 0; #if 0 dataObjInp_t dirRegInp; structFileOprInp_t structFileOprInp; #endif specCollCache_t *specCollCache = NULL; resolveLinkedPath (rsComm, structFileExtAndRegInp->objPath, &specCollCache, &structFileExtAndRegInp->condInput); resolveLinkedPath (rsComm, structFileExtAndRegInp->collection, &specCollCache, NULL); if (!isSameZone (structFileExtAndRegInp->objPath, structFileExtAndRegInp->collection)) return SYS_CROSS_ZONE_MV_NOT_SUPPORTED; memset (&dataObjInp, 0, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, structFileExtAndRegInp->objPath, MAX_NAME_LEN); /* replicate the condInput. may have resource input */ replKeyVal (&structFileExtAndRegInp->condInput, &dataObjInp.condInput); dataObjInp.openFlags = O_RDONLY; remoteFlag = getAndConnRemoteZone (rsComm, &dataObjInp, &rodsServerHost, REMOTE_OPEN); if (remoteFlag < 0) { return (remoteFlag); } else if (remoteFlag == REMOTE_HOST) { status = rcStructFileExtAndReg (rodsServerHost->conn, structFileExtAndRegInp); return status; } /* open the structured file */ addKeyVal (&dataObjInp.condInput, NO_OPEN_FLAG_KW, ""); l1descInx = _rsDataObjOpen (rsComm, &dataObjInp); if (l1descInx < 0) { rodsLog (LOG_ERROR, "rsStructFileExtAndReg: _rsDataObjOpen of %s error. status = %d", dataObjInp.objPath, l1descInx); return (l1descInx); } rescInfo = L1desc[l1descInx].dataObjInfo->rescInfo; rescGroupName = L1desc[l1descInx].dataObjInfo->rescGroupName; remoteFlag = resolveHostByRescInfo (rescInfo, &rodsServerHost); bzero (&dataObjCloseInp, sizeof (dataObjCloseInp)); dataObjCloseInp.l1descInx = l1descInx; if (remoteFlag == REMOTE_HOST) { addKeyVal (&structFileExtAndRegInp->condInput, RESC_NAME_KW, rescInfo->rescName); if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) { return status; } status = rcStructFileExtAndReg (rodsServerHost->conn, structFileExtAndRegInp); rsDataObjClose (rsComm, &dataObjCloseInp); return status; } status = chkCollForExtAndReg (rsComm, structFileExtAndRegInp->collection, NULL); if (status < 0) return status; dataObjInfo = L1desc[l1descInx].dataObjInfo; createPhyBundleDir (rsComm, dataObjInfo->filePath, phyBunDir); status = unbunPhyBunFile (rsComm, dataObjInp.objPath, rescInfo, dataObjInfo->filePath, phyBunDir, dataObjInfo->dataType, 0); if (status == SYS_DIR_IN_VAULT_NOT_EMPTY) { /* rename the phyBunDir */ tmpStr = strdup(phyBunDir); // cppcheck - Undefined behavior: same parameter and destination in snprintf(). snprintf (phyBunDir, MAX_NAME_LEN, "%s.%-d", tmpStr, (int) random ()); free(tmpStr); status = unbunPhyBunFile (rsComm, dataObjInp.objPath, rescInfo, dataObjInfo->filePath, phyBunDir, dataObjInfo->dataType, 0); } if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileExtAndReg:unbunPhyBunFile err for %s to dir %s.stat=%d", dataObjInfo->filePath, phyBunDir, status); rsDataObjClose (rsComm, &dataObjCloseInp); return status; } if (getValByKey (&structFileExtAndRegInp->condInput, FORCE_FLAG_KW) != NULL) { flags = flags | FORCE_FLAG_FLAG; } if (getValByKey (&structFileExtAndRegInp->condInput, BULK_OPR_KW) != NULL) { status = bulkRegUnbunSubfiles (rsComm, rescInfo, rescGroupName, structFileExtAndRegInp->collection, phyBunDir, flags, NULL); } else { status = regUnbunSubfiles (rsComm, rescInfo, rescGroupName, structFileExtAndRegInp->collection, phyBunDir, flags, NULL); } if (status == CAT_NO_ROWS_FOUND) { /* some subfiles have been deleted. harmless */ status = 0; } else if (status < 0) { rodsLog (LOG_ERROR, "_rsUnbunAndRegPhyBunfile: rsStructFileExtAndReg for dir %s.stat=%d", phyBunDir, status); } rsDataObjClose (rsComm, &dataObjCloseInp); return status; }