]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
oxenstored: allow self-conflicts
authorThomas Sanders <thomas.sanders@citrix.com>
Thu, 23 Mar 2017 19:06:54 +0000 (19:06 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Tue, 28 Mar 2017 12:07:04 +0000 (13:07 +0100)
We already avoid inter-domain conflicts but now allow intra-domain
conflicts.  Although there are no known practical examples of a domain
that might perform operations that conflict with its own transactions,
this is conceivable, so here we avoid changing those semantics
unnecessarily.

When a transaction commit fails with a conflict and we look through
the history of commits to see which connection(s) to blame, ignore
historical commits that were made by the same connection as the
failing commit.

Signed-off-by: Thomas Sanders <thomas.sanders@citrix.com>
Reviewed-by: Jonathan Davies <jonathan.davies@citrix.com>
tools/ocaml/xenstored/history.ml
tools/ocaml/xenstored/process.ml

index e941e2bfb52aadc85ef2424ce455076d366ca5b3..4079588896a04efa0c2ae282e8268e47d306260d 100644 (file)
@@ -60,11 +60,12 @@ let push (x: history_record) =
        | Some d -> if not (Domain.is_free_to_conflict d) then history := x :: !history
 
 (* Find the connections from records since commit-count [since] for which [f record] returns [true] *)
-let filter_connections ~since ~f =
+let filter_connections ~ignore ~since ~f =
        (* The "mem" call is an optimisation, to avoid calling f if we have picked con already. *)
        (* Using a hash table rather than a list is to optimise the "mem" call. *)
        List.fold_left (fun acc hist_rec ->
                if hist_rec.finish_count > since
+               && not (hist_rec.con == ignore)
                && not (Hashtbl.mem acc hist_rec.con)
                && f hist_rec
                then Hashtbl.replace acc hist_rec.con ();
index 0570d82d8cd39f0e0187539def6ae2cac62ac67b..88fea3467a8b3ef6b5d3d68b46702c927cb7c7bf 100644 (file)
@@ -335,7 +335,7 @@ let transaction_replay c t doms cons =
                                        then (punish hist_rec.History.con; true)
                                        else false
                                ) in
-                               let guilty_cons = History.filter_connections ~since:t.Transaction.start_count ~f:judge_and_sentence in
+                               let guilty_cons = History.filter_connections ~ignore:c ~since:t.Transaction.start_count ~f:judge_and_sentence in
                                if Hashtbl.length guilty_cons = 0 then debug "Found no culprit for conflict in %s: must be self or not in history." con;
                                false
                        )