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;
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);
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 ->
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
(*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
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 =
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)
)
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
)
)
+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
*)
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 .. =