From b1a0c1adea3991455459d9fb4823f1c75dabe0c6 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Thu, 3 Nov 2011 11:26:45 -0700 Subject: [PATCH] locker: fix race in locking 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 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/teuthology/locker/api.py b/teuthology/locker/api.py index d5091ffef2..881e718594 100644 --- a/teuthology/locker/api.py +++ b/teuthology/locker/api.py @@ -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()')) -- 2.39.5