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

[Xen-devel] [PATCH 2/2] oxenstored: perform a 3-way merge of the quota after a transaction



From: Jerome Maloberti <jerome.maloberti@xxxxxxxxxx>

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.

Signed-off-by: Jerome Maloberti <jerome.maloberti@xxxxxxxxxx>
Signed-off-by: Euan Harris <euan.harris@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 ->
-- 
1.7.9.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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