[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 33/33] tcl daemons: Use with-db



Fixes a number of latent bugs where the jobdb refcount might get out
of step.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 sg-execute-flight       |  82 ++++++++++++++++++-------------------
 tcl/JobDB-Executive.tcl | 106 ++++++++++++++++++++++++------------------------
 2 files changed, 93 insertions(+), 95 deletions(-)

diff --git a/sg-execute-flight b/sg-execute-flight
index 14c8cda..7932c29 100755
--- a/sg-execute-flight
+++ b/sg-execute-flight
@@ -28,48 +28,48 @@ proc check {} {
 
     if {$stopping} return
 
-    jobdb::db-open
-
-    set nqueued [jobdb::db-execute-array dummy "
-        SELECT job FROM jobs j
-         WHERE j.flight = $flight
-           AND j.status = 'queued'
-         LIMIT 1
-    "]
-
-    set nrunning [llength $running]
-    log "flight $flight nqueued=$nqueued nrunning=$nrunning"
-
-    if {!$nqueued && !$nrunning} {
-        prequit finished
-        exec ./cs-flight-bless $flight $blessing running 2>@ stderr
-        exit 0
-    }
+    jobdb::with-db {
+
+       set nqueued [jobdb::db-execute-array dummy "
+           SELECT job FROM jobs j
+            WHERE j.flight = $flight
+              AND j.status = 'queued'
+            LIMIT 1
+       "]
+
+       set nrunning [llength $running]
+       log "flight $flight nqueued=$nqueued nrunning=$nrunning"
+
+       if {!$nqueued && !$nrunning} {
+           prequit finished
+           exec ./cs-flight-bless $flight $blessing running 2>@ stderr
+           exit 0
+       }
+
+       jobdb::db-execute-array jobinfo "
+           SELECT * FROM jobs j
+            WHERE j.flight = $flight
+              AND j.status = 'queued'
+              AND 0 = (SELECT count(*) FROM jobs d
+                        WHERE d.flight = $flight
+                          AND ( d.status = 'queued'
+                             OR d.status = 'preparing'
+                             OR d.status = 'running'
+                             OR d.status = 'retriable' )
+                          AND (d.job IN (SELECT val FROM runvars r
+                                        WHERE r.flight = $flight
+                                          AND r.job = j.job
+                                          AND r.name LIKE '%job')
+                           OR (d.flight || '.' || d.job) IN
+                                        (SELECT val FROM runvars r
+                                        WHERE r.flight = $flight
+                                          AND r.job = j.job
+                                          AND r.name LIKE '%job'))
+                      )
+            ORDER BY job
+       " maybe-spawn-job
 
-    jobdb::db-execute-array jobinfo "
-        SELECT * FROM jobs j
-         WHERE j.flight = $flight
-           AND j.status = 'queued'
-           AND 0 = (SELECT count(*) FROM jobs d
-                     WHERE d.flight = $flight
-                       AND ( d.status = 'queued'
-                          OR d.status = 'preparing'
-                          OR d.status = 'running'
-                          OR d.status = 'retriable' )
-                       AND (d.job IN (SELECT val FROM runvars r
-                                     WHERE r.flight = $flight
-                                       AND r.job = j.job
-                                       AND r.name LIKE '%job')
-                        OR (d.flight || '.' || d.job) IN
-                                     (SELECT val FROM runvars r
-                                     WHERE r.flight = $flight
-                                       AND r.job = j.job
-                                       AND r.name LIKE '%job'))
-                   )
-         ORDER BY job
-    " maybe-spawn-job
-
-    jobdb::db-close
+    }
 }
 
 proc prequit {why} {
diff --git a/tcl/JobDB-Executive.tcl b/tcl/JobDB-Executive.tcl
index 07a0438..0f450c1 100644
--- a/tcl/JobDB-Executive.tcl
+++ b/tcl/JobDB-Executive.tcl
@@ -28,36 +28,36 @@ proc logputs {f m} {
 
 proc prepare {job} {
     global flight jobinfo
-    db-open
-    set found 0
-    db-execute-array jobinfo "
-        SELECT job, status, recipe FROM jobs
-                       WHERE   flight = [pg_quote $flight]
-                       AND     job = [pg_quote $job]
-    " {
-       switch -exact -- $jobinfo(status) {
-           queued - preparing - retriable - play { incr found }
-           default {
-               error "job $flight.$job status $jobinfo(status)"
+    with-db {
+       set found 0
+       db-execute-array jobinfo "
+           SELECT job, status, recipe FROM jobs
+                           WHERE       flight = [pg_quote $flight]
+                           AND job = [pg_quote $job]
+       " {
+           switch -exact -- $jobinfo(status) {
+               queued - preparing - retriable - play { incr found }
+               default {
+                   error "job $flight.$job status $jobinfo(status)"
+               }
            }
        }
-    }
-    if {!$found} {
-       error "job $flight.$job not found"
-    }
+       if {!$found} {
+           error "job $flight.$job not found"
+       }
 
-    setstatus preparing
-    db-close
+       setstatus preparing
+    }
 }
 
 proc job-set-status-unlocked {flight job st} {
-    db-open
-    db-execute "
-            UPDATE jobs SET status='$st'
-                WHERE flight=$flight AND job='$job'
-                  AND status<>'aborted' AND status<>'broken'
-    "
-    db-close
+    with-db {
+       db-execute "
+               UPDATE jobs SET status='$st'
+                   WHERE flight=$flight AND job='$job'
+                     AND status<>'aborted' AND status<>'broken'
+       "
+    }
 }
 
 proc job-set-status {flight job st} {
@@ -221,38 +221,36 @@ proc lock-tables {tables} {
 proc spawn-step-begin {flight job ts stepnovar} {
     upvar 1 $stepnovar stepno
 
-    db-open
-
-    db-execute BEGIN
-    db-execute "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"
-    if {[catch {
-        lock-tables flights
-       db-execute-array stepinfo "
-            SELECT max(stepno) AS maxstep FROM steps
-                WHERE flight=[pg_quote $flight] AND job=[pg_quote $job]
-        "
-        set stepno $stepinfo(maxstep)
-       if {[string length $stepno]} {
-           incr stepno
-       } else {
-           set stepno 1
+    with-db {
+       db-execute BEGIN
+       db-execute "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"
+       if {[catch {
+           lock-tables flights
+           db-execute-array stepinfo "
+               SELECT max(stepno) AS maxstep FROM steps
+                   WHERE flight=[pg_quote $flight] AND job=[pg_quote $job]
+           "
+           set stepno $stepinfo(maxstep)
+           if {[string length $stepno]} {
+               incr stepno
+           } else {
+               set stepno 1
+           }
+           db-execute "
+               INSERT INTO steps
+                   VALUES ([pg_quote $flight], [pg_quote $job], $stepno,
+                           [pg_quote $ts], 'running',
+                           'STARTING')
+           "
+           db-execute COMMIT
+       } emsg]} {
+           global errorInfo errorCode
+           set ei $errorInfo
+           set ec $errorCode
+           catch { db-execute ROLLBACK }
+           error $emsg $ei $ec
        }
-       db-execute "
-            INSERT INTO steps
-                VALUES ([pg_quote $flight], [pg_quote $job], $stepno,
-                        [pg_quote $ts], 'running',
-                        'STARTING')
-        "
-       db-execute COMMIT
-    } emsg]} {
-       global errorInfo errorCode
-       set ei $errorInfo
-       set ec $errorCode
-       catch { db-execute ROLLBACK }
-        db-close
-       error $emsg $ei $ec
     }
-    db-close
 }
 
 proc spawn-step-commit {flight job stepno testid} {
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.