autoupdater: add timeouts to wget calls

The -T parameter only seems to limit the maximum time between received
packets, but not the overall run time.

This adds simple timeouts to the wget calls (5 minutes for the manifest,
30 minutes for the image). The implementation is very simple, only checking
the manifest timeout each time a line was received, and the image timeout
once a second. A more elegent fix seems like overkill, as the Lua
autoupdater will be replaced with a new implementation after Gluon 2016.2
anyways.
This commit is contained in:
Matthias Schiffer 2016-09-08 03:09:30 +02:00
parent 1acb4b1d3a
commit 90380414f1
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
2 changed files with 35 additions and 7 deletions

View File

@ -7,14 +7,29 @@ module('autoupdater.util', package.seeall)
-- Executes a command in the background, without parsing the command through a shell (in contrast to os.execute)
function exec(...)
function exec(timeout, ...)
local pid, errno, error = nixio.fork()
if pid == 0 then
nixio.execp(...)
os.exit(127)
elseif pid > 0 then
local wpid, status, code = nixio.waitpid(pid)
return wpid and status == 'exited' and code
if timeout then
local starttime = os.time()
while true do
if os.difftime(os.time(), starttime) > timeout then
nixio.kill(pid, nixio.const.SIGTERM)
end
local wpid, status, code = nixio.waitpid(pid, 'nohang')
if wpid then
return wpid and status == 'exited' and code
end
nixio.nanosleep(1)
end
else
local wpid, status, code = nixio.waitpid(pid)
return wpid and status == 'exited' and code
end
else
return pid, errno, error
end
@ -69,7 +84,7 @@ function run_dir(dir)
for _, entry in ipairs(files) do
if is_ok(entry) then
exec(dir .. '/' .. entry)
exec(nil, dir .. '/' .. entry)
end
end
end

View File

@ -129,9 +129,21 @@ local function read_manifest(mirror)
-- Remove potential trailing slash
mirror = mirror:gsub('/$', '')
local starttime = os.time()
local manifest_loader = io.popen(string.format("exec wget -T 120 -O- '%s/%s.manifest'", mirror, branch.name), 'r')
-- Read all lines from the manifest
-- The upper part is saves to lines, the lower part to sigs
for line in io.popen(string.format("exec wget -T 120 -O- '%s/%s.manifest'", mirror, branch.name), 'r'):lines() do
-- The upper part is saved to lines, the lower part to sigs
for line in manifest_loader:lines() do
-- If the manifest download takes more than 5 minutes, we don't really
-- have a chance to download a whole image
if os.difftime(os.time(), starttime) > 300 then
io.stderr:write("Timeout while reading manifest.\n")
manifest_loader:close()
return nil
end
if not sep then
if line == '---' then
sep = true
@ -194,7 +206,8 @@ end
-- Downloads the firmware image from a mirror to a given output file
local function fetch_firmware(mirror, filename, output)
if autoupdater_util.exec('wget', '-T', '120', '-O', output, mirror .. '/' .. filename) ~= 0 then
-- Let's give the image download 30 minutes, hopefully more than enough
if autoupdater_util.exec(1800, 'wget', '-T', '120', '-O', output, mirror .. '/' .. filename) ~= 0 then
io.stderr:write('Error downloading the image from ' .. mirror .. '\n')
return false
end