From: Vincent Hanquez Date: Wed, 12 Aug 2009 12:53:33 +0000 (+0100) Subject: add a main monitor thread that control the quit functionality. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=18d9ad10f079a3f6f9355a3bdab241cc964b948e;p=xenclient%2Ftoolstack.git add a main monitor thread that control the quit functionality. also add the skeleton for starting a dbus monitor where to receive RPCs. --- diff --git a/xenvm/vmstate.ml b/xenvm/vmstate.ml index 9af2ca7..1283c2b 100644 --- a/xenvm/vmstate.ml +++ b/xenvm/vmstate.ml @@ -39,8 +39,19 @@ type locks = { l_start: Mutex.t; } +type monitor_state = { + monitor_use_dbus: bool; + monitor_use_json: bool; + mutable monitor_json_quit: bool; + mutable monitor_dbus_quit: bool; +} + type vm_state = { vm_uuid: string; + vm_monitors: monitor_state; + quit_mutex: Mutex.t; + quit_condition: Condition.t; + mutable quit_requested: bool; mutable vm_config_path: string; mutable vm_arch: Domain.domarch; mutable vm_domid: int; @@ -57,6 +68,15 @@ type vm_state = { let state_init uuid config_path cfg = { vm_uuid = uuid; + vm_monitors = { + monitor_use_dbus = false; + monitor_use_json = true; + monitor_json_quit = false; + monitor_dbus_quit = false; + }; + quit_mutex = Mutex.create (); + quit_condition = Condition.create (); + quit_requested = false; vm_config_path = config_path; vm_arch = if cfg.hvm then Domain.Arch_HVM else Domain.Arch_native; vm_domid = (-1); diff --git a/xenvm/xenvm.ml b/xenvm/xenvm.ml index 1ec82ba..cd4a127 100644 --- a/xenvm/xenvm.ml +++ b/xenvm/xenvm.ml @@ -27,6 +27,13 @@ let thread_create f x = let (_: Thread.t) = Thread.create f x in () +let notify_quit state = + Mutex.lock state.quit_mutex; + state.quit_requested <- true; + Condition.signal state.quit_condition; + Mutex.unlock state.quit_mutex; + () + let string_of_exn exn = match exn with | Hotplug.Device_timeout dev -> @@ -393,7 +400,7 @@ let reread_config state path = let cfg = Config.of_file state.vm_uuid (fun errors -> ()) path in state.vm_next_cfg <- Some cfg -let do_task quit state (task, args) = +let do_task state (task, args) = let optional_arg default f args s = try f args s with Tasks.Argument_not_found _ -> default in @@ -405,7 +412,7 @@ let do_task quit state (task, args) = (*maybe assert_vmstate task_vmstate_required;*) match task with | Tasks.Quit -> - quit := true; Xenvmlib.Ok + notify_quit state; Xenvmlib.Ok | Tasks.Help -> do_help (); | Tasks.Destroy -> with_xcs (fun xc xs -> Vmact.stop_vm xc xs state); Xenvmlib.Ok @@ -500,18 +507,11 @@ let do_task quit state (task, args) = reread_config state path; Xenvmlib.Ok -let monitor_rpc socket state = - let read_config_noexn state path = - try reread_config state path - with exn -> - info "receive exception reading config file ignoring: %s" - (string_of_exn exn) - in +let monitor_rpc_json socket state = let assert_vmstate expected = if expected <> state.vm_lifestate then raise (Vmact.Vm_bad_state (expected, state.vm_lifestate)); in - let quit = ref false in let connections = ref [] in let reply_error con error = @@ -538,7 +538,7 @@ let monitor_rpc socket state = let reply_id = match rpc.Jsonrpc.request_id with Some id -> id | None -> Json.Int 0L in let reply = try - let r = do_task quit state (task, params) in + let r = do_task state (task, params) in match r with | Xenvmlib.Ok -> Jsonrpc.response_make_success reply_id Json.Null | Xenvmlib.Msg msg -> Jsonrpc.response_make_success reply_id (Json.String msg) @@ -614,10 +614,7 @@ let monitor_rpc socket state = ) in - Sys.set_signal Sys.sigint (Sys.Signal_handle (fun i -> quit := true)); - Sys.set_signal Sys.sighup (Sys.Signal_handle (fun i -> read_config_noexn state None)); - - while not !quit + while not state.vm_monitors.monitor_json_quit do let has_work = List.fold_left (fun acc con -> acc || con_has_work con) false !connections in let timeout = if has_work then 0. else 1. in @@ -651,6 +648,9 @@ let monitor_rpc socket state = ) ) +let monitor_rpc_dbus state = + () + (* * Monitor is in charge of 2 things: listen to VM requests, and listen to user queries. * - vm requests are: spontaneous shutdown and reboot @@ -658,7 +658,28 @@ let monitor_rpc socket state = *) let monitor socket state = thread_create monitor_vm state; - monitor_rpc socket state + if state.vm_monitors.monitor_use_json then + thread_create (monitor_rpc_json socket) state; + if state.vm_monitors.monitor_use_dbus then + thread_create monitor_rpc_dbus state; + + let read_config_noexn state path = + try reread_config state path + with exn -> + info "receive exception reading config file ignoring: %s" + (string_of_exn exn) + in + + Sys.set_signal Sys.sigint (Sys.Signal_handle (fun i -> notify_quit state)); + Sys.set_signal Sys.sighup (Sys.Signal_handle (fun i -> read_config_noexn state None)); + + Mutex.lock state.quit_mutex; + while not state.quit_requested do + Condition.wait state.quit_condition state.quit_mutex; + done; + Mutex.unlock state.quit_mutex; + Thread.delay 0.5; (* give time for others threads to finish what they are doing .. *) + exit 0 (********* let do_snapshot .. =