Skip to content

Commit 45e2ea9

Browse files
committed
CA-423369: fix suspend-SR space check
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 77c6bf3. Signed-off-by: Rob Hoes <rob.hoes@citrix.com>
1 parent 00c6f68 commit 45e2ea9

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
@@ -4028,10 +4028,7 @@ let suspend ~__context ~self =
40284028
in
40294029
Int64.(ram |> add vgpu |> add 104857600L)
40304030
in
4031-
let suspend_SR =
4032-
Helpers.choose_suspend_sr ~__context ~vm:self
4033-
~required_space:space_needed
4034-
in
4031+
let suspend_SR = Helpers.choose_suspend_sr ~__context ~vm:self in
40354032
let sm_config =
40364033
[
40374034
(Constants._sm_vm_hint, id)
@@ -4041,11 +4038,22 @@ let suspend ~__context ~self =
40414038
in
40424039
Helpers.call_api_functions ~__context (fun rpc session_id ->
40434040
let vdi =
4044-
XenAPI.VDI.create ~rpc ~session_id ~name_label:"Suspend image"
4045-
~name_description:"Suspend image" ~sR:suspend_SR
4046-
~virtual_size:space_needed ~sharable:false ~read_only:false
4047-
~_type:`suspend ~other_config:[] ~xenstore_data:[] ~sm_config
4048-
~tags:[]
4041+
try
4042+
XenAPI.VDI.create ~rpc ~session_id ~name_label:"Suspend image"
4043+
~name_description:"Suspend image" ~sR:suspend_SR
4044+
~virtual_size:space_needed ~sharable:false ~read_only:false
4045+
~_type:`suspend ~other_config:[] ~xenstore_data:[] ~sm_config
4046+
~tags:[]
4047+
with Api_errors.Server_error ("SR_BACKEND_FAILURE_44", _) ->
4048+
let sr_uuid = Db.SR.get_uuid ~__context ~self:suspend_SR in
4049+
error "Not enough free space on suspend SR %s; need %Ld B" sr_uuid
4050+
space_needed ;
4051+
raise
4052+
(Api_errors.Server_error
4053+
( Api_errors.sr_suspend_space_insufficient
4054+
, [Ref.string_of suspend_SR]
4055+
)
4056+
)
40494057
in
40504058
let d = disk_of_vdi ~__context ~self:vdi |> Option.get in
40514059
Db.VM.set_suspend_VDI ~__context ~self ~value:vdi ;

0 commit comments

Comments
 (0)