Skip to content

Commit

Permalink
Merge pull request #282 from lindig/CP-18289
Browse files Browse the repository at this point in the history
CP-18289 add booleans to VM state: nomigrate, nested_virt
  • Loading branch information
lindig authored Aug 17, 2016
2 parents 6317b6f + 10e4264 commit 50bb4c8
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 2 deletions.
34 changes: 34 additions & 0 deletions lib/platform.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(*
* Copyright (C) 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.
*)


type platformdata = (string * string) list

let is_valid ~key ~platformdata =
(not (List.mem_assoc key platformdata)) ||
(match List.assoc key platformdata |> String.lowercase with
| "true" | "1" | "false" | "0" -> true
| v -> false
)

let is_true ~key ~platformdata ~default =
try
match List.assoc key platformdata |> String.lowercase with
| "true" | "1" -> true
| "false" | "0" -> false
| _ -> default (* Check for validity using is_valid if required *)
with Not_found ->
default


36 changes: 36 additions & 0 deletions lib/platform.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(*
* Copyright (C) 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.
*)

(* This module defines interpretation of boolean platform values. It
* matches the interpretation implemented in XenAPI for these values.
*)

type platformdata = (string * string) list

(** [is_valid key platformdata] returns true if:
* 1. The key is _not_ in platformdata (absence of key is valid) or
* 2. The key is in platformdata, associated with a booleanish value *)
val is_valid: key:string -> platformdata:platformdata -> bool

(** [is_true key platformdata default] returns true, if the platformdata
* contains a value for key that is "true" or "1". It returns false, if
* a value "0" or "false" exists. If the key doesn't exist or contains
* none of the values above, [default] is returned.
*)
val is_true:
key:string ->
platformdata:platformdata ->
default:bool ->
bool

2 changes: 2 additions & 0 deletions lib/xenops_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ let halted_vm = {
last_start_time = 0.;
shadow_multiplier_target = 1.;
hvm = false;
nomigrate=false;
nested_virt=false;
}

let unplugged_pci = {
Expand Down
41 changes: 40 additions & 1 deletion xc/xenops_server_xen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,25 @@ module VmExtra = struct
build_info: Domain.build_info option;
ty: Vm.builder_info option;
last_start_time: float;
nomigrate: bool; (* platform:nomigrate at boot time *)
nested_virt: bool (* platform:nested_virt at boot time *)
} with rpc

let default_persistent_t =
{ build_info = None
; ty = None
; last_start_time = 0.0
; nomigrate = false
; nested_virt = false
}

(* override rpc code generated for persistent_t. It is important that
* this code is before the declaration of type t because otherwise
* the rpc code for type t won't use it. *)
let persistent_t_of_rpc rpc =
Rpc.struct_extend rpc (rpc_of_persistent_t default_persistent_t)
|> persistent_t_of_rpc

type non_persistent_t = {
create_info: Domain.create_info;
vcpu_max: int;
Expand Down Expand Up @@ -759,6 +776,8 @@ module VM = struct
(* Earlier than the PV drivers update time, therefore
any cached PV driver information will be kept. *)
last_start_time = 0.;
nomigrate = false;
nested_virt = false
} |> VmExtra.rpc_of_persistent_t |> Jsonrpc.to_string

let mkints n =
Expand Down Expand Up @@ -855,7 +874,19 @@ module VM = struct
x.VmExtra.persistent, x.VmExtra.non_persistent
| None -> begin
debug "VM = %s; has no stored domain-level configuration, regenerating" vm.Vm.id;
let persistent = { VmExtra.build_info = None; ty = None; last_start_time = Unix.gettimeofday ()} in
let persistent =
{ VmExtra.build_info = None
; ty = None
; last_start_time = Unix.gettimeofday ()
; nomigrate = Platform.is_true
~key:"nomigrate"
~platformdata:vm.Xenops_interface.Vm.platformdata
~default:false
; nested_virt=Platform.is_true
~key:"nested_virt"
~platformdata:vm.Xenops_interface.Vm.platformdata
~default:false
} in
let non_persistent = generate_non_persistent_state xc xs vm in
persistent, non_persistent
end in
Expand Down Expand Up @@ -1638,6 +1669,14 @@ module VM = struct
end;
hvm = di.Xenctrl.hvm_guest;
shadow_multiplier_target = shadow_multiplier_target;
nomigrate = begin match vme with
| None -> false
| Some x -> x.VmExtra.persistent.VmExtra.nomigrate
end;
nested_virt = begin match vme with
| None -> false
| Some x -> x.VmExtra.persistent.VmExtra.nested_virt
end
}
)

Expand Down
39 changes: 38 additions & 1 deletion xl/xenops_server_xenlight.ml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ module VmExtra = struct
build_info: Domain.build_info option;
ty: Vm.builder_info option;
last_start_time: float;
nomigrate: bool; (* platform:nomigrate at boot time *)
nested_virt: bool (* platform:nested_virt at boot time *)
} with rpc

type non_persistent_t = {
Expand All @@ -256,6 +258,19 @@ module VmExtra = struct
persistent: persistent_t;
non_persistent: non_persistent_t;
} with rpc

let default_persistent_t =
{ build_info = None
; ty = None
; last_start_time = 0.0
; nomigrate = false
; nested_virt = false
}

(* override rpc code generated for persistent_t *)
let persistent_t_of_rpc rpc =
Rpc.struct_extend rpc (rpc_of_persistent_t default_persistent_t)
|> persistent_t_of_rpc
end

module DB = struct
Expand Down Expand Up @@ -1793,6 +1808,8 @@ module VM = struct
(* Earlier than the PV drivers update time, therefore
any cached PV driver information will be kept. *)
last_start_time = 0.;
nomigrate = false;
nested_virt = false
} |> VmExtra.rpc_of_persistent_t |> Jsonrpc.to_string

(* Could use fold_left to get the same value, but that would necessarily go through the whole list everytime, instead of the first n items, only. *)
Expand Down Expand Up @@ -2087,7 +2104,19 @@ module VM = struct
x.VmExtra.persistent, x.VmExtra.non_persistent
| None -> begin
debug "VM = %s; has no stored domain-level configuration, regenerating" vm.Vm.id;
let persistent = { VmExtra.build_info = None; ty = None; last_start_time = Unix.gettimeofday () } in
let persistent =
{ VmExtra.build_info = None
; ty = None
; last_start_time = Unix.gettimeofday ()
; nomigrate = Platform.is_true
~key:"nomigrate"
~platformdata:vm.Xenops_interface.Vm.platformdata
~default:false
; nested_virt=Platform.is_true
~key:"nested_virt"
~platformdata:vm.Xenops_interface.Vm.platformdata
~default:false
} in
let non_persistent = generate_non_persistent_state xs vm in
persistent, non_persistent
end in
Expand Down Expand Up @@ -2682,6 +2711,14 @@ module VM = struct
end;
shadow_multiplier_target = shadow_multiplier_target;
hvm;
nomigrate = begin match vme with
| None -> false
| Some x -> x.VmExtra.persistent.VmExtra.nomigrate
end;
nested_virt = begin match vme with
| None -> false
| Some x -> x.VmExtra.persistent.VmExtra.nested_virt
end
}
)

Expand Down

0 comments on commit 50bb4c8

Please sign in to comment.