Skip to content

Commit

Permalink
Merge pull request #2699 from kc284/master
Browse files Browse the repository at this point in the history
CA-215578: Fixed issue where halted control domains were deleted from…
  • Loading branch information
Jon Ludlam committed Jul 13, 2016
2 parents cfaeac1 + a06e369 commit 23b0d22
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 13 deletions.
1 change: 1 addition & 0 deletions ocaml/test/OMakefile
Expand Up @@ -42,6 +42,7 @@ OCAML_OBJS = \
test_map_check \
test_pool_apply_edition \
test_pool_license \
test_pool_restore_database \
test_platformdata \
test_sm_features \
test_gpu_group \
Expand Down
1 change: 1 addition & 0 deletions ocaml/test/suite.ml
Expand Up @@ -34,6 +34,7 @@ let base_suite =
Test_map_check.test;
Test_pool_apply_edition.test;
Test_pool_license.test;
Test_pool_restore_database.test;
Test_platformdata.test;
Test_sm_features.test;
Test_gpu_group.test;
Expand Down
48 changes: 48 additions & 0 deletions ocaml/test/test_pool_restore_database.ml
@@ -0,0 +1,48 @@
(*
* Copyright (C) 2016 Citrix Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)

open OUnit
open Test_common
open Dbsync_master

let run_test vm =
let (nameLabel, isControlDomain, powerState) = vm in
let __context = Test_common.make_test_database () in
let vm = Test_common.make_vm ~__context ~name_label:nameLabel ()
in
Db.VM.set_is_control_domain ~__context ~self:vm ~value:isControlDomain;
Db.VM.set_power_state ~__context ~self:vm ~value:powerState;
Db.VM.set_resident_on ~__context ~self:vm ~value:Ref.null;

Dbsync_master.reset_vms_running_on_missing_hosts ~__context;

assert_equal ~msg:(Printf.sprintf "The VM %s is not halted" nameLabel)
(Db.VM.get_power_state ~__context ~self:vm) `Halted

let test_cases = [
("vm1", false, `Running);
("vm2", false, `Halted);
("dom1", true, `Running);
("dom2", true, `Halted)
]

let test_reset_vms_on_missing_host () =
List.iter run_test test_cases


let test =
"pool_restore_database" >:::
[
"test_reset_vms_on_missing_host" >:: test_reset_vms_on_missing_host;
]
19 changes: 7 additions & 12 deletions ocaml/xapi/dbsync_master.ml
Expand Up @@ -81,18 +81,13 @@ let refresh_console_urls ~__context =
If these are control domains we destroy them, otherwise we reset them to Halted. *)
let reset_vms_running_on_missing_hosts ~__context =
List.iter (fun vm ->
let vm_r = Db.VM.get_record ~__context ~self:vm in
let valid_resident_on = Db.is_valid_ref __context vm_r.API.vM_resident_on in
if not valid_resident_on then begin
if vm_r.API.vM_is_control_domain then begin
info "Deleting control domain VM uuid '%s' ecause VM.resident_on refers to a Host which is nolonger in the Pool" vm_r.API.vM_uuid;
Db.VM.destroy ~__context ~self:vm
end else if vm_r.API.vM_power_state = `Running then begin
let msg = Printf.sprintf "Resetting VM uuid '%s' to Halted because VM.resident_on refers to a Host which is nolonger in the Pool" vm_r.API.vM_uuid in
info "%s" msg;
Helpers.log_exn_continue msg (fun () -> Xapi_vm_lifecycle.force_state_reset ~__context ~self:vm ~value:`Halted) ()
end
end) (Db.VM.get_all ~__context)
let vm_r = Db.VM.get_record ~__context ~self:vm in
let valid_resident_on = Db.is_valid_ref __context vm_r.API.vM_resident_on in
if (not valid_resident_on) && (vm_r.API.vM_power_state = `Running) then begin
let msg = Printf.sprintf "Resetting VM uuid '%s' to Halted because VM.resident_on refers to a Host which is no longer in the Pool" vm_r.API.vM_uuid in
info "%s" msg;
Helpers.log_exn_continue msg (fun () -> Xapi_vm_lifecycle.force_state_reset ~__context ~self:vm ~value:`Halted) ()
end) (Db.VM.get_all ~__context)

(** Release 'locks' on VMs in the Halted state: ie {VBD,VIF}.{currently_attached,reserved}
Note that the {allowed,current}_operations fields are non-persistent so blanked on *master* startup (not slave)
Expand Down
2 changes: 1 addition & 1 deletion ocaml/xapi/xapi_vm_lifecycle.ml
Expand Up @@ -497,7 +497,7 @@ let force_state_reset_keep_current_operations ~__context ~self ~value:state =
if state = `Halted then begin
(* archive the rrd for this vm *)
let vm_uuid = Db.VM.get_uuid ~__context ~self in
Rrdd.archive_rrd ~vm_uuid ~remote_address:(try Some (Pool_role.get_master_address ()) with _ -> None)
log_and_ignore_exn (fun () -> Rrdd.archive_rrd ~vm_uuid ~remote_address:(try Some (Pool_role.get_master_address ()) with _ -> None))
end;

Db.VM.set_power_state ~__context ~self ~value:state;
Expand Down

0 comments on commit 23b0d22

Please sign in to comment.