luci页面“save&apply”的实现分析
页面上配置的“保存&应用”功能的实现:
最终调用到/etc/config/ucitrack的配置文件。
例如配置无线时,对应ucitrack配置文件中的
config network
option init network
list affects dhcp
list affects radvd
config wireless
list affects network // 更改无线参数时,会影响network相关的配置,会重新调用其初始化脚本initscript
段部分
问题一、那么如何添加到ucitrack配置文件中的呢?
答:是通过uci-defaults手动添加的。
搜索一下可以发现:
./feeds/packages/net/mwan3-luci/files/etc/uci-defaults
./feeds/oldpackages/net/wing/files/etc/uci-defaults
./feeds/luci/i18n/portuguese-brazilian/root/etc/uci-defaults
./feeds/luci/i18n/hungarian/root/etc/uci-defaults
./feeds/luci/i18n/ukrainian/root/etc/uci-defaults
./feeds/luci/i18n/hebrew/root/etc/uci-defaults
./feeds/luci/i18n/vietnamese/root/etc/uci-defaults
./feeds/luci/i18n/catalan/root/etc/uci-defaults
./feeds/luci/i18n/german/root/etc/uci-defaults
./feeds/luci/i18n/norwegian/root/etc/uci-defaults
./feeds/luci/i18n/english/root/etc/uci-defaults
./feeds/luci/i18n/chinese/root/etc/uci-defaults
./feeds/luci/i18n/greek/root/etc/uci-defaults
./feeds/luci/i18n/spanish/root/etc/uci-defaults
./feeds/luci/i18n/russian/root/etc/uci-defaults
./feeds/luci/i18n/polish/root/etc/uci-defaults
./feeds/luci/i18n/romanian/root/etc/uci-defaults
./feeds/luci/i18n/japanese/root/etc/uci-defaults
./feeds/luci/i18n/malay/root/etc/uci-defaults
./feeds/luci/i18n/french/root/etc/uci-defaults
./feeds/luci/i18n/swedish/root/etc/uci-defaults
./feeds/luci/i18n/italian/root/etc/uci-defaults
./feeds/luci/i18n/portuguese/root/etc/uci-defaults
./feeds/luci/themes/freifunk-bno/root/etc/uci-defaults
./feeds/luci/themes/openwrt/root/etc/uci-defaults
./feeds/luci/themes/bootstrap/root/etc/uci-defaults
./feeds/luci/themes/freifunk-generic/root/etc/uci-defaults
./feeds/luci/applications/luci-mmc-over-gpio/root/etc/uci-defaults
./feeds/luci/applications/luci-meshwizard/root/etc/uci-defaults
./feeds/luci/applications/luci-ushare/root/etc/uci-defaults
./feeds/luci/applications/luci-hwmqos/root/etc/uci-defaults
./feeds/luci/applications/luci-hd-idle/root/etc/uci-defaults
./feeds/luci/applications/luci-wshaper/root/etc/uci-defaults
./feeds/luci/applications/luci-p910nd/root/etc/uci-defaults
./feeds/luci/applications/luci-p2pblock/root/etc/uci-defaults
./feeds/luci/applications/luci-upnp/root/etc/uci-defaults
./feeds/luci/applications/luci-olsr/root/etc/uci-defaults
./feeds/luci/applications/luci-ser2net/root/etc/uci-defaults
./feeds/luci/applications/luci-polipo/root/etc/uci-defaults
./feeds/luci/applications/luci-statistics/root/etc/uci-defaults
./feeds/luci/applications/luci-backdoor/root/etc/uci-defaults
./feeds/luci/applications/luci-watchcat/root/etc/uci-defaults
./feeds/luci/applications/luci-ahcp/root/etc/uci-defaults
./feeds/luci/applications/luci-freifunk-diagnostics/root/etc/uci-defaults
./feeds/luci/applications/luci-vnstat/root/etc/uci-defaults
./feeds/luci/applications/luci-radvd/root/etc/uci-defaults
./feeds/luci/applications/luci-minidlna/root/etc/uci-defaults
./feeds/luci/applications/luci-transmission/root/etc/uci-defaults
./feeds/luci/applications/luci-asterisk/root/etc/uci-defaults
./feeds/luci/contrib/uci/hostfiles/bin/uci-defaults
./feeds/luci/contrib/package/freifunk-common/files/etc/uci-defaults
./feeds/luci/contrib/package/freifunk-gwcheck/root/etc/uci-defaults
./feeds/luci/contrib/package/freifunk-mapupdate/root/etc/uci-defaults
./feeds/luci/contrib/package/freifunk-policyrouting/files/etc/uci-defaults
./build_dir/target-mips_34kc_uClibc-0.9.33.2/root-ar71xx/etc/uci-defaults
查看 ./feeds/luci/i18n/chinese/root/etc/uci-defaults 文件,可以看到
文件内容如下:
#!/bin/sh
uci batch <<-EOF
set luci.languages.zh_cn=chinese
commit luci
EOF
利用uci命令,配置了两条,
1) uci set luci.languages.zh_cn=chinese 配置了/etc/config/luci中的languages
2) uci commit luci 提交luci的更改
这个并没有使用到ucitrack配置文件。
再看另外一个 ./feeds/luci/applications/luci-hwmqos/root/etc/uci-defaults 文件,可以看到
文件内容如下:
#!/bin/sh
#add service depends
uci -q batch <<-EOF >/dev/null
delete ucitrack.@hwmqos[-1]
add ucitrack hwmqos
set ucitrack.@hwmqos[-1].init=hwmqos
commit ucitrack
EOF
rm -f /tmp/luci-indexcahe
exit 0
利用uci命令,批量配置了如下命令:
1)uci delete ucitrack.@hwmqos[-1] 删除ucitrack配置文件中的hwmqos相关内容
2)uci add ucitrack hwmqos 增加ucitrack配置文件中的hwmqos
3)uci set ucitarck.@hwmqos[-1].init=hwmqos 相关的起始脚本(initscript)为/etc/init.d/hwmqos
4)uci commit ucitrack 提交变更的文件
问题二、配置文件中的affects干嘛用?
答:其实直接作用就是查找到相关的配置文件,再根据配置文件找到相关的起始脚本。当配置变更时,重新启用脚本。
关于affects 在uci.lua中定义如下:
-- Return a list of initscripts affected by configuration changes.
-- 返回一些跟此配置更改相关的初始化脚本列表,
function Cursor._affected(self, configlist)
configlist = type(configlist) == "table" and configlist or {configlist}
local c = cursor()
c:load("ucitrack")
-- Resolve dependencies
-- 分解依赖情况
local reloadlist = {}
local function _resolve_deps(name)
local reload = {name}
local deps = {}
c:foreach("ucitrack", name,
function(section)
if section.affects then
for i, aff in ipairs(section.affects) do
deps[#deps+1] = aff -- 将依赖的配置文件保存到deps数组中去(本例中是将network保存进去)
end
end
end)
for i, dep in ipairs(deps) do
for j, add in ipairs(_resolve_deps(dep)) do
reload[#reload+1] = add -- 将所有依赖列表保存到一个数组reload中去(此处wireless只有一个依赖项affects,就是network)
end
end
return reload
end
-- Collect initscripts
-- 搜集初始化脚本
for j, config in ipairs(configlist) do
for i, e in ipairs(_resolve_deps(config)) do
if not util.contains(reloadlist, e) then -- 检测包reloadlist中是否含配置文件(cofig),若有包含,将其加入到reloadlist数组中
reloadlist[#reloadlist+1] = e
end
end
return reloadlist
end
问题三、html页面“save&apply”如何实现的
通过调用"cbi.apply"最后调用到uci.lua脚本中的Cursor.apply.
其实现过程为:
--- Applies UCI configuration changes
-- @param configlist List of UCI configurations
-- @param command Don't apply only return the command
function Cursor.apply(self, configlist, command)
configlist = self:_affected(configlist)
if command then
return { "/sbin/luci-reload", unpack(configlist) } // 调用luci-reload
else
return os.execute("/sbin/luci-reload %s >/dev/null 2>&1" % table.concat(configlist, " ")) // 调用luci-reload
end
end
从函数apply可以看出,均是调用luci-reload。
问题四、luci-reload的实现过程,luci-reload是个shell脚本。
#!/bin/sh
. /lib/functions.sh
apply_config() {
config_get init "$1" init
config_get exec "$1" exec
config_get test "$1" test
echo "$2" > "/var/run/luci-reload-status" // 将状态写入到临时文件中
[ -n "$init" ] && reload_init "$2" "$init" "$test" // 若ucitrack配置文件中init相关参数存在,则进行reload_init
[ -n "$exec" ] && reload_exec "$2" "$exec" "$test" // 若ucitrack配置文件中exec相关参数存在,则进行reload_exec
}
reload_exec() {
local service="$1"
local ok="$3"
set -- $2
local cmd="$1"; shift
[ -x "$cmd" ] && { // cmd具有可执行权限
echo "Reloading $service... "
( $cmd "$@" ) 2>/dev/null 1>&2 // 执行 “cmd +所有参数”
[ -n "$ok" -a "$?" != "$ok" ] && echo '!!! Failed to reload' $service '!!!' // 若执行失败,则打印消息
}
}
reload_init() {
[ -x /etc/init.d/$2 ] && /etc/init.d/$2 enabled && {
echo "Reloading $1... "
/etc/init.d/$2 reload >/dev/null 2>&1 // 执行脚本的 reload
[ -n "$3" -a "$?" != "$3" ] && echo '!!! Failed to reload' $1 '!!!' // 若执行失败,则打印消息
}
}
lock "/var/run/luci-reload" // 1、防止多个线程同时调用luci-reload脚本,加锁
config_load ucitrack // 2、加载配置文件/etc/config/ucitrack
for i in $*; do
config_foreach apply_config $i $i // 3、遍历所有相关配置和文件,进行重新初始化相关进程
done
rm -f "/var/run/luci-reload-status" // 删除luci-reload-status状态文件
lock -u "/var/run/luci-reload" // 解锁
===========================================
2017年1月16日补充:
整个实现过程如下:
(1)页面上有"Save & Apply"的功能选项的页面,在单击按钮时,会调用到"changes.htm"页面。页面中关于按钮定义如下:
<form class="inline" method="get" action="<%=controller%>/admin/uci/saveapply">
<input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" />
<input class="cbi-button cbi-button-save" type="submit" value="<%:Save & Apply%>" />
</form>
对应的动作为 ../admin/uci/saveapply
(2)打开对应的 uci.lua文件,可以看到 saveapply对应的定义如下:
entry({"admin", "uci", "saveapply"}, call("action_apply"), _("Save & Apply"), 10).query = {redir=redir}
action_apply()函数实现如下:
function action_apply()
local path = luci.dispatcher.context.path
local uci = luci.model.uci.cursor()
local changes = uci:changes()
local reload = {}
-- Collect files to be applied and commit changes
for r, tbl in pairs(changes) do
table.insert(reload, r)
if path[#path] ~= "apply" then
uci:load(r)
uci:commit(r)
uci:unload(r)
end
end
luci.template.render("admin_uci/apply", { 跳转到界面apply.htm
changes = next(changes) and changes,
configs = reload
})
end
(3)apply.htm中主要内容如下:
<%+cbi/apply_xhr%> 添加页面 apply_xhr.htm
<%+admin_uci/changelog%> 添加页面 changelog.htm
<%- cbi_apply_xhr('uci-apply', configs) -%> 去掉调用脚本cbi_apply_xhr
(4)查看 apply_xhr.htm
luci页面“save&apply”的实现分析的更多相关文章
- Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析
加速IE浏览器自动化执行效率:Selenium自动化中DOM,XPATH,CSS定位Web页面对象的优劣性分析 1.技术背景 在Web应用中,用户通过键盘在输入框中输入值和鼠标点击按钮,链 ...
- 页面装载js及性能分析方法
一.装载 先装载静态页面的引用js文件,然后查找引用文件中是否包含onload函数,比如main.js中包含onload函数,在main.js中查找是否有对其他js文件的引用,优先装载引用js文件,被 ...
- 数据分析在web交互设计中的作用 页面跳出率 100% 原因分析
通过分析访问的路径,发现,访问者访问其他页面,直接跳出 页面跳出率 100% 说明: 连作者都发现的导航路径不清晰 对导航进行改版:清晰.明了
- Function.prototype.apply.call 理解分析
首先需要了解apply,call的基本用法,其目的是改变调用方法中的this指向,将其指向为传入的对象,改变this的指向,两种方法接收参数的方式不同. 代码:console.log var cons ...
- Web系统页面打印技术实现与分析
1 Web页面打印概述应用WEB化,不论对开发商,还是对用户来说,实在是一种很经济的选择,因为基于WEB的应用,客户端的规则很简单,容易学习,容易维护,容易发布.在WEB系统中,打印的确是个烦人的问题 ...
- 【代码审计】五指CMS_v4.1.0 copyfrom.php 页面存在SQL注入漏洞分析
0x00 环境准备 五指CMS官网:https://www.wuzhicms.com/ 网站源码版本:五指CMS v4.1.0 UTF-8 开源版 程序源码下载:https://www.wuzhi ...
- 【代码审计】iZhanCMS_v2.1 前台IndexController.php页面存在SQL注入 漏洞分析
0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...
- 【代码审计】iZhanCMS_v2.1 前台GoodsController.php页面存在SQL注入漏洞分析
0x00 环境准备 iZhanCMS官网:http://www.izhancms.com 网站源码版本:爱站CMS(zend6.0) V2.1 程序源码下载:http://www.izhancms ...
- 【代码审计】LaySNS_v2.2.0 System.php页面存在代码执行漏洞分析.
0x00 环境准备 LaySNS官网:http://www.laysns.com/ 网站源码版本:LaySNS_v2.2.0 程序源码下载:https://pan.lanzou.com/i0l38 ...
随机推荐
- Xcode插件推荐
deriveddata-exterminator: A magic button in Xcode to exterminate the current project's DerivedData d ...
- JTable,TableModel,DefaultTableModel与AbstractTableModel的小结
1 表格JTable并不存储自己的数据,而是从表格模型那里获取它的数据 2 TableModel本身是一个interface,在这个interface里面定义了若干的方法,包括了存取表格字段(cell ...
- Trie - leetcode [字典树/前缀树]
208. Implement Trie (Prefix Tree) 字母的字典树每个节点要定义一个大小为26的子节点指针数组,然后用一个标志符用来记录到当前位置为止是否为一个词,初始化的时候讲26个子 ...
- fileupload实现控制大小进行图片上传
if ($(".img-upload").length > 0) { $('.img-upload').fileupload({ type: 'POST', url: &qu ...
- 升级ruby
1.安装 RVM RVM:Ruby Version Manager,Ruby版本管理器,包括Ruby的版本管理和Gem库管理(gemset) $ curl -L get.rvm.io | bash - ...
- CodeForces 708B Recover the String
构造. 根据$a[0][0]$可以求得$0$的个数$p$,根据$a[1][1]$可以求得$1$的个数$q$. 如果找不到$p$或$q$,那么就无解. 每一个$0$放到序列中的任何一个位置,假设和前面的 ...
- 去掉UItableview section headerview黏性
UITabelView在style为plain时,在上拉是section始终粘在最顶上而不是跟随滚动而消失或者出现 可以通过设置UIEdgeInsetsMake: - (void)scrollView ...
- 不安装rpm包,取出rpm包里的文件
1.查看rpm包里的文件 [root@VM_166_132 ~]# rpm -qlp mysql5.6.29-1-3.x86_64.rpm |more/etc/ld.so.conf.d/mysql-5 ...
- emguCv3.x 实现字符分割,轮廓检测
/// <summary> /// 获取区域 /// </summary> /// <param name="bitmap"></para ...
- ucenter无法双向同步setting[allowsynlogin]为0问题解决
深入探索ucenter各种通信失败问题飞狐ITWeb问题描述:A,B两个应用,A的登录操作等同步到B,而B无法同步到A,即只能从A单向同步到B,AB之间没有实现双向同步以前碰到过没记录,这次记录下来查 ...