Left base folder: D:\eng_usr\gsurka\XAPI\mnr25272-ocaml-base Right base folder: D:\eng_usr\gsurka\XAPI\mnr25272-ocaml-mtc File: xapi\dbsync_slave.ml 624c624,625 < let mark_as_attached = is_management_pif || was_pif_brought_up_at_start_of_day in --- > let mark_as_attached = is_management_pif || was_pif_brought_up_at_start_of_day || > (Mtc.is_pif_attached_to_mtc_vms_and_should_not_be_offline ~__context ~self) in File: xapi\message_forwarding.ml 2699a2700 > if not (Mtc.is_vdi_accessed_by_protected_VM ~__context ~vdi:self) then begin 2701a2703 > end; File: xapi\mtc.ml 33a34,43 > module Internal = struct > > let read_one_line file = > let inchan = open_in file in > try > let result = input_line inchan in > close_in inchan; > result > with exn -> close_in inchan; raise exn > end 54a65,66 > let mtc_pvm_key = "mtc_pvm" > let mtc_vdi_share_key = "mtc_vdi_shareable" 243d254 < if (is_this_vm_protected ~__context ~self) then ( 251d261 < ) 257d266 < if (is_this_vm_protected ~__context ~self) then ( 290d298 < ) else `ACKED 306a315,385 > > > > (* > * ----------------------------------------------------------------------------- > * Network Functions > * ----------------------------------------------------------------------------- > *) > (* Determine if we should allow the specified PIF to be marked not online when XAPI is > * restarted. Returns TRUE if this is a PIF fielding a VIF attached to an MTC- > * protected VM and we don't want it marked offline because we have checked here that the > * PIF and its bridge are already up. > *) > let is_pif_attached_to_mtc_vms_and_should_not_be_offline ~__context ~self = > try > > (* Get the VMs that are hooked up to this PIF *) > let network = Db.PIF.get_network ~__context ~self in > let vifs = Db.Network.get_VIFs ~__context ~self:network in > > > (* Figure out the VIFs attached to local MTC VMs and then derive their networks, bridges and PIFs *) > let vms = List.map (fun vif -> > Db.VIF.get_VM ~__context ~self:vif) > vifs in > let localhost = Helpers.get_localhost ~__context in > let resident_vms = List.filter (fun vm -> > localhost = (Db.VM.get_resident_on ~__context ~self:vm)) > vms in > let protected_vms = List.filter (fun vm -> > List.mem_assoc mtc_pvm_key (Db.VM.get_other_config ~__context ~self:vm)) > resident_vms in > > let protected_vms_uuid = List.map (fun vm -> > Db.VM.get_uuid ~__context ~self:vm) > protected_vms in > > > (* If we have protected VMs using this PIF, then decide whether it should be marked offline *) > if protected_vms <> [] then begin > let current = Netdev.network.Netdev.list () in > let bridge = Db.Network.get_bridge ~__context ~self:network in > let nic = Db.PIF.get_device ~__context ~self in > debug "The following MTC VMs are using %s for PIF %s: [%s]" > nic > (Db.PIF.get_uuid ~__context ~self) > (String.concat "; " protected_vms_uuid); > > let nic_device_path = Printf.sprintf "/sys/class/net/%s/operstate" nic in > let nic_device_state = Internal.read_one_line nic_device_path in > > let bridge_device_path = Printf.sprintf "/sys/class/net/%s/operstate" bridge in > let bridge_device_state = Internal.read_one_line bridge_device_path in > > (* The PIF should be marked online if: > 1) its network has a bridge created in dom0 and > 2) the bridge link is up and > 3) the physical NIC is up and > 4) the bridge operational state is up (unknown is also up). > *) > let mark_online = (List.mem bridge current) && > (Netdev.Link.is_up bridge) && > nic_device_state = "up" && > (bridge_device_state = "up" || > bridge_device_state = "unknown") in > > debug "Its current operational state is %s. Therefore we'll be marking it as %s" > nic_device_state (if mark_online then "online" else "offline"); > mark_online > end else false > with _ -> false 330a410,428 > (* Raises an exception if the destination VM is not in the expected power state: halted *) > let verify_dest_vm_power_state ~__context ~vm = > let actual = Db.VM.get_power_state ~__context ~self:vm in > if actual != `Halted then > raise(Api_errors.Server_error(Api_errors.vm_bad_power_state, [Ref.string_of vm; "halted"; (Record_util.power_to_string actual)])) > > (* Returns true if VDI is accessed by an MTC-protected VM *) > let is_vdi_accessed_by_protected_VM ~__context ~vdi = > > let uuid = Uuid.of_string (Db.VDI.get_uuid ~__context ~self:vdi) in > > let protected_vdi = List.mem_assoc mtc_vdi_share_key (Db.VDI.get_other_config ~__context ~self:vdi) in > > (* Return TRUE if this VDI is attached to a protected VM *) > if protected_vdi then begin > debug "VDI %s is attached to a Marathon-protected VM" (Uuid.to_string uuid); > true > end else > false File: xapi\storage_access.ml 185,186c186,188 < if is_already_attached uuid && (mode <> get_mode uuid) then --- > (* MTC: A protected VM needs to have its disks mounted into two VMs: one as R+W and another as RO *) > if is_already_attached uuid && (mode <> get_mode uuid) && > not (Mtc.is_vdi_accessed_by_protected_VM ~__context ~vdi:self) then File: xapi\vmops.ml 788c788 < let clean_shutdown_with_reason ?(at = fun _ -> ()) ~xal ~__context ~self domid reason = --- > let clean_shutdown_with_reason ?(at = fun _ -> ()) ~xal ~__context ~self ?(rel_timeout = 5.) domid reason = 825,826c826,827 < result := Some (Xal.wait_release xal ~timeout:5. domid); --- > debug "MTC: calling xal.wait_release timeout=%f" rel_timeout; > result := Some (Xal.wait_release xal ~timeout:rel_timeout domid); File: xapi\xapi_vm_migrate.ml 111a112,115 > > if TaskHelper.is_cancelling ~__context > then raise (Api_errors.Server_error(Api_errors.task_cancelled, [ Ref.string_of (Context.get_task_id __context) ])); > 122c126,128 < Mtc.event_notify_entering_suspend ~__context ~self; --- > > if TaskHelper.is_cancelling ~__context > then raise (Api_errors.Server_error(Api_errors.task_cancelled, [ Ref.string_of (Context.get_task_id __context) ])); 123,124c130,132 < let ack = Mtc.event_wait_entering_suspend_acked ~timeout:60. ~__context ~self in --- > if (Mtc.is_this_vm_protected ~__context ~self) then ( > Mtc.event_notify_entering_suspend ~__context ~self; > let ack = Mtc.event_wait_entering_suspend_acked ~timeout:60. ~__context ~self in 126c134 < (* If we got the ack, then proceed to shutdown the domain with the suspend --- > (* If we got the ack, then proceed to shutdown the domain with the suspend 129,132c137,140 < if (ack = `ACKED) then begin < match Vmops.clean_shutdown_with_reason ~xal ~__context ~self domid Domain.Suspend with < | Xal.Suspended -> () (* good *) < | Xal.Crashed -> --- > if (ack = `ACKED) then begin > match Vmops.clean_shutdown_with_reason ~xal ~__context ~self ~rel_timeout:0.25 domid Domain.Suspend with > | Xal.Suspended -> () (* good *) > | Xal.Crashed -> 134,137c142,145 < | Xal.Rebooted -> < raise (Api_errors.Server_error(Api_errors.vm_rebooted, [ Ref.string_of self ])) < | Xal.Vanished < | Xal.Halted -> --- > | Xal.Rebooted -> > raise (Api_errors.Server_error(Api_errors.vm_rebooted, [ Ref.string_of self ])) > | Xal.Vanished > | Xal.Halted -> 139,141c147,153 < | Xal.Shutdown x -> vm_migrate_failed (Printf.sprintf "Domain shutdown for unexpected reason: %d" x) < end else < vm_migrate_failed "Failed to receive suspend acknowledgement within timeout period or an abort was requested." --- > | Xal.Shutdown x -> vm_migrate_failed (Printf.sprintf "Domain shutdown for unexpected reason: %d" x) > end else > vm_migrate_failed "Failed to receive suspend acknowledgement within timeout period or an abort was requested." > ) else ( > Vmops.clean_shutdown_with_reason ~xal ~__context ~self domid Domain.Suspend; > () > ) 254a267,272 > > (* Recover an MTC VM if abort was requested during the suspended phase *) > if Mtc.event_check_for_abort_req ~__context ~self:vm then ( > vm_migrate_failed "An external abort event was detected during the VM suspend phase."; > ); > 304,308c322,328 < < (* Now send across the RRD *) < (try Monitor_rrds.migrate_push ~__context (Db.VM.get_uuid ~__context ~self:vm) host with e -> < debug "Caught exception while trying to push rrds: %s" (ExnHelper.string_of_exn e); < log_backtrace ()); --- > (* MTC: don't send RRDs since MTC VMs are not really migrated. *) > if not (Mtc.is_this_vm_protected ~__context ~self:vm) then ( > (* Now send across the RRD *) > (try Monitor_rrds.migrate_push ~__context (Db.VM.get_uuid ~__context ~self:vm) host with e -> > debug "Caught exception while trying to push rrds: %s" (ExnHelper.string_of_exn e); > log_backtrace ()); > ); 314c334,339 < Handshake.recv_success fd --- > Handshake.recv_success fd; > if Mtc.is_this_vm_protected ~__context ~self:vm then ( > let hvm = Helpers.has_booted_hvm ~__context ~self:vm in > debug "Sender 7a. resuming source domain"; > Domain.resume ~xc ~xs ~hvm ~cooperative:true domid > ); 319,320c345,347 < Xapi_vm_lifecycle.force_state_reset ~__context ~self:vm ~value:`Halted; --- > (* MTC: don't reset state upon failure. MTC VMs will simply resume *) > if not (Mtc.is_this_vm_protected ~__context ~self:vm) then > Xapi_vm_lifecycle.force_state_reset ~__context ~self:vm ~value:`Halted; 323a351,353 > if Mtc.is_this_vm_protected ~__context ~self:vm then ( > debug "MTC: Sender won't clean up by destroying remains of local domain"; > ) else ( 331a362 > ) 569a601,603 > (* Set the task allowed_operations to include cancel *) > TaskHelper.set_cancellable ~__context; > 636a671,678 > with_xc_and_xs (fun xc xs -> > if Mtc.is_this_vm_protected ~__context ~self:vm then ( > debug "MTC: exception encountered. Resuming source domain"; > let domid = Int64.to_int (Db.VM.get_domid ~__context ~self:vm) in > let hvm = Helpers.has_booted_hvm ~__context ~self:vm in > Domain.resume ~xc ~xs ~hvm ~cooperative:true domid > )); > 804a847,850 > (* MTC-3009: The dest VM of a Marathon protected VM MUST be in halted state. *) > if Mtc.is_this_vm_protected ~__context ~self:dest_vm then ( > Mtc.verify_dest_vm_power_state ~__context ~vm:dest_vm > ); File: xenguest\xenguest_main.ml 156a157,158 > > Sys.set_signal Sys.sigterm (Sys.Signal_handle (fun i -> debug "Signal handler killing PID=%d" pid; Unix.kill pid Sys.sigterm)); File: xenops\device.ml 1400,1401c1401,1405 < Watch.wait_for ~xs (Watch.value_to_become pw state) --- > (* MTC: The default timeout for this operation was 20mins, which is > * way too long for our software to recover successfully. > * Talk to Citrix about this > *) > Watch.wait_for ~xs ~timeout:30. (Watch.value_to_become pw state) File: xenops\domain.ml 99,100c100,101 < let flags = --- > let flags = if info.hvm then ( > let default_flags = 102a104,117 > if (List.mem_assoc "hap" info.platformdata) then ( > if (List.assoc "hap" info.platformdata) = "false" then ( > debug "HAP will be disabled for VM %s." (Uuid.to_string uuid); > [ Xc.CDF_HVM ] > ) else if (List.assoc "hap" info.platformdata) = "true" then ( > debug "HAP will be enabled for VM %s." (Uuid.to_string uuid); > [ Xc.CDF_HVM; Xc.CDF_HAP ] > ) else ( > debug "Unrecognized HAP platform value. Assuming default settings for VM %s." (Uuid.to_string uuid); > default_flags > ) > ) else > default_flags > ) else [] in