Example #1
0
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)
Example #2
0
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
Example #3
0
def main():
    if len(sys.argv) < 3:
        print 'Provide controller IP address and port'
        print 'Usage: python agentRun.py controllerIP controllerPort'
        sys.exit()
    LogUtil.InitLogging()
    ctrlAddress = sys.argv[1]
    ctrlPort = sys.argv[2]
    if ctrlAddress != 'localhost':
        try:
            struct.unpack('I', socket.inet_pton(socket.AF_INET, ctrlAddress))
        except socket.error, msg:
            print 'Controller IP Address Invalid: ' + ctrlAddress
            sys.exit()
Example #4
0
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)
Example #5
0
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)
Example #6
0
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)
Example #7
0
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)
Example #8
0
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)
Example #9
0
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)
Example #10
0
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)
Example #11
0
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')
Example #12
0
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'
Example #13
0
def scheduleLoopRun():
    #debugLog('schedule', 'schedule loop', time.time())
    #EvalLog('{0:6f},59,start one round of schedule loop'.format(time.time()))
    global evalTimestamp
    global measureLatency
    LogUtil.EvalLog('JobExecutionLoop', evalTimestamp)
    LogUtil.EvalLog('MeasureLatency', measureLatency)
    evalTimestamp = 'Begin${0:6f}'.format(time.time())
    measureLatency = 'Begin${0:6f}'.format(time.time())
    if stopSchedule:
        #debugLog('schedule', 'catch stop signal')
        #EvalLog('{0:6f},60,schedule loop catches stop signal and exit'.format(time.time()))
        logging.info('schedule loop should stop now.')
        return
    # next loop
    currentTime = time.time()
    if jobFlowQueue.minDeadline():
        delta = currentTime - jobFlowQueue.minDeadline() - 0.1
    else:
        delta = 0.0
    if delta < minRunInterval:
        nextLoop = Timer((minRunInterval - delta), scheduleLoopRun)
    else:
        nextLoop = Timer(minRunInterval, scheduleLoopRun)
    nextLoop.start()
    # schedule jobs to run
    jobFlowToRun = []
    connMeasureJobFlow = []
    procMeasureJobFlow = []
    machineMeasureJobFlow = []
    #debugLog('schedule', 'current time:', currentTime, 'jobFlowQueue:', jobFlowQueue.debug())
    while (not jobFlowQueue.isEmpty()) and (jobFlowQueue.minDeadline() <
                                            currentTime):
        jobFlowKey = jobFlowQueue.pop()
        jobFlowToRun.append(jobFlowKey)
        measureType = sourceJobTable[jobFlowKey].measureType
        if measureType == 'conn':
            connMeasureJobFlow.append(jobFlowKey)
        elif measureType == 'proc':
            procMeasureJobFlow.append(jobFlowKey)
        elif measureType == 'machine':
            machineMeasureJobFlow.append(jobFlowKey)
        sourceJobTable[jobFlowKey].updateDeadline()
        jobFlowQueue.push(sourceJobTable[jobFlowKey].deadline, jobFlowKey)
    #EvalLog('{0:6f},61,done preparing jobFlows to run: {1}'.format(time.time(), jobFlowToRun))
    #debugLog('schedule', 'job flow to run: ', jobFlowToRun, \
    #                     'connMeasureJobFlow:', connMeasureJobFlow, \
    #                     'procMeasureJobFlow:', procMeasureJobFlow, \
    #                     'machineMeasureJobFlow:', machineMeasureJobFlow)
    evalTimestamp += '#ScheduleDone${0:6f}'.format(time.time())
    if IsLazyTableEnabled():
        if connMeasureJobFlow:
            connThread = Thread(target=agentConnMeasure.connMeasureRun,
                                args=(connMeasureJobFlow, None))
            connThread.daemon = True
            connThread.start()
        if procMeasureJobFlow:
            procThread = Thread(target=agentProcMeasure.procMeasureRun,
                                args=(procMeasureJobFlow, None))
            procThread.daemon = True
            procThread.start()
        if machineMeasureJobFlow:
            machineThread = Thread(target=agentProcMeasure.machineMeasureRun,
                                   args=(machineMeasureJobFlow, None))
            machineThread.daemon = True
            machineThread.start()
    else:
        #EvalLog('{0:6f},109,start no-lazy-m operation'.format(time.time()))
        connThread = Thread(target=agentConnMeasure.connMeasureRun,
                            args=(connMeasureJobFlow, None))
        connThread.daemon = True
        procThread = Thread(target=agentProcMeasure.procMeasureRunAll,
                            args=(procMeasureJobFlow, None))
        procThread.daemon = True
        machineThread = Thread(target=agentProcMeasure.machineMeasureRun,
                               args=(machineMeasureJobFlow, None))
        machineThread.daemon = True
        connThread.start()
        procThread.start()
        machineThread.start()
        connThread.join()
        procThread.join()
        machineThread.join()