]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
locker: fix race in locking
authorJosh Durgin <josh.durgin@dreamhost.com>
Thu, 3 Nov 2011 18:26:45 +0000 (11:26 -0700)
committerJosh Durgin <josh.durgin@dreamhost.com>
Thu, 3 Nov 2011 18:29:18 +0000 (11:29 -0700)
The isolation level is lower than I thought. This made it possible for
two clients to think they both locked the same machines, since the
update would still be modifying each row to change the locked_since
time.

teuthology/locker/api.py

index d5091ffef28141a3ff22bb79bdbb4a63b70a4ea5..881e718594c5052b8c3240922b882fc9e6c6d3c6 100644 (file)
@@ -82,18 +82,20 @@ class Lock:
         tries = 0
         while True:
             try:
+                # transaction will be rolled back if an exception is raised
                 with DB.transaction():
                     results = list(DB.select('machine', what='name, sshpubkey',
-                                             where='locked = false and up = true',
+                                             where='locked = false AND up = true',
                                              limit=num))
                     if len(results) < num:
                         raise web.HTTPError(status='503 Service Unavailable')
                     name_keys = {}
                     for row in results:
                         name_keys[row.name] = row.sshpubkey
+                    where_cond = web.db.sqlors('name = ', name_keys.keys()) \
+                        + ' AND locked = false AND up = true'
                     num_locked = DB.update('machine',
-                                           where=web.db.sqlors('name = ',
-                                                               name_keys.keys()),
+                                           where=where_cond,
                                            locked=True,
                                            locked_by=user,
                                            locked_since=web.db.SQLLiteral('NOW()'))