diff -Nru swift-2.2.2/debian/changelog swift-2.2.2/debian/changelog --- swift-2.2.2/debian/changelog 2015-08-06 00:08:08.000000000 -0700 +++ swift-2.2.2/debian/changelog 2017-05-23 15:37:20.000000000 -0700 @@ -1,3 +1,13 @@ +swift (2.2.2-0ubuntu1.3~cloud1) trusty; urgency=medium + + * Fix issue where swift daemons crash while writing logs to a stopped + rsyslogd /dev/log socket. (LP: #1683076) + - d/patches/fix-infinite-recursion-logging.patch: Cherry-picked from + upstream stable/newton branch to avoid infinite loops when logging + while rsyslogd is stopped. + + -- Billy Olsen Tue, 23 May 2017 15:37:20 -0700 + swift (2.2.2-0ubuntu1.3~cloud0) trusty-kilo; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru swift-2.2.2/debian/patches/fix-infinite-recursion-logging.patch swift-2.2.2/debian/patches/fix-infinite-recursion-logging.patch --- swift-2.2.2/debian/patches/fix-infinite-recursion-logging.patch 1969-12-31 17:00:00.000000000 -0700 +++ swift-2.2.2/debian/patches/fix-infinite-recursion-logging.patch 2017-05-23 15:37:20.000000000 -0700 @@ -0,0 +1,142 @@ +From 83508b97b352ef903878510f85794cd54da53155 Mon Sep 17 00:00:00 2001 +From: Samuel Merritt +Date: Wed, 23 Mar 2016 13:51:47 -0700 +Subject: [PATCH 1/1] Fix infinite recursion during logging when syslog is down + +Change-Id: Ia9ecffc88ce43616977e141498e5ee404f2c29c4 +(cherry picked from commit 95efd3f9035ec4141e1b182516f040a59a3e5aa6) +--- + swift/common/utils.py | 54 +++++++++++++++++++++++++++++++++++------- + test/unit/common/test_utils.py | 42 ++++++++++++++++++++++++++++++++ + 2 files changed, 88 insertions(+), 8 deletions(-) + +Forwarded: Not-Needed +Bug: https://launchpad.net/bugs/1683076 +Origin: upstream, https://github.com/openstack/swift/commit/95efd3f9035ec4141e1b182516f040a59a3e5aa6 + +Index: swift-2.2.2/swift/common/utils.py +=================================================================== +--- swift-2.2.2.orig/swift/common/utils.py 2017-05-23 15:36:55.944784976 -0700 ++++ swift-2.2.2/swift/common/utils.py 2017-05-23 15:36:55.940784881 -0700 +@@ -913,19 +913,54 @@ + + class LoggerFileObject(object): + ++ # Note: this is greenthread-local storage ++ _cls_thread_local = threading.local() ++ + def __init__(self, logger): + self.logger = logger + + def write(self, value): +- value = value.strip() +- if value: +- if 'Connection reset by peer' in value: +- self.logger.error(_('STDOUT: Connection reset by peer')) +- else: +- self.logger.error(_('STDOUT: %s'), value) ++ # We can get into a nasty situation when logs are going to syslog ++ # and syslog dies. ++ # ++ # It's something like this: ++ # ++ # (A) someone logs something ++ # ++ # (B) there's an exception in sending to /dev/log since syslog is ++ # not working ++ # ++ # (C) logging takes that exception and writes it to stderr (see ++ # logging.Handler.handleError) ++ # ++ # (D) stderr was replaced with a LoggerFileObject at process start, ++ # so the LoggerFileObject takes the provided string and tells ++ # its logger to log it (to syslog, naturally). ++ # ++ # Then, steps B through D repeat until we run out of stack. ++ if getattr(self._cls_thread_local, 'already_called_write', False): ++ return ++ ++ self._cls_thread_local.already_called_write = True ++ try: ++ value = value.strip() ++ if value: ++ if 'Connection reset by peer' in value: ++ self.logger.error(_('STDOUT: Connection reset by peer')) ++ else: ++ self.logger.error(_('STDOUT: %s'), value) ++ finally: ++ self._cls_thread_local.already_called_write = False + + def writelines(self, values): +- self.logger.error(_('STDOUT: %s'), '#012'.join(values)) ++ if getattr(self._cls_thread_local, 'already_called_writelines', False): ++ return ++ ++ self._cls_thread_local.already_called_writelines = True ++ try: ++ self.logger.error(_('STDOUT: %s'), '#012'.join(values)) ++ finally: ++ self._cls_thread_local.already_called_writelines = False + + def close(self): + pass +Index: swift-2.2.2/test/unit/common/test_utils.py +=================================================================== +--- swift-2.2.2.orig/test/unit/common/test_utils.py 2017-05-23 15:36:55.944784976 -0700 ++++ swift-2.2.2/test/unit/common/test_utils.py 2017-05-23 16:44:33.408929508 -0700 +@@ -17,6 +17,7 @@ + + from test.unit import temptree + ++import contextlib + import ctypes + import errno + import eventlet +@@ -1103,6 +1104,47 @@ + self.assertEquals(options['once'], True) + self.assertEquals(options['extra_args'], ['plugin_name']) + ++ def test_LoggerFileObject_recursion(self): ++ crashy_calls = [0] ++ ++ class CrashyLogger(logging.Handler): ++ def emit(self, record): ++ crashy_calls[0] += 1 ++ try: ++ # Pretend to be trying to sendt o syslog, but syslogd is ++ # dead. We need the raise here to set sys.exc_info. ++ raise socket.error(errno.ENOTCONN, "This is an ex-syslog") ++ except socket.error: ++ self.handleError(record) ++ ++ logger = logging.getLogger() ++ logger.addHandler(CrashyLogger()) ++ ++ # Set up some real file descriptors for stdio. If you run ++ # nosetests with "-s", you already have real files there, but ++ # otherwise they're StringIO objects. ++ # ++ # In any case, since capture_stdio() closes sys.stdin and friends, ++ # we'd want to set up some sacrificial files so as to not goof up ++ # the testrunner. ++ new_stdin = open(os.devnull, 'r+b') ++ new_stdout = open(os.devnull, 'w+b') ++ new_stderr = open(os.devnull, 'w+b') ++ ++ with contextlib.closing(new_stdin), contextlib.closing(new_stdout), \ ++ contextlib.closing(new_stderr): ++ # logging.raiseExceptions is set to False in test/__init__.py, but ++ # is True in Swift daemons, and the error doesn't manifest without ++ # it. ++ with mock.patch('sys.stdin', new_stdin), \ ++ mock.patch('sys.stdout', new_stdout), \ ++ mock.patch.object(logging, 'raiseExceptions', True): ++ # note: since stdio is hooked up to /dev/null in here, using ++ # pdb is basically impossible. Sorry about that. ++ utils.capture_stdio(logger) ++ logger.info("I like ham") ++ self.assertTrue(crashy_calls[0], 1) ++ + def test_parse_options_errors(self): + orig_stdout = sys.stdout + orig_stderr = sys.stderr diff -Nru swift-2.2.2/debian/patches/series swift-2.2.2/debian/patches/series --- swift-2.2.2/debian/patches/series 2015-07-30 10:15:27.000000000 -0700 +++ swift-2.2.2/debian/patches/series 2017-05-23 15:24:03.000000000 -0700 @@ -3,3 +3,4 @@ x-auth-token-should-be-bytestring.patch fix-tempauth-acl-checks.patch increase-httplib-maxheaders.patch +fix-infinite-recursion-logging.patch