/* Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using XenAdmin.Actions; using XenAdmin.Commands; using XenAdmin.Controls.Ballooning; using XenAdmin.Core; using XenAPI; namespace XenAdmin.Dialogs { public partial class BallooningDialog : XenDialogBase { private long origStaticMax; private List vmList; private VMMemoryControlsEdit memoryControls; private bool advanced; public BallooningDialog() { InitializeComponent(); } public BallooningDialog(VM vm, bool advanced) : base(vm.Connection) { InitializeComponent(); vmList = new List(1) {vm}; origStaticMax = vm.memory_static_max; this.advanced = advanced; if (advanced) { memoryControls = new VMMemoryControlsAdvanced(); labelRubric.Text = vm.is_a_template ? Messages.BALLOONING_RUBRIC_ADVANCED_TEMPLATE : Messages.BALLOONING_RUBRIC_ADVANCED; } else { memoryControls = new VMMemoryControlsBasic(); ((VMMemoryControlsBasic)memoryControls).InstallTools += BallooningDialog_InstallTools; labelRubric.Text = vm.is_a_template ? Messages.BALLOONING_RUBRIC_TEMPLATE : Messages.BALLOONING_RUBRIC; } panel1.Controls.Add(memoryControls); } protected override void OnShown(EventArgs e) { memoryControls.VMs = vmList; base.OnShown(e); } private void buttonOK_Click(object sender, EventArgs e) { memoryControls.UnfocusSpinners(); var hasBallooning = vmList[0].has_ballooning(); var confirmChange = ConfirmAndChange(this, vmList, hasBallooning ? (long)memoryControls.dynamic_min : (long)memoryControls.static_max, // dynamic_min and _max should stay equal to static_max for VMs without ballooning hasBallooning ? (long)memoryControls.dynamic_max : (long)memoryControls.static_max, (long)memoryControls.static_max, origStaticMax, advanced); if (confirmChange) Close(); } private void BallooningDialog_InstallTools(object sender, EventArgs e) { Close(); } private static List ConfirmAndCalcActions(IWin32Window parentWindow, List VMs, long dynamic_min, long dynamic_max, long static_max, long prev_static_max, bool advanced, bool suppressHistory) { if (prev_static_max / Util.BINARY_MEGA == static_max / Util.BINARY_MEGA) // don't want to throw warning dialog just for rounding errors { if (dynamic_min == static_max) dynamic_min = prev_static_max; if (dynamic_max == static_max) dynamic_max = prev_static_max; static_max = prev_static_max; } else { // If not all VMs Halted, confirm static_max changes, and abort if necessary foreach (VM vm in VMs) { if (vm.power_state != vm_power_state.Halted) { // Six(!) possible messages depending on the exact configuration. // (Could have an additional message for VMs without ballooning but with tools, e.g. on a free host, for which we can do a // clean shutdown: but having a false positive for the scarier message about force shutdown is not too bad). // We assume that all VMs have the same has_ballooning. string msg; if (advanced) msg = (VMs.Count == 1 ? Messages.CONFIRM_CHANGE_STATIC_MAX_SINGULAR : Messages.CONFIRM_CHANGE_STATIC_MAX_PLURAL); else if (vm.has_ballooning() && !Helpers.FeatureForbidden(vm, Host.RestrictDMC)) msg = (VMs.Count == 1 ? Messages.CONFIRM_CHANGE_MEMORY_MAX_SINGULAR : Messages.CONFIRM_CHANGE_MEMORY_MAX_PLURAL); else msg = (VMs.Count == 1 ? Messages.CONFIRM_CHANGE_MEMORY_SINGULAR : Messages.CONFIRM_CHANGE_MEMORY_PLURAL); DialogResult dialogResult; using (var dlg = new ThreeButtonDialog( new ThreeButtonDialog.Details(SystemIcons.Warning, msg, Messages.XENCENTER), ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo)) { dialogResult = dlg.ShowDialog(parentWindow); } if (DialogResult.Yes != dialogResult) return null; break; } } } List actions = new List(VMs.Count); foreach (VM vm in VMs) { ChangeMemorySettingsAction action = new ChangeMemorySettingsAction( vm, string.Format(Messages.ACTION_CHANGE_MEMORY_SETTINGS, vm.Name()), (long)vm.memory_static_min, dynamic_min, dynamic_max, static_max,VMOperationCommand.WarningDialogHAInvalidConfig,VMOperationCommand.StartDiagnosisForm, suppressHistory); actions.Add(action); } return actions; } public static bool ConfirmAndChange(IWin32Window parentWindow, List VMs, long dynamic_min, long dynamic_max, long static_max, long prev_static_max, bool advanced) { List actions = ConfirmAndCalcActions(parentWindow, VMs, dynamic_min, dynamic_max, static_max, prev_static_max, advanced, false); if (actions == null) return false; foreach (ChangeMemorySettingsAction action in actions) action.RunAsync(); return true; } public static ChangeMemorySettingsAction ConfirmAndReturnAction(IWin32Window parentWindow, VM vm, long dynamic_min, long dynamic_max, long static_max, long prev_static_max, bool advanced) { List vms = new List(1); vms.Add(vm); List actions = ConfirmAndCalcActions(parentWindow, vms, dynamic_min, dynamic_max, static_max, prev_static_max, advanced, true); if (actions == null || actions.Count == 0) return null; else return actions[0]; } } }