mir3c/squashfs-root/usr/sbin/miqosd

329 lines
8.0 KiB
Plaintext
Raw Permalink Normal View History

2018-05-25 08:49:31 +00:00
#!/usr/bin/lua
-- miqos 主框架
local socket=require("socket")
local io= require 'io'
local libunix= require 'socket.unix'
local json= require 'json'
local unsock=assert(libunix())
-- 单一流的设备,比如电视/盒子,用来做设备最低带宽预留
band_reserve_hosts={
changed=true,
['video']={},
['other']={},
}
-- 特殊设备优先级
special_host_list={
host={
},
changed=false,
}
require "miqos.common"
require "miqos.command"
--require "miqos.rule_by_flow"
require "miqos.rule_by_host"
require "miqos.rule_by_prio"
require "miqos.rule_by_service"
local QOS_CMD
--read args
QOS_VER='CTF'
if #arg >= 1 then
if arg[1] == 'std' then
QOS_VER='STD'
elseif arg[1] == 'ctf' then
QOS_VER='CTF'
elseif arg[1] == 'fix' then
QOS_VER='FIX'
elseif arg[1] == 'hwqos' then
QOS_VER='HWQOS'
else
QOS_VER='FIX'
QOS_CMD=arg
end
else
clean_sock()
logger(3,'======== Process Exit. =====')
os.exit(0)
end
-----全局定义-----------------
g_group_def=nil
g_class_def={}
-- TODO: 暂时关闭,需要看测试结果
g_enable_stab=false
---
g_leaf_type='fq_codel' --,sfq,fq_codel
--g_leaf_type='sfq' --,sfq,fq_codel
function clean_sock()
unsock:close()
util.exec('rm -rf ' .. cfg.server.path)
end
-- 清除规则,并退出服务
function system_exit()
cleanup_system()
clean_sock()
logger(3,'======== Process Exit. =====')
os.exit(0)
end
-- 系统初始化
local function system_init()
-- 将配置文件copy到tmp内存中,并初始化cursor
if not cfg2tmp() then
return false
end
-- 读取网络配置
if not read_network_conf() then
logger(3, 'failed to read network config!')
return false
end
-- read_qos_config()
-- SIGTERM to clear and exit
px.signal(px.SIGTERM,
function ()
logger(3,'signal TERM to stop miqos.')
system_exit()
end)
px.signal(px.SIGINT,
function ()
logger(3,'signal INT to stop miqos.')
system_exit()
end)
return true
end
g_ifb_status=''
local function check_ifb_up()
if QOS_VER == 'HWQOS' then
return true
end
-- 如果ifb状态未UP,则尝试UP
if g_ifb_status ~= UP then
--check if dev ifb0 is up
local ifb_up = '/usr/sbin/ip link set ifb0 up '
local ifb_check = '/usr/sbin/ip link show ifb0 |grep "state DOWN"'
local ret = util.exec(ifb_up)
ret = util.exec(ifb_check)
if ret == '' then
g_ifb_status = UP
else
logger(3, 'ifb0 is not up, wait for next link up.')
return false -- 继续下一次set link up
end
end
return true
end
-- 更新调用QoS
local function update_qos_rules()
local ret=false
if not check_ifb_up() then return false end
-- 读取配置文件TODO: 这里需要添加一个触发开关只有通过命令行触发的配置改变才能激发重读qos config
if not read_qos_config() then
-- logger(3,'config no changed.')
return false
end
if qdisc[cur_qdisc].changed() or old_qdisc ~= cur_qdisc then
ret = qdisc[cur_qdisc].apply(old_qdisc,cfg.bands,cfg.DEVS,false)
cfg.qdisc.old = cfg.qdisc.cur
end
return ret
end
-- 为FIX-版本更新简化QoS
local function update_fix_qos_rules()
-- 读取配置文件
if not read_qos_config() then
return false
end
if cfg.enabled.flag == '0' then -- clean rule & exit if qos off
system_exit()
end
if qdisc[cur_qdisc] then
if qdisc[cur_qdisc].apply then
logger(3,'-------------apply '..cur_qdisc)
return qdisc[cur_qdisc].apply(nil,cfg.bands,cfg.DEVS,true,true)
end
else
logger(3, 'service-mode-qdisc not exist.')
end
return false
end
-- 读取uptime计数
local function get_uptime()
local pp=io.open('/proc/uptime')
local n=pp:read('*n')
pp:close()
return math.ceil(n)
end
-- 主循环
local function main_loop()
util.exec('rm -rf ' .. cfg.server.path)
assert(unsock:bind(cfg.server.path))
assert(unsock:listen())
unsock:settimeout(1)
local now_time = get_uptime()
local next_qos_time = now_time
local delta
local gc_timer=0
-- tables for select event
local set=newset()
set:insert(unsock) -- add 'server' into select events
while true do
now_time = get_uptime() -- 读取当前的uptime ticks
if now_time >= next_qos_time then
if update_qos_rules() then
gc_timer = gc_timer + 1
if gc_timer >= 180 then
gc_timer = 0
local tmp_cnt = collectgarbage('count')
logger(3,p_sysinfo())
end
-- 更新tc的counters,便于直接调用返回
update_counters(cfg.DEVS)
end
next_qos_time = now_time + cfg.check_interval -- 更新下一次update QOS检测时间
end
delta = next_qos_time - now_time
if delta > cfg.check_interval then
logger(3, "Warning!!! plz check Update QoS delta = " .. delta .. ", it's too long!!!!")
delta = cfg.check_interval
end
local readable, _, error = socket.select(set, nil , delta)
for _,v in ipairs(readable) do
if v == unsock then
-- logger(3, 'new client come in ...')
local clt=v:accept()
if clt then
clt:settimeout(1)
set:insert(clt)
else
logger(3, 'accept client error.')
end
else
local data,error = v:receive()
if error then
v:close()
-- logger(3, 'client is disconnected.')
set:remove(v)
else
local args=string.split(data,' ')
local res,execflag='',''
if not args[1] then
res={status=3,data='cmd is NULL.'}
elseif args[1] == 'die' then
v:send(json.encode({status=0}) .. "\n")
v:close()
logger(3,"======== COMMAND `qos die` ============")
system_exit() ---===OVER NOW===---
else
-- 命令行的处理
res,execflag = process_cmd(unpack(args))
if execflag then -- 触发立即执行更新qos操作
next_qos_time = 0
end
end
v:send(json.encode(res) .. '\n')
v:close()
set:remove(v)
end
end
end
end
end
function main_once()
-- FIX 模式强制service模式
cur_qdisc='service'
local res={result=0,data='ok'}
cfg.DEVS={
UP={dev=read_interfaces("wan"),id='2',},
DOWN={dev="ifb0",id='1',},
}
if not QOS_CMD or not QOS_CMD[1] then
update_fix_qos_rules()
else
-- 命令行的处理
read_qos_config()
res,execflag = process_cmd(unpack(QOS_CMD))
if execflag then -- 触发立即执行更新qos操作
update_fix_qos_rules()
end
end
if g_debug then pr(res) end
end
--[[main]]-------------------
local function main()
if system_init() then
local s,e
if QOS_VER == 'FIX' then
-- logger(3, 'apply rule as FIX mode.')
s, e = pcall(function() main_once() end)
else
-- logger(3, 'apply rule as non-FIX mode.')
s, e = pcall(function() main_loop() end)
end
if not s
then
logger(3,e)
cleanup_system()
end
else
logger(3, 'system initial failed. exit.')
end
end
main()
--[[main end]]-------------------