瀏覽代碼

ctrl-c must not kill the ssh subprocess, fixes #6912

Thomas Waldmann 2 年之前
父節點
當前提交
0ab82d57e4
共有 2 個文件被更改,包括 17 次插入2 次删除
  1. 13 0
      src/borg/helpers/process.py
  2. 4 2
      src/borg/remote.py

+ 13 - 0
src/borg/helpers/process.py

@@ -236,6 +236,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,

+ 4 - 2
src/borg/remote.py

@@ -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
@@ -582,7 +582,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()