Skip to content

Commit 58f09ac

Browse files
authored
CP-31566 define xenopsd fast resume operation (#6780)
Define and implement an operation that uses Xen's fast resume to reume a domain. This operation is currently not used but has been tested. It is accessible from the xenopsd CLI ("xenops-cli") for experiments.
2 parents 68a7737 + 88ece89 commit 58f09ac

File tree

10 files changed

+93
-0
lines changed

10 files changed

+93
-0
lines changed

ocaml/xapi-idl/xen/xenops_interface.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,10 @@ module XenopsAPI (R : RPC) = struct
855855
declare "VM.resume" []
856856
(debug_info_p @-> vm_id_p @-> disk_p @-> returning task_id_p err)
857857

858+
let fast_resume =
859+
declare "VM.fast_resume" []
860+
(debug_info_p @-> vm_id_p @-> returning task_id_p err)
861+
858862
let s3suspend =
859863
declare "VM.s3suspend" []
860864
(debug_info_p @-> vm_id_p @-> returning task_id_p err)

ocaml/xenopsd/cli/main.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,25 @@ let resume_cmd =
317317
, Cmd.info "resume" ~sdocs:_common_options ~doc ~man
318318
)
319319

320+
let fast_resume_cmd =
321+
let vm = vm_arg "resumed" in
322+
let doc = "fast-resume a VM" in
323+
let man =
324+
[
325+
`S "DESCRIPTION"
326+
; `P "Fast-resume a VM."
327+
; `P
328+
{|The suspended domain will be resumed
329+
and the VM will be left in a Running state.|}
330+
; `S "ERRORS"
331+
; `P "Something about the current power state."
332+
]
333+
@ help
334+
in
335+
( Term.(ret (const Xn.fast_resume $ common_options_t $ vm))
336+
, Cmd.info "fast-resume" ~sdocs:_common_options ~doc ~man
337+
)
338+
320339
let pause_cmd =
321340
let vm = vm_arg "paused" in
322341
let doc = "pause a VM" in
@@ -491,6 +510,7 @@ let cmds =
491510
; reboot_cmd
492511
; suspend_cmd
493512
; resume_cmd
513+
; fast_resume_cmd
494514
; pause_cmd
495515
; unpause_cmd
496516
; import_cmd

ocaml/xenopsd/cli/xn.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,15 @@ let suspend _copts disk x =
873873

874874
let suspend copts disk x = diagnose_error (need_vm (suspend copts disk) x)
875875

876+
let fast_resume _copts x =
877+
let open Vm in
878+
let vm, _ = find_by_name x in
879+
Client.VM.fast_resume dbg vm.id
880+
|> wait_for_task dbg
881+
|> success_task ignore_task
882+
883+
let fast_resume copts x = diagnose_error (need_vm (fast_resume copts) x)
884+
876885
let resume _copts disk x =
877886
(* We don't currently store where the suspend image is *)
878887
let disk =

ocaml/xenopsd/cli/xn.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ val resume :
4747
-> string option
4848
-> [> `Error of bool * string | `Ok of unit]
4949

50+
val fast_resume :
51+
'a -> string option -> [> `Error of bool * string | `Ok of unit]
52+
5053
val console_connect :
5154
'a -> string option -> [> `Error of bool * string | `Ok of unit]
5255

ocaml/xenopsd/lib/xenops_server.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ type atomic =
164164
(** takes suspend data, plus optionally vGPU state data *)
165165
| VM_restore of (Vm.id * data * data option)
166166
(** takes suspend data, plus optionally vGPU state data *)
167+
| VM_fast_resume of Vm.id
167168
| VM_delay of (Vm.id * float) (** used to suppress fast reboot loops *)
168169
| VM_rename of (Vm.id * Vm.id * rename_when)
169170
| VM_import_metadata of (Vm.id * Metadata.t)
@@ -279,6 +280,8 @@ let rec name_of_atomic = function
279280
"VM_save"
280281
| VM_restore _ ->
281282
"VM_restore"
283+
| VM_fast_resume _ ->
284+
"VM_fast_resume"
282285
| VM_delay _ ->
283286
"VM_delay"
284287
| VM_rename _ ->
@@ -2377,6 +2380,9 @@ let rec perform_atomic ~progress_callback ?result (op : atomic)
23772380
let extras = [] in
23782381
B.VM.restore t progress_callback (VM_DB.read_exn id) vbds vifs data
23792382
vgpu_data extras
2383+
| VM_fast_resume id ->
2384+
debug "VM.fast_resume %s" id ;
2385+
B.VM.resume t (VM_DB.read_exn id)
23802386
| VM_delay (id, t) ->
23812387
debug "VM %s: waiting for %.2f before next VM action" id t ;
23822388
Thread.delay t
@@ -2669,6 +2675,7 @@ and trigger_cleanup_after_failure_atom op t =
26692675
| VM_s3resume id
26702676
| VM_save (id, _, _, _)
26712677
| VM_restore (id, _, _)
2678+
| VM_fast_resume id
26722679
| VM_delay (id, _)
26732680
| VM_softreboot id ->
26742681
immediate_operation dbg id (VM_check_state id)
@@ -3828,6 +3835,8 @@ module VM = struct
38283835

38293836
let resume _ dbg id disk = queue_operation dbg id (VM_resume (id, Disk disk))
38303837

3838+
let fast_resume _ dbg id = queue_operation dbg id (Atomic (VM_fast_resume id))
3839+
38313840
let s3suspend _ dbg id = queue_operation dbg id (Atomic (VM_s3suspend id))
38323841

38333842
let s3resume _ dbg id = queue_operation dbg id (Atomic (VM_s3resume id))
@@ -4409,6 +4418,7 @@ let _ =
44094418
Server.VM.reboot (VM.reboot ()) ;
44104419
Server.VM.suspend (VM.suspend ()) ;
44114420
Server.VM.resume (VM.resume ()) ;
4421+
Server.VM.fast_resume (VM.fast_resume ()) ;
44124422
Server.VM.s3suspend (VM.s3suspend ()) ;
44134423
Server.VM.s3resume (VM.s3resume ()) ;
44144424
Server.VM.export_metadata (VM.export_metadata ()) ;

ocaml/xenopsd/lib/xenops_server_plugin.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ module type S = sig
159159
-> string list
160160
-> unit
161161

162+
val resume : Xenops_task.task_handle -> Vm.t -> unit
163+
162164
val s3suspend : Xenops_task.task_handle -> Vm.t -> unit
163165

164166
val s3resume : Xenops_task.task_handle -> Vm.t -> unit

ocaml/xenopsd/lib/xenops_server_skeleton.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ module VM = struct
9797

9898
let restore _ _ _ _ _ _ _ = unimplemented __FUNCTION__
9999

100+
let resume _ _ = unimplemented __FUNCTION__
101+
100102
let s3suspend _ _ = unimplemented __FUNCTION__
101103

102104
let s3resume _ _ = unimplemented __FUNCTION__

ocaml/xenopsd/xc/domain.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,19 @@ let build (task : Xenops_task.task_handle) ~xc ~xs ~store_domid ~console_domid
13631363
build_post ~xc ~xs ~target_mib ~static_max_mib domid domain_type store_mfn
13641364
store_port local_stuff vm_stuff
13651365

1366+
let resume_post ~xc:_ ~xs domid =
1367+
let dom_path = xs.Xs.getdomainpath domid in
1368+
let store_mfn_s = xs.Xs.read (dom_path ^ "/store/ring-ref") in
1369+
let store_mfn = Nativeint.of_string store_mfn_s in
1370+
let store_port = int_of_string (xs.Xs.read (dom_path ^ "/store/port")) in
1371+
xs.Xs.introduce domid store_mfn store_port
1372+
1373+
let resume (task : Xenops_task.task_handle) ~xc ~xs ~qemu_domid ~domain_type
1374+
domid =
1375+
Xenctrl.domain_resume_fast xc domid ;
1376+
resume_post ~xc ~xs domid ;
1377+
if domain_type = `hvm then Device.Dm.resume task ~xs ~qemu_domid domid
1378+
13661379
type suspend_flag = Live | Debug
13671380

13681381
let dm_flags =

ocaml/xenopsd/xc/domain.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ val build :
242242
-> unit
243243
(** Restore a domain using the info provided *)
244244

245+
val resume :
246+
Xenops_task.Xenops_task.task_handle
247+
-> xc:Xenctrl.handle
248+
-> xs:Ezxenstore_core.Xenstore.Xs.xsh
249+
-> qemu_domid:int
250+
-> domain_type:[`hvm | `pv | `pvh]
251+
-> domid
252+
-> unit
253+
(** Fast resume *)
254+
245255
val restore :
246256
Xenops_task.Xenops_task.task_handle
247257
-> xc:Xenctrl.handle

ocaml/xenopsd/xc/xenops_server_xen.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,6 +3021,26 @@ module VM = struct
30213021
Domain.shutdown ~xc ~xs di.Xenctrl.domid Domain.S3Suspend
30223022
)
30233023

3024+
let resume t vm =
3025+
on_domain t vm (fun xc xs task _vm di ->
3026+
let domid = di.Xenctrl.domid in
3027+
let qemu_domid = this_domid ~xs in
3028+
let domain_type =
3029+
match get_domain_type ~xs di with
3030+
| Vm.Domain_HVM ->
3031+
`hvm
3032+
| Vm.Domain_PV ->
3033+
`pv
3034+
| Vm.Domain_PVinPVH ->
3035+
`pvh
3036+
| Vm.Domain_PVH ->
3037+
`pvh
3038+
| Vm.Domain_undefined ->
3039+
failwith "undefined domain type: cannot resume"
3040+
in
3041+
Domain.resume task ~xc ~xs ~qemu_domid ~domain_type domid
3042+
)
3043+
30243044
let s3resume t vm =
30253045
(* XXX: TODO: monitor the guest's response; track the s3 state *)
30263046
on_domain t vm (fun xc _xs _task _vm di ->

0 commit comments

Comments
 (0)