Skip to content

Commit 0537e7f

Browse files
authored
CA-423369: fix suspend-SR space check (backport) (#6883)
Unfortunately, the SR size and utilisation fields are only set after an SR scan, and the new space check has been incorrectly rejecting suspends in some cases. Fix this by just catching the error from `VDI.create` and raising the new error to make it clear that it is the suspend SR that is out of space. Fixes 9402e88. (cherry picked from commit 45e2ea9)
2 parents 28dce05 + 0143af4 commit 0537e7f

File tree

2 files changed

+35
-40
lines changed

2 files changed

+35
-40
lines changed

ocaml/xapi/helpers.ml

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,44 +1134,31 @@ let get_sr_free_space ~__context ~sr =
11341134
Int64.sub size utilisation
11351135

11361136
(* Returns an SR suitable for suspending this VM *)
1137-
let choose_suspend_sr ~__context ~vm ~required_space =
1137+
let choose_suspend_sr ~__context ~vm =
11381138
(* If the VM.suspend_SR exists, use that. If it fails, try the Pool.suspend_image_SR. *)
11391139
(* If that fails, try the Host.suspend_image_SR. *)
11401140
let vm_sr = Db.VM.get_suspend_SR ~__context ~self:vm in
11411141
let pool = get_pool ~__context in
11421142
let pool_sr = Db.Pool.get_suspend_image_SR ~__context ~self:pool in
11431143
let resident_on = Db.VM.get_resident_on ~__context ~self:vm in
11441144
let host_sr = Db.Host.get_suspend_image_sr ~__context ~self:resident_on in
1145-
let sr =
1146-
match
1147-
( check_sr_exists_for_host ~__context ~self:vm_sr ~host:resident_on
1148-
, check_sr_exists_for_host ~__context ~self:pool_sr ~host:resident_on
1149-
, check_sr_exists_for_host ~__context ~self:host_sr ~host:resident_on
1150-
)
1151-
with
1152-
| Some x, _, _ ->
1153-
x
1154-
| _, Some x, _ ->
1155-
x
1156-
| _, _, Some x ->
1157-
x
1158-
| None, None, None ->
1159-
raise
1160-
(Api_errors.Server_error
1161-
(Api_errors.vm_no_suspend_sr, [Ref.string_of vm])
1162-
)
1163-
in
1164-
let free_space = get_sr_free_space ~__context ~sr in
1165-
if free_space < required_space then (
1166-
let sr_str = Ref.string_of sr in
1167-
error "%s: SR %s free=%Ld needed=%Ld" __FUNCTION__ sr_str free_space
1168-
required_space ;
1169-
raise
1170-
(Api_errors.Server_error
1171-
(Api_errors.sr_suspend_space_insufficient, [sr_str])
1172-
)
1173-
) else
1174-
sr
1145+
match
1146+
( check_sr_exists_for_host ~__context ~self:vm_sr ~host:resident_on
1147+
, check_sr_exists_for_host ~__context ~self:pool_sr ~host:resident_on
1148+
, check_sr_exists_for_host ~__context ~self:host_sr ~host:resident_on
1149+
)
1150+
with
1151+
| Some x, _, _ ->
1152+
x
1153+
| _, Some x, _ ->
1154+
x
1155+
| _, _, Some x ->
1156+
x
1157+
| None, None, None ->
1158+
raise
1159+
(Api_errors.Server_error
1160+
(Api_errors.vm_no_suspend_sr, [Ref.string_of vm])
1161+
)
11751162

11761163
(* return the operations filtered for cancels functions *)
11771164
let cancel_tasks ~__context ~ops ~all_tasks_in_db

ocaml/xapi/xapi_xenops.ml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3994,10 +3994,7 @@ let suspend ~__context ~self =
39943994
in
39953995
Int64.(ram |> add vgpu |> add 104857600L)
39963996
in
3997-
let suspend_SR =
3998-
Helpers.choose_suspend_sr ~__context ~vm:self
3999-
~required_space:space_needed
4000-
in
3997+
let suspend_SR = Helpers.choose_suspend_sr ~__context ~vm:self in
40013998
let sm_config =
40023999
[
40034000
(Constants._sm_vm_hint, id)
@@ -4007,11 +4004,22 @@ let suspend ~__context ~self =
40074004
in
40084005
Helpers.call_api_functions ~__context (fun rpc session_id ->
40094006
let vdi =
4010-
XenAPI.VDI.create ~rpc ~session_id ~name_label:"Suspend image"
4011-
~name_description:"Suspend image" ~sR:suspend_SR
4012-
~virtual_size:space_needed ~sharable:false ~read_only:false
4013-
~_type:`suspend ~other_config:[] ~xenstore_data:[] ~sm_config
4014-
~tags:[]
4007+
try
4008+
XenAPI.VDI.create ~rpc ~session_id ~name_label:"Suspend image"
4009+
~name_description:"Suspend image" ~sR:suspend_SR
4010+
~virtual_size:space_needed ~sharable:false ~read_only:false
4011+
~_type:`suspend ~other_config:[] ~xenstore_data:[] ~sm_config
4012+
~tags:[]
4013+
with Api_errors.Server_error ("SR_BACKEND_FAILURE_44", _) ->
4014+
let sr_uuid = Db.SR.get_uuid ~__context ~self:suspend_SR in
4015+
error "Not enough free space on suspend SR %s; need %Ld B" sr_uuid
4016+
space_needed ;
4017+
raise
4018+
(Api_errors.Server_error
4019+
( Api_errors.sr_suspend_space_insufficient
4020+
, [Ref.string_of suspend_SR]
4021+
)
4022+
)
40154023
in
40164024
let d = disk_of_vdi ~__context ~self:vdi |> Option.get in
40174025
Db.VM.set_suspend_VDI ~__context ~self ~value:vdi ;

0 commit comments

Comments
 (0)