modules: add backup module for mtdblock devices 2122/head
authorRosy Song <rosysong@rosinson.com>
Sat, 8 Sep 2018 07:07:01 +0000 (15:07 +0800)
committerRosy Song <rosysong@rosinson.com>
Sat, 8 Sep 2018 07:07:01 +0000 (15:07 +0800)
Signed-off-by: Rosy Song <rosysong@rosinson.com>
modules/luci-base/luasrc/sys.lua
modules/luci-mod-admin-full/luasrc/controller/admin/system.lua
modules/luci-mod-admin-full/luasrc/view/admin_system/flashops.htm

index 823e20770c2d90635436a7c54be3c5e2618c6068..1436a3a235f3b556d68d8b1baf4fb4580485974e 100644 (file)
@@ -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.
index 2fa7847fc6d2d2bf77bf8d07494f1620b7dcc50c..46d2e36c32b1b1a523aa696305c6fbb6ba44c529 100644 (file)
@@ -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"
index f3d2e8d7b09defe0dd51d5fa79089effddbc8971..8204d38e3435e25e81ed23fe5809f2b9219dd563 100644 (file)
                        <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">