void CSwitchMgr::delMacMap(const INT1* mac) { if (NULL == mac) return; INT1 macStr[20] = {0}; mac2str((UINT1*)mac, macStr); LOG_DEBUG_FMT("before delete mapping mac[%s], m_macMap size[%lu] ...", macStr, m_macMap.size()); #if 0 //m_mutex.lock(); m_rwlock.wlock(); #if 1 m_macSockfdMap.erase(macStr); #else m_macSockfdMap.remove(macStr); #endif //m_mutex.unlock(); m_rwlock.unlock(); #else m_macMap.erase(macStr); #endif LOG_DEBUG_FMT("after delete mapping mac[%s], m_macMap size[%lu] ...", macStr, m_macMap.size()); }
INT4 COfGetConfigReplyHandler::handle(CSmartPtr<CMsgCommon> msg) { CMsg* ofmsg = (CMsg*)msg.getPtr(); LOG_DEBUG_FMT("%s[%p] handle new msg of path[%s] on sockfd[%d] ...", toString(), this, ofmsg->getPath().c_str(), ofmsg->getSockfd()); INT4 sockfd = ofmsg->getSockfd(); CSmartPtr<CSwitch> sw = CControl::getInstance()->getSwitchMgr().getSwitch(sockfd); if (sw.isNull()) { LOG_WARN_FMT("CSwitch not created for sockfd[%d] !", sockfd); COfConnectMgr::processSystemFailure(sockfd); return BNC_ERR; } INT1* data = ofmsg->getData(); if (NULL == data) { LOG_WARN_FMT("%s[%p] received msg with no data from sockfd[%d] !", toString(), this, sockfd); return BNC_ERR; } LOG_DEBUG_FMT("send OFPT13_BARRIER_REQUEST to switch with sockfd[%d] ...", sockfd); BOOL ret = COfMsgUtil::sendOfpMsg(sockfd, OFP13_VERSION, OFPT13_BARRIER_REQUEST); if (!ret) { LOG_WARN_FMT("send OFPT13_BARRIER_REQUEST to switch with sockfd[%d] failed !", sockfd); COfConnectMgr::processPeerEnterUnreach(sw); return BNC_ERR; } return BNC_OK; }
void CSwitchMgr::addMacMap(const INT1* mac, CSmartPtr<CSwitch>& sw) { if (NULL == mac) return; INT1 macStr[20] = {0}; mac2str((UINT1*)mac, macStr); LOG_DEBUG_FMT("before add mapping mac[%s], m_macMap size[%lu] ...", macStr, m_macMap.size()); #if 0 //m_mutex.lock(); m_rwlock.wlock(); #if 1 m_macSockfdMap.insert(CMacSockfdMap::value_type(macStr, sockfd)); #else m_macSockfdMap.insert(macStr, sockfd); #endif //m_mutex.unlock(); m_rwlock.unlock(); #else if (!m_macMap.insert(macStr, sw)) LOG_WARN_FMT("add mapping mac[%s] failed !", macStr); #endif LOG_DEBUG_FMT("after add mapping mac[%s], m_macMap size[%lu] ...", macStr, m_macMap.size()); }
Variant ClientBase::sendReturnResponse(RequestID requestID, const Variant &v) { std::ostringstream stream; unsigned int size = 0; char type = RT_RETURN; LOG_DEBUG_FMT(0, "Send return response on request %1% value %2%", requestID % v.repr()); stream.write((const char*)&size, sizeof(size)); stream.write(&type, sizeof(type)); stream.write((const char*)&requestID, sizeof(requestID)); m_storage.packVariant(stream, v, shared_from_this()); return sendBuffer(type, requestID, stream); }
Variant ClientBase::syncCall(ObjectID id, const string &name, const Variant &args, bool withResult) { LOG_DEBUG_FMT(0, "Call <object id %d>.%s(%s)", id % name % args.repr()); if(withResult) { sendCallRequest(RT_CALL_FUNC, getNextRequestID(), id, name, args); //return recvAnswer(); } else { sendCallRequest(RT_CALL_PROC, getNextRequestID(), id, name, args); } return Variant(); }
static void* work(void* param) { if (NULL == param) { LOG_ERROR("handler thread start failed, null param!"); return NULL; } CHandlerParam* hdparam = (CHandlerParam*)param; UINT8 threadId = (UINT8)pthread_self(); LOG_WARN_FMT("%s[%p] start thread with pid[%d]threadId[%llu] on path[%s] ...", hdparam->m_handler->toString(), hdparam->m_handler, getpid(), threadId, hdparam->m_path.c_str()); prctl(PR_SET_NAME, (unsigned long)hdparam->m_handler->toString()); while (1) { try { if (hdparam->m_sem.wait() == 0) { hdparam->m_handler->handle(hdparam->m_path); } else { LOG_ERROR_FMT("%s sem_wait on path %s failed[%d]!", hdparam->m_handler->toString(), hdparam->m_path.c_str(), errno); } } catch (...) { LOG_ERROR_FMT("%s[%p] catch exception !", hdparam->m_handler->toString(), hdparam->m_handler); } } delete hdparam; LOG_DEBUG_FMT("%s thread stop, threadId:%llu, path:%s", hdparam->m_handler->toString(), threadId, hdparam->m_path.c_str()); return NULL; }
void COfPortStatusHandler::handle(CSmartPtr<CMsgQueue>& queue) { LOG_DEBUG_FMT("%s recv new msg ..., queue size = %lu", toString().c_str(), queue->size()); UINT1 version = 0; CSmartPtr<CMsg> msg; while (queue->try_pop(msg)) { version = msg->getVersion(); if (OFP13_VERSION == version) { handler13(msg); } else if (OFP10_VERSION == version) { handler10(msg); } } }
Variant ClientBase::asyncCall(ObjectID id, const string &name, const Variant &args, bool withResult, float timeout, FutureResultPtr &written) { LOG_DEBUG_FMT(0, "Async call <object id %d>.%s(%s)", id % name % args.repr()); unsigned int requestID = getNextRequestID(); if(withResult) { FutureResultPtr future(new FutureResult); m_callbacks[requestID] = future; written = sendCallRequest(RT_CALL_FUNC, requestID, id, name, args).toFuture(); return future; } else { written = sendCallRequest(RT_CALL_PROC, requestID, id, name, args).toFuture(); } return Variant(); }
void ClientBase::cancelRequestQueue(const std::exception &error) { int count = 0; while(!m_messageQueue.empty()) { RequestData &rd = m_messageQueue.front(); if(rd.type == RT_CALL_PROC || rd.type == RT_CALL_FUNC) { FutureResultMap::iterator it = m_callbacks.find(rd.id); if(it != m_callbacks.end()) { ++count; it->second->errback(error); m_callbacks.erase(it); } } m_messageQueue.pop(); } LOG_DEBUG_FMT(0, "Canceling %d request queue items", count); }
static void* work(void* param) { if (NULL == param) { LOG_ERROR("CEventConsumer start thread failed, null param!"); return NULL; } CSemThread* semThread = (CSemThread*)param; UINT8 threadId = (UINT8)pthread_self(); LOG_WARN_FMT("%s start thread with pid[%d]threadId[%llu] on path[%s] ...", semThread->m_notifier->toString(), getpid(), threadId, semThread->m_path.c_str()); prctl(PR_SET_NAME, (unsigned long)semThread->m_notifier->toString()); while (1) { try { if (semThread->m_sem.wait() == 0) { semThread->m_notifier->consume(semThread->m_path); } else { LOG_ERROR_FMT("%s sem_wait on path %s failed[%d]!", semThread->m_notifier->toString(), semThread->m_path.c_str(), errno); } } catch (...) { LOG_ERROR("catch exception !"); } } LOG_DEBUG_FMT("%s thread stop, threadId:%llu, path:%s", semThread->m_notifier->toString(), threadId, semThread->m_path.c_str()); return NULL; }
INT4 CSwitchMgr::addSwitch(INT4 sockfd, const INT1* mac, UINT4 ip, UINT2 port) { CSmartPtr<CSwitch> sw; INT1 macStr[20] = {0}; LOG_DEBUG_FMT("addSwitch with sockfd[%d]mac[%s]ip[%s]port[%u]", sockfd, mac2str((UINT1*)mac, macStr), inet_htoa(ip), port); if (isValidMac(mac)) { CSmartPtr<CSwitch> swOld = getSwitchByMac(mac); if (swOld.isNotNull()) { LOG_DEBUG_FMT("getSwitchByMac[%s] returns sockfd[%d]mac[%s]ip[%s]port[%u]", mac2str((UINT1*)mac, macStr), swOld->getSockfd(), mac2str((UINT1*)swOld->getSwMac(), macStr), inet_htoa(swOld->getSwIp()), swOld->getSwPort()); m_rwlock.wlock(); delMacMap(mac); delIpMap(swOld->getSwIp()); delDpidMap(swOld->getDpid()); delTagMap(swOld->getTag()); delSwitchMap(swOld->getSockfd()); m_rwlock.unlock(); switch_dupl_conn_t duplConn = {swOld->getSwIp(), swOld->getSwPort(), swOld->getSockfd(), swOld->getState()}; sw = swOld; sw->setSockfd(sockfd); sw->setSwIp(ip); sw->setSwPort(port); sw->m_heartbeatTimes = 0; sw->m_heartbeatInterim = 0; COfConnectMgr::processPeerReconn(sw, duplConn); } else { #ifdef USING_SWITCH_MEM_POOL CSwitch* swNew = allocSwitch(); if (NULL == swNew) { LOG_ERROR_FMT("allocSwitch failed !"); return BNC_ERR; } new(swNew) CSwitch(sockfd, mac, ip, port); sw = CSmartPtr<CSwitch>(swNew, deleteSwitch); #else CSwitch* swNew = new CSwitch(sockfd, mac, ip, port); if (NULL == swNew) { LOG_ERROR_FMT("new CSwitch failed !"); return BNC_ERR; } sw = CSmartPtr<CSwitch>(swNew); #endif COfConnectMgr::processPeerConnect(sw); } sw->setState(SW_STATE_NEW_ACCEPT); m_rwlock.wlock(); addSwitchMap(sockfd, sw); addMacMap(mac, sw); addIpMap(ip, sw); m_rwlock.unlock(); } else { LOG_DEBUG_FMT("addSwitch with sockfd[%d]invalid mac[%s]ip[%s]port[%u]", sockfd, mac2str((UINT1*)mac, macStr), inet_htoa(ip), port); //seems mininet sws have all zero mac and same ip #ifdef USING_SWITCH_MEM_POOL CSwitch* swNew = allocSwitch(); if (NULL == swNew) { LOG_ERROR_FMT("allocSwitch failed !"); return BNC_ERR; } new(swNew) CSwitch(sockfd, mac, ip, port); sw = CSmartPtr<CSwitch>(swNew, deleteSwitch); #else CSwitch* swNew = new CSwitch(sockfd, mac, ip, port); if (NULL == swNew) { LOG_ERROR_FMT("new CSwitch failed !"); return BNC_ERR; } sw = CSmartPtr<CSwitch>(swNew); #endif COfConnectMgr::processPeerConnect(sw); sw->setState(SW_STATE_NEW_ACCEPT); if (CConf::getInstance()->isMininet(ip)) sw->setState(SW_STATE_STABLE); m_rwlock.wlock(); addSwitchMap(sockfd, sw); m_rwlock.unlock(); } if (OFPCR_ROLE_SLAVE != CClusterService::getInstance()->getControllerRole()) { UINT4 tag = CControl::getInstance()->getTagMgr().alloc(); if (CTagMgr::invalid_tag != tag) { sw->setTag(tag); addTagMap(tag, sw); } } return BNC_OK; }
bool ClientBase::processInput(Variant &result, const string &data) { char type; RequestID requestID; std::istringstream stream(data); m_requireProcessing = false; stream.read(&type, sizeof(type)); if(type == RT_RETURN || type == RT_CALL_PROC || type == RT_CALL_FUNC || type == RT_DELOBJ) { stream.read((char*)&requestID, sizeof(requestID)); } if(type == RT_RETURN) { if(!asyncMode()) { if(m_syncRequestStack.empty()) { throw std::runtime_error((boost::format("Unexpected return answer %1%") % requestID).str()); } if(m_syncRequestStack.top() != requestID) { throw std::runtime_error( (boost::format("Invalid return request id (expected request %1%, but received %2%)") % m_syncRequestStack.top() % requestID).str()); } } //result.unpack(stream); m_storage.unpackVariant(stream, result, shared_from_this()); LOG_DEBUG_FMT(0, "Receive answer on request %d value %s", requestID % result.repr()); //m_storage.replaceIDsToObjects(result, shared_from_this()); if(asyncMode()) { return findAndStartCallback(result, requestID); } else { if(result.isException()) throw result.toException(); } return true; //Результат вызова обработан } else if(type == RT_CALL_PROC || type == RT_CALL_FUNC) { ObjectID id; stream.read((char*)&id, sizeof(id)); string name; unpackStr(stream, name, 1); Variant args; //args.unpack(stream); //m_storage.replaceIDsToObjects(args, shared_from_this()); m_storage.unpackVariant(stream, args, shared_from_this()); LOG_DEBUG_FMT(0, "Receive request %d call <object id %d>.%s(%s)", requestID % id % name % args.repr()); FutureResultPtr written; if(type == RT_CALL_FUNC) { result = m_storage.localCall(id, name, args, true, -1, written); if(written) //Отложенный результат удаленного транзитного вызова { written->addCallback(boost::bind(&ClientBase::startRead, shared_from_this(), Variant())); FutureResultPtr f = result.toFuture(); f->addBoth(boost::bind(&ClientBase::sendReturnResponse, shared_from_this(), requestID, _1)); return false; } if(result.isFuture()) //Отложенный результат локального вызова { FutureResultPtr f = result.toFuture(); f->addBoth(boost::bind(&ClientBase::disableProcessing, shared_from_this(), requestID, _1)); return true; } else //Результат локального вызова { FutureResultPtr f = sendReturnResponse(requestID, result).toFuture(); f->addCallback(boost::bind(&ClientBase::startRead, shared_from_this(), Variant())); return false; } } else { m_storage.localCall(id, name, args, false, -1, written); if(written) { written->addCallback(boost::bind(&ClientBase::startRead, shared_from_this(), Variant())); return false; } return true; } } else if(type == RT_DELOBJ) { ObjectID id; stream.read((char*)&id, sizeof(id)); LOG_DEBUG_FMT(0, "Receive request %d on delete object %d", requestID % id); m_storage.deleteObject(id); return true; } return false; }