WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-api

[Xen-API] [PATCH 1 of 3] CA-34933: For each host, cache the session used

To: xen-api@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-API] [PATCH 1 of 3] CA-34933: For each host, cache the session used communicating within the pool
From: Thomas Gazagnaire <thomas.gazagnaire@xxxxxxxxxx>
Date: Tue, 8 Dec 2009 14:54:34 +0000
Delivery-date: Tue, 08 Dec 2009 06:58:20 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1260284073@steel>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Thomas Gazagnaire <thomas.gazagnaire@xxxxxxxxxx>
# Date 1260283362 0
# Node ID 2acddc1fa6a2fb77b1534a1089b28e4ba4412520
# Parent  1f49f00797faf725de371513be573e0ca0badb26
CA-34933: For each host, cache the session used communicating within the pool.

Signed-off-by: Thomas Gazagnaire <thomas.gazagnaire@xxxxxxxxxx>

diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/idl/ocaml_backend/context.ml
--- a/ocaml/idl/ocaml_backend/context.ml        Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/idl/ocaml_backend/context.ml        Tue Dec 08 14:42:42 2009 +0000
@@ -45,6 +45,11 @@
   match x.session_id with
     | None -> failwith "Could not find a session_id"
     | Some x -> x
+
+let has_session_id x =
+       match x.session_id with
+       | None -> false
+       | Some _ -> true
 
 let forwarded_task ctx =
   ctx.forwarded_task  
diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/idl/ocaml_backend/context.mli
--- a/ocaml/idl/ocaml_backend/context.mli       Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/idl/ocaml_backend/context.mli       Tue Dec 08 14:42:42 2009 +0000
@@ -48,6 +48,7 @@
 (** [session_of_t __context] returns the session id stored in [__context]. In 
case there is no session id in this
     context, it fails with [Failure "Could not find a session_id"]. *)
 val get_session_id : t -> API.ref_session
+val has_session_id : t -> bool
 
 (** [get_task_id __context] returns the task id stored in [__context]. Such a 
task can be either a task stored in 
     database or a tempory task (also called dummy). *)
diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/xapi/helpers.ml
--- a/ocaml/xapi/helpers.ml     Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/xapi/helpers.ml     Tue Dec 08 14:42:42 2009 +0000
@@ -94,47 +94,43 @@
       (* Slave has to go back to master via network *)
       Xmlrpcclient.do_secure_xml_rpc 
        ~subtask_of
-  ~use_stunnel_cache:true
+       ~use_stunnel_cache:true
     ~version:"1.1" ~host:(Pool_role.get_master_address ())
     ~port:!Xapi_globs.https_port ~path:"/" xml 
     (* No auth needed over unix domain socket *)
 
+let do_internal_login ~__context =
+       let login =
+               if Pool_role.is_master () then
+                       (fun () ->
+                                if Context.has_session_id __context && 
Db.Session.get_pool ~__context ~self:(Context.get_session_id __context) then
+                                        Context.get_session_id __context
+                                else begin
+                                        let rpc = make_rpc ~__context in
+                                        let session_id = 
Client.Client.Session.slave_login rpc (get_localhost ~__context) 
!Xapi_globs.pool_secret in
+                                        debug "local login done";
+                                        session_id
+                                end)
+               else
+                       (fun () ->
+                                let rpc = make_rpc ~__context in
+                                let session_id = 
Client.Client.Session.slave_login rpc (get_localhost ~__context) 
!Xapi_globs.pool_secret in
+                                debug "slave login done";
+                                session_id) in
+       Xapi_globs.get_internal_session login
+
+let with_cached_session ~__context fn =
+       try fn (do_internal_login ~__context)
+       with Api_errors.Server_error (error,_) as e when error = 
Api_errors.session_authentication_failed ->
+               Xapi_globs.reset_internal_session_cache ();
+               debug "remote client call finished with exception %s; cleaning 
the session cache" (Printexc.to_string e);
+               raise e
+
 (** Log into pool master using the client code, call a function
     passing it the rpc function and session id, logout when finished. *)
 let call_api_functions ~__context f =
-  let rpc = make_rpc ~__context in
-  let () = debug "logging into master" in
-  (* If we're the master then our existing session may be a client one without 
'pool' flag set, so
-     we consider making a new one. If we're a slave then our existing session 
(if we have one) must
-     have the 'pool' flag set because it would have been created for us in the 
message forwarding layer
-     in the master, so we just re-use it. [If we haven't got an existing 
session in our context then
-     we always make a new one *)
-  let require_explicit_logout = ref false in
-  let do_master_login () =
-    let session = Client.Client.Session.slave_login rpc (get_localhost 
~__context) !Xapi_globs.pool_secret in
-      require_explicit_logout := true;
-      session 
-  in
-  let session_id =
-      try
-        if Pool_role.is_master() then 
-      begin
-        let session_id = Context.get_session_id __context in
-          if Db.Session.get_pool ~__context ~self:session_id 
-          then session_id
-          else do_master_login ()
-      end 
-      else Context.get_session_id __context
-      with _ -> 
-      do_master_login ()
-  in
-  let () = debug "login done" in
-  finally 
-    (fun () -> f rpc session_id) 
-    (fun () ->
-       debug "remote client call finished; logging out";
-       if !require_explicit_logout 
-      then Client.Client.Session.logout rpc session_id)
+       let rpc = make_rpc ~__context in
+       with_cached_session ~__context (fun session_id ->  f rpc session_id)
 
 let call_emergency_mode_functions hostname f = 
   let rpc xml = Xmlrpcclient.do_secure_xml_rpc ~version:"1.0" ~host:hostname
diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/xapi/message_forwarding.ml
--- a/ocaml/xapi/message_forwarding.ml  Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/xapi/message_forwarding.ml  Tue Dec 08 14:42:42 2009 +0000
@@ -191,11 +191,8 @@
     ~port:!Xapi_globs.https_port ~path:"/" xml
 
 let call_slave_with_session remote_rpc_fn __context host (task_opt: 
API.ref_task option) f =
-  let session_id = Xapi_session.login_no_password ~__context ~uname:None ~host 
~pool:true ~is_local_superuser:true ~subject:(Ref.null) ~auth_user_sid:"" 
~rbac_permissions:[] in
   let hostname = Db.Host.get_address ~__context ~self:host in
-  Pervasiveext.finally
-    (fun ()->f session_id (remote_rpc_fn __context hostname task_opt))
-    (fun ()->Server_helpers.exec_with_new_task ~session_id "local logout in 
message forwarder" (fun __context -> Xapi_session.logout ~__context))
+  Helpers.with_cached_session ~__context (fun session_id -> f session_id 
(remote_rpc_fn __context hostname task_opt))
 
 let call_slave_with_local_session remote_rpc_fn __context host (task_opt: 
API.ref_task option) f =
   let hostname = Db.Host.get_address ~__context ~self:host in
diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/xapi/xapi.ml
--- a/ocaml/xapi/xapi.ml        Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/xapi/xapi.ml        Tue Dec 08 14:42:42 2009 +0000
@@ -394,8 +394,7 @@
             debug "Master claims he has no record of us being a slave";
             Xapi_host.set_emergency_mode_error 
Api_errors.host_unknown_to_master [ localhost_uuid ];
             Some Permanent
-        | `ok -> 
-            None
+        | `ok -> None
       )
   with 
   | Api_errors.Server_error(code, params) when code = 
Api_errors.session_authentication_failed ->
diff -r 1f49f00797fa -r 2acddc1fa6a2 ocaml/xapi/xapi_globs.ml
--- a/ocaml/xapi/xapi_globs.ml  Fri Dec 04 16:04:36 2009 +0000
+++ b/ocaml/xapi/xapi_globs.ml  Tue Dec 08 14:42:42 2009 +0000
@@ -15,6 +15,7 @@
 (** A central location for settings related to xapi *)
  
 open Stringext
+open Threadext
 open Printf
 
 (* xapi process returns this code on exit when it wants to be restarted *)
@@ -22,6 +23,19 @@
 
 let pool_secret_path = "/etc/xensource/ptoken"
 let pool_secret = ref ""
+let internal_session : [`session] Ref.t option ref = ref None
+
+let internal_session_mutex = Mutex.create ()
+let get_internal_session login_fn =
+       Mutex.execute internal_session_mutex (fun () ->
+               match !internal_session with
+               | None ->
+                         let session = login_fn () in
+                         internal_session := Some session;
+                         session
+               | Some session -> session)
+let reset_internal_session_cache () =
+       Mutex.execute internal_session_mutex (fun () -> internal_session := 
None)
 
 let localhost_ref : [`host] Ref.t ref = ref Ref.null
 
6 files changed, 52 insertions(+), 40 deletions(-)
ocaml/idl/ocaml_backend/context.ml  |    5 ++
ocaml/idl/ocaml_backend/context.mli |    1 
ocaml/xapi/helpers.ml               |   64 ++++++++++++++++-------------------
ocaml/xapi/message_forwarding.ml    |    5 --
ocaml/xapi/xapi.ml                  |    3 -
ocaml/xapi/xapi_globs.ml            |   14 +++++++


Attachment: xen-api.hg-3.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api
<Prev in Thread] Current Thread [Next in Thread>