def cmd_add_queue(interface, queueId, rate): if rate < 100: # if < 100K bits per second, just let it go with 100Kbps rate = 100 command1 = "tc class add dev {0} parent 1:fffe classid 1:{1} htb rate {2}kbit".format(interface, queueId, rate) command2 = "tc filter add dev {0} protocol ip parent 1: prio 0 handle {1} fw flowid 1:{1}".format(interface, queueId) call(command1, shell=True, executable='/bin/bash') call(command2, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_add_queue', command1, command2)
def _initTrafficControl(): dataPlaneIp = _getDataPlaneIp() command = "ifconfig | grep -B1 {0} | head -n1 | cut -b1-6".format(dataPlaneIp) global _interface _interface = check_output(command, shell=True, executable='/bin/bash') _interface = _interface.split(' ')[0] LogUtil.DebugLog('control', 'the data plane interface', _interface) cmd_clear_rule(_interface) cmd_add_qdisc(_interface) cmd_add_root(_interface) global _isInitialized _isInitialized = True
def AddConnToJob(connCriterion, jobId): app = None saddr = None sport = None daddr = None dport = None for (key, value) in connCriterion.iteritems(): if key == 'app': app = value elif key == 'srcIP': saddr = value elif key == 'srcPort': sport = value elif key == 'dstIP': daddr = value elif key == 'dstPort': dport = value connKey = str((app, saddr, sport, daddr, dport)) if connKey not in _connsInJob: _connsInJob[connKey] = jobId (queueId, _) = JobAndQueueRate[jobId] iptablesRule = 'OUTPUT ' if saddr: iptablesRule += '-s {0} '.format(saddr) if daddr: iptablesRule += '-d {0} '.format(daddr) iptablesRule += '-p tcp ' if sport: iptablesRule += '--sport {0} '.format(sport) if dport: iptablesRule += '--dport {0} '.format(dport) #if app: #pid = check_output('ps aux | grep '+app+' | head -n 1 | cut -b 10-14', shell=True, executable='/bin/bash') #pid = pid.lstrip().rstrip('\n') #iptablesRule.append('-m owner --pid-owner '+pid) iptablesRule += '-j MARK --set-mark {0}'.format(queueId) LogUtil.DebugLog('control', 'new iptables rule', iptablesRule) cmd_add_rule(iptablesRule)
def cmd_show_class(interface, className): command = "tc -s class show dev {0} | grep {1}".format(interface, className) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_show_class', command)
def cmd_del_queue(interface, queueId): command = "tc class del dev {0} parent 1:fffe classid 1:{1} &> /dev/null".format(interface, queueId) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_del_queue', command)
def cmd_add_rule(rule): command = "iptables -A {0}".format(rule) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_add_rule', command)
def cmd_modify_queue(interface, queueId, rate): if rate < 100: rate = 100 command = "tc class change dev {0} parent 1:fffe classid 1:{1} htb rate {2}kbit".format(interface, queueId, rate) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_modify_queue', command)
def cmd_add_root(interface): command = "tc class add dev {0} parent 1: classid 1:fffe htb rate 1000mbit".format(interface) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_add_root', command)
def cmd_add_qdisc(interface): command = "tc qdisc add dev {0} root handle 1: htb".format(interface) call(command, shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_add_gdisc', command)
def cmd_clear_rule(interface): call("tc qdisc del dev {0} root &> /dev/null".format(interface), shell=True, executable='/bin/bash') call("iptables --flush &> /dev/null", shell=True, executable='/bin/bash') LogUtil.DebugLog('control', 'done cmd_clear_rule')
def agentManagerRun(ctrlAddress, ctrlPort): LogUtil.DebugLog('manager', 'start to run agent manager') #EvalLog('{0:6f},50,agentManager starts in pid {1}'.format(time.time(), os.getpid())) global CtrlAddress CtrlAddress = ctrlAddress global sourceJobTable sourceJobTable = {} global socketTable socketTable = {} global sourceJobSkList sourceJobSkList = {} global minRunInterval sourceJobQueue = Queue() socketCriteriaQueue = Queue() rcvModuleProcess = RcvModuleProcess(sourceJobQueue, socketCriteriaQueue) dirServiceProcess = DirServiceProcess(socketCriteriaQueue, sourceJobQueue) try: #EvalLog('{0:6f},51,start rcvModule and dirService processes'.format(time.time())) rcvModuleProcess.start() dirServiceProcess.start() # wait for rcv module to boot #EvalLog('{0:6f},52,wait {1} seconds for rcvModule to boot'.format(time.time(), minRunInterval)) time.sleep(minRunInterval) global sndToCtrl sndToCtrl = HostAgentSndSocket(ctrlAddress, ctrlPort) scheduleLoop = Timer(minRunInterval, scheduleLoopRun) scheduleLoop.start() time.sleep(minRunInterval / 2.0) while True: #EvalLog('{0:6f},53,enter main loop to process new source job'.format(time.time())) currentTime = time.time() while not sourceJobQueue.empty(): #EvalLog('{0:6f},54,got one new item from IPC queue'.format(time.time())) (itemType, itemContent) = sourceJobQueue.get_nowait() if itemType == IPCType['NewSourceJob']: newSourceJob = itemContent #debugLog('job', 'new source job', newSourceJob.debug()) registerComputePart(newSourceJob) key = composeKey(newSourceJob.jobId, newSourceJob.flowId) if (len(sourceJobTable) == 0) or (minRunInterval > (newSourceJob.period / 1000.0)): minRunInterval = newSourceJob.period / 1000.0 alreadyPassedPeriods = int( float(currentTime - newSourceJob.createTime) / float(newSourceJob.period / 1000.0)) newSourceJob.deadline = newSourceJob.createTime + newSourceJob.period / 1000.0 * ( alreadyPassedPeriods + 1) newSourceJob.lastSequence = alreadyPassedPeriods jobFlowQueue.push(newSourceJob.deadline, key) sourceJobTable[key] = newSourceJob #EvalLog('{0:6f},55,process one new source job done'.format(time.time())) elif itemType == IPCType['UpdateSourceJob']: (jobId, middleAddress) = itemContent for key in sourceJobTable.iterkeys(): if keyContainJobId(key, jobId): sourceJobTable[key].middleAddress = middleAddress break #EvalLog('{0:6f},112,update middle address {1} for source job {2}'.format(time.time(), middleAddress, jobId)) elif itemType == IPCType['NewSocket']: (sockfd, theSock) = itemContent socketTable[sockfd] = theSock elif itemType == IPCType['DeleteSocket']: if itemContent in socketTable: del socketTable[itemContent] elif itemType == IPCType['AddSkToJobFlow']: (jobFlow, sockfd) = itemContent if jobFlow not in sourceJobSkList: sourceJobSkList[jobFlow] = [] if sockfd not in sourceJobSkList[jobFlow]: sourceJobSkList[jobFlow].append(sockfd) elif itemType == IPCType['RemoveSkFromJobFlow']: (jobFlow, sockfd) = itemContent if (jobFlow in sourceJobSkList) and ( sockfd in sourceJobSkList[jobFlow]): sourceJobSkList[jobFlow].remove(sockfd) elif itemType == IPCType['UpdateControlJob']: (jobId, newAction) = itemContent if newAction[0][0] == 'RateLimit': if jobId in agentRateLimitModule.JobAndQueueRate: newRate = int(newAction[0][1]) agentRateLimitModule.UpdateRateLimitJob( jobId, newRate) #debugLog('manager', 'one round of main loop') #for id in sourceJobTable.keys(): #debugLog('manager', 'jobId@flowId: ', id, 'sourceJob: ', sourceJobTable[id].debug()) #debugLog('manager', 'socketTable', socketTable) #debugLog('manager', 'sourceJobSkList', sourceJobSkList) #debugLog('manager', 'time: ', time.time()) #EvalLog('{0:6f},56,done one round of main loop. start to sleep {1} seconds'.format(time.time(), minRunInterval)) time.sleep(minRunInterval) except KeyboardInterrupt: logging.info('Catch KeyboardInterrupt in agent manager main loop') print 'Catch KeyboardInterrupt in agent manager main loop' #EvalLog('{0:6f},57,catch keyboard interrupt. start to clean up'.format(time.time())) finally: #EvalLog('{0:6f},58,ready to exit agent manager. wait {1} seconds for other processes to end'.format(time.time(), minRunInterval)) global stopSchedule stopSchedule = True agentProcMeasure.cleanup() dirServiceProcess.terminate() dirServiceProcess.join() rcvModuleProcess.terminate() rcvModuleProcess.join() logging.info( 'Agent manager cleans everything up, and is ready to stop.') print 'Exit from agent manager'