mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-07-22 11:59:33 +00:00
backups: Properly cleanup after downloading an archive
Closes: #2354. - Process spawned for raw IO should be collected using wait(). Closing the specially created pipe early causes an exception in the child process when it tries to write to stderr the JSON result of executed method. Tests: - Monitor the output of 'journalctl -f'. Download and archive. Without the patch, an error is printed as described in the bug. With the but no such error is printed. Downloaded file is the same in both cases. - Writing a log message in cleanup_func shows that the process has been waited for and the FDs have been closed. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
03484bd026
commit
d710ab0790
@ -196,6 +196,9 @@ class BaseBorgRepository(abc.ABC):
|
||||
"""Override to call read() instead of readline()."""
|
||||
chunk = self.read(io.DEFAULT_BUFFER_SIZE)
|
||||
if not chunk:
|
||||
if getattr(self, 'cleanup_func'):
|
||||
self.cleanup_func()
|
||||
|
||||
raise StopIteration
|
||||
|
||||
return chunk
|
||||
@ -204,12 +207,27 @@ class BaseBorgRepository(abc.ABC):
|
||||
self._get_archive_path(archive_name),
|
||||
self._get_encryption_passpharse(), _raw_output=True)
|
||||
|
||||
os.close(read_fd) # Don't use the pipe for communication, just stdout
|
||||
# Write the method request with args to the process
|
||||
proc.stdin.write(input_)
|
||||
proc.stdin.close()
|
||||
proc.stderr.close() # writing to stderr in child will cause SIGPIPE
|
||||
|
||||
return BufferedReader(proc.stdout)
|
||||
def _cleanup_func():
|
||||
"""After the process has been read from, cleanup the process."""
|
||||
try:
|
||||
if proc.stdout:
|
||||
proc.stdout.close()
|
||||
|
||||
if proc.stderr:
|
||||
proc.stderr.close()
|
||||
|
||||
proc.wait(30)
|
||||
os.close(read_fd)
|
||||
except Exception:
|
||||
logger.exception('Closing process failed after download')
|
||||
|
||||
reader = BufferedReader(proc.stdout)
|
||||
reader.cleanup_func = _cleanup_func
|
||||
return reader
|
||||
|
||||
def _get_archive_path(self, archive_name):
|
||||
"""Return full borg path for an archive."""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user