diff options
Diffstat (limited to 'system/xen/xsa/xsa206-4.8-0012-oxenstored-allow-self-conflicts.patch')
-rw-r--r-- | system/xen/xsa/xsa206-4.8-0012-oxenstored-allow-self-conflicts.patch | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/system/xen/xsa/xsa206-4.8-0012-oxenstored-allow-self-conflicts.patch b/system/xen/xsa/xsa206-4.8-0012-oxenstored-allow-self-conflicts.patch new file mode 100644 index 0000000000..4a46db4c14 --- /dev/null +++ b/system/xen/xsa/xsa206-4.8-0012-oxenstored-allow-self-conflicts.patch @@ -0,0 +1,58 @@ +From d3a8b4ffde38f01aa7f497d07404478b6f90041c Mon Sep 17 00:00:00 2001 +From: Thomas Sanders <thomas.sanders@citrix.com> +Date: Thu, 23 Mar 2017 19:06:54 +0000 +Subject: [PATCH 12/15] oxenstored: allow self-conflicts + +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. + +Reported-by: Juergen Gross <jgross@suse.com> +Signed-off-by: Thomas Sanders <thomas.sanders@citrix.com> +Reviewed-by: Jonathan Davies <jonathan.davies@citrix.com> +--- + tools/ocaml/xenstored/history.ml | 3 ++- + tools/ocaml/xenstored/process.ml | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/ocaml/xenstored/history.ml b/tools/ocaml/xenstored/history.ml +index e941e2b..4079588 100644 +--- a/tools/ocaml/xenstored/history.ml ++++ b/tools/ocaml/xenstored/history.ml +@@ -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 (); +diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml +index 5e5a1ab..b56e3fc 100644 +--- a/tools/ocaml/xenstored/process.ml ++++ b/tools/ocaml/xenstored/process.ml +@@ -350,7 +350,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 + ) +-- +2.1.4 + |