Explorar el Código

Merge pull request #1330 from enkore/issue/972

recreate: fix hogged signal handlers
TW hace 9 años
padre
commit
963bdd340c
Se han modificado 2 ficheros con 31 adiciones y 20 borrados
  1. 20 20
      src/borg/archiver.py
  2. 11 0
      src/borg/helpers.py

+ 20 - 20
src/borg/archiver.py

@@ -40,6 +40,7 @@ from .helpers import update_excludes, check_extension_modules
 from .helpers import dir_is_tagged, is_slow_msgpack, yes, sysinfo
 from .helpers import dir_is_tagged, is_slow_msgpack, yes, sysinfo
 from .helpers import log_multi
 from .helpers import log_multi
 from .helpers import parse_pattern, PatternMatcher, PathPrefixPattern
 from .helpers import parse_pattern, PatternMatcher, PathPrefixPattern
+from .helpers import signal_handler
 from .item import Item
 from .item import Item
 from .key import key_creator, RepoKey, PassphraseKey
 from .key import key_creator, RepoKey, PassphraseKey
 from .platform import get_flags
 from .platform import get_flags
@@ -938,27 +939,26 @@ class Archiver:
                                      file_status_printer=self.print_file_status,
                                      file_status_printer=self.print_file_status,
                                      dry_run=args.dry_run)
                                      dry_run=args.dry_run)
 
 
-        signal.signal(signal.SIGTERM, interrupt)
-        signal.signal(signal.SIGINT, interrupt)
-
-        if args.location.archive:
-            name = args.location.archive
-            if recreater.is_temporary_archive(name):
-                self.print_error('Refusing to work on temporary archive of prior recreate: %s', name)
-                return self.exit_code
-            recreater.recreate(name, args.comment)
-        else:
-            for archive in manifest.list_archive_infos(sort_by='ts'):
-                name = archive.name
+        with signal_handler(signal.SIGTERM, interrupt), \
+             signal_handler(signal.SIGINT, interrupt):
+            if args.location.archive:
+                name = args.location.archive
                 if recreater.is_temporary_archive(name):
                 if recreater.is_temporary_archive(name):
-                    continue
-                print('Processing', name)
-                if not recreater.recreate(name, args.comment):
-                    break
-        manifest.write()
-        repository.commit()
-        cache.commit()
-        return self.exit_code
+                    self.print_error('Refusing to work on temporary archive of prior recreate: %s', name)
+                    return self.exit_code
+                recreater.recreate(name, args.comment)
+            else:
+                for archive in manifest.list_archive_infos(sort_by='ts'):
+                    name = archive.name
+                    if recreater.is_temporary_archive(name):
+                        continue
+                    print('Processing', name)
+                    if not recreater.recreate(name, args.comment):
+                        break
+            manifest.write()
+            repository.commit()
+            cache.commit()
+            return self.exit_code
 
 
     @with_repository(manifest=False)
     @with_repository(manifest=False)
     def do_with_lock(self, args, repository):
     def do_with_lock(self, args, repository):

+ 11 - 0
src/borg/helpers.py

@@ -7,6 +7,7 @@ import os.path
 import platform
 import platform
 import pwd
 import pwd
 import re
 import re
+import signal
 import socket
 import socket
 import sys
 import sys
 import stat
 import stat
@@ -16,6 +17,7 @@ import unicodedata
 import uuid
 import uuid
 from binascii import hexlify
 from binascii import hexlify
 from collections import namedtuple, deque
 from collections import namedtuple, deque
+from contextlib import contextmanager
 from datetime import datetime, timezone, timedelta
 from datetime import datetime, timezone, timedelta
 from fnmatch import translate
 from fnmatch import translate
 from functools import wraps, partial
 from functools import wraps, partial
@@ -1535,3 +1537,12 @@ class CompressionDecider2:
         compr_args.update(compr_spec)
         compr_args.update(compr_spec)
         logger.debug("len(data) == %d, len(lz4(data)) == %d, choosing %s", data_len, cdata_len, compr_spec)
         logger.debug("len(data) == %d, len(lz4(data)) == %d, choosing %s", data_len, cdata_len, compr_spec)
         return compr_args, Chunk(data, **meta)
         return compr_args, Chunk(data, **meta)
+
+
+@contextmanager
+def signal_handler(signo, handler):
+    old_signal_handler = signal.signal(signo, handler)
+    try:
+        yield
+    finally:
+        signal.signal(signo, old_signal_handler)