Skip to content

Commit e1a57fa

Browse files
committed
CA-408552: 3/3 Improve bootstrom performance by save db ops
Move ops unrelated db operation outside of returned function Signed-off-by: Lin Liu <[email protected]>
1 parent e8440b3 commit e1a57fa

File tree

2 files changed

+123
-129
lines changed

2 files changed

+123
-129
lines changed

ocaml/xapi/xapi_vdi.ml

Lines changed: 85 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,84 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
6868
let _ref = Ref.string_of _ref' in
6969
let current_ops = record.Db_actions.vDI_current_operations in
7070
let reset_on_boot = record.Db_actions.vDI_on_boot = `reset in
71+
let rolling_upgrade_in_progress =
72+
Helpers.rolling_upgrade_in_progress ~__context
73+
in
74+
(* check to see whether it's a local cd drive *)
75+
let sr = record.Db_actions.vDI_SR in
76+
let sr_type = Db.SR.get_type ~__context ~self:sr in
77+
let is_tools_sr = Db.SR.get_is_tools_sr ~__context ~self:sr in
78+
(* Check to see if any PBDs are attached *)
79+
let open Xapi_database.Db_filter_types in
80+
let pbds_attached =
81+
match pbd_records with
82+
| [] ->
83+
Db.PBD.get_records_where ~__context
84+
~expr:
85+
(And
86+
( Eq (Field "SR", Literal (Ref.string_of sr))
87+
, Eq (Field "currently_attached", Literal "true")
88+
)
89+
)
90+
| _ ->
91+
List.filter
92+
(fun (_, pbd_record) ->
93+
pbd_record.API.pBD_SR = sr && pbd_record.API.pBD_currently_attached
94+
)
95+
pbd_records
96+
in
97+
98+
(* Only a 'live' operation can be performed if there are active (even RO) devices *)
99+
let my_active_vbd_records =
100+
match vbd_records with
101+
| None ->
102+
List.map snd
103+
(Db.VBD.get_internal_records_where ~__context
104+
~expr:
105+
(And
106+
( Eq (Field "VDI", Literal _ref)
107+
, Or
108+
( Eq (Field "currently_attached", Literal "true")
109+
, Eq (Field "reserved", Literal "true")
110+
)
111+
)
112+
)
113+
)
114+
| Some records ->
115+
List.filter
116+
(fun vbd_record ->
117+
vbd_record.Db_actions.vBD_VDI = _ref'
118+
&& (vbd_record.Db_actions.vBD_currently_attached
119+
|| vbd_record.Db_actions.vBD_reserved
120+
)
121+
)
122+
records
123+
in
124+
let my_active_rw_vbd_records =
125+
List.filter (fun vbd -> vbd.Db_actions.vBD_mode = `RW) my_active_vbd_records
126+
in
127+
(* VBD operations (plug/unplug) (which should be transient) cause us to serialise *)
128+
let my_has_current_operation_vbd_records =
129+
match vbd_records with
130+
| None ->
131+
List.map snd
132+
(Db.VBD.get_internal_records_where ~__context
133+
~expr:
134+
(And
135+
( Eq (Field "VDI", Literal _ref)
136+
, Not (Eq (Field "current_operations", Literal "()"))
137+
)
138+
)
139+
)
140+
| Some records ->
141+
List.filter
142+
(fun vbd_record ->
143+
vbd_record.Db_actions.vBD_VDI = _ref'
144+
&& vbd_record.Db_actions.vBD_current_operations <> []
145+
)
146+
records
147+
in
148+
71149
(* Policy:
72150
1. any current_operation besides copy implies exclusivity; fail everything
73151
else; except vdi mirroring is in current operations and destroy is performed
@@ -83,11 +161,15 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
83161
5. HA prevents you from deleting statefiles or metadata volumes
84162
6. During rolling pool upgrade, only operations known by older releases are allowed
85163
*)
164+
let sm_features =
165+
Xapi_sr_operations.features_of_sr_internal ~__context ~_type:sr_type
166+
in
167+
let vdi_is_ha_state_or_redolog =
168+
List.mem record.Db_actions.vDI_type [`ha_statefile; `redo_log]
169+
in
170+
86171
fun op ->
87172
let* () =
88-
let rolling_upgrade_in_progress =
89-
Helpers.rolling_upgrade_in_progress ~__context
90-
in
91173
if
92174
rolling_upgrade_in_progress
93175
&& not
@@ -113,30 +195,6 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
113195
else
114196
Ok ()
115197
in
116-
(* check to see whether it's a local cd drive *)
117-
let sr = record.Db_actions.vDI_SR in
118-
let sr_type = Db.SR.get_type ~__context ~self:sr in
119-
let is_tools_sr = Db.SR.get_is_tools_sr ~__context ~self:sr in
120-
(* Check to see if any PBDs are attached *)
121-
let open Xapi_database.Db_filter_types in
122-
let pbds_attached =
123-
match pbd_records with
124-
| [] ->
125-
Db.PBD.get_records_where ~__context
126-
~expr:
127-
(And
128-
( Eq (Field "SR", Literal (Ref.string_of sr))
129-
, Eq (Field "currently_attached", Literal "true")
130-
)
131-
)
132-
| _ ->
133-
List.filter
134-
(fun (_, pbd_record) ->
135-
pbd_record.API.pBD_SR = sr
136-
&& pbd_record.API.pBD_currently_attached
137-
)
138-
pbd_records
139-
in
140198
let* () =
141199
if pbds_attached = [] && op = `resize then
142200
Error (Api_errors.sr_no_pbds, [Ref.string_of sr])
@@ -146,58 +204,6 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
146204

147205
(* check to see whether VBDs exist which are using this VDI *)
148206

149-
(* Only a 'live' operation can be performed if there are active (even RO) devices *)
150-
let my_active_vbd_records =
151-
match vbd_records with
152-
| None ->
153-
List.map snd
154-
(Db.VBD.get_internal_records_where ~__context
155-
~expr:
156-
(And
157-
( Eq (Field "VDI", Literal _ref)
158-
, Or
159-
( Eq (Field "currently_attached", Literal "true")
160-
, Eq (Field "reserved", Literal "true")
161-
)
162-
)
163-
)
164-
)
165-
| Some records ->
166-
List.filter
167-
(fun vbd_record ->
168-
vbd_record.Db_actions.vBD_VDI = _ref'
169-
&& (vbd_record.Db_actions.vBD_currently_attached
170-
|| vbd_record.Db_actions.vBD_reserved
171-
)
172-
)
173-
records
174-
in
175-
let my_active_rw_vbd_records =
176-
List.filter
177-
(fun vbd -> vbd.Db_actions.vBD_mode = `RW)
178-
my_active_vbd_records
179-
in
180-
(* VBD operations (plug/unplug) (which should be transient) cause us to serialise *)
181-
let my_has_current_operation_vbd_records =
182-
match vbd_records with
183-
| None ->
184-
List.map snd
185-
(Db.VBD.get_internal_records_where ~__context
186-
~expr:
187-
(And
188-
( Eq (Field "VDI", Literal _ref)
189-
, Not (Eq (Field "current_operations", Literal "()"))
190-
)
191-
)
192-
)
193-
| Some records ->
194-
List.filter
195-
(fun vbd_record ->
196-
vbd_record.Db_actions.vBD_VDI = _ref'
197-
&& vbd_record.Db_actions.vBD_current_operations <> []
198-
)
199-
records
200-
in
201207
(* If the VBD is currently_attached then some operations can still be
202208
performed ie: VDI.clone (if the VM is suspended we have to have the
203209
'allow_clone_suspended_vm' flag); VDI.snapshot; VDI.resize_online;
@@ -275,9 +281,6 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
275281
else
276282
Ok ()
277283
in
278-
let sm_features =
279-
Xapi_sr_operations.features_of_sr_internal ~__context ~_type:sr_type
280-
in
281284
let* () = check_sm_feature_error op sm_features sr in
282285
let allowed_for_cbt_metadata_vdi =
283286
match op with
@@ -341,16 +344,7 @@ let check_operation_error ~__context ?sr_records:_ ?(pbd_records = [])
341344
else
342345
Ok ()
343346
in
344-
let vdi_is_ha_state_or_redolog =
345-
List.mem record.Db_actions.vDI_type [`ha_statefile; `redo_log]
346-
in
347347
let check_destroy () =
348-
let ha_enable_in_progress =
349-
Xapi_pool_helpers.ha_enable_in_progress ~__context
350-
in
351-
let ha_disable_in_progress =
352-
Xapi_pool_helpers.ha_disable_in_progress ~__context
353-
in
354348
if sr_type = "udev" then
355349
Error (Api_errors.vdi_is_a_physical_device, [_ref])
356350
else if is_tools_sr then

ocaml/xapi/xapi_vm_lifecycle.ml

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,7 @@ let nested_virt ~__context vm metrics =
393393
let key = "nested-virt" in
394394
Vm_platform.is_true ~key ~platformdata ~default:false
395395

396-
let is_mobile ~__context vm strict =
397-
let metrics = Db.VM.get_metrics ~__context ~self:vm in
396+
let is_mobile ~__context vm strict metrics =
398397
(not @@ nomigrate ~__context vm metrics)
399398
&& (not @@ nested_virt ~__context vm metrics)
400399
|| not strict
@@ -447,6 +446,42 @@ let check_operation_error ~__context ~ref =
447446
vmr.Db_actions.vM_VBDs
448447
|> List.filter (Db.is_valid_ref __context)
449448
in
449+
let current_ops = vmr.Db_actions.vM_current_operations in
450+
let metrics = Db.VM.get_metrics ~__context ~self:ref in
451+
let is_nested_virt = nested_virt ~__context ref metrics in
452+
let is_domain_zero =
453+
Db.VM.get_by_uuid ~__context ~uuid:vmr.Db_actions.vM_uuid
454+
|> Helpers.is_domain_zero ~__context
455+
in
456+
let vdis_reset_and_caching =
457+
List.filter_map
458+
(fun vdi ->
459+
try
460+
let sm_config = Db.VDI.get_sm_config ~__context ~self:vdi in
461+
Some
462+
( List.assoc_opt "on_boot" sm_config = Some "reset"
463+
, bool_of_assoc "caching" sm_config
464+
)
465+
with _ -> None
466+
)
467+
vdis
468+
in
469+
let sriov_pcis = nvidia_sriov_pcis ~__context vmr.Db_actions.vM_VGPUs in
470+
let is_not_sriov pci = not @@ List.mem pci sriov_pcis in
471+
let pcis = vmr.Db_actions.vM_attached_PCIs in
472+
let is_appliance_valid =
473+
Db.is_valid_ref __context vmr.Db_actions.vM_appliance
474+
in
475+
let is_protection_policy_valid =
476+
Db.is_valid_ref __context vmr.Db_actions.vM_protection_policy
477+
in
478+
let rolling_upgrade_in_progress =
479+
Helpers.rolling_upgrade_in_progress ~__context
480+
in
481+
let is_snapshort_schedule_valid =
482+
Db.is_valid_ref __context vmr.Db_actions.vM_snapshot_schedule
483+
in
484+
450485
fun ~op ~strict ->
451486
let current_error = None in
452487
let check c f = match c with Some e -> Some e | None -> f () in
@@ -470,7 +505,6 @@ let check_operation_error ~__context ~ref =
470505
(* if other operations are in progress, check that the new operation is allowed concurrently with them. *)
471506
let current_error =
472507
check current_error (fun () ->
473-
let current_ops = vmr.Db_actions.vM_current_operations in
474508
if
475509
List.length current_ops <> 0
476510
&& not (is_allowed_concurrently ~op ~current_ops)
@@ -520,15 +554,13 @@ let check_operation_error ~__context ~ref =
520554
check current_error (fun () ->
521555
match op with
522556
| (`suspend | `checkpoint | `pool_migrate | `migrate_send)
523-
when not (is_mobile ~__context ref strict) ->
557+
when not (is_mobile ~__context ref strict metrics) ->
524558
Some (Api_errors.vm_is_immobile, [ref_str])
525559
| _ ->
526560
None
527561
)
528562
in
529563
let current_error =
530-
let metrics = Db.VM.get_metrics ~__context ~self:ref in
531-
let is_nested_virt = nested_virt ~__context ref metrics in
532564
check current_error (fun () ->
533565
match op with
534566
| `changing_dynamic_range when is_nested_virt && strict ->
@@ -542,10 +574,6 @@ let check_operation_error ~__context ~ref =
542574
(* make use of the Helpers.ballooning_enabled_for_vm function. *)
543575
let current_error =
544576
check current_error (fun () ->
545-
let is_domain_zero =
546-
Db.VM.get_by_uuid ~__context ~uuid:vmr.Db_actions.vM_uuid
547-
|> Helpers.is_domain_zero ~__context
548-
in
549577
if (op = `changing_VCPUs || op = `destroy) && is_domain_zero then
550578
Some
551579
( Api_errors.operation_not_allowed
@@ -592,19 +620,6 @@ let check_operation_error ~__context ~ref =
592620
(* Check for an error due to VDI caching/reset behaviour *)
593621
let current_error =
594622
check current_error (fun () ->
595-
let vdis_reset_and_caching =
596-
List.filter_map
597-
(fun vdi ->
598-
try
599-
let sm_config = Db.VDI.get_sm_config ~__context ~self:vdi in
600-
Some
601-
( List.assoc_opt "on_boot" sm_config = Some "reset"
602-
, bool_of_assoc "caching" sm_config
603-
)
604-
with _ -> None
605-
)
606-
vdis
607-
in
608623
if
609624
op = `checkpoint
610625
|| op = `snapshot
@@ -633,9 +648,6 @@ let check_operation_error ~__context ~ref =
633648
(* If a PCI device is passed-through, check if the operation is allowed *)
634649
let current_error =
635650
check current_error @@ fun () ->
636-
let sriov_pcis = nvidia_sriov_pcis ~__context vmr.Db_actions.vM_VGPUs in
637-
let is_not_sriov pci = not @@ List.mem pci sriov_pcis in
638-
let pcis = vmr.Db_actions.vM_attached_PCIs in
639651
match op with
640652
| (`suspend | `checkpoint | `pool_migrate | `migrate_send)
641653
when List.exists is_not_sriov pcis ->
@@ -666,9 +678,6 @@ let check_operation_error ~__context ~ref =
666678
in
667679
(* Check for errors caused by VM being in an appliance. *)
668680
let current_error =
669-
let is_appliance_valid =
670-
Db.is_valid_ref __context vmr.Db_actions.vM_appliance
671-
in
672681
check current_error (fun () ->
673682
if is_appliance_valid then
674683
check_appliance ~vmr ~op ~ref_str
@@ -678,9 +687,6 @@ let check_operation_error ~__context ~ref =
678687
in
679688
(* Check for errors caused by VM being assigned to a protection policy. *)
680689
let current_error =
681-
let is_protection_policy_valid =
682-
Db.is_valid_ref __context vmr.Db_actions.vM_protection_policy
683-
in
684690
check current_error (fun () ->
685691
if is_protection_policy_valid then
686692
check_protection_policy ~vmr ~op ~ref_str
@@ -690,9 +696,6 @@ let check_operation_error ~__context ~ref =
690696
in
691697
(* Check for errors caused by VM being assigned to a snapshot schedule. *)
692698
let current_error =
693-
let is_snapshort_schedule_valid =
694-
Db.is_valid_ref __context vmr.Db_actions.vM_snapshot_schedule
695-
in
696699
check current_error (fun () ->
697700
if is_snapshort_schedule_valid then
698701
check_snapshot_schedule ~vmr ~ref_str op
@@ -716,9 +719,6 @@ let check_operation_error ~__context ~ref =
716719
)
717720
in
718721
let current_error =
719-
let rolling_upgrade_in_progress =
720-
Helpers.rolling_upgrade_in_progress ~__context
721-
in
722722
check current_error (fun () ->
723723
if
724724
rolling_upgrade_in_progress

0 commit comments

Comments
 (0)