/********************************************************** *see readFromDB in FileRec, similar structure * ***********************************************************/ void VersionRec::readFromDB(mongo::DBClientConnection& conn, string versionID) { auto_ptr<mongo::DBClientCursor> cursor = conn.query("fileRecords.FileVersion", MONGO_QUERY("_id" << mongo::OID(versionID))); if (cursor->more()) { //convert to VersionRec BSONObj record = cursor->next(); this->versionid = versionID; this->tmpname = record.getStringField("Tempname"); this->filehash = record.getStringField("filehash"); this->length = record.getIntField("length"); this->modifytime.tv_nsec = record.getField("Mtnsec").numberLong(); this->modifytime.tv_sec = record.getField("mtsec").numberLong(); this->versionnumber = record.getIntField("Version"); //similar to the comments collection in readfromDB in FileRec vector<BSONElement> hashes(record.getField("Blktable").Array()); for (vector<BSONElement>::iterator it = hashes.begin(); it != hashes.end(); ++it) { BSONObj blockdata = it->Obj(); BSONElement blocknum = blockdata.getField("Blknum"); BSONElement blockhash = blockdata.getField("hash"); VersionDiffBlock tmp; tmp.blockNo = blocknum.Int(); tmp.blockHash = blockhash.String(); changesAppend(tmp); } } else{ cout << "could not find version " << versionID << endl; } }
// Copies ops out of the bgsync queue into the deque passed in as a parameter. // Returns true if the batch should be ended early. // Batch should end early if we encounter a command, or if // there are no further ops in the bgsync queue to read. // This function also blocks 1 second waiting for new ops to appear in the bgsync // queue. We can't block forever because there are maintenance things we need // to periodically check in the loop. bool SyncTail::tryPopAndWaitForMore(SyncTail::OpQueue* ops, ReplicationCoordinator* replCoord) { BSONObj op; // Check to see if there are ops waiting in the bgsync queue bool peek_success = peek(&op); if (!peek_success) { // if we don't have anything in the queue, wait a bit for something to appear if (ops->empty()) { replCoord->signalDrainComplete(); // block up to 1 second _networkQueue->waitForMore(); return false; } // otherwise, apply what we have return true; } const char* ns = op["ns"].valuestrsafe(); // check for commands if ((op["op"].valuestrsafe()[0] == 'c') || // Index builds are acheived through the use of an insert op, not a command op. // The following line is the same as what the insert code uses to detect an index build. ( *ns != '\0' && nsToCollectionSubstring(ns) == "system.indexes" )) { if (ops->empty()) { // apply commands one-at-a-time ops->push_back(op); _networkQueue->consume(); } // otherwise, apply what we have so far and come back for the command return true; } // check for oplog version change BSONElement elemVersion = op["v"]; int curVersion = 0; if (elemVersion.eoo()) // missing version means version 1 curVersion = 1; else curVersion = elemVersion.Int(); if (curVersion != OPLOG_VERSION) { severe() << "expected oplog version " << OPLOG_VERSION << " but found version " << curVersion << " in oplog entry: " << op; fassertFailedNoTrace(18820); } // Copy the op to the deque and remove it from the bgsync queue. ops->push_back(op); _networkQueue->consume(); // Go back for more ops return false; }
TEST(ExtractBSON, ExtractField) { BSONObj obj = BSON("a" << 1 << "b" << "hello"); BSONElement element; ASSERT_OK(bsonExtractField(obj, "a", &element)); ASSERT_EQUALS(1, element.Int()); ASSERT_OK(bsonExtractField(obj, "b", &element)); ASSERT_EQUALS(std::string("hello"), element.str()); ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractField(obj, "c", &element)); }
TEST(ExtractBSON, ExtractTypedField) { BSONObj obj = BSON("a" << 1 << "b" << "hello"); BSONElement element; ASSERT_OK(bsonExtractTypedField(obj, "a", NumberInt, &element)); ASSERT_EQUALS(1, element.Int()); ASSERT_OK(bsonExtractTypedField(obj, "b", String, &element)); ASSERT_EQUALS(std::string("hello"), element.str()); ASSERT_EQUALS(ErrorCodes::NoSuchKey, bsonExtractTypedField(obj, "c", String, &element)); ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "a", String, &element)); ASSERT_EQUALS(ErrorCodes::TypeMismatch, bsonExtractTypedField(obj, "b", NumberDouble, &element)); }
BOOLEAN omRemoveBusinessCommand::_isDiscoveredBusiness( BSONObj &buzInfo ) { BSONElement eleAddType = buzInfo.getField( OM_BUSINESS_FIELD_ADDTYPE ) ; if ( eleAddType.isNumber() && OM_BUSINESS_ADDTYPE_DISCOVERY == eleAddType.Int()) { return TRUE ; } return FALSE ; }
void SyncTail::setOplogVersion(const BSONObj& op) { BSONElement version = op["v"]; // old primaries do not get the unique index ignoring feature // because some of their ops are not imdepotent, see // SERVER-7186 if (version.eoo()) { theReplSet->oplogVersion = 1; RARELY log() << "warning replset primary is an older version than we are; upgrade recommended" << endl; } else { theReplSet->oplogVersion = version.Int(); } }
// Takes the authentication state from the given BSONObj void AuthenticationTable::setFromBSON( const BSONObj& obj ) { _dbs.clear(); BSONObjIterator it( obj ); while ( it.more() ) { BSONElement dbInfo = it.next(); BSONElement subObj = dbInfo.Obj().firstElement(); Auth auth; auth.user = subObj.fieldName(); auth.level = static_cast<Auth::Level>(subObj.Int()); _dbs[dbInfo.fieldName()] = auth; } }
/********************************************************** *reads from db and converts bson to FileRec object * ***********************************************************/ void FileRec::readFromDB(mongo::DBClientConnection& conn, string filename) { boost::filesystem::path p(filename); //get filename from path string file(p.filename().c_str()); auto_ptr<mongo::DBClientCursor> cursor = conn.query("fileRecords.Filerec", MONGO_QUERY("filename" << file)); if (cursor->more()) { BSONObj record = cursor->next(); //get data from db and store in the FileRec this->filename = record.getStringField("filename"); this->tempname = record.getStringField("Tempname"); this->recentHash = record.getStringField("curhash"); this->origHash = record.getStringField("ovhash"); this->length = record.getIntField("length"); this->versionCount = record.getIntField("nversions"); this->modifytime.tv_nsec = record.getField("Mtnsec").numberLong(); this->modifytime.tv_sec = record.getField("mtsec").numberLong(); this->refNum = record.getIntField("currentversion"); vector<BSONElement> hashes(record.getField("FileBlkHashes").Array()); for (vector<BSONElement>::iterator it = hashes.begin(); it != hashes.end(); ++it) { appendBlock((*it).String()); } //comments is an array of objects so it takes a bit of nesting to convert vector<BSONElement> array = record["comments"].Array(); //convert to array for (vector<BSONElement>::iterator ar = array.begin(); ar != array.end(); ++ar) { BSONObj commentdata = ar->Obj(); //store object at array[x] into BSONObj BSONElement version = commentdata.getField("version"); //convert BSONElement commentdb = commentdata.getField("comment"); comment data; data.comment = commentdb.String(); data.version = version.Int(); appendComment(data); } if (record.hasElement("versionrec")) { //again an array of objects vector<BSONElement> array = record["versionrec"].Array(); for (vector<BSONElement>::iterator it = array.begin(); it != array.end(); ++it) { BSONObj versionRecord = it->Obj(); BSONElement id = versionRecord.getField("id"); appendVersion(id.String()); } } } }
auto_ptr<DBClientCursor> DBClientReplicaSet::checkSlaveQueryResult( auto_ptr<DBClientCursor> result ){ BSONObj error; bool isError = result->peekError( &error ); if( ! isError ) return result; // We only check for "not master or secondary" errors here // If the error code here ever changes, we need to change this code also BSONElement code = error["code"]; if( code.isNumber() && code.Int() == 13436 /* not master or secondary */ ){ isntSecondary(); throw DBException( str::stream() << "slave " << _slaveHost.toString() << " is no longer secondary", 14812 ); } return result; }
SafeNum::SafeNum(const BSONElement& element) { switch (element.type()) { case NumberInt: _type = NumberInt; _value.int32Val = element.Int(); break; case NumberLong: _type = NumberLong; _value.int64Val = element.Long(); break; case NumberDouble: _type = NumberDouble; _value.doubleVal = element.Double(); break; default: _type = EOO; } }
// PD_TRACE_DECLARE_FUNCTION ( SDB__RTNCONTEXTLOB_OPEN, "_rtnContextLob::open" ) INT32 _rtnContextLob::open( const BSONObj &lob, BOOLEAN isLocal, _pmdEDUCB *cb, SDB_DPSCB *dpsCB ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__RTNCONTEXTLOB_OPEN ) ; BSONElement mode ; BSONElement oid ; BSONElement fullName = lob.getField( FIELD_NAME_COLLECTION ) ; if ( String != fullName.type() ) { PD_LOG( PDERROR, "can not find collection name in lob[%s]", lob.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } oid = lob.getField( FIELD_NAME_LOB_OID ) ; if ( jstOID != oid.type() ) { PD_LOG( PDERROR, "invalid oid in meta bsonobj:%s", lob.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } mode = lob.getField( FIELD_NAME_LOB_OPEN_MODE ) ; if ( NumberInt != mode.type() ) { PD_LOG( PDERROR, "invalid mode in meta bsonobj:%s", lob.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; } if ( isLocal ) { _stream = SDB_OSS_NEW _rtnLocalLobStream() ; } else { _stream = SDB_OSS_NEW _rtnCoordLobStream() ; } if ( NULL == _stream ) { PD_LOG( PDERROR, "failed to allocate mem." ) ; rc = SDB_OOM ; goto error ; } _stream->setDPSCB( dpsCB ) ; rc = _stream->open( fullName.valuestr(), oid.OID(), mode.Int(), cb ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to open lob stream:%d", rc ) ; goto error ; } _isOpened = TRUE ; _hitEnd = FALSE ; done: PD_TRACE_EXITRC( SDB__RTNCONTEXTLOB_OPEN, rc ) ; return rc ; error: goto done ; }
// Copies ops out of the bgsync queue into the deque passed in as a parameter. // Returns true if the batch should be ended early. // Batch should end early if we encounter a command, or if // there are no further ops in the bgsync queue to read. // This function also blocks 1 second waiting for new ops to appear in the bgsync // queue. We can't block forever because there are maintenance things we need // to periodically check in the loop. bool SyncTail::tryPopAndWaitForMore(SyncTail::OpQueue* ops) { BSONObj op; // Check to see if there are ops waiting in the bgsync queue bool peek_success = peek(&op); if (!peek_success) { // if we don't have anything in the queue, wait a bit for something to appear if (ops->empty()) { // block up to 1 second _networkQueue->waitForMore(); return false; } // otherwise, apply what we have return true; } const char* ns = op["ns"].valuestrsafe(); // check for commands if ((op["op"].valuestrsafe()[0] == 'c') || // Index builds are acheived through the use of an insert op, not a command op. // The following line is the same as what the insert code uses to detect an index build. ( *ns != '\0' && nsToCollectionSubstring(ns) == "system.indexes" )) { if (ops->empty()) { // apply commands one-at-a-time ops->push_back(op); _networkQueue->consume(); } // otherwise, apply what we have so far and come back for the command return true; } // check for oplog version change BSONElement elemVersion = op["v"]; int curVersion = 0; if (elemVersion.eoo()) // missing version means version 1 curVersion = 1; else curVersion = elemVersion.Int(); if (curVersion != oplogVersion) { // Version changes cause us to end a batch. // If we are starting a new batch, reset version number // and continue. if (ops->empty()) { oplogVersion = curVersion; } else { // End batch early return true; } } // Copy the op to the deque and remove it from the bgsync queue. ops->push_back(op); _networkQueue->consume(); // Go back for more ops return false; }
INT32 _spdFMP::_extractMsg( BSONObj &msg, BOOLEAN &extracted ) { INT32 rc = SDB_OK ; extracted = FALSE ; SDB_ASSERT( 0 <= _expect, "impossible" ) ; /// magic has already been found. if ( sizeof( SPD_MAGIC ) == _expect ) { found: if ( (_totalRead - _itr) < (INT32)sizeof(INT32) ) { extracted = FALSE ; goto done ; } else { SINT32 bsonLen = *((SINT32 *)(_readBuf+_itr)) ; if ( (_totalRead - _itr) < bsonLen ) { rc = FALSE ; goto done ; } else if ( (_totalRead - _itr) == bsonLen ) { SDB_ASSERT( _itr >= (INT32)sizeof( SPD_MAGIC ) , "impossible" ) ; BSONObj tmp ; try { tmp = BSONObj( _readBuf + _itr ) ; } catch ( std::exception &e ) { PD_LOG( PDERROR, "unexpected err happened:%s", e.what() ) ; rc = SDB_SYS ; goto error ; } if ( sizeof( SPD_MAGIC ) == _itr ) { /// only a bson msg. msg = tmp ; extracted = TRUE ; } else { /// not only a bson msg. _readBuf[_itr - 4] = '\0' ; BSONElement retCode = tmp.getField( FMP_RES_CODE ) ; BSONElement errMsg = tmp.getField( FMP_ERR_MSG ) ; /// some code like 'print' may return msg more than a bsonobj. /// we must parse it's return code. if it is ok, we ignore /// print. else we put it into errmsg. if ( !retCode.eoo() && NumberInt != retCode.type() ) { rc = SDB_SYS ; PD_LOG( PDERROR, "invalid type of retCode:%d", retCode.type() ) ; goto error ; } else if ( !retCode.eoo() ) { if ( SDB_OK != retCode.Int() ) { if ( !errMsg.eoo() ) { msg = tmp ; } else { BSONObjBuilder builder ; builder.append( FMP_ERR_MSG, _readBuf ) ; builder.append( retCode ) ; msg = builder.obj() ; } } else { msg = tmp ; } } else { /// retCode is eoo. msg = tmp ; } extracted = TRUE ; } } else { SDB_ASSERT( FALSE, "impossible" ) ; rc = SDB_SYS ; PD_LOG( PDERROR, "left len can not be lager than objsize" ) ; goto error ; } } } else { while ( _itr < _totalRead && (UINT32)_expect < sizeof( SPD_MAGIC ) ) { if ( SPD_MAGIC[_expect] == _readBuf[_itr] ) { ++_itr ; ++_expect ; if ( sizeof( SPD_MAGIC ) == _expect ) { goto found ; } } else if ( 0 == _expect ) { ++_itr ; } else { _expect = 0 ; } } } done: return rc ; error: goto done ; }
static void bson2bamboo(const dclass::DistributedType *type, const BSONElement &element, Datagram &dg) { switch(type->get_type()) { case dclass::Type::T_INT8: { dg.add_int8(element.Int()); } break; case dclass::Type::T_INT16: { dg.add_int16(element.Int()); } break; case dclass::Type::T_INT32: { dg.add_int32(element.Int()); } break; case dclass::Type::T_INT64: { dg.add_int64(element.Int()); } break; case dclass::Type::T_UINT8: { dg.add_uint8(element.Int()); } break; case dclass::Type::T_UINT16: { dg.add_uint16(element.Int()); } break; case dclass::Type::T_UINT32: { dg.add_uint32(element.Int()); } break; case dclass::Type::T_UINT64: { dg.add_uint64(element.Int()); } break; case dclass::Type::T_CHAR: { string str = element.String(); if(str.size() != 1) { throw mongo::DBException("Expected single-length string for char field", 0); } dg.add_uint8(str[0]); } break; case dclass::Type::T_FLOAT32: { dg.add_float32(element.Number()); } break; case dclass::Type::T_FLOAT64: { dg.add_float64(element.Number()); } break; case dclass::Type::T_STRING: { dg.add_data(element.String()); } break; case dclass::Type::T_VARSTRING: { dg.add_string(element.String()); } break; case dclass::Type::T_BLOB: { int len; const uint8_t *rawdata = (const uint8_t *)element.binData(len); dg.add_data(rawdata, len); } break; case dclass::Type::T_VARBLOB: { int len; const uint8_t *rawdata = (const uint8_t *)element.binData(len); dg.add_blob(rawdata, len); } break; case dclass::Type::T_ARRAY: { const dclass::ArrayType *array = type->as_array(); std::vector<BSONElement> data = element.Array(); for(auto it = data.begin(); it != data.end(); ++it) { bson2bamboo(array->get_element_type(), *it, dg); } } break; case dclass::Type::T_VARARRAY: { const dclass::ArrayType *array = type->as_array(); std::vector<BSONElement> data = element.Array(); DatagramPtr newdg = Datagram::create(); for(auto it = data.begin(); it != data.end(); ++it) { bson2bamboo(array->get_element_type(), *it, *newdg); } dg.add_blob(newdg->get_data(), newdg->size()); } break; case dclass::Type::T_STRUCT: { const dclass::Struct *s = type->as_struct(); size_t fields = s->get_num_fields(); for(unsigned int i = 0; i < fields; ++i) { const dclass::Field *field = s->get_field(i); bson2bamboo(field->get_type(), element[field->get_name()], dg); } } break; case dclass::Type::T_METHOD: { const dclass::Method *m = type->as_method(); size_t parameters = m->get_num_parameters(); for(unsigned int i = 0; i < parameters; ++i) { const dclass::Parameter *parameter = m->get_parameter(i); string name = parameter->get_name(); if(name.empty() || element[name].eoo()) { stringstream n; n << "_" << i; name = n.str(); } bson2bamboo(parameter->get_type(), element[name], dg); } } break; case dclass::Type::T_INVALID: default: assert(false); break; } }
INT32 _fmpController::_handleOneLoop( const BSONObj &obj, INT32 step ) { INT32 rc = SDB_OK ; BSONObj res ; if ( FMP_CONTROL_STEP_BEGIN == step ) { UINT32 seqID = 1 ; BSONElement beSeq = obj.getField( FMP_SEQ_ID ) ; if ( beSeq.isNumber() ) { seqID = (UINT32)beSeq.numberInt() ; } BSONElement diag = obj.getField( FMP_DIAG_PATH ) ; if ( !diag.eoo() && String == diag.type() ) { CHAR diaglogShort[ OSS_MAX_PATHSIZE + 1 ] = { 0 } ; ossSnprintf( diaglogShort, OSS_MAX_PATHSIZE, "%s_%u.%s", PD_FMP_DIAGLOG_PREFIX, seqID, PD_FMP_DIAGLOG_SUBFIX ) ; CHAR diaglog[ OSS_MAX_PATHSIZE + 1 ] = {0} ; engine::utilBuildFullPath( diag.valuestrsafe(), diaglogShort, OSS_MAX_PATHSIZE, diaglog ) ; sdbEnablePD( diaglog ) ; } BSONElement localService = obj.getField( FMP_LOCAL_SERVICE ) ; if ( !localService.eoo() && String == localService.type() && 0 == ossStrlen(FMP_COORD_SERVICE) ) { ossMemcpy( FMP_COORD_SERVICE, localService.valuestrsafe(), ossStrlen( localService.valuestrsafe() ) + 1 ) ; } BSONElement localUser = obj.getField( FMP_LOCAL_USERNAME ) ; if ( String == localUser.type() ) { ossStrncpy( g_UserName, localUser.valuestrsafe(), OSS_MAX_PATHSIZE ) ; } BSONElement localPass = obj.getField( FMP_LOCAL_PASSWORD ) ; if ( String == localPass.type() ) { ossStrncpy( g_Password, localPass.valuestrsafe(), OSS_MAX_PATHSIZE ) ; } BSONElement fType = obj.getField( FMP_FUNC_TYPE ) ; if ( fType.eoo() ) { rc = _createVM( FMP_FUNC_TYPE_JS ) ; if ( SDB_OK != rc ) { PD_LOG(PDERROR, "failed to create vm:%d", rc ) ; res = BSON( FMP_ERR_MSG << "failed to create vm" << FMP_RES_CODE << rc ) ; goto error ; } rc = _vm->init( obj ) ; if ( SDB_OK != rc ) { PD_LOG(PDERROR, "failed to init vm:%d", rc ) ; res = BSON( FMP_ERR_MSG << "failed to init vm" << FMP_RES_CODE << rc ) ; goto error ; } } else if ( NumberInt != fType.type() ) { PD_LOG( PDERROR, "invalid type of func type:%s", fType.toString().c_str() ) ; rc = SDB_SYS ; res = BSON( FMP_ERR_MSG << "invalid type of func type" << FMP_RES_CODE << SDB_SYS ) ; goto error ; } else { rc = _createVM( fType.Int() ) ; if ( SDB_OK != rc ) { PD_LOG(PDERROR, "failed to create vm:%d", rc ) ; res = BSON( FMP_ERR_MSG << "failed to create vm" << FMP_RES_CODE << rc ) ; goto error ; } rc = _vm->init( obj ) ; if ( SDB_OK != rc ) { PD_LOG(PDERROR, "failed to init vm:%d", rc ) ; res = BSON( FMP_ERR_MSG << "failed to init vm" << FMP_RES_CODE << rc ) ; goto error ; } } } else if ( FMP_CONTROL_STEP_DOWNLOAD == step ) { SDB_ASSERT( NULL != _vm, "impossible" ) ; rc = _vm->eval( obj, res ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to pre eval func:%s, rc:%d", obj.toString(FALSE, TRUE).c_str(), rc ) ; if ( res.isEmpty() ) { res = BSON( FMP_ERR_MSG << "failed to pre eval func" << FMP_RES_CODE << rc ) ; } goto error ; } } else if ( FMP_CONTROL_STEP_EVAL == step ) { rc = _vm->initGlobalDB( res ) ; if ( rc ) { PD_LOG( PDWARNING, "Failed to init global db: %s", res.toString( FALSE, TRUE ).c_str() ) ; } rc = _vm->eval( obj, res ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to eval func:%s, rc:%d", obj.toString(FALSE, TRUE).c_str(), rc ) ; if ( res.isEmpty() ) { res = BSON( FMP_ERR_MSG << "failed to eval func" << FMP_RES_CODE << rc ) ; } goto error ; } } else if ( FMP_CONTROL_STEP_FETCH == step ) { BSONObj next ; rc = _vm->fetch( next ) ; if ( !next.isEmpty() ) { res = next ; } else { PD_LOG( PDERROR, "a empty obj was fetched out" ) ; rc = SDB_SYS ; res = BSON( FMP_ERR_MSG << "a empty obj was fetched out" << FMP_RES_CODE << rc ) ; goto error ; } if ( SDB_DMS_EOC == rc ) { _clear() ; } else if ( SDB_OK != rc ) { goto error ; } } else { SDB_ASSERT( FALSE, "impossible" ) ; } done: { INT32 rrc = SDB_OK ; if ( !res.isEmpty() ) { rrc = _writeMsg( res ) ; } else { rrc = _writeMsg( BSON( FMP_RES_CODE << rc ) ) ; } if ( SDB_OK != rrc ) { rc = rrc ; PD_LOG( PDERROR, "failed to write msg:%d", rc ) ; } } return rc ; error: goto done ; }
INT32 _fmpController::_runLoop() { INT32 rc = SDB_OK ; BSONObj obj ; BSONElement ele ; while ( TRUE ) { INT32 step = FMP_CONTROL_STEP_INVALID ; rc = _readMsg( obj ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to read msg:%d",rc ) ; goto error ; } ele = obj.getField( FMP_CONTROL_FIELD ) ; if ( ele.eoo() ) { step = FMP_CONTROL_STEP_DOWNLOAD ; } else if ( NumberInt != ele.type() ) { PD_LOG( PDERROR, "failed to find control filed:%s", obj.toString().c_str() ) ; rc = SDB_SYS ; goto error ; } else { step = ele.Int() ; } if ( FMP_CONTROL_STEP_QUIT == step ) { _clear() ; rc = _writeMsg( OK_RES ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to write res of reset:%d", rc ) ; goto error ; } break ; } else if ( FMP_CONTROL_STEP_RESET == step ) { _clear() ; rc = _writeMsg( OK_RES ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to write res of reset:%d", rc ) ; goto error ; } continue ; } else { } if ( !FMP_VALID_STEP(step) ) { PD_LOG( PDERROR, "invalid step number[%d], now step[%d]", ele.Int(), _step ) ; rc = SDB_SYS ; goto error ; } rc = _handleOneLoop( obj, step ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to handle one loop:%d", rc) ; _clear() ; } FMP_STEP_AUTO_CHANGE( step ) ; } done: return rc ; error: goto done ; }