/* 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.ComponentModel; using System.Windows.Forms; using XenAdmin.Actions; using XenAdmin.Commands; using XenAPI; namespace XenAdmin.Dialogs { public partial class ControlDomainMemoryDialog : XenDialogBase { private Host host; private Host_metrics hostMetrics; private double origMemory; public const int MAXIMUM_DOM0_MEMORY_GB = 256; public ControlDomainMemoryDialog(Host host) : base(host.Connection) { InitializeComponent(); this.host = host; this.host.PropertyChanged += Server_PropertyChanged; hostMetrics = connection.Resolve(this.host.metrics); if (hostMetrics != null) hostMetrics.PropertyChanged += Server_PropertyChanged; Text = string.Format(Messages.CONTROL_DOMAIN_MEMORY_DIALOG_TITLE, this.host.Name()); Populate(); } private void UpdateMaintenanceWarning() { Host_metrics metrics = host.Connection.Resolve(host.metrics); bool maintenanceMode = host.MaintenanceMode() || (metrics != null && !metrics.live); tplMaintenanceWarning.Visible = !maintenanceMode; tplRebootWarning.Visible = maintenanceMode; memorySpinner.Enabled = maintenanceMode; } private void Populate() { VM vm = host.ControlDomainZero(); // Since updates come in dribs and drabs, avoid error if new max and min arrive // out of sync and maximum < minimum. if (vm.memory_dynamic_max >= vm.memory_dynamic_min) { double min = vm.memory_static_min; double max = Math.Min(vm.memory_dynamic_min + host.memory_available_calc(), MAXIMUM_DOM0_MEMORY_GB * Util.BINARY_GIGA); double value = vm.memory_dynamic_min; // Avoid setting the range to exclude the current value: CA-40041 if (value > max) max = value; if (value < min) min = value; memorySpinner.SetRange(0, MAXIMUM_DOM0_MEMORY_GB * Util.BINARY_GIGA); // reset spinner limits memorySpinner.Initialize(value, max); memorySpinner.SetRange(min, max); } origMemory = memorySpinner.Value; UpdateMaintenanceWarning(); } private bool HasChanged() { return memorySpinner.Value != origMemory; } private bool SaveChanges() { if (!HasChanged()) return false; var mem = memorySpinner.Value; DialogResult dialogResult; using (var dlg = new WarningDialog(Messages.CONFIRM_CHANGE_CONTROL_DOMAIN_MEMORY, ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo)) { dialogResult = dlg.ShowDialog(this); } if (DialogResult.Yes != dialogResult) return false; var actions = new List(); var action = new ChangeControlDomainMemoryAction(host, (long)mem, false); actions.Add(action); actions.Add(new RebootHostAction(host, AddHostToPoolCommand.NtolDialog)); var multipleAction = new MultipleAction(connection, string.Format(Messages.ACTION_CHANGE_CONTROL_DOMAIN_MEMORY, host.Name()), string.Format(Messages.ACTION_CHANGE_CONTROL_DOMAIN_MEMORY, host.Name()), Messages.COMPLETED, actions, true, false, true); multipleAction.RunAsync(); return true; } private void Cleanup() { host.PropertyChanged -= Server_PropertyChanged; if (hostMetrics != null) hostMetrics.PropertyChanged -= Server_PropertyChanged; } private void Server_PropertyChanged(object sender, PropertyChangedEventArgs e) { Program.Invoke(this, Populate); } private void OkButton_Click(object sender, EventArgs e) { if (SaveChanges()) { DialogResult = DialogResult.OK; } } private void maintenanceModeLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { new HostMaintenanceModeCommand(Program.MainWindow, host, HostMaintenanceModeCommandParameter.Enter).Run(); } private void ControlDomainMemoryDialog_FormClosing(object sender, FormClosingEventArgs e) { Cleanup(); } } }