Permalink
Browse files

xenopsd: switch to holding the VM's power state as Running over a reb…

…oot transient

This makes it easier to delete objects and events reliably.

Signed-off-by: David Scott <dave.scott@eu.citrix.com>
  • Loading branch information...
1 parent ad00f94 commit fecd3bf00a32294831ce60b48c924aeb5772861e David Scott committed Mar 22, 2012
View
@@ -25,7 +25,7 @@ open Xenops_interface
let xenapi_of_xenops_power_state = function
| Some Running -> `Running
- | Some Halted -> `Running (* reboot transient *)
+ | Some Halted -> `Halted
| Some Suspended -> `Suspended
| Some Paused -> `Paused
| None -> `Halted
@@ -330,7 +330,6 @@ module MD = struct
on_crash = on_crash_behaviour vm.API.vM_actions_after_crash;
on_shutdown = on_normal_exit_behaviour vm.API.vM_actions_after_shutdown;
on_reboot = on_normal_exit_behaviour vm.API.vM_actions_after_reboot;
- transient = true;
pci_msitranslate = pci_msitranslate;
pci_power_mgmt = false;
}
@@ -506,6 +505,14 @@ let pull_metadata_from_xenopsd ~__context id =
Client.VM.remove dbg id |> success;
md)
+let delete_metadata_from_xenopsd ~__context id =
+ Mutex.execute metadata_m
+ (fun () ->
+ let dbg = Context.string_of_task __context in
+ info "xenops: VM.remove %s" id;
+ Client.VM.remove dbg id |> success
+ )
+
let update_metadata_in_xenopsd ~__context ~self =
let id = id_of_vm ~__context ~self in
Mutex.execute metadata_m
@@ -656,6 +663,8 @@ let update_vm ~__context id =
Db.VM.set_ha_always_run ~__context ~self ~value:false;
Storage_access.reset ~__context ~vm:self;
end;
+ if power_state = `Halted
+ then delete_metadata_from_xenopsd ~__context id;
(* This will mark VBDs, VIFs as detached and clear resident_on
if the VM has permenantly shutdown. *)
Xapi_vm_lifecycle.force_state_reset ~__context ~self ~value:power_state;
@@ -1027,7 +1036,6 @@ let manage_dom0 dbg =
on_crash = [];
on_shutdown = [];
on_reboot = [];
- transient = false;
pci_msitranslate = true;
pci_power_mgmt = false;
} |> ignore;
View
@@ -169,7 +169,6 @@ let create_vm id =
on_crash = [ Vm.Shutdown ];
on_shutdown = [ Vm.Shutdown ];
on_reboot = [ Vm.Start ];
- transient = false;
pci_msitranslate = true;
pci_power_mgmt = false;
}
View
@@ -261,9 +261,8 @@ let print_vm id =
_vm_pci_power_mgmt, if vm_t.pci_power_mgmt then "1" else "0";
] in
- let transient = [ "# transient", string_of_bool vm_t.transient ] in
String.concat "\n" (List.map (fun (k, v) -> Printf.sprintf "%s=%s" k v)
- (name @ boot @ vcpus @ memory @ vbds @ vifs @ pcis @ global_pci_opts @ transient))
+ (name @ boot @ vcpus @ memory @ vbds @ vifs @ pcis @ global_pci_opts))
let add filename =
@@ -352,7 +351,6 @@ let add filename =
on_crash = [ Vm.Shutdown ];
on_shutdown = [ Vm.Shutdown ];
on_reboot = [ Vm.Start ];
- transient = false;
pci_msitranslate = pci_msitranslate;
pci_power_mgmt = pci_power_mgmt;
} in
@@ -163,7 +163,6 @@ module Vm = struct
on_crash: action list;
on_shutdown: action list;
on_reboot: action list;
- transient: bool;
pci_msitranslate: bool;
pci_power_mgmt: bool;
}
@@ -609,6 +609,17 @@ module WorkerPool = struct
done
end
+(* Keep track of which VMs we're rebooting so we avoid transient glitches
+ where the power_state becomes Halted *)
+let rebooting_vms = ref []
+let rebooting_vms_m = Mutex.create ()
+let rebooting id f =
+ Mutex.execute rebooting_vms_m (fun () -> rebooting_vms := id :: !rebooting_vms);
+ finally f
+ (fun () -> Mutex.execute rebooting_vms_m (fun () -> rebooting_vms := List.filter (fun x -> x <> id) !rebooting_vms))
+let is_rebooting id =
+ Mutex.execute rebooting_vms_m (fun () -> List.mem id !rebooting_vms)
+
let export_metadata id =
let module B = (val get_backend () : S) in
let vm_t = VM_DB.read_exn id in
@@ -688,7 +699,6 @@ let rec atomics_of_operation = function
(PCI_DB.pcis id |> pci_plug_order)
)
| VM_poweroff (id, timeout) ->
- let vm_t = VM_DB.read_exn id in
let reason =
if timeout = None
then Xenops_hooks.reason__hard_shutdown
@@ -698,7 +708,7 @@ let rec atomics_of_operation = function
] @ (atomics_of_operation (VM_shutdown (id, timeout))
) @ [
VM_hook_script(id, Xenops_hooks.VM_post_destroy, reason)
- ] @ (if vm_t.Vm.transient then [ VM_remove id ] else [])
+ ]
| VM_reboot (id, timeout) ->
let reason =
if timeout = None
@@ -937,7 +947,7 @@ let rec perform ?subtask (op: operation) (t: Xenops_task.t) : unit =
VM_DB.signal id
| VM_reboot (id, timeout) ->
debug "VM.reboot %s" id;
- perform_atomics (atomics_of_operation op) t;
+ rebooting id (fun () -> perform_atomics (atomics_of_operation op) t);
VM_DB.signal id
| VM_shutdown (id, timeout) ->
debug "VM.shutdown %s" id;
@@ -1058,8 +1068,7 @@ let rec perform ?subtask (op: operation) (t: Xenops_task.t) : unit =
debug "VM %s rebooted too quickly; inserting delay" id;
[ Atomic (VM_delay (id, 15.)) ]
end else [] in
- let restart = [ VM_shutdown (id, None); VM_start id; Atomic (VM_unpause id) ] in
- delay @ restart
+ delay @ [ VM_reboot (id, None) ]
in
let operations = List.concat (List.map operations_of_action actions) in
List.iter (fun x -> perform x t) operations;
@@ -1337,6 +1346,8 @@ module VM = struct
let module B = (val get_backend () : S) in
let vm_t = VM_DB.read_exn x in
let state = B.VM.get_state vm_t in
+ (* If we're rebooting the VM then keep the power state running *)
+ let state = if is_rebooting x then { state with Vm.power_state = Running } else state in
vm_t, state
let stat _ dbg id =
Debug.with_thread_associated dbg (fun () -> return (stat' id)) ()

0 comments on commit fecd3bf

Please sign in to comment.