mirror of
https://github.com/borgbackup/borg.git
synced 2025-03-04 10:39:50 +00:00
Merge pull request #6944 from ThomasWaldmann/fix-ctrl-c-remote-repo-1.2
ctrl-c must not kill important subprocesses, fixes #6912
This commit is contained in:
commit
ec389edc83
3 changed files with 22 additions and 7 deletions
|
@ -73,7 +73,7 @@ try:
|
|||
from .helpers import umount
|
||||
from .helpers import flags_root, flags_dir, flags_special_follow, flags_special
|
||||
from .helpers import msgpack
|
||||
from .helpers import sig_int
|
||||
from .helpers import sig_int, ignore_sigint
|
||||
from .helpers import iter_separated
|
||||
from .helpers import get_tar_filter
|
||||
from .nanorst import rst_to_terminal
|
||||
|
@ -527,7 +527,7 @@ class Archiver:
|
|||
if not dry_run:
|
||||
try:
|
||||
try:
|
||||
proc = subprocess.Popen(args.paths, stdout=subprocess.PIPE)
|
||||
proc = subprocess.Popen(args.paths, stdout=subprocess.PIPE, preexec_fn=ignore_sigint)
|
||||
except (FileNotFoundError, PermissionError) as e:
|
||||
self.print_error('Failed to execute command: %s', e)
|
||||
return self.exit_code
|
||||
|
@ -546,7 +546,7 @@ class Archiver:
|
|||
paths_sep = eval_escapes(args.paths_delimiter) if args.paths_delimiter is not None else '\n'
|
||||
if args.paths_from_command:
|
||||
try:
|
||||
proc = subprocess.Popen(args.paths, stdout=subprocess.PIPE)
|
||||
proc = subprocess.Popen(args.paths, stdout=subprocess.PIPE, preexec_fn=ignore_sigint)
|
||||
except (FileNotFoundError, PermissionError) as e:
|
||||
self.print_error('Failed to execute command: %s', e)
|
||||
return self.exit_code
|
||||
|
|
|
@ -228,6 +228,19 @@ class SigIntManager:
|
|||
sig_int = SigIntManager()
|
||||
|
||||
|
||||
def ignore_sigint():
|
||||
"""
|
||||
Ignore SIGINT, see also issue #6912.
|
||||
|
||||
Ctrl-C will send a SIGINT to both the main process (borg) and subprocesses
|
||||
(e.g. ssh for remote ssh:// repos), but often we do not want the subprocess
|
||||
getting killed (e.g. because it is still needed to cleanly shut down borg).
|
||||
|
||||
To avoid that: Popen(..., preexec_fn=ignore_sigint)
|
||||
"""
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
|
||||
|
||||
def popen_with_error_handling(cmd_line: str, log_prefix='', **kwargs):
|
||||
"""
|
||||
Handle typical errors raised by subprocess.Popen. Return None if an error occurred,
|
||||
|
@ -315,10 +328,10 @@ def create_filter_process(cmd, stream, stream_close, inbound=True):
|
|||
# for us to do something while we block on the process for something different.
|
||||
if inbound:
|
||||
proc = popen_with_error_handling(cmd, stdout=subprocess.PIPE, stdin=filter_stream,
|
||||
log_prefix='filter-process: ', env=env)
|
||||
log_prefix='filter-process: ', env=env, preexec_fn=ignore_sigint)
|
||||
else:
|
||||
proc = popen_with_error_handling(cmd, stdin=subprocess.PIPE, stdout=filter_stream,
|
||||
log_prefix='filter-process: ', env=env)
|
||||
log_prefix='filter-process: ', env=env, preexec_fn=ignore_sigint)
|
||||
if not proc:
|
||||
raise Error(f'filter {cmd}: process creation failed')
|
||||
stream = proc.stdout if inbound else proc.stdin
|
||||
|
|
|
@ -26,7 +26,7 @@ from .helpers import replace_placeholders
|
|||
from .helpers import sysinfo
|
||||
from .helpers import format_file_size
|
||||
from .helpers import safe_unlink
|
||||
from .helpers import prepare_subprocess_env
|
||||
from .helpers import prepare_subprocess_env, ignore_sigint
|
||||
from .logger import create_logger, setup_logging
|
||||
from .helpers import msgpack
|
||||
from .repository import Repository
|
||||
|
@ -557,7 +557,9 @@ class RemoteRepository:
|
|||
if not testing:
|
||||
borg_cmd = self.ssh_cmd(location) + borg_cmd
|
||||
logger.debug('SSH command line: %s', borg_cmd)
|
||||
self.p = Popen(borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env)
|
||||
# we do not want the ssh getting killed by Ctrl-C/SIGINT because it is needed for clean shutdown of borg.
|
||||
# borg's SIGINT handler tries to write a checkpoint and requires the remote repo connection.
|
||||
self.p = Popen(borg_cmd, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, preexec_fn=ignore_sigint)
|
||||
self.stdin_fd = self.p.stdin.fileno()
|
||||
self.stdout_fd = self.p.stdout.fileno()
|
||||
self.stderr_fd = self.p.stderr.fileno()
|
||||
|
|
Loading…
Add table
Reference in a new issue