summaryrefslogtreecommitdiff
path: root/swift
diff options
context:
space:
mode:
authorClay Gerrard <clay.gerrard@gmail.com>2014-03-17 16:00:46 -0700
committerClay Gerrard <clay.gerrard@gmail.com>2014-03-17 16:13:43 -0700
commit2e8bc44c9d0586813587a5711f8e857a31393326 (patch)
treea744b2466080dcc904a8c0e622ab657e011a48b5 /swift
parent6cdf784e2f0e3b37fb040d24b57c9ed92166e6c7 (diff)
downloadswift-2e8bc44c9d0586813587a5711f8e857a31393326.tar.gz
Fix race on container recreate
There was a path on container recreate that would sometimes allow db to get reinitialized without updating put_timestamp. Replication would of course fix it up, but that node would think it's database was deleted till then desipite just ok'ing a request with a newer X-Timestamp than the deleted_timestamp on disk. Change-Id: I8b98afb2aac2e433b6ecb5c421ba0d778cef42fa Closes-Bug: #1292784
Diffstat (limited to 'swift')
-rw-r--r--swift/container/server.py26
1 files changed, 15 insertions, 11 deletions
diff --git a/swift/container/server.py b/swift/container/server.py
index 7f6e30ad9..4242465bf 100644
--- a/swift/container/server.py
+++ b/swift/container/server.py
@@ -227,6 +227,20 @@ class ContainerController(object):
return HTTPNoContent(request=req)
return HTTPNotFound()
+ def _update_or_create(self, req, broker, timestamp):
+ if not os.path.exists(broker.db_file):
+ try:
+ broker.initialize(timestamp)
+ except DatabaseAlreadyExists:
+ pass
+ else:
+ return True # created
+ created = broker.is_deleted()
+ broker.update_put_timestamp(timestamp)
+ if broker.is_deleted():
+ raise HTTPConflict(request=req)
+ return created
+
@public
@timing_stats()
def PUT(self, req):
@@ -261,17 +275,7 @@ class ContainerController(object):
req.headers['x-etag'])
return HTTPCreated(request=req)
else: # put container
- if not os.path.exists(broker.db_file):
- try:
- broker.initialize(timestamp)
- created = True
- except DatabaseAlreadyExists:
- created = False
- else:
- created = broker.is_deleted()
- broker.update_put_timestamp(timestamp)
- if broker.is_deleted():
- return HTTPConflict(request=req)
+ created = self._update_or_create(req, broker, timestamp)
metadata = {}
metadata.update(
(key, (value, timestamp))