summaryrefslogtreecommitdiffhomepage
path: root/modules
diff options
context:
space:
mode:
authorHannu Nyman <hannu.nyman@iki.fi>2018-09-14 20:05:36 +0300
committerGitHub <noreply@github.com>2018-09-14 20:05:36 +0300
commit6bea6eebf0f6d05473ee30ed8634c27c02f9c194 (patch)
tree7b03f3a5e576618dd2a0c3ed13a4c2d48e374bc7 /modules
parent9e5baf9b3a1a52d51489446d4dac06338113c159 (diff)
parent9840d310e2e3a54a3d53fc206f2d406402b42128 (diff)
Merge pull request #2122 from rosysong/backup
Backup: add firmware backup for mtdblock devices
Diffstat (limited to 'modules')
-rw-r--r--modules/luci-base/luasrc/sys.lua18
-rw-r--r--modules/luci-mod-admin-full/luasrc/controller/admin/system.lua18
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm34
3 files changed, 70 insertions, 0 deletions
diff --git a/modules/luci-base/luasrc/sys.lua b/modules/luci-base/luasrc/sys.lua
index 823e20770..1436a3a23 100644
--- a/modules/luci-base/luasrc/sys.lua
+++ b/modules/luci-base/luasrc/sys.lua
@@ -70,6 +70,24 @@ function mounts()
return data
end
+function mtds()
+ local data = {}
+
+ if fs.access("/proc/mtd") then
+ for l in io.lines("/proc/mtd") do
+ local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"')
+ if s and n then
+ local d = {}
+ d.size = tonumber(s, 16)
+ d.name = n
+ table.insert(data, d)
+ end
+ end
+ end
+
+ return data
+end
+
-- containing the whole environment is returned otherwise this function returns
-- the corresponding string value for the given name or nil if no such variable
-- exists.
diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
index 2fa7847fc..46d2e36c3 100644
--- a/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
+++ b/modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
@@ -35,6 +35,7 @@ function index()
entry({"admin", "system", "flashops"}, call("action_flashops"), _("Backup / Flash Firmware"), 70)
entry({"admin", "system", "flashops", "reset"}, post("action_reset"))
entry({"admin", "system", "flashops", "backup"}, post("action_backup"))
+ entry({"admin", "system", "flashops", "backupmtdblock"}, post("action_backupmtdblock"))
entry({"admin", "system", "flashops", "backupfiles"}, form("admin_system/backupfiles"))
-- call() instead of post() due to upload handling!
@@ -318,6 +319,23 @@ function action_backup()
luci.ltn12.pump.all(reader, luci.http.write)
end
+function action_backupmtdblock()
+ local http = require "luci.http"
+ local mv = http.formvalue("mtdblockname")
+ local m, s, n = mv:match('^([^%s]+)/([^%s]+)/([^%s]+)')
+
+ local reader = ltn12_popen("dd if=/dev/mtd%s conv=fsync,notrunc 2>/dev/null" % n)
+
+ luci.http.header(
+ 'Content-Disposition', 'attachment; filename="backup-%s-%s-%s.bin"' %{
+ luci.sys.hostname(), m,
+ os.date("%Y-%m-%d")
+ })
+
+ luci.http.prepare_content("application/octet-stream")
+ luci.ltn12.pump.all(reader, luci.http.write)
+end
+
function action_restore()
local fs = require "nixio.fs"
local http = require "luci.http"
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm b/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm
index f3d2e8d7b..8204d38e3 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm
@@ -59,6 +59,40 @@
<div class="cbi-section-error"><%:The backup archive does not appear to be a valid gzip file.%></div>
<% end %>
</div>
+
+ <% local mtds = require("luci.sys").mtds(); if #mtds > 0 then -%>
+ <h3><%:Save mtdblock contents%></h3>
+ <div class="cbi-section-descr"><%:Click "Save mtdblock" to download specified mtdblock file. (NOTE: THIS FEATURE IS FOR PROFESSIONALS! )%></div>
+ <div class="cbi-section-node">
+ <form class="inline" method="post" action="<%=url('admin/system/flashops/backupmtdblock')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <div class="cbi-value">
+ <label class="cbi-value-title" for="mtdblockname"><%:Choose mtdblock%></label>
+ <div class="cbi-value-field">
+ <select class="cbi-input-select" data-update="change" name="mtdblockname" id="mtdblockname">
+ <% for i, key in ipairs(mtds) do
+ if key and key.name ~= "rootfs_data" then -%>
+ <option<%=
+ attr("id", "mtdblockname-" .. key.name) ..
+ attr("value", key.name .. '/'.. key.size .. '/' .. i - 1) ..
+ attr("data-index", i) ..
+ ifattr(key.name == "linux" or key.name == "firmware", "selected", "selected")
+ %>><%=pcdata(key.name)%></option>
+ <% end
+ end -%>
+ </select>
+ </div>
+ </div>
+ <div class="cbi-value cbi-value-last<% if reset_avail then %> cbi-value-error<% end %>">
+ <label class="cbi-value-title" for="image"><%:Download mtdblock%></label>
+ <div class="cbi-value-field">
+ <input type="submit" class="cbi-button cbi-button-action important" value="<%:Save mtdblock%>" />
+ </div>
+ </div>
+ </form>
+ </div>
+ <% end %>
+
</div>
<div class="cbi-section">