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

[Xen-changelog] [xen stable-4.4] oxenstored: perform a 3-way merge of the quota after a transaction



commit 53a6387e03de85e6f06a45e4699e93fa88ab39a6
Author:     Jerome Maloberti <jerome.maloberti@xxxxxxxxxx>
AuthorDate: Fri Mar 24 16:57:40 2017 +0000
Commit:     Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Wed Apr 5 15:26:37 2017 +0100

    oxenstored: perform a 3-way merge of the quota after a transaction
    
    At a beginning of a transaction, the quotas from the global store
    are duplicated and modified by the transaction. If during the
    transaction, an action associated to no transaction is concurrently
    executed, the quotas of the global store are updated, and then the
    updates are lost when the transaction merges.
    
    We fix this problem by keeping another copy of the quota at the
    beginning of the transaction, and performing a 3-way merge between
    the quotas from the transaction and the "original" copy of the quota
    onto the quota of the global store.
    
    Reported-by: Juergen Gross <jgross@xxxxxxxx>
    Signed-off-by: Jerome Maloberti <jerome.maloberti@xxxxxxxxxx>
    Signed-off-by: Euan Harris <euan.harris@xxxxxxxxxx>
    Acked-by: David Scott <dave.scott@xxxxxxxxxx>
---
 tools/ocaml/xenstored/quota.ml       |  5 +++++
 tools/ocaml/xenstored/store.ml       | 13 +++++--------
 tools/ocaml/xenstored/transaction.ml |  4 +++-
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/tools/ocaml/xenstored/quota.ml b/tools/ocaml/xenstored/quota.ml
index c668302..e6953c6 100644
--- a/tools/ocaml/xenstored/quota.ml
+++ b/tools/ocaml/xenstored/quota.ml
@@ -81,3 +81,8 @@ let add_entry quota id =
 
 let add quota diff =
        Hashtbl.iter (fun id nb -> set_entry quota id (get_entry quota id + 
nb)) diff.cur
+
+let merge orig_quota mod_quota dest_quota =
+         Hashtbl.iter (fun id nb -> let diff = nb - (get_entry orig_quota id) 
in
+                               if diff <> 0 then
+                                       set_entry dest_quota id ((get_entry 
dest_quota id) + diff)) mod_quota.cur
diff --git a/tools/ocaml/xenstored/store.ml b/tools/ocaml/xenstored/store.ml
index 3efe515..223ee21 100644
--- a/tools/ocaml/xenstored/store.ml
+++ b/tools/ocaml/xenstored/store.ml
@@ -188,20 +188,17 @@ let rec get_deepest_existing_node node = function
                with Not_found -> node, false
 
 let set_node rnode path nnode =
-       let quota = Quota.create () in
-       if !Quota.activate then Node.recurse (fun node -> Quota.add_entry quota 
(Node.get_owner node)) nnode;
        if path = [] then
-               nnode, quota
+               nnode
        else
                let set_node node name =
                        try
                                let ent = Node.find node name in
-                               if !Quota.activate then Node.recurse (fun node 
-> Quota.del_entry quota (Node.get_owner node)) ent;
                                Node.replace_child node ent nnode
                        with Not_found ->
                                Node.add_child node nnode
                        in
-               apply_modify rnode path set_node, quota
+               apply_modify rnode path set_node
 
 (* read | ls | getperms use this *)
 let rec lookup node path fct =
@@ -375,10 +372,10 @@ let dump_buffer store = dump_store_buf store.root
 
 
 (* modifying functions with quota udpate *)
-let set_node store path node =
-       let root, quota_diff = Path.set_node store.root path node in
+let set_node store path node orig_quota mod_quota =
+       let root = Path.set_node store.root path node in
        store.root <- root;
-       Quota.add store.quota quota_diff
+       Quota.merge orig_quota mod_quota store.quota
 
 let write store perm path value =
        let node, existing = get_deepest_existing_node store path in
diff --git a/tools/ocaml/xenstored/transaction.ml 
b/tools/ocaml/xenstored/transaction.ml
index e59d681..77de4e8 100644
--- a/tools/ocaml/xenstored/transaction.ml
+++ b/tools/ocaml/xenstored/transaction.ml
@@ -74,6 +74,7 @@ type ty = No | Full of (int * Store.Node.t * Store.t)
 type t = {
        ty: ty;
        store: Store.t;
+       quota: Quota.t;
        mutable ops: (Xenbus.Xb.Op.operation * Store.Path.t) list;
        mutable read_lowpath: Store.Path.t option;
        mutable write_lowpath: Store.Path.t option;
@@ -84,6 +85,7 @@ let make id store =
        {
                ty = ty;
                store = if id = none then store else Store.copy store;
+               quota = Quota.copy store.Store.quota;
                ops = [];
                read_lowpath = None;
                write_lowpath = None;
@@ -155,7 +157,7 @@ let commit ~con t =
 
                                        (* it has to be in the store, otherwise 
it means bugs
                                           in the lowpath registration. we 
don't need to handle none. *)
-                                       maybe (fun n -> Store.set_node cstore p 
n) n;
+                                       maybe (fun n -> Store.set_node cstore p 
n t.quota store.Store.quota) n;
                                        Logging.write_coalesce ~tid:(get_id t) 
~con (Store.Path.to_string p);
                                ) t.write_lowpath;
                                maybe (fun p ->
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

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

 


Rackspace

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