]> xenbits.xensource.com Git - xen.git/commitdiff
oxenstored: only record operations with side-effects in history
authorJonathan Davies <jonathan.davies@citrix.com>
Thu, 23 Mar 2017 14:20:33 +0000 (14:20 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 5 Apr 2017 14:22:33 +0000 (15:22 +0100)
There is no need to record "read" operations as they will never cause another
transaction to fail.

Signed-off-by: Jonathan Davies <jonathan.davies@citrix.com>
Reviewed-by: Thomas Sanders <thomas.sanders@citrix.com>
Backport 4.6 -> 4.5 by removing reference to XS_RESET_WATCHES.

Reported-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/ocaml/xenstored/process.ml

index c38e3ad8b72257bc1c77fd0e69f0d95b232cbeaf..2c2276772243dbc94fc296a720fbf7e289e49b0c 100644 (file)
@@ -442,6 +442,36 @@ let function_of_type ty =
        | Xenbus.Xb.Op.Invalid           -> reply_ack do_error
        | _                              -> function_of_type_simple_op ty
 
+(**
+ * Determines which individual (non-transactional) operations we want to retain.
+ * We only want to retain operations that have side-effects in the store since
+ * these can be the cause of transactions failing.
+ *)
+let retain_op_in_history ty =
+       match ty with
+       | Xenbus.Xb.Op.Write
+       | Xenbus.Xb.Op.Mkdir
+       | Xenbus.Xb.Op.Rm
+       | Xenbus.Xb.Op.Setperms          -> true
+       | Xenbus.Xb.Op.Debug
+       | Xenbus.Xb.Op.Directory
+       | Xenbus.Xb.Op.Read
+       | Xenbus.Xb.Op.Getperms
+       | Xenbus.Xb.Op.Watch
+       | Xenbus.Xb.Op.Unwatch
+       | Xenbus.Xb.Op.Transaction_start
+       | Xenbus.Xb.Op.Transaction_end
+       | Xenbus.Xb.Op.Introduce
+       | Xenbus.Xb.Op.Release
+       | Xenbus.Xb.Op.Getdomainpath
+       | Xenbus.Xb.Op.Watchevent
+       | Xenbus.Xb.Op.Error
+       | Xenbus.Xb.Op.Isintroduced
+       | Xenbus.Xb.Op.Resume
+       | Xenbus.Xb.Op.Set_target
+       | Xenbus.Xb.Op.Restrict
+       | Xenbus.Xb.Op.Invalid           -> false
+
 (**
  * Nothrow guarantee.
  *)
@@ -458,10 +488,18 @@ let process_packet ~store ~cons ~doms ~con ~req =
                                Connection.get_transaction con tid
                        in
 
-               let before = Store.copy store in
-               let response = input_handle_error ~cons ~doms ~fct ~con ~t ~req in
-               let after = Store.copy store in
-               if tid = Transaction.none then record_commit ~con ~tid ~before ~after;
+               let execute () = input_handle_error ~cons ~doms ~fct ~con ~t ~req in
+
+               let response =
+                       (* Note that transactions are recorded in history separately. *)
+                       if tid = Transaction.none && retain_op_in_history ty then begin
+                               let before = Store.copy store in
+                               let response = execute () in
+                               let after = Store.copy store in
+                               record_commit ~con ~tid ~before ~after;
+                               response
+                       end else execute ()
+               in
 
                let response = try
                        if tid <> Transaction.none then