From: Jonathan Davies Date: Thu, 23 Mar 2017 14:20:33 +0000 (+0000) Subject: oxenstored: only record operations with side-effects in history X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=235b5d540a1fd863ec2c6b3901df12f55d422b7b;p=xen.git oxenstored: only record operations with side-effects in history There is no need to record "read" operations as they will never cause another transaction to fail. Signed-off-by: Jonathan Davies Reviewed-by: Thomas Sanders Backport 4.6 -> 4.5 by removing reference to XS_RESET_WATCHES. Reported-by: Juergen Gross Signed-off-by: Ian Jackson --- diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml index c38e3ad8b7..2c22767722 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -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