From f6482bdece27144ee083a53d696469528d7940c2 Mon Sep 17 00:00:00 2001
From: Thierry Carrez <thierry@openstack.org>
Date: Thu, 16 Apr 2015 22:08:47 +0200
Subject: [PATCH 1/5] Set default branch to stable/kilo

Open stable/kilo branch by setting defaultbranch for git-review.

Change-Id: I81bcda30f99173416eaaa3f1d42da32f3ab5b6d2
---
 .gitreview | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitreview b/.gitreview
index d7c52c0593..94552c9bcb 100644
--- a/.gitreview
+++ b/.gitreview
@@ -2,3 +2,4 @@
 host=review.openstack.org
 port=29418
 project=openstack/swift.git
+defaultbranch=stable/kilo

From 51e31c5c7147f3ba61437e132b12b491ca718ce4 Mon Sep 17 00:00:00 2001
From: Clay Gerrard <clay.gerrard@gmail.com>
Date: Wed, 15 Apr 2015 15:31:06 -0700
Subject: [PATCH 2/5] Don't apply the wrong Etag validation to rebuilt
 fragments

Because of the object-server's interaction with ssync sender's
X-Backend-Replication-Headers when a object (or fragment archive) is
pushed unmodified to another node it's ETag value is duped into the
recieving ends metadata as Etag.  This interacts poorly with the
reconstructor's RebuildingECDiskFileStream which can not know ahead of
time the ETag of the fragment archive being rebuilt.

Don't send the Etag from the local source fragment archive being used as
the basis for the rebuilt fragent archive's metadata along to ssync.

Closes-Bug: 1446800
Change-Id: Ie59ad93a67a7f439c9a84cd9cff31540f97f334a
---
 swift/obj/reconstructor.py              |  34 +++----
 test/probe/common.py                    |   5 +
 test/probe/test_reconstructor_revert.py | 120 +++++++++++++++++++++++-
 test/unit/obj/test_reconstructor.py     |  18 +---
 4 files changed, 143 insertions(+), 34 deletions(-)

diff --git a/swift/obj/reconstructor.py b/swift/obj/reconstructor.py
index 0ee2afbf6d..db078de2fc 100644
--- a/swift/obj/reconstructor.py
+++ b/swift/obj/reconstructor.py
@@ -49,6 +49,21 @@ SYNC, REVERT = ('sync_only', 'sync_revert')
 hubs.use_hub(get_hub())
 
 
+def _get_partners(frag_index, part_nodes):
+    """
+    Returns the left and right partners of the node whose index is
+    equal to the given frag_index.
+
+    :param frag_index: a fragment index
+    :param part_nodes: a list of primary nodes
+    :returns: [<node-to-left>, <node-to-right>]
+    """
+    return [
+        part_nodes[(frag_index - 1) % len(part_nodes)],
+        part_nodes[(frag_index + 1) % len(part_nodes)],
+    ]
+
+
 class RebuildingECDiskFileStream(object):
     """
     This class wraps the the reconstructed fragment archive data and
@@ -65,7 +80,8 @@ class RebuildingECDiskFileStream(object):
         # update the FI and delete the ETag, the obj server will
         # recalc on the other side...
         self.metadata['X-Object-Sysmeta-Ec-Frag-Index'] = frag_index
-        del self.metadata['ETag']
+        for etag_key in ('ETag', 'Etag'):
+            self.metadata.pop(etag_key, None)
 
         self.frag_index = frag_index
         self.rebuilt_fragment_iter = rebuilt_fragment_iter
@@ -382,20 +398,6 @@ class ObjectReconstructor(Daemon):
                 self.kill_coros()
             self.last_reconstruction_count = self.reconstruction_count
 
-    def _get_partners(self, frag_index, part_nodes):
-        """
-        Returns the left and right partners of the node whose index is
-        equal to the given frag_index.
-
-        :param frag_index: a fragment index
-        :param part_nodes: a list of primary nodes
-        :returns: [<node-to-left>, <node-to-right>]
-        """
-        return [
-            part_nodes[(frag_index - 1) % len(part_nodes)],
-            part_nodes[(frag_index + 1) % len(part_nodes)],
-        ]
-
     def _get_hashes(self, policy, path, recalculate=None, do_listdir=False):
         df_mgr = self._df_router[policy]
         hashed, suffix_hashes = tpool_reraise(
@@ -715,7 +717,7 @@ class ObjectReconstructor(Daemon):
                     job_type=SYNC,
                     frag_index=frag_index,
                     suffixes=suffixes,
-                    sync_to=self._get_partners(frag_index, part_nodes),
+                    sync_to=_get_partners(frag_index, part_nodes),
                 )
                 # ssync callback to rebuild missing fragment_archives
                 sync_job['sync_diskfile_builder'] = self.reconstruct_fa
diff --git a/test/probe/common.py b/test/probe/common.py
index 1311cc178a..7d1e754014 100644
--- a/test/probe/common.py
+++ b/test/probe/common.py
@@ -299,6 +299,11 @@ class ProbeTest(unittest.TestCase):
             path_parts.append(str(part))
         return os.path.join(*path_parts)
 
+    def config_number(self, node):
+        _server_type, config_number = get_server_number(
+            node['port'], self.port2server)
+        return config_number
+
     def get_to_final_state(self):
         # these .stop()s are probably not strictly necessary,
         # but may prevent race conditions
diff --git a/test/probe/test_reconstructor_revert.py b/test/probe/test_reconstructor_revert.py
index 2a7bd7c834..39739b617d 100755
--- a/test/probe/test_reconstructor_revert.py
+++ b/test/probe/test_reconstructor_revert.py
@@ -18,6 +18,9 @@ from hashlib import md5
 import unittest
 import uuid
 import os
+import random
+import shutil
+from collections import defaultdict
 
 from test.probe.common import ECProbeTest
 
@@ -25,6 +28,7 @@ from swift.common import direct_client
 from swift.common.storage_policy import EC_POLICY
 from swift.common.manager import Manager
 from swift.common.utils import renamer
+from swift.obj import reconstructor
 
 from swiftclient import client
 
@@ -233,7 +237,7 @@ class TestReconstructorRevert(ECProbeTest):
         # fire up reconstructor on handoff nodes only
         for hnode in hnodes:
             hnode_id = (hnode['port'] - 6000) / 10
-            self.reconstructor.once(number=hnode_id, override_devices=['sdb8'])
+            self.reconstructor.once(number=hnode_id)
 
         # check the first node to make sure its gone
         try:
@@ -253,6 +257,120 @@ class TestReconstructorRevert(ECProbeTest):
             self.fail('Node data on %r was not fully destoryed!' %
                       (onodes[0]))
 
+    def test_reconstruct_from_reverted_fragment_archive(self):
+        headers = {'X-Storage-Policy': self.policy.name}
+        client.put_container(self.url, self.token, self.container_name,
+                             headers=headers)
+
+        # get our node lists
+        opart, onodes = self.object_ring.get_nodes(
+            self.account, self.container_name, self.object_name)
+
+        # find a primary server that only has one of it's devices in the
+        # primary node list
+        group_nodes_by_config = defaultdict(list)
+        for n in onodes:
+            group_nodes_by_config[self.config_number(n)].append(n)
+        for config_number, node_list in group_nodes_by_config.items():
+            if len(node_list) == 1:
+                break
+        else:
+            self.fail('ring balancing did not use all available nodes')
+        primary_node = node_list[0]
+        primary_device = self.device_dir('object', primary_node)
+        self.kill_drive(primary_device)
+
+        # PUT object
+        contents = Body()
+        etag = client.put_object(self.url, self.token, self.container_name,
+                                 self.object_name, contents=contents)
+        self.assertEqual(contents.etag, etag)
+
+        # fix the primary device and sanity GET
+        self.revive_drive(primary_device)
+        self.assertEqual(etag, self.proxy_get())
+
+        # find a handoff holding the fragment
+        for hnode in self.object_ring.get_more_nodes(opart):
+            try:
+                reverted_fragment_etag = self.direct_get(hnode, opart)
+            except direct_client.DirectClientException as err:
+                if err.http_status != 404:
+                    raise
+            else:
+                break
+        else:
+            self.fail('Unable to find handoff fragment!')
+
+        # we'll force the handoff device to revert instead of potentially
+        # racing with rebuild by deleting any other fragments that may be on
+        # the same server
+        handoff_fragment_etag = None
+        for node in onodes:
+            if node['port'] == hnode['port']:
+                # we'll keep track of the etag of this fragment we're removing
+                # in case we need it later (queue forshadowing music)...
+                try:
+                    handoff_fragment_etag = self.direct_get(node, opart)
+                except direct_client.DirectClientException as err:
+                    if err.http_status != 404:
+                        raise
+                    # this just means our handoff device was on the same
+                    # machine as the primary!
+                    continue
+                # use the primary nodes device - not the hnode device
+                part_dir = self.storage_dir('object', node, part=opart)
+                shutil.rmtree(part_dir, True)
+
+        # revert from handoff device with reconstructor
+        self.reconstructor.once(number=self.config_number(hnode))
+
+        # verify fragment reverted to primary server
+        self.assertEqual(reverted_fragment_etag,
+                         self.direct_get(primary_node, opart))
+
+        # now we'll remove some data on one of the primary node's partners
+        partner = random.choice(reconstructor._get_partners(
+            primary_node['index'], onodes))
+
+        try:
+            rebuilt_fragment_etag = self.direct_get(partner, opart)
+        except direct_client.DirectClientException as err:
+            if err.http_status != 404:
+                raise
+            # partner already had it's fragment removed
+            if (handoff_fragment_etag is not None and
+                    hnode['port'] == partner['port']):
+                # oh, well that makes sense then...
+                rebuilt_fragment_etag = handoff_fragment_etag
+            else:
+                # I wonder what happened?
+                self.fail('Partner inexplicably missing fragment!')
+        part_dir = self.storage_dir('object', partner, part=opart)
+        shutil.rmtree(part_dir, True)
+
+        # sanity, it's gone
+        try:
+            self.direct_get(partner, opart)
+        except direct_client.DirectClientException as err:
+            if err.http_status != 404:
+                raise
+        else:
+            self.fail('successful GET of removed partner fragment archive!?')
+
+        # and force the primary node to do a rebuild
+        self.reconstructor.once(number=self.config_number(primary_node))
+
+        # and validate the partners rebuilt_fragment_etag
+        try:
+            self.assertEqual(rebuilt_fragment_etag,
+                             self.direct_get(partner, opart))
+        except direct_client.DirectClientException as err:
+            if err.http_status != 404:
+                raise
+            else:
+                self.fail('Did not find rebuilt fragment on partner node')
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/test/unit/obj/test_reconstructor.py b/test/unit/obj/test_reconstructor.py
index 93a50e84de..b7254f4343 100755
--- a/test/unit/obj/test_reconstructor.py
+++ b/test/unit/obj/test_reconstructor.py
@@ -293,22 +293,6 @@ class TestGlobalSetupObjectReconstructor(unittest.TestCase):
             writer.commit(timestamp)
         return df
 
-    def debug_wtf(self):
-        # won't include this in the final, just handy reminder of where
-        # things are...
-        for pol in [p for p in POLICIES if p.policy_type == EC_POLICY]:
-            obj_ring = pol.object_ring
-            for part_num in self.part_nums:
-                print "\n part_num %s " % part_num
-                part_nodes = obj_ring.get_part_nodes(int(part_num))
-                print "\n part_nodes %s " % part_nodes
-                for local_dev in obj_ring.devs:
-                    partners = self.reconstructor._get_partners(
-                        local_dev['id'], obj_ring, part_num)
-                    if partners:
-                        print "\n local_dev %s \n partners %s " % (local_dev,
-                                                                   partners)
-
     def assert_expected_jobs(self, part_num, jobs):
         for job in jobs:
             del job['path']
@@ -702,7 +686,7 @@ class TestGlobalSetupObjectReconstructor(unittest.TestCase):
                 part_nodes = obj_ring.get_part_nodes(int(part_num))
                 primary_ids = [n['id'] for n in part_nodes]
                 for node in part_nodes:
-                    partners = self.reconstructor._get_partners(
+                    partners = object_reconstructor._get_partners(
                         node['index'], part_nodes)
                     left = partners[0]['id']
                     right = partners[1]['id']

From 281cb1c210f0292bad190cabaae447145fa5eade Mon Sep 17 00:00:00 2001
From: Tushar Gohad <tushar.gohad@intel.com>
Date: Wed, 15 Apr 2015 17:34:48 -0700
Subject: [PATCH 3/5] Bump PyECLib version from 1.0.3 to 1.0.7

In addition to fixing several bugs, 1.0.7 eliminates the need for a
few work-around code in Swift.  This code was only to hide issues in
the current version, but it also ends up breaking some third-party
integration.  In order to enable expected functionality and to avoid
dealing with deprecation issues right from the beginning, we need to
bump the minium PyECLib requirement to 1.0.7.

Closes-Bug: 1446727
Change-Id: I03e059e7335656c22be28ffd6157b56e13bdfc1b
---
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index 27d507901a..9f81b844ae 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,4 +9,4 @@ netifaces>=0.5,!=0.10.0,!=0.10.1
 pastedeploy>=1.3.3
 simplejson>=2.0.9
 xattr>=0.4
-PyECLib>=1.0.3
+PyECLib>=1.0.7

From cd7c58e93690fd25f5266754d0593c656dd51e2e Mon Sep 17 00:00:00 2001
From: Kota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>
Date: Mon, 20 Apr 2015 00:18:25 -0700
Subject: [PATCH 4/5] Use reconstruct insetad of decode/encode

With bumping PyECLib up to 1.0.7 on global requirements,
we can use the "reconstruct" function directly instead
of the current hack doing decode/encode on reconstructor.
That is because the hack was for treating PyECLib < 1.0.7
(strictly jearsure scheme) reconstruction bug so we don't
have to do decode/encode anymore.

Closes-Bug: 1446801
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Change-Id: I69aae495670e3d0bdebe665f73915547a4d56f99
---
 swift/obj/reconstructor.py          | 10 ++------
 test/unit/obj/test_reconstructor.py | 39 +++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/swift/obj/reconstructor.py b/swift/obj/reconstructor.py
index db078de2fc..4385e42cc9 100644
--- a/swift/obj/reconstructor.py
+++ b/swift/obj/reconstructor.py
@@ -276,14 +276,8 @@ class ObjectReconstructor(Daemon):
                                           rebuilt_fragment_iter)
 
     def _reconstruct(self, policy, fragment_payload, frag_index):
-        # XXX with jerasure this doesn't work if we need to rebuild a
-        # parity fragment, and not all data fragments are available
-        # segment = policy.pyeclib_driver.reconstruct(
-        #     fragment_payload, [frag_index])[0]
-
-        # for safety until pyeclib 1.0.7 we'll just use decode and encode
-        segment = policy.pyeclib_driver.decode(fragment_payload)
-        return policy.pyeclib_driver.encode(segment)[frag_index]
+        return policy.pyeclib_driver.reconstruct(fragment_payload,
+                                                 [frag_index])[0]
 
     def make_rebuilt_fragment_iter(self, responses, path, policy, frag_index):
         """
diff --git a/test/unit/obj/test_reconstructor.py b/test/unit/obj/test_reconstructor.py
index b7254f4343..23e70543f7 100755
--- a/test/unit/obj/test_reconstructor.py
+++ b/test/unit/obj/test_reconstructor.py
@@ -2347,6 +2347,45 @@ class TestObjectReconstructor(unittest.TestCase):
                 self.assertEqual(md5(fixed_body).hexdigest(),
                                  md5(broken_body).hexdigest())
 
+    def test_reconstruct_parity_fa_with_data_node_failure(self):
+        job = {
+            'partition': 0,
+            'policy': self.policy,
+        }
+        part_nodes = self.policy.object_ring.get_part_nodes(0)
+        node = part_nodes[-4]
+        metadata = {
+            'name': '/a/c/o',
+            'Content-Length': 0,
+            'ETag': 'etag',
+        }
+
+        # make up some data (trim some amount to make it unaligned with
+        # segment size)
+        test_data = ('rebuild' * self.policy.ec_segment_size)[:-454]
+        etag = md5(test_data).hexdigest()
+        ec_archive_bodies = make_ec_archive_bodies(self.policy, test_data)
+
+        # the scheme is 10+4, so this gets a parity node
+        broken_body = ec_archive_bodies.pop(-4)
+
+        base_responses = list((200, body) for body in ec_archive_bodies)
+        for error in (Timeout(), 404, Exception('kaboom!')):
+            responses = list(base_responses)
+            # grab a data node index
+            error_index = random.randint(0, self.policy.ec_ndata - 1)
+            responses[error_index] = (error, '')
+            headers = {'X-Object-Sysmeta-Ec-Etag': etag}
+            codes, body_iter = zip(*responses)
+            with mocked_http_conn(*codes, body_iter=body_iter,
+                                  headers=headers):
+                df = self.reconstructor.reconstruct_fa(
+                    job, node, dict(metadata))
+                fixed_body = ''.join(df.reader())
+                self.assertEqual(len(fixed_body), len(broken_body))
+                self.assertEqual(md5(fixed_body).hexdigest(),
+                                 md5(broken_body).hexdigest())
+
     def test_reconstruct_fa_errors_fails(self):
         job = {
             'partition': 0,

From f8dee761bd36f857aa1288c27e095907032fad68 Mon Sep 17 00:00:00 2001
From: Andreas Jaeger <aj@suse.de>
Date: Mon, 20 Apr 2015 11:15:35 +0200
Subject: [PATCH 5/5] Release Import of Translations from Transifex

Manual import of Translations from Transifex. This change also removes
all po files that are less than 66 per cent translated since such
partially translated files will not help users.

This updates also recreates all pot (translation source files) to
reflect the state of the repository.

This change needs to be done manually since the automatic import does
not handle the proposed branches and we need to sync with latest
translations.

Note: This is part of importing of translations, there are no new
translations for this project, thus only the pot file gets updated.

Change-Id: I0cbfdae3bd1662da54c58e91a13f49419eba9b2d
---
 swift/locale/swift.pot                  | 503 ++++++++++++++----------
 swift/locale/zh_CN/LC_MESSAGES/swift.po | 479 +++++++++++++---------
 2 files changed, 588 insertions(+), 394 deletions(-)

diff --git a/swift/locale/swift.pot b/swift/locale/swift.pot
index f7a79f7239..4845819076 100644
--- a/swift/locale/swift.pot
+++ b/swift/locale/swift.pot
@@ -6,9 +6,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: swift 2.2.2.post136\n"
+"Project-Id-Version: swift 2.3.0rc1.1.gf6482bd\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-03-24 06:06+0000\n"
+"POT-Creation-Date: 2015-04-20 11:15+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -63,98 +63,98 @@ msgstr ""
 msgid "ERROR Could not get account info %s"
 msgstr ""
 
-#: swift/account/reaper.py:133 swift/common/utils.py:2127
-#: swift/obj/diskfile.py:470 swift/obj/updater.py:87 swift/obj/updater.py:130
+#: swift/account/reaper.py:134 swift/common/utils.py:2127
+#: swift/obj/diskfile.py:476 swift/obj/updater.py:88 swift/obj/updater.py:131
 #, python-format
 msgid "Skipping %s as it is not mounted"
 msgstr ""
 
-#: swift/account/reaper.py:137
+#: swift/account/reaper.py:138
 msgid "Exception in top-level account reaper loop"
 msgstr ""
 
-#: swift/account/reaper.py:140
+#: swift/account/reaper.py:141
 #, python-format
 msgid "Devices pass completed: %.02fs"
 msgstr ""
 
-#: swift/account/reaper.py:237
+#: swift/account/reaper.py:238
 #, python-format
 msgid "Beginning pass on account %s"
 msgstr ""
 
-#: swift/account/reaper.py:254
+#: swift/account/reaper.py:255
 #, python-format
 msgid "Exception with containers for account %s"
 msgstr ""
 
-#: swift/account/reaper.py:261
+#: swift/account/reaper.py:262
 #, python-format
 msgid "Exception with account %s"
 msgstr ""
 
-#: swift/account/reaper.py:262
+#: swift/account/reaper.py:263
 #, python-format
 msgid "Incomplete pass on account %s"
 msgstr ""
 
-#: swift/account/reaper.py:264
+#: swift/account/reaper.py:265
 #, python-format
 msgid ", %s containers deleted"
 msgstr ""
 
-#: swift/account/reaper.py:266
+#: swift/account/reaper.py:267
 #, python-format
 msgid ", %s objects deleted"
 msgstr ""
 
-#: swift/account/reaper.py:268
+#: swift/account/reaper.py:269
 #, python-format
 msgid ", %s containers remaining"
 msgstr ""
 
-#: swift/account/reaper.py:271
+#: swift/account/reaper.py:272
 #, python-format
 msgid ", %s objects remaining"
 msgstr ""
 
-#: swift/account/reaper.py:273
+#: swift/account/reaper.py:274
 #, python-format
 msgid ", %s containers possibly remaining"
 msgstr ""
 
-#: swift/account/reaper.py:276
+#: swift/account/reaper.py:277
 #, python-format
 msgid ", %s objects possibly remaining"
 msgstr ""
 
-#: swift/account/reaper.py:279
+#: swift/account/reaper.py:280
 msgid ", return codes: "
 msgstr ""
 
-#: swift/account/reaper.py:283
+#: swift/account/reaper.py:284
 #, python-format
 msgid ", elapsed: %.02fs"
 msgstr ""
 
-#: swift/account/reaper.py:289
+#: swift/account/reaper.py:290
 #, python-format
 msgid "Account %s has not been reaped since %s"
 msgstr ""
 
-#: swift/account/reaper.py:348 swift/account/reaper.py:396
-#: swift/account/reaper.py:463 swift/container/updater.py:306
+#: swift/account/reaper.py:349 swift/account/reaper.py:397
+#: swift/account/reaper.py:464 swift/container/updater.py:306
 #, python-format
 msgid "Exception with %(ip)s:%(port)s/%(device)s"
 msgstr ""
 
-#: swift/account/reaper.py:368
+#: swift/account/reaper.py:369
 #, python-format
 msgid "Exception with objects for container %(container)s for account %(account)s"
 msgstr ""
 
 #: swift/account/server.py:275 swift/container/server.py:582
-#: swift/obj/server.py:730
+#: swift/obj/server.py:910
 #, python-format
 msgid "ERROR __call__ error with %(method)s %(path)s "
 msgstr ""
@@ -270,90 +270,90 @@ msgstr ""
 msgid "Unexpected response: %s"
 msgstr ""
 
-#: swift/common/manager.py:62
+#: swift/common/manager.py:63
 msgid "WARNING: Unable to modify file descriptor limit.  Running as non-root?"
 msgstr ""
 
-#: swift/common/manager.py:69
+#: swift/common/manager.py:70
 msgid "WARNING: Unable to modify memory limit.  Running as non-root?"
 msgstr ""
 
-#: swift/common/manager.py:76
+#: swift/common/manager.py:77
 msgid "WARNING: Unable to modify max process limit.  Running as non-root?"
 msgstr ""
 
-#: swift/common/manager.py:194
+#: swift/common/manager.py:195
 msgid ""
 "\n"
 "user quit"
 msgstr ""
 
-#: swift/common/manager.py:231 swift/common/manager.py:543
+#: swift/common/manager.py:232 swift/common/manager.py:544
 #, python-format
 msgid "No %s running"
 msgstr ""
 
-#: swift/common/manager.py:244
+#: swift/common/manager.py:245
 #, python-format
 msgid "%s (%s) appears to have stopped"
 msgstr ""
 
-#: swift/common/manager.py:254
+#: swift/common/manager.py:255
 #, python-format
 msgid "Waited %s seconds for %s to die; giving up"
 msgstr ""
 
-#: swift/common/manager.py:437
+#: swift/common/manager.py:438
 #, python-format
 msgid "Unable to locate config %sfor %s"
 msgstr ""
 
-#: swift/common/manager.py:441
+#: swift/common/manager.py:442
 msgid "Found configs:"
 msgstr ""
 
-#: swift/common/manager.py:485
+#: swift/common/manager.py:486
 #, python-format
 msgid "Signal %s  pid: %s  signal: %s"
 msgstr ""
 
-#: swift/common/manager.py:492
+#: swift/common/manager.py:493
 #, python-format
 msgid "Removing stale pid file %s"
 msgstr ""
 
-#: swift/common/manager.py:495
+#: swift/common/manager.py:496
 #, python-format
 msgid "No permission to signal PID %d"
 msgstr ""
 
-#: swift/common/manager.py:540
+#: swift/common/manager.py:541
 #, python-format
 msgid "%s #%d not running (%s)"
 msgstr ""
 
-#: swift/common/manager.py:547 swift/common/manager.py:640
-#: swift/common/manager.py:643
+#: swift/common/manager.py:548 swift/common/manager.py:641
+#: swift/common/manager.py:644
 #, python-format
 msgid "%s running (%s - %s)"
 msgstr ""
 
-#: swift/common/manager.py:646
+#: swift/common/manager.py:647
 #, python-format
 msgid "%s already started..."
 msgstr ""
 
-#: swift/common/manager.py:655
+#: swift/common/manager.py:656
 #, python-format
 msgid "Running %s once"
 msgstr ""
 
-#: swift/common/manager.py:657
+#: swift/common/manager.py:658
 #, python-format
 msgid "Starting %s"
 msgstr ""
 
-#: swift/common/manager.py:664
+#: swift/common/manager.py:665
 #, python-format
 msgid "%s does not exist"
 msgstr ""
@@ -373,7 +373,12 @@ msgstr ""
 msgid "Error limiting server %s"
 msgstr ""
 
-#: swift/common/request_helpers.py:387
+#: swift/common/request_helpers.py:102
+#, python-format
+msgid "No policy with index %s"
+msgstr ""
+
+#: swift/common/request_helpers.py:395
 msgid "ERROR: An error occurred while retrieving segments"
 msgstr ""
 
@@ -436,51 +441,51 @@ msgstr ""
 msgid "Unable to find %s config section in %s"
 msgstr ""
 
-#: swift/common/utils.py:2348
+#: swift/common/utils.py:2353
 #, python-format
 msgid "Invalid X-Container-Sync-To format %r"
 msgstr ""
 
-#: swift/common/utils.py:2353
+#: swift/common/utils.py:2358
 #, python-format
 msgid "No realm key for %r"
 msgstr ""
 
-#: swift/common/utils.py:2357
+#: swift/common/utils.py:2362
 #, python-format
 msgid "No cluster endpoint for %r %r"
 msgstr ""
 
-#: swift/common/utils.py:2366
+#: swift/common/utils.py:2371
 #, python-format
 msgid ""
 "Invalid scheme %r in X-Container-Sync-To, must be \"//\", \"http\", or "
 "\"https\"."
 msgstr ""
 
-#: swift/common/utils.py:2370
+#: swift/common/utils.py:2375
 msgid "Path required in X-Container-Sync-To"
 msgstr ""
 
-#: swift/common/utils.py:2373
+#: swift/common/utils.py:2378
 msgid "Params, queries, and fragments not allowed in X-Container-Sync-To"
 msgstr ""
 
-#: swift/common/utils.py:2378
+#: swift/common/utils.py:2383
 #, python-format
 msgid "Invalid host %r in X-Container-Sync-To"
 msgstr ""
 
-#: swift/common/utils.py:2570
+#: swift/common/utils.py:2575
 msgid "Exception dumping recon cache"
 msgstr ""
 
-#: swift/common/wsgi.py:175
+#: swift/common/wsgi.py:197
 #, python-format
 msgid "Could not bind to %s:%s after trying for %s seconds"
 msgstr ""
 
-#: swift/common/wsgi.py:185
+#: swift/common/wsgi.py:207
 msgid ""
 "WARNING: SSL should only be enabled for testing purposes. Use external "
 "SSL termination for a production deployment."
@@ -521,27 +526,27 @@ msgstr ""
 msgid "Warning: Cannot ratelimit without a memcached client"
 msgstr ""
 
-#: swift/common/middleware/recon.py:78
+#: swift/common/middleware/recon.py:80
 msgid "Error reading recon cache file"
 msgstr ""
 
-#: swift/common/middleware/recon.py:80
+#: swift/common/middleware/recon.py:82
 msgid "Error parsing recon cache file"
 msgstr ""
 
-#: swift/common/middleware/recon.py:82
+#: swift/common/middleware/recon.py:84
 msgid "Error retrieving recon data"
 msgstr ""
 
-#: swift/common/middleware/recon.py:151
+#: swift/common/middleware/recon.py:158
 msgid "Error listing devices"
 msgstr ""
 
-#: swift/common/middleware/recon.py:247
+#: swift/common/middleware/recon.py:254
 msgid "Error reading ringfile"
 msgstr ""
 
-#: swift/common/middleware/recon.py:261
+#: swift/common/middleware/recon.py:268
 msgid "Error reading swift.conf"
 msgstr ""
 
@@ -648,52 +653,61 @@ msgid ""
 "later)"
 msgstr ""
 
-#: swift/container/sync.py:193
+#: swift/container/sync.py:217
+msgid ""
+"Configuration option internal_client_conf_path not defined. Using default"
+" configuration, See internal-client.conf-sample for options"
+msgstr ""
+
+#: swift/container/sync.py:230
+#, python-format
+msgid "Unable to load internal client from config: %r (%s)"
+msgstr ""
+
+#: swift/container/sync.py:264
 msgid "Begin container sync \"once\" mode"
 msgstr ""
 
-#: swift/container/sync.py:205
+#: swift/container/sync.py:276
 #, python-format
 msgid "Container sync \"once\" mode completed: %.02fs"
 msgstr ""
 
-#: swift/container/sync.py:213
+#: swift/container/sync.py:284
 #, python-format
 msgid ""
 "Since %(time)s: %(sync)s synced [%(delete)s deletes, %(put)s puts], "
 "%(skip)s skipped, %(fail)s failed"
 msgstr ""
 
-#: swift/container/sync.py:266
+#: swift/container/sync.py:337
 #, python-format
 msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
 msgstr ""
 
-#: swift/container/sync.py:322
+#: swift/container/sync.py:393
 #, python-format
 msgid "ERROR Syncing %s"
 msgstr ""
 
-#: swift/container/sync.py:410
+#: swift/container/sync.py:476
 #, python-format
-msgid ""
-"Unknown exception trying to GET: %(node)r %(account)r %(container)r "
-"%(object)r"
+msgid "Unknown exception trying to GET: %(account)r %(container)r %(object)r"
 msgstr ""
 
-#: swift/container/sync.py:444
+#: swift/container/sync.py:510
 #, python-format
 msgid "Unauth %(sync_from)r => %(sync_to)r"
 msgstr ""
 
-#: swift/container/sync.py:450
+#: swift/container/sync.py:516
 #, python-format
 msgid ""
 "Not found %(sync_from)r => %(sync_to)r                       - object "
 "%(obj_name)r"
 msgstr ""
 
-#: swift/container/sync.py:457 swift/container/sync.py:464
+#: swift/container/sync.py:523 swift/container/sync.py:530
 #, python-format
 msgid "ERROR Syncing %(db_file)s %(row)s"
 msgstr ""
@@ -703,8 +717,8 @@ msgstr ""
 msgid "ERROR:  Failed to get paths to drive partitions: %s"
 msgstr ""
 
-#: swift/container/updater.py:91 swift/obj/replicator.py:484
-#: swift/obj/replicator.py:570
+#: swift/container/updater.py:91 swift/obj/reconstructor.py:788
+#: swift/obj/replicator.py:487 swift/obj/replicator.py:575
 #, python-format
 msgid "%s is not mounted"
 msgstr ""
@@ -816,42 +830,57 @@ msgstr ""
 msgid "ERROR auditing: %s"
 msgstr ""
 
-#: swift/obj/diskfile.py:318
+#: swift/obj/diskfile.py:323 swift/obj/diskfile.py:2305
 #, python-format
 msgid "Quarantined %(hsh_path)s to %(quar_path)s because it is not a directory"
 msgstr ""
 
-#: swift/obj/diskfile.py:409
+#: swift/obj/diskfile.py:414 swift/obj/diskfile.py:2373
 msgid "Error hashing suffix"
 msgstr ""
 
-#: swift/obj/diskfile.py:484 swift/obj/updater.py:169
+#: swift/obj/diskfile.py:486 swift/obj/updater.py:162
 #, python-format
-msgid "Directory %s does not map to a valid policy"
+msgid "Directory %r does not map to a valid policy (%s)"
 msgstr ""
 
-#: swift/obj/diskfile.py:678
+#: swift/obj/diskfile.py:737
 #, python-format
 msgid "Quarantined %(object_path)s to %(quar_path)s because it is not a directory"
 msgstr ""
 
-#: swift/obj/diskfile.py:869
+#: swift/obj/diskfile.py:936 swift/obj/diskfile.py:1795
 #, python-format
 msgid "Problem cleaning up %s"
 msgstr ""
 
-#: swift/obj/diskfile.py:1168
+#: swift/obj/diskfile.py:1253
 #, python-format
 msgid "ERROR DiskFile %(data_file)s close failure: %(exc)s : %(stack)s"
 msgstr ""
 
-#: swift/obj/diskfile.py:1449
+#: swift/obj/diskfile.py:1543
 #, python-format
 msgid ""
 "Client path %(client)s does not match path stored in object metadata "
 "%(meta)s"
 msgstr ""
 
+#: swift/obj/diskfile.py:1797
+#, python-format
+msgid "Problem fsyncing durable state file: %s"
+msgstr ""
+
+#: swift/obj/diskfile.py:1802
+#, python-format
+msgid "No space left on device for %s"
+msgstr ""
+
+#: swift/obj/diskfile.py:1806
+#, python-format
+msgid "Problem writing durable state file: %s"
+msgstr ""
+
 #: swift/obj/expirer.py:79
 #, python-format
 msgid "Pass completed in %ds; %d objects expired"
@@ -881,326 +910,394 @@ msgstr ""
 msgid "Exception while deleting object %s %s %s"
 msgstr ""
 
-#: swift/obj/mem_server.py:87
+#: swift/obj/reconstructor.py:189 swift/obj/reconstructor.py:472
+#, python-format
+msgid "Invalid response %(resp)s from %(full_path)s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:195
+#, python-format
+msgid "Trying to GET %(full_path)s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:301
+#, python-format
+msgid "Error trying to rebuild %(path)s policy#%(policy)d frag#%(frag_index)s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:324
 #, python-format
 msgid ""
-"ERROR Container update failed: %(status)d response from "
-"%(ip)s:%(port)s/%(dev)s"
+"%(reconstructed)d/%(total)d (%(percentage).2f%%) partitions reconstructed"
+" in %(time).2fs (%(rate).2f/sec, %(remaining)s remaining)"
 msgstr ""
 
-#: swift/obj/mem_server.py:93
-#, python-format
-msgid "ERROR container update failed with %(ip)s:%(port)s/%(dev)s"
-msgstr ""
-
-#: swift/obj/replicator.py:138
-#, python-format
-msgid "Killing long-running rsync: %s"
-msgstr ""
-
-#: swift/obj/replicator.py:152
-#, python-format
-msgid "Bad rsync return code: %(ret)d <- %(args)s"
-msgstr ""
-
-#: swift/obj/replicator.py:159 swift/obj/replicator.py:163
-#, python-format
-msgid "Successful rsync of %(src)s at %(dst)s (%(time).03f)"
-msgstr ""
-
-#: swift/obj/replicator.py:278
-#, python-format
-msgid "Removing %s objects"
-msgstr ""
-
-#: swift/obj/replicator.py:286
-msgid "Error syncing handoff partition"
-msgstr ""
-
-#: swift/obj/replicator.py:292
-#, python-format
-msgid "Removing partition: %s"
-msgstr ""
-
-#: swift/obj/replicator.py:347
-#, python-format
-msgid "%(ip)s/%(device)s responded as unmounted"
-msgstr ""
-
-#: swift/obj/replicator.py:352
-#, python-format
-msgid "Invalid response %(resp)s from %(ip)s"
-msgstr ""
-
-#: swift/obj/replicator.py:387
-#, python-format
-msgid "Error syncing with node: %s"
-msgstr ""
-
-#: swift/obj/replicator.py:391
-msgid "Error syncing partition"
-msgstr ""
-
-#: swift/obj/replicator.py:404
-#, python-format
-msgid ""
-"%(replicated)d/%(total)d (%(percentage).2f%%) partitions replicated in "
-"%(time).2fs (%(rate).2f/sec, %(remaining)s remaining)"
-msgstr ""
-
-#: swift/obj/replicator.py:415
+#: swift/obj/reconstructor.py:337 swift/obj/replicator.py:419
 #, python-format
 msgid ""
 "%(checked)d suffixes checked - %(hashed).2f%% hashed, %(synced).2f%% "
 "synced"
 msgstr ""
 
-#: swift/obj/replicator.py:422
+#: swift/obj/reconstructor.py:344 swift/obj/replicator.py:426
 #, python-format
 msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
 msgstr ""
 
-#: swift/obj/replicator.py:430
+#: swift/obj/reconstructor.py:352
+#, python-format
+msgid "Nothing reconstructed for %s seconds."
+msgstr ""
+
+#: swift/obj/reconstructor.py:381 swift/obj/replicator.py:463
+msgid "Lockup detected.. killing live coros."
+msgstr ""
+
+#: swift/obj/reconstructor.py:442
+#, python-format
+msgid "Trying to sync suffixes with %s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:467
+#, python-format
+msgid "%s responded as unmounted"
+msgstr ""
+
+#: swift/obj/reconstructor.py:849 swift/obj/replicator.py:295
+#, python-format
+msgid "Removing partition: %s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:865
+msgid "Ring change detected. Aborting current reconstruction pass."
+msgstr ""
+
+#: swift/obj/reconstructor.py:884
+msgid "Exception in top-levelreconstruction loop"
+msgstr ""
+
+#: swift/obj/reconstructor.py:894
+msgid "Running object reconstructor in script mode."
+msgstr ""
+
+#: swift/obj/reconstructor.py:903
+#, python-format
+msgid "Object reconstruction complete (once). (%.02f minutes)"
+msgstr ""
+
+#: swift/obj/reconstructor.py:910
+msgid "Starting object reconstructor in daemon mode."
+msgstr ""
+
+#: swift/obj/reconstructor.py:914
+msgid "Starting object reconstruction pass."
+msgstr ""
+
+#: swift/obj/reconstructor.py:919
+#, python-format
+msgid "Object reconstruction complete. (%.02f minutes)"
+msgstr ""
+
+#: swift/obj/replicator.py:139
+#, python-format
+msgid "Killing long-running rsync: %s"
+msgstr ""
+
+#: swift/obj/replicator.py:153
+#, python-format
+msgid "Bad rsync return code: %(ret)d <- %(args)s"
+msgstr ""
+
+#: swift/obj/replicator.py:160 swift/obj/replicator.py:164
+#, python-format
+msgid "Successful rsync of %(src)s at %(dst)s (%(time).03f)"
+msgstr ""
+
+#: swift/obj/replicator.py:281
+#, python-format
+msgid "Removing %s objects"
+msgstr ""
+
+#: swift/obj/replicator.py:289
+msgid "Error syncing handoff partition"
+msgstr ""
+
+#: swift/obj/replicator.py:351
+#, python-format
+msgid "%(ip)s/%(device)s responded as unmounted"
+msgstr ""
+
+#: swift/obj/replicator.py:356
+#, python-format
+msgid "Invalid response %(resp)s from %(ip)s"
+msgstr ""
+
+#: swift/obj/replicator.py:391
+#, python-format
+msgid "Error syncing with node: %s"
+msgstr ""
+
+#: swift/obj/replicator.py:395
+msgid "Error syncing partition"
+msgstr ""
+
+#: swift/obj/replicator.py:408
+#, python-format
+msgid ""
+"%(replicated)d/%(total)d (%(percentage).2f%%) partitions replicated in "
+"%(time).2fs (%(rate).2f/sec, %(remaining)s remaining)"
+msgstr ""
+
+#: swift/obj/replicator.py:434
 #, python-format
 msgid "Nothing replicated for %s seconds."
 msgstr ""
 
-#: swift/obj/replicator.py:459
-msgid "Lockup detected.. killing live coros."
-msgstr ""
-
-#: swift/obj/replicator.py:573
+#: swift/obj/replicator.py:578
 msgid "Ring change detected. Aborting current replication pass."
 msgstr ""
 
-#: swift/obj/replicator.py:594
+#: swift/obj/replicator.py:599
 msgid "Exception in top-level replication loop"
 msgstr ""
 
-#: swift/obj/replicator.py:603
+#: swift/obj/replicator.py:608
 msgid "Running object replicator in script mode."
 msgstr ""
 
-#: swift/obj/replicator.py:621
+#: swift/obj/replicator.py:626
 #, python-format
 msgid "Object replication complete (once). (%.02f minutes)"
 msgstr ""
 
-#: swift/obj/replicator.py:628
+#: swift/obj/replicator.py:633
 msgid "Starting object replicator in daemon mode."
 msgstr ""
 
-#: swift/obj/replicator.py:632
+#: swift/obj/replicator.py:637
 msgid "Starting object replication pass."
 msgstr ""
 
-#: swift/obj/replicator.py:637
+#: swift/obj/replicator.py:642
 #, python-format
 msgid "Object replication complete. (%.02f minutes)"
 msgstr ""
 
-#: swift/obj/server.py:202
+#: swift/obj/server.py:231
 #, python-format
 msgid ""
 "ERROR Container update failed (saving for async update later): %(status)d"
 " response from %(ip)s:%(port)s/%(dev)s"
 msgstr ""
 
-#: swift/obj/server.py:209
+#: swift/obj/server.py:238
 #, python-format
 msgid ""
 "ERROR container update failed with %(ip)s:%(port)s/%(dev)s (saving for "
 "async update later)"
 msgstr ""
 
-#: swift/obj/server.py:244
+#: swift/obj/server.py:273
 #, python-format
 msgid ""
 "ERROR Container update failed: different numbers of hosts and devices in "
 "request: \"%s\" vs \"%s\""
 msgstr ""
 
-#: swift/obj/updater.py:62
+#: swift/obj/updater.py:63
 #, python-format
 msgid "ERROR: Unable to access %(path)s: %(error)s"
 msgstr ""
 
-#: swift/obj/updater.py:77
+#: swift/obj/updater.py:78
 msgid "Begin object update sweep"
 msgstr ""
 
-#: swift/obj/updater.py:103
+#: swift/obj/updater.py:104
 #, python-format
 msgid ""
 "Object update sweep of %(device)s completed: %(elapsed).02fs, %(success)s"
 " successes, %(fail)s failures"
 msgstr ""
 
-#: swift/obj/updater.py:112
+#: swift/obj/updater.py:113
 #, python-format
 msgid "Object update sweep completed: %.02fs"
 msgstr ""
 
-#: swift/obj/updater.py:121
+#: swift/obj/updater.py:122
 msgid "Begin object update single threaded sweep"
 msgstr ""
 
-#: swift/obj/updater.py:135
+#: swift/obj/updater.py:136
 #, python-format
 msgid ""
 "Object update single threaded sweep completed: %(elapsed).02fs, "
 "%(success)s successes, %(fail)s failures"
 msgstr ""
 
-#: swift/obj/updater.py:187
+#: swift/obj/updater.py:179
 #, python-format
 msgid "ERROR async pending file with unexpected name %s"
 msgstr ""
 
-#: swift/obj/updater.py:217
+#: swift/obj/updater.py:209
 #, python-format
 msgid "ERROR Pickle problem, quarantining %s"
 msgstr ""
 
-#: swift/obj/updater.py:282
+#: swift/obj/updater.py:274
 #, python-format
 msgid "ERROR with remote server %(ip)s:%(port)s/%(device)s"
 msgstr ""
 
-#: swift/proxy/server.py:380
+#: swift/proxy/server.py:405
 msgid "ERROR Unhandled exception in request"
 msgstr ""
 
-#: swift/proxy/server.py:435
+#: swift/proxy/server.py:460
 #, python-format
 msgid "Node error limited %(ip)s:%(port)s (%(device)s)"
 msgstr ""
 
-#: swift/proxy/server.py:452 swift/proxy/server.py:470
+#: swift/proxy/server.py:477 swift/proxy/server.py:495
 #, python-format
 msgid "%(msg)s %(ip)s:%(port)s/%(device)s"
 msgstr ""
 
-#: swift/proxy/server.py:540
+#: swift/proxy/server.py:571
 #, python-format
 msgid "ERROR with %(type)s server %(ip)s:%(port)s/%(device)s re: %(info)s"
 msgstr ""
 
-#: swift/proxy/controllers/account.py:63
+#: swift/proxy/controllers/account.py:64
 msgid "Account"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:698 swift/proxy/controllers/base.py:731
-#: swift/proxy/controllers/obj.py:192 swift/proxy/controllers/obj.py:319
-#: swift/proxy/controllers/obj.py:366 swift/proxy/controllers/obj.py:382
-#: swift/proxy/controllers/obj.py:593
+#: swift/proxy/controllers/base.py:752 swift/proxy/controllers/base.py:814
+#: swift/proxy/controllers/obj.py:364 swift/proxy/controllers/obj.py:411
+#: swift/proxy/controllers/obj.py:427 swift/proxy/controllers/obj.py:643
+#: swift/proxy/controllers/obj.py:1130 swift/proxy/controllers/obj.py:1591
+#: swift/proxy/controllers/obj.py:1763 swift/proxy/controllers/obj.py:1908
+#: swift/proxy/controllers/obj.py:2093
 msgid "Object"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:699
+#: swift/proxy/controllers/base.py:753
 msgid "Trying to read during GET (retrying)"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:732
+#: swift/proxy/controllers/base.py:815
 msgid "Trying to read during GET"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:736
+#: swift/proxy/controllers/base.py:819
 #, python-format
 msgid "Client did not read from proxy within %ss"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:741
+#: swift/proxy/controllers/base.py:824
 msgid "Client disconnected on read"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:743
+#: swift/proxy/controllers/base.py:826
 msgid "Trying to send to client"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:780 swift/proxy/controllers/base.py:1049
+#: swift/proxy/controllers/base.py:863 swift/proxy/controllers/base.py:1141
 #, python-format
 msgid "Trying to %(method)s %(path)s"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:817 swift/proxy/controllers/base.py:1037
-#: swift/proxy/controllers/obj.py:357 swift/proxy/controllers/obj.py:402
+#: swift/proxy/controllers/base.py:902 swift/proxy/controllers/base.py:1129
+#: swift/proxy/controllers/obj.py:402 swift/proxy/controllers/obj.py:450
+#: swift/proxy/controllers/obj.py:1900 swift/proxy/controllers/obj.py:2138
 msgid "ERROR Insufficient Storage"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:820
+#: swift/proxy/controllers/base.py:905
 #, python-format
 msgid "ERROR %(status)d %(body)s From %(type)s Server"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:1040
+#: swift/proxy/controllers/base.py:1132
 #, python-format
 msgid "ERROR %(status)d Trying to %(method)s %(path)sFrom Container Server"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:1152
+#: swift/proxy/controllers/base.py:1260
 #, python-format
 msgid "%(type)s returning 503 for %(statuses)s"
 msgstr ""
 
-#: swift/proxy/controllers/container.py:97 swift/proxy/controllers/obj.py:118
+#: swift/proxy/controllers/container.py:98 swift/proxy/controllers/obj.py:161
 msgid "Container"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:320
+#: swift/proxy/controllers/obj.py:365 swift/proxy/controllers/obj.py:1592
 #, python-format
 msgid "Trying to write to %s"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:361
+#: swift/proxy/controllers/obj.py:406 swift/proxy/controllers/obj.py:1903
 #, python-format
 msgid "ERROR %(status)d Expect: 100-continue From Object Server"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:367
+#: swift/proxy/controllers/obj.py:412 swift/proxy/controllers/obj.py:1909
 #, python-format
 msgid "Expect: 100-continue on %s"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:383
+#: swift/proxy/controllers/obj.py:428
 #, python-format
 msgid "Trying to get final status of PUT to %s"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:406
+#: swift/proxy/controllers/obj.py:454 swift/proxy/controllers/obj.py:2143
 #, python-format
 msgid "ERROR %(status)d %(body)s From Object Server re: %(path)s"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:663
+#: swift/proxy/controllers/obj.py:716
 #, python-format
 msgid "Object PUT returning 412, %(statuses)r"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:672
+#: swift/proxy/controllers/obj.py:725
 #, python-format
 msgid "Object PUT returning 202 for 409: %(req_timestamp)s <= %(timestamps)r"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:755
+#: swift/proxy/controllers/obj.py:811 swift/proxy/controllers/obj.py:2048
 #, python-format
 msgid "ERROR Client read timeout (%ss)"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:762
+#: swift/proxy/controllers/obj.py:818 swift/proxy/controllers/obj.py:2055
 msgid "ERROR Exception causing client disconnect"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:767
+#: swift/proxy/controllers/obj.py:823 swift/proxy/controllers/obj.py:2060
 msgid "Client disconnected without sending enough data"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:813
+#: swift/proxy/controllers/obj.py:869
 #, python-format
 msgid "Object servers returned %s mismatched etags"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:817
+#: swift/proxy/controllers/obj.py:873 swift/proxy/controllers/obj.py:2218
 msgid "Object PUT"
 msgstr ""
 
+#: swift/proxy/controllers/obj.py:2035
+#, python-format
+msgid "Not enough object servers ack'ed (got %d)"
+msgstr ""
+
+#: swift/proxy/controllers/obj.py:2094
+#, python-format
+msgid "Trying to get %s status of PUT to %s"
+msgstr ""
+
diff --git a/swift/locale/zh_CN/LC_MESSAGES/swift.po b/swift/locale/zh_CN/LC_MESSAGES/swift.po
index b123396e0d..8c239cc188 100644
--- a/swift/locale/zh_CN/LC_MESSAGES/swift.po
+++ b/swift/locale/zh_CN/LC_MESSAGES/swift.po
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version:  Swift\n"
 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-03-24 06:06+0000\n"
-"PO-Revision-Date: 2015-03-24 04:20+0000\n"
+"POT-Creation-Date: 2015-04-20 11:15+0200\n"
+"PO-Revision-Date: 2015-04-15 12:48+0000\n"
 "Last-Translator: openstackjenkins <jenkins@openstack.org>\n"
 "Language-Team: Chinese (China) "
 "(http://www.transifex.com/projects/p/swift/language/zh_CN/)\n"
@@ -65,98 +65,98 @@ msgstr "审计失败%s: %s"
 msgid "ERROR Could not get account info %s"
 msgstr "错误:无法获取账号信息%s"
 
-#: swift/account/reaper.py:133 swift/common/utils.py:2127
-#: swift/obj/diskfile.py:470 swift/obj/updater.py:87 swift/obj/updater.py:130
+#: swift/account/reaper.py:134 swift/common/utils.py:2127
+#: swift/obj/diskfile.py:476 swift/obj/updater.py:88 swift/obj/updater.py:131
 #, python-format
 msgid "Skipping %s as it is not mounted"
 msgstr "挂载失败 跳过%s"
 
-#: swift/account/reaper.py:137
+#: swift/account/reaper.py:138
 msgid "Exception in top-level account reaper loop"
 msgstr "异常出现在top-level账号reaper环"
 
-#: swift/account/reaper.py:140
+#: swift/account/reaper.py:141
 #, python-format
 msgid "Devices pass completed: %.02fs"
 msgstr "设备通过完成: %.02fs"
 
-#: swift/account/reaper.py:237
+#: swift/account/reaper.py:238
 #, python-format
 msgid "Beginning pass on account %s"
 msgstr "账号%s开始通过"
 
-#: swift/account/reaper.py:254
+#: swift/account/reaper.py:255
 #, python-format
 msgid "Exception with containers for account %s"
 msgstr "账号%s内容器出现异常"
 
-#: swift/account/reaper.py:261
+#: swift/account/reaper.py:262
 #, python-format
 msgid "Exception with account %s"
 msgstr "账号%s出现异常"
 
-#: swift/account/reaper.py:262
+#: swift/account/reaper.py:263
 #, python-format
 msgid "Incomplete pass on account %s"
 msgstr "账号%s未完成通过"
 
-#: swift/account/reaper.py:264
+#: swift/account/reaper.py:265
 #, python-format
 msgid ", %s containers deleted"
 msgstr ",删除容器%s"
 
-#: swift/account/reaper.py:266
+#: swift/account/reaper.py:267
 #, python-format
 msgid ", %s objects deleted"
 msgstr ",删除对象%s"
 
-#: swift/account/reaper.py:268
+#: swift/account/reaper.py:269
 #, python-format
 msgid ", %s containers remaining"
 msgstr ",剩余容器%s"
 
-#: swift/account/reaper.py:271
+#: swift/account/reaper.py:272
 #, python-format
 msgid ", %s objects remaining"
 msgstr ",剩余对象%s"
 
-#: swift/account/reaper.py:273
+#: swift/account/reaper.py:274
 #, python-format
 msgid ", %s containers possibly remaining"
 msgstr ",可能剩余容器%s"
 
-#: swift/account/reaper.py:276
+#: swift/account/reaper.py:277
 #, python-format
 msgid ", %s objects possibly remaining"
 msgstr ",可能剩余对象%s"
 
-#: swift/account/reaper.py:279
+#: swift/account/reaper.py:280
 msgid ", return codes: "
 msgstr ",返回代码:"
 
-#: swift/account/reaper.py:283
+#: swift/account/reaper.py:284
 #, python-format
 msgid ", elapsed: %.02fs"
 msgstr ",耗时:%.02fs"
 
-#: swift/account/reaper.py:289
+#: swift/account/reaper.py:290
 #, python-format
 msgid "Account %s has not been reaped since %s"
 msgstr "账号%s自%s起未被reaped"
 
-#: swift/account/reaper.py:348 swift/account/reaper.py:396
-#: swift/account/reaper.py:463 swift/container/updater.py:306
+#: swift/account/reaper.py:349 swift/account/reaper.py:397
+#: swift/account/reaper.py:464 swift/container/updater.py:306
 #, python-format
 msgid "Exception with %(ip)s:%(port)s/%(device)s"
 msgstr "%(ip)s:%(port)s/%(device)s出现异常"
 
-#: swift/account/reaper.py:368
+#: swift/account/reaper.py:369
 #, python-format
 msgid "Exception with objects for container %(container)s for account %(account)s"
 msgstr "账号%(account)s容器%(container)s的对象出现异常"
 
 #: swift/account/server.py:275 swift/container/server.py:582
-#: swift/obj/server.py:730
+#: swift/obj/server.py:910
 #, python-format
 msgid "ERROR __call__ error with %(method)s %(path)s "
 msgstr "%(method)s %(path)s出现错误__call__ error"
@@ -272,19 +272,19 @@ msgstr "尝试复制时发生错误"
 msgid "Unexpected response: %s"
 msgstr "意外响应:%s"
 
-#: swift/common/manager.py:62
+#: swift/common/manager.py:63
 msgid "WARNING: Unable to modify file descriptor limit.  Running as non-root?"
 msgstr "警告:无法修改文件描述限制。是否按非root运行?"
 
-#: swift/common/manager.py:69
+#: swift/common/manager.py:70
 msgid "WARNING: Unable to modify memory limit.  Running as non-root?"
 msgstr "警告:无法修改内存极限,是否按非root运行?"
 
-#: swift/common/manager.py:76
+#: swift/common/manager.py:77
 msgid "WARNING: Unable to modify max process limit.  Running as non-root?"
 msgstr "警告:无法修改最大运行极限,是否按非root运行?"
 
-#: swift/common/manager.py:194
+#: swift/common/manager.py:195
 msgid ""
 "\n"
 "user quit"
@@ -292,72 +292,72 @@ msgstr ""
 "\n"
 "用户退出"
 
-#: swift/common/manager.py:231 swift/common/manager.py:543
+#: swift/common/manager.py:232 swift/common/manager.py:544
 #, python-format
 msgid "No %s running"
 msgstr "无%s账号运行"
 
-#: swift/common/manager.py:244
+#: swift/common/manager.py:245
 #, python-format
 msgid "%s (%s) appears to have stopped"
 msgstr "%s (%s)显示已停止"
 
-#: swift/common/manager.py:254
+#: swift/common/manager.py:255
 #, python-format
 msgid "Waited %s seconds for %s to die; giving up"
 msgstr "等待%s秒直到%s停止;放弃"
 
-#: swift/common/manager.py:437
+#: swift/common/manager.py:438
 #, python-format
 msgid "Unable to locate config %sfor %s"
-msgstr "无法找到配置%s的%s"
+msgstr ""
 
-#: swift/common/manager.py:441
+#: swift/common/manager.py:442
 msgid "Found configs:"
 msgstr "找到配置"
 
-#: swift/common/manager.py:485
+#: swift/common/manager.py:486
 #, python-format
 msgid "Signal %s  pid: %s  signal: %s"
 msgstr "发出信号%s  pid: %s  信号: %s"
 
-#: swift/common/manager.py:492
+#: swift/common/manager.py:493
 #, python-format
 msgid "Removing stale pid file %s"
 msgstr "移除原有pid文件%s"
 
-#: swift/common/manager.py:495
+#: swift/common/manager.py:496
 #, python-format
 msgid "No permission to signal PID %d"
 msgstr "无权限发送信号PID%d"
 
-#: swift/common/manager.py:540
+#: swift/common/manager.py:541
 #, python-format
 msgid "%s #%d not running (%s)"
 msgstr "%s #%d无法运行(%s)"
 
-#: swift/common/manager.py:547 swift/common/manager.py:640
-#: swift/common/manager.py:643
+#: swift/common/manager.py:548 swift/common/manager.py:641
+#: swift/common/manager.py:644
 #, python-format
 msgid "%s running (%s - %s)"
 msgstr "%s运行(%s - %s)"
 
-#: swift/common/manager.py:646
+#: swift/common/manager.py:647
 #, python-format
 msgid "%s already started..."
 msgstr "%s已启动..."
 
-#: swift/common/manager.py:655
+#: swift/common/manager.py:656
 #, python-format
 msgid "Running %s once"
 msgstr "运行%s一次"
 
-#: swift/common/manager.py:657
+#: swift/common/manager.py:658
 #, python-format
 msgid "Starting %s"
 msgstr "启动%s"
 
-#: swift/common/manager.py:664
+#: swift/common/manager.py:665
 #, python-format
 msgid "%s does not exist"
 msgstr "%s不存在"
@@ -377,7 +377,12 @@ msgstr "%(action)s错误 高性能内存对象缓存: %(server)s"
 msgid "Error limiting server %s"
 msgstr "服务器出现错误%s "
 
-#: swift/common/request_helpers.py:387
+#: swift/common/request_helpers.py:102
+#, python-format
+msgid "No policy with index %s"
+msgstr ""
+
+#: swift/common/request_helpers.py:395
 msgid "ERROR: An error occurred while retrieving segments"
 msgstr ""
 
@@ -440,51 +445,51 @@ msgstr "无法从%s读取设置"
 msgid "Unable to find %s config section in %s"
 msgstr "无法在%s中查找到%s设置部分"
 
-#: swift/common/utils.py:2348
+#: swift/common/utils.py:2353
 #, python-format
 msgid "Invalid X-Container-Sync-To format %r"
 msgstr "无效的X-Container-Sync-To格式%r"
 
-#: swift/common/utils.py:2353
+#: swift/common/utils.py:2358
 #, python-format
 msgid "No realm key for %r"
 msgstr "%r权限key不存在"
 
-#: swift/common/utils.py:2357
+#: swift/common/utils.py:2362
 #, python-format
 msgid "No cluster endpoint for %r %r"
 msgstr "%r %r的集群节点不存在"
 
-#: swift/common/utils.py:2366
+#: swift/common/utils.py:2371
 #, python-format
 msgid ""
 "Invalid scheme %r in X-Container-Sync-To, must be \"//\", \"http\", or "
 "\"https\"."
 msgstr "在X-Container-Sync-To中%r是无效的方案,须为\"//\", \"http\", or \"https\"。"
 
-#: swift/common/utils.py:2370
+#: swift/common/utils.py:2375
 msgid "Path required in X-Container-Sync-To"
 msgstr "在X-Container-Sync-To中路径是必须的"
 
-#: swift/common/utils.py:2373
+#: swift/common/utils.py:2378
 msgid "Params, queries, and fragments not allowed in X-Container-Sync-To"
 msgstr "在X-Container-Sync-To中,变量,查询和碎片不被允许"
 
-#: swift/common/utils.py:2378
+#: swift/common/utils.py:2383
 #, python-format
 msgid "Invalid host %r in X-Container-Sync-To"
 msgstr "X-Container-Sync-To中无效主机%r"
 
-#: swift/common/utils.py:2570
+#: swift/common/utils.py:2575
 msgid "Exception dumping recon cache"
 msgstr "执行dump recon的时候出现异常"
 
-#: swift/common/wsgi.py:175
+#: swift/common/wsgi.py:197
 #, python-format
 msgid "Could not bind to %s:%s after trying for %s seconds"
 msgstr "尝试过%s秒后无法捆绑%s:%s"
 
-#: swift/common/wsgi.py:185
+#: swift/common/wsgi.py:207
 msgid ""
 "WARNING: SSL should only be enabled for testing purposes. Use external "
 "SSL termination for a production deployment."
@@ -527,27 +532,27 @@ msgstr ""
 msgid "Warning: Cannot ratelimit without a memcached client"
 msgstr "警告:缺失缓存客户端 无法控制流量 "
 
-#: swift/common/middleware/recon.py:78
+#: swift/common/middleware/recon.py:80
 msgid "Error reading recon cache file"
 msgstr "读取recon cache file时出现错误"
 
-#: swift/common/middleware/recon.py:80
+#: swift/common/middleware/recon.py:82
 msgid "Error parsing recon cache file"
 msgstr "解析recon cache file时出现错误"
 
-#: swift/common/middleware/recon.py:82
+#: swift/common/middleware/recon.py:84
 msgid "Error retrieving recon data"
 msgstr "检索recon data时出现错误"
 
-#: swift/common/middleware/recon.py:151
+#: swift/common/middleware/recon.py:158
 msgid "Error listing devices"
 msgstr "设备列表时出现错误"
 
-#: swift/common/middleware/recon.py:247
+#: swift/common/middleware/recon.py:254
 msgid "Error reading ringfile"
 msgstr "读取ringfile时出现错误"
 
-#: swift/common/middleware/recon.py:261
+#: swift/common/middleware/recon.py:268
 msgid "Error reading swift.conf"
 msgstr "读取swift.conf时出现错误"
 
@@ -654,16 +659,27 @@ msgid ""
 "later)"
 msgstr "错误 账号更新失败 %(ip)s:%(port)s/%(device)s (稍后尝试)"
 
-#: swift/container/sync.py:193
+#: swift/container/sync.py:217
+msgid ""
+"Configuration option internal_client_conf_path not defined. Using default"
+" configuration, See internal-client.conf-sample for options"
+msgstr ""
+
+#: swift/container/sync.py:230
+#, python-format
+msgid "Unable to load internal client from config: %r (%s)"
+msgstr ""
+
+#: swift/container/sync.py:264
 msgid "Begin container sync \"once\" mode"
 msgstr "开始容器同步\"once\"模式"
 
-#: swift/container/sync.py:205
+#: swift/container/sync.py:276
 #, python-format
 msgid "Container sync \"once\" mode completed: %.02fs"
 msgstr "容器同步\"once\"模式完成:%.02fs"
 
-#: swift/container/sync.py:213
+#: swift/container/sync.py:284
 #, python-format
 msgid ""
 "Since %(time)s: %(sync)s synced [%(delete)s deletes, %(put)s puts], "
@@ -672,36 +688,34 @@ msgstr ""
 "自%(time)s起:%(sync)s完成同步 [%(delete)s 删除, %(put)s 上传], \"\n"
 "\"%(skip)s 跳过, %(fail)s 失败"
 
-#: swift/container/sync.py:266
+#: swift/container/sync.py:337
 #, python-format
 msgid "ERROR %(db_file)s: %(validate_sync_to_err)s"
 msgstr "错误 %(db_file)s: %(validate_sync_to_err)s"
 
-#: swift/container/sync.py:322
+#: swift/container/sync.py:393
 #, python-format
 msgid "ERROR Syncing %s"
 msgstr "同步时发生错误%s"
 
-#: swift/container/sync.py:410
+#: swift/container/sync.py:476
 #, python-format
-msgid ""
-"Unknown exception trying to GET: %(node)r %(account)r %(container)r "
-"%(object)r"
-msgstr "尝试获取时发生未知的异常%(node)r %(account)r %(container)r %(object)r"
+msgid "Unknown exception trying to GET: %(account)r %(container)r %(object)r"
+msgstr ""
 
-#: swift/container/sync.py:444
+#: swift/container/sync.py:510
 #, python-format
 msgid "Unauth %(sync_from)r => %(sync_to)r"
 msgstr "未授权%(sync_from)r => %(sync_to)r"
 
-#: swift/container/sync.py:450
+#: swift/container/sync.py:516
 #, python-format
 msgid ""
 "Not found %(sync_from)r => %(sync_to)r                       - object "
 "%(obj_name)r"
 msgstr "未找到: %(sync_from)r => %(sync_to)r - object %(obj_name)r"
 
-#: swift/container/sync.py:457 swift/container/sync.py:464
+#: swift/container/sync.py:523 swift/container/sync.py:530
 #, python-format
 msgid "ERROR Syncing %(db_file)s %(row)s"
 msgstr "同步错误 %(db_file)s %(row)s"
@@ -711,8 +725,8 @@ msgstr "同步错误 %(db_file)s %(row)s"
 msgid "ERROR:  Failed to get paths to drive partitions: %s"
 msgstr "%s未挂载"
 
-#: swift/container/updater.py:91 swift/obj/replicator.py:484
-#: swift/obj/replicator.py:570
+#: swift/container/updater.py:91 swift/obj/reconstructor.py:788
+#: swift/obj/replicator.py:487 swift/obj/replicator.py:575
 #, python-format
 msgid "%s is not mounted"
 msgstr "%s未挂载"
@@ -834,42 +848,57 @@ msgstr "错误:无法执行审计:%s"
 msgid "ERROR auditing: %s"
 msgstr "审计错误:%s"
 
-#: swift/obj/diskfile.py:318
+#: swift/obj/diskfile.py:323 swift/obj/diskfile.py:2305
 #, python-format
 msgid "Quarantined %(hsh_path)s to %(quar_path)s because it is not a directory"
 msgstr "隔离%(hsh_path)s和%(quar_path)s因为非目录"
 
-#: swift/obj/diskfile.py:409
+#: swift/obj/diskfile.py:414 swift/obj/diskfile.py:2373
 msgid "Error hashing suffix"
 msgstr "执行Hashing后缀时发生错误"
 
-#: swift/obj/diskfile.py:484 swift/obj/updater.py:169
+#: swift/obj/diskfile.py:486 swift/obj/updater.py:162
 #, python-format
-msgid "Directory %s does not map to a valid policy"
-msgstr "目录%s无法映射到一个有效的policy"
+msgid "Directory %r does not map to a valid policy (%s)"
+msgstr ""
 
-#: swift/obj/diskfile.py:678
+#: swift/obj/diskfile.py:737
 #, python-format
 msgid "Quarantined %(object_path)s to %(quar_path)s because it is not a directory"
 msgstr "隔离%(object_path)s和%(quar_path)s因为非目录"
 
-#: swift/obj/diskfile.py:869
+#: swift/obj/diskfile.py:936 swift/obj/diskfile.py:1795
 #, python-format
 msgid "Problem cleaning up %s"
 msgstr "问题清除%s"
 
-#: swift/obj/diskfile.py:1168
+#: swift/obj/diskfile.py:1253
 #, python-format
 msgid "ERROR DiskFile %(data_file)s close failure: %(exc)s : %(stack)s"
 msgstr "磁盘文件错误%(data_file)s关闭失败: %(exc)s : %(stack)s"
 
-#: swift/obj/diskfile.py:1449
+#: swift/obj/diskfile.py:1543
 #, python-format
 msgid ""
 "Client path %(client)s does not match path stored in object metadata "
 "%(meta)s"
 msgstr "客户路径%(client)s与对象元数据中存储的路径%(meta)s不符"
 
+#: swift/obj/diskfile.py:1797
+#, python-format
+msgid "Problem fsyncing durable state file: %s"
+msgstr ""
+
+#: swift/obj/diskfile.py:1802
+#, python-format
+msgid "No space left on device for %s"
+msgstr ""
+
+#: swift/obj/diskfile.py:1806
+#, python-format
+msgid "Problem writing durable state file: %s"
+msgstr ""
+
 #: swift/obj/expirer.py:79
 #, python-format
 msgid "Pass completed in %ds; %d objects expired"
@@ -899,67 +928,138 @@ msgstr "未处理的异常"
 msgid "Exception while deleting object %s %s %s"
 msgstr "执行删除对象时发生异常%s %s %s"
 
-#: swift/obj/mem_server.py:87
+#: swift/obj/reconstructor.py:189 swift/obj/reconstructor.py:472
 #, python-format
-msgid ""
-"ERROR Container update failed: %(status)d response from "
-"%(ip)s:%(port)s/%(dev)s"
-msgstr "错误 容器更新失败:%(status)d 从%(ip)s:%(port)s/%(dev)s得到回应"
-
-#: swift/obj/mem_server.py:93
-#, python-format
-msgid "ERROR container update failed with %(ip)s:%(port)s/%(dev)s"
-msgstr "错误 容器更新失败%(ip)s:%(port)s/%(dev)s"
-
-#: swift/obj/replicator.py:138
-#, python-format
-msgid "Killing long-running rsync: %s"
-msgstr "终止long-running同步: %s"
-
-#: swift/obj/replicator.py:152
-#, python-format
-msgid "Bad rsync return code: %(ret)d <- %(args)s"
-msgstr "Bad rsync返还代码:%(ret)d <- %(args)s"
-
-#: swift/obj/replicator.py:159 swift/obj/replicator.py:163
-#, python-format
-msgid "Successful rsync of %(src)s at %(dst)s (%(time).03f)"
-msgstr "成功的rsync %(src)s at %(dst)s (%(time).03f)"
-
-#: swift/obj/replicator.py:278
-#, python-format
-msgid "Removing %s objects"
+msgid "Invalid response %(resp)s from %(full_path)s"
 msgstr ""
 
-#: swift/obj/replicator.py:286
-msgid "Error syncing handoff partition"
-msgstr "执行同步切换分区时发生错误"
+#: swift/obj/reconstructor.py:195
+#, python-format
+msgid "Trying to GET %(full_path)s"
+msgstr ""
 
-#: swift/obj/replicator.py:292
+#: swift/obj/reconstructor.py:301
+#, python-format
+msgid "Error trying to rebuild %(path)s policy#%(policy)d frag#%(frag_index)s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:324
+#, python-format
+msgid ""
+"%(reconstructed)d/%(total)d (%(percentage).2f%%) partitions reconstructed"
+" in %(time).2fs (%(rate).2f/sec, %(remaining)s remaining)"
+msgstr ""
+
+#: swift/obj/reconstructor.py:337 swift/obj/replicator.py:419
+#, python-format
+msgid ""
+"%(checked)d suffixes checked - %(hashed).2f%% hashed, %(synced).2f%% "
+"synced"
+msgstr "%(checked)d后缀已被检查 %(hashed).2f%% hashed, %(synced).2f%% synced"
+
+#: swift/obj/reconstructor.py:344 swift/obj/replicator.py:426
+#, python-format
+msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
+msgstr "分区时间: max %(max).4fs, min %(min).4fs, med %(med).4fs"
+
+#: swift/obj/reconstructor.py:352
+#, python-format
+msgid "Nothing reconstructed for %s seconds."
+msgstr ""
+
+#: swift/obj/reconstructor.py:381 swift/obj/replicator.py:463
+msgid "Lockup detected.. killing live coros."
+msgstr "检测到lockup。终止正在执行的coros"
+
+#: swift/obj/reconstructor.py:442
+#, python-format
+msgid "Trying to sync suffixes with %s"
+msgstr ""
+
+#: swift/obj/reconstructor.py:467
+#, python-format
+msgid "%s responded as unmounted"
+msgstr ""
+
+#: swift/obj/reconstructor.py:849 swift/obj/replicator.py:295
 #, python-format
 msgid "Removing partition: %s"
 msgstr "移除分区:%s"
 
-#: swift/obj/replicator.py:347
+#: swift/obj/reconstructor.py:865
+msgid "Ring change detected. Aborting current reconstruction pass."
+msgstr ""
+
+#: swift/obj/reconstructor.py:884
+msgid "Exception in top-levelreconstruction loop"
+msgstr ""
+
+#: swift/obj/reconstructor.py:894
+msgid "Running object reconstructor in script mode."
+msgstr ""
+
+#: swift/obj/reconstructor.py:903
+#, python-format
+msgid "Object reconstruction complete (once). (%.02f minutes)"
+msgstr ""
+
+#: swift/obj/reconstructor.py:910
+msgid "Starting object reconstructor in daemon mode."
+msgstr ""
+
+#: swift/obj/reconstructor.py:914
+msgid "Starting object reconstruction pass."
+msgstr ""
+
+#: swift/obj/reconstructor.py:919
+#, python-format
+msgid "Object reconstruction complete. (%.02f minutes)"
+msgstr ""
+
+#: swift/obj/replicator.py:139
+#, python-format
+msgid "Killing long-running rsync: %s"
+msgstr "终止long-running同步: %s"
+
+#: swift/obj/replicator.py:153
+#, python-format
+msgid "Bad rsync return code: %(ret)d <- %(args)s"
+msgstr "Bad rsync返还代码:%(ret)d <- %(args)s"
+
+#: swift/obj/replicator.py:160 swift/obj/replicator.py:164
+#, python-format
+msgid "Successful rsync of %(src)s at %(dst)s (%(time).03f)"
+msgstr "成功的rsync %(src)s at %(dst)s (%(time).03f)"
+
+#: swift/obj/replicator.py:281
+#, python-format
+msgid "Removing %s objects"
+msgstr ""
+
+#: swift/obj/replicator.py:289
+msgid "Error syncing handoff partition"
+msgstr "执行同步切换分区时发生错误"
+
+#: swift/obj/replicator.py:351
 #, python-format
 msgid "%(ip)s/%(device)s responded as unmounted"
 msgstr "%(ip)s/%(device)s的回应为未挂载"
 
-#: swift/obj/replicator.py:352
+#: swift/obj/replicator.py:356
 #, python-format
 msgid "Invalid response %(resp)s from %(ip)s"
 msgstr "无效的回应%(resp)s来自%(ip)s"
 
-#: swift/obj/replicator.py:387
+#: swift/obj/replicator.py:391
 #, python-format
 msgid "Error syncing with node: %s"
 msgstr "执行同步时节点%s发生错误"
 
-#: swift/obj/replicator.py:391
+#: swift/obj/replicator.py:395
 msgid "Error syncing partition"
 msgstr "执行同步分区时发生错误"
 
-#: swift/obj/replicator.py:404
+#: swift/obj/replicator.py:408
 #, python-format
 msgid ""
 "%(replicated)d/%(total)d (%(percentage).2f%%) partitions replicated in "
@@ -968,259 +1068,256 @@ msgstr ""
 "%(replicated)d/%(total)d (%(percentage).2f%%) 分区被复制 持续时间为 \"\n"
 "\"%(time).2fs (%(rate).2f/sec, %(remaining)s remaining)"
 
-#: swift/obj/replicator.py:415
-#, python-format
-msgid ""
-"%(checked)d suffixes checked - %(hashed).2f%% hashed, %(synced).2f%% "
-"synced"
-msgstr "%(checked)d后缀已被检查 %(hashed).2f%% hashed, %(synced).2f%% synced"
-
-#: swift/obj/replicator.py:422
-#, python-format
-msgid "Partition times: max %(max).4fs, min %(min).4fs, med %(med).4fs"
-msgstr "分区时间: max %(max).4fs, min %(min).4fs, med %(med).4fs"
-
-#: swift/obj/replicator.py:430
+#: swift/obj/replicator.py:434
 #, python-format
 msgid "Nothing replicated for %s seconds."
 msgstr "%s秒无复制"
 
-#: swift/obj/replicator.py:459
-msgid "Lockup detected.. killing live coros."
-msgstr "检测到lockup。终止正在执行的coros"
-
-#: swift/obj/replicator.py:573
+#: swift/obj/replicator.py:578
 msgid "Ring change detected. Aborting current replication pass."
 msgstr "Ring改变被检测到。退出现有的复制通过"
 
-#: swift/obj/replicator.py:594
+#: swift/obj/replicator.py:599
 msgid "Exception in top-level replication loop"
 msgstr "top-level复制圈出现异常"
 
-#: swift/obj/replicator.py:603
+#: swift/obj/replicator.py:608
 msgid "Running object replicator in script mode."
 msgstr "在加密模式下执行对象复制"
 
-#: swift/obj/replicator.py:621
+#: swift/obj/replicator.py:626
 #, python-format
 msgid "Object replication complete (once). (%.02f minutes)"
 msgstr "对象复制完成(一次)。(%.02f minutes)"
 
-#: swift/obj/replicator.py:628
+#: swift/obj/replicator.py:633
 msgid "Starting object replicator in daemon mode."
 msgstr "在守护模式下开始对象复制"
 
-#: swift/obj/replicator.py:632
+#: swift/obj/replicator.py:637
 msgid "Starting object replication pass."
 msgstr "开始通过对象复制"
 
-#: swift/obj/replicator.py:637
+#: swift/obj/replicator.py:642
 #, python-format
 msgid "Object replication complete. (%.02f minutes)"
 msgstr "对象复制完成。(%.02f minutes)"
 
-#: swift/obj/server.py:202
+#: swift/obj/server.py:231
 #, python-format
 msgid ""
 "ERROR Container update failed (saving for async update later): %(status)d"
 " response from %(ip)s:%(port)s/%(dev)s"
 msgstr "错误 容器更新失败(正在保存 稍后同步更新):%(status)d回应来自%(ip)s:%(port)s/%(dev)s"
 
-#: swift/obj/server.py:209
+#: swift/obj/server.py:238
 #, python-format
 msgid ""
 "ERROR container update failed with %(ip)s:%(port)s/%(dev)s (saving for "
 "async update later)"
 msgstr "错误 容器更新失败%(ip)s:%(port)s/%(dev)s(正在保存 稍后同步更新)"
 
-#: swift/obj/server.py:244
+#: swift/obj/server.py:273
 #, python-format
 msgid ""
 "ERROR Container update failed: different numbers of hosts and devices in "
 "request: \"%s\" vs \"%s\""
 msgstr "错误 容器更新失败:主机数量和设备数量不符合请求: \"%s\" vs \"%s\""
 
-#: swift/obj/updater.py:62
+#: swift/obj/updater.py:63
 #, python-format
 msgid "ERROR: Unable to access %(path)s: %(error)s"
 msgstr ""
 
-#: swift/obj/updater.py:77
+#: swift/obj/updater.py:78
 msgid "Begin object update sweep"
 msgstr "开始对象更新扫除"
 
-#: swift/obj/updater.py:103
+#: swift/obj/updater.py:104
 #, python-format
 msgid ""
 "Object update sweep of %(device)s completed: %(elapsed).02fs, %(success)s"
 " successes, %(fail)s failures"
 msgstr "%(device)s对象更新扫除完成:%(elapsed).02fs, %(success)s成功, %(fail)s失败"
 
-#: swift/obj/updater.py:112
+#: swift/obj/updater.py:113
 #, python-format
 msgid "Object update sweep completed: %.02fs"
 msgstr "对象更新扫除完成:%.02fs"
 
-#: swift/obj/updater.py:121
+#: swift/obj/updater.py:122
 msgid "Begin object update single threaded sweep"
 msgstr "开始对象更新单线程扫除"
 
-#: swift/obj/updater.py:135
+#: swift/obj/updater.py:136
 #, python-format
 msgid ""
 "Object update single threaded sweep completed: %(elapsed).02fs, "
 "%(success)s successes, %(fail)s failures"
 msgstr "对象更新单线程扫除完成:%(elapsed).02fs,%(success)s 成功, %(fail)s 失败"
 
-#: swift/obj/updater.py:187
+#: swift/obj/updater.py:179
 #, python-format
 msgid "ERROR async pending file with unexpected name %s"
 msgstr "执行同步等待文件 文件名不可知%s"
 
-#: swift/obj/updater.py:217
+#: swift/obj/updater.py:209
 #, python-format
 msgid "ERROR Pickle problem, quarantining %s"
 msgstr "错误 Pickle问题 隔离%s"
 
-#: swift/obj/updater.py:282
+#: swift/obj/updater.py:274
 #, python-format
 msgid "ERROR with remote server %(ip)s:%(port)s/%(device)s"
 msgstr "远程服务器发生错误 %(ip)s:%(port)s/%(device)s"
 
-#: swift/proxy/server.py:380
+#: swift/proxy/server.py:405
 msgid "ERROR Unhandled exception in request"
 msgstr "错误 未处理的异常发出请求"
 
-#: swift/proxy/server.py:435
+#: swift/proxy/server.py:460
 #, python-format
 msgid "Node error limited %(ip)s:%(port)s (%(device)s)"
 msgstr "节点错误极限 %(ip)s:%(port)s (%(device)s)"
 
-#: swift/proxy/server.py:452 swift/proxy/server.py:470
+#: swift/proxy/server.py:477 swift/proxy/server.py:495
 #, python-format
 msgid "%(msg)s %(ip)s:%(port)s/%(device)s"
 msgstr "%(msg)s %(ip)s:%(port)s/%(device)s"
 
-#: swift/proxy/server.py:540
+#: swift/proxy/server.py:571
 #, python-format
 msgid "ERROR with %(type)s server %(ip)s:%(port)s/%(device)s re: %(info)s"
 msgstr "%(type)s服务器发生错误 %(ip)s:%(port)s/%(device)s re: %(info)s"
 
-#: swift/proxy/controllers/account.py:63
+#: swift/proxy/controllers/account.py:64
 msgid "Account"
 msgstr "账号"
 
-#: swift/proxy/controllers/base.py:698 swift/proxy/controllers/base.py:731
-#: swift/proxy/controllers/obj.py:192 swift/proxy/controllers/obj.py:319
-#: swift/proxy/controllers/obj.py:366 swift/proxy/controllers/obj.py:382
-#: swift/proxy/controllers/obj.py:593
+#: swift/proxy/controllers/base.py:752 swift/proxy/controllers/base.py:814
+#: swift/proxy/controllers/obj.py:364 swift/proxy/controllers/obj.py:411
+#: swift/proxy/controllers/obj.py:427 swift/proxy/controllers/obj.py:643
+#: swift/proxy/controllers/obj.py:1130 swift/proxy/controllers/obj.py:1591
+#: swift/proxy/controllers/obj.py:1763 swift/proxy/controllers/obj.py:1908
+#: swift/proxy/controllers/obj.py:2093
 msgid "Object"
 msgstr "对象"
 
-#: swift/proxy/controllers/base.py:699
+#: swift/proxy/controllers/base.py:753
 msgid "Trying to read during GET (retrying)"
 msgstr "执行GET时尝试读取(重新尝试)"
 
-#: swift/proxy/controllers/base.py:732
+#: swift/proxy/controllers/base.py:815
 msgid "Trying to read during GET"
 msgstr "执行GET时尝试读取"
 
-#: swift/proxy/controllers/base.py:736
+#: swift/proxy/controllers/base.py:819
 #, python-format
 msgid "Client did not read from proxy within %ss"
 msgstr "客户尚未从代理处读取%ss"
 
-#: swift/proxy/controllers/base.py:741
+#: swift/proxy/controllers/base.py:824
 msgid "Client disconnected on read"
 msgstr "客户读取时中断"
 
-#: swift/proxy/controllers/base.py:743
+#: swift/proxy/controllers/base.py:826
 msgid "Trying to send to client"
 msgstr "尝试发送到客户端"
 
-#: swift/proxy/controllers/base.py:780 swift/proxy/controllers/base.py:1049
+#: swift/proxy/controllers/base.py:863 swift/proxy/controllers/base.py:1141
 #, python-format
 msgid "Trying to %(method)s %(path)s"
 msgstr "尝试执行%(method)s %(path)s"
 
-#: swift/proxy/controllers/base.py:817 swift/proxy/controllers/base.py:1037
-#: swift/proxy/controllers/obj.py:357 swift/proxy/controllers/obj.py:402
+#: swift/proxy/controllers/base.py:902 swift/proxy/controllers/base.py:1129
+#: swift/proxy/controllers/obj.py:402 swift/proxy/controllers/obj.py:450
+#: swift/proxy/controllers/obj.py:1900 swift/proxy/controllers/obj.py:2138
 msgid "ERROR Insufficient Storage"
 msgstr "错误 存储空间不足"
 
-#: swift/proxy/controllers/base.py:820
+#: swift/proxy/controllers/base.py:905
 #, python-format
 msgid "ERROR %(status)d %(body)s From %(type)s Server"
 msgstr "错误 %(status)d %(body)s 来自 %(type)s 服务器"
 
-#: swift/proxy/controllers/base.py:1040
+#: swift/proxy/controllers/base.py:1132
 #, python-format
 msgid "ERROR %(status)d Trying to %(method)s %(path)sFrom Container Server"
 msgstr ""
 
-#: swift/proxy/controllers/base.py:1152
+#: swift/proxy/controllers/base.py:1260
 #, python-format
 msgid "%(type)s returning 503 for %(statuses)s"
 msgstr "%(type)s 返回 503 在 %(statuses)s"
 
-#: swift/proxy/controllers/container.py:97 swift/proxy/controllers/obj.py:118
+#: swift/proxy/controllers/container.py:98 swift/proxy/controllers/obj.py:161
 msgid "Container"
 msgstr "容器"
 
-#: swift/proxy/controllers/obj.py:320
+#: swift/proxy/controllers/obj.py:365 swift/proxy/controllers/obj.py:1592
 #, python-format
 msgid "Trying to write to %s"
 msgstr "尝试执行书写%s"
 
-#: swift/proxy/controllers/obj.py:361
+#: swift/proxy/controllers/obj.py:406 swift/proxy/controllers/obj.py:1903
 #, python-format
 msgid "ERROR %(status)d Expect: 100-continue From Object Server"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:367
+#: swift/proxy/controllers/obj.py:412 swift/proxy/controllers/obj.py:1909
 #, python-format
 msgid "Expect: 100-continue on %s"
 msgstr "已知:100-continue on %s"
 
-#: swift/proxy/controllers/obj.py:383
+#: swift/proxy/controllers/obj.py:428
 #, python-format
 msgid "Trying to get final status of PUT to %s"
 msgstr "尝试执行获取最后的PUT状态%s"
 
-#: swift/proxy/controllers/obj.py:406
+#: swift/proxy/controllers/obj.py:454 swift/proxy/controllers/obj.py:2143
 #, python-format
 msgid "ERROR %(status)d %(body)s From Object Server re: %(path)s"
 msgstr "错误 %(status)d %(body)s 来自 对象服务器 re: %(path)s"
 
-#: swift/proxy/controllers/obj.py:663
+#: swift/proxy/controllers/obj.py:716
 #, python-format
 msgid "Object PUT returning 412, %(statuses)r"
 msgstr "对象PUT返还 412,%(statuses)r "
 
-#: swift/proxy/controllers/obj.py:672
+#: swift/proxy/controllers/obj.py:725
 #, python-format
 msgid "Object PUT returning 202 for 409: %(req_timestamp)s <= %(timestamps)r"
 msgstr ""
 
-#: swift/proxy/controllers/obj.py:755
+#: swift/proxy/controllers/obj.py:811 swift/proxy/controllers/obj.py:2048
 #, python-format
 msgid "ERROR Client read timeout (%ss)"
 msgstr "错误 客户读取超时(%ss)"
 
-#: swift/proxy/controllers/obj.py:762
+#: swift/proxy/controllers/obj.py:818 swift/proxy/controllers/obj.py:2055
 msgid "ERROR Exception causing client disconnect"
 msgstr "错误 异常导致客户端中断连接"
 
-#: swift/proxy/controllers/obj.py:767
+#: swift/proxy/controllers/obj.py:823 swift/proxy/controllers/obj.py:2060
 msgid "Client disconnected without sending enough data"
 msgstr "客户中断 尚未发送足够"
 
-#: swift/proxy/controllers/obj.py:813
+#: swift/proxy/controllers/obj.py:869
 #, python-format
 msgid "Object servers returned %s mismatched etags"
 msgstr "对象服务器返还%s不匹配etags"
 
-#: swift/proxy/controllers/obj.py:817
+#: swift/proxy/controllers/obj.py:873 swift/proxy/controllers/obj.py:2218
 msgid "Object PUT"
 msgstr "对象上传"
 
+#: swift/proxy/controllers/obj.py:2035
+#, python-format
+msgid "Not enough object servers ack'ed (got %d)"
+msgstr ""
+
+#: swift/proxy/controllers/obj.py:2094
+#, python-format
+msgid "Trying to get %s status of PUT to %s"
+msgstr ""
+