mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
Ensure mem/maxmem changes affect persistent config.
Split the Domain API into two pieces: 'hotplug memory' and 'define memory'. This allows us to catch hotplug errors and inform the user.
This commit is contained in:
parent
705b50419a
commit
fb7a999a81
@ -1545,44 +1545,38 @@ class vmmDetails(gobject.GObject):
|
|||||||
|
|
||||||
def config_memory_apply(self, src):
|
def config_memory_apply(self, src):
|
||||||
self.refresh_config_memory()
|
self.refresh_config_memory()
|
||||||
exc = None
|
hotplug_err = False
|
||||||
|
|
||||||
curmem = None
|
curmem = None
|
||||||
maxmem = self.config_get_maxmem()
|
maxmem = self.config_get_maxmem()
|
||||||
if self.window.get_widget("config-memory").get_property("sensitive"):
|
if self.window.get_widget("config-memory").get_property("sensitive"):
|
||||||
curmem = self.config_get_memory()
|
curmem = self.config_get_memory()
|
||||||
|
|
||||||
logging.info("Setting max-memory for " + self.vm.get_name() +
|
if curmem:
|
||||||
" to " + str(maxmem))
|
curmem = int(curmem) * 1024
|
||||||
|
if maxmem:
|
||||||
|
maxmem = int(maxmem) * 1024
|
||||||
|
|
||||||
actual_cur = self.vm.get_memory()
|
try:
|
||||||
if curmem is not None:
|
if self.vm.is_active():
|
||||||
logging.info("Setting memory for " + self.vm.get_name() +
|
self.vm.hotplug_both_mem(curmem, maxmem)
|
||||||
" to " + str(curmem))
|
except Exception, e:
|
||||||
if (maxmem * 1024) < actual_cur:
|
logging.debug("Memory hotplug failed: %s" % str(e))
|
||||||
# Set current first to avoid error
|
hotplug_err = True
|
||||||
try:
|
|
||||||
self.vm.set_memory(curmem * 1024)
|
|
||||||
self.vm.set_max_memory(maxmem * 1024)
|
|
||||||
except Exception, e:
|
|
||||||
exc = e
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
self.vm.set_max_memory(maxmem * 1024)
|
|
||||||
self.vm.set_memory(curmem * 1024)
|
|
||||||
except Exception, e:
|
|
||||||
exc = e
|
|
||||||
|
|
||||||
else:
|
# Change persisten config
|
||||||
try:
|
try:
|
||||||
self.vm.set_max_memory(maxmem * 1024)
|
self.vm.define_both_mem(curmem, maxmem)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
exc = e
|
|
||||||
|
|
||||||
if exc:
|
|
||||||
self.err.show_err(_("Error changing memory values: %s" % str(e)),
|
self.err.show_err(_("Error changing memory values: %s" % str(e)),
|
||||||
"".join(traceback.format_exc()))
|
"".join(traceback.format_exc()))
|
||||||
else:
|
return
|
||||||
self.window.get_widget("config-memory-apply").set_sensitive(False)
|
|
||||||
|
if hotplug_err:
|
||||||
|
self.err.show_info(_("These changes will take effect after the "
|
||||||
|
"next guest reboot. "))
|
||||||
|
|
||||||
|
self.window.get_widget("config-memory-apply").set_sensitive(False)
|
||||||
|
|
||||||
def config_boot_options_changed(self, src):
|
def config_boot_options_changed(self, src):
|
||||||
self.window.get_widget("config-boot-options-apply").set_sensitive(True)
|
self.window.get_widget("config-boot-options-apply").set_sensitive(True)
|
||||||
|
@ -1240,19 +1240,55 @@ class vmmDomain(gobject.GObject):
|
|||||||
vcpus = int(vcpus)
|
vcpus = int(vcpus)
|
||||||
self.vm.setVcpus(vcpus)
|
self.vm.setVcpus(vcpus)
|
||||||
|
|
||||||
def set_memory(self, memory):
|
def hotplug_memory(self, memory):
|
||||||
memory = int(memory)
|
if memory != self.get_memory():
|
||||||
# capture updated information due to failing to get proper maxmem setting
|
self.vm.setMemory(memory)
|
||||||
# if both current & max allocation are set simultaneously
|
|
||||||
maxmem = self.vm.info()
|
|
||||||
if (memory > maxmem[1]):
|
|
||||||
logging.warning("Requested memory " + str(memory) + " over maximum " + str(self.maximum_memory()))
|
|
||||||
memory = self.maximum_memory()
|
|
||||||
self.vm.setMemory(memory)
|
|
||||||
|
|
||||||
def set_max_memory(self, memory):
|
def hotplug_maxmem(self, maxmem):
|
||||||
memory = int(memory)
|
if maxmem != self.maximum_memory():
|
||||||
self.vm.setMaxMemory(memory)
|
self.vm.setMaxMemory(maxmem)
|
||||||
|
|
||||||
|
def hotplug_both_mem(self, memory, maxmem):
|
||||||
|
logging.info("Hotplugging curmem=%s maxmem=%s for VM '%s'" %
|
||||||
|
(memory, maxmem, self.get_name()))
|
||||||
|
|
||||||
|
if self.is_active():
|
||||||
|
actual_cur = self.get_memory()
|
||||||
|
if memory:
|
||||||
|
if maxmem < actual_cur:
|
||||||
|
# Set current first to avoid error
|
||||||
|
self.hotplug_memory(memory)
|
||||||
|
self.hotplug_maxmem(maxmem)
|
||||||
|
else:
|
||||||
|
self.hotplug_maxmem(maxmem)
|
||||||
|
self.hotplug_memory(memory)
|
||||||
|
else:
|
||||||
|
self.hotplug_maxmem(maxmem)
|
||||||
|
|
||||||
|
def define_both_mem(self, memory, maxmem):
|
||||||
|
# Make sure we correctly define the XML with new values, since
|
||||||
|
# setMem and setMaxMem don't (or, aren't supposed to) affect
|
||||||
|
# the persistent config
|
||||||
|
self.invalidate_xml()
|
||||||
|
|
||||||
|
def set_mem_node(doc, ctx, memval, xpath):
|
||||||
|
node = ctx.xpathEval(xpath)
|
||||||
|
node = (node and node[0] or None)
|
||||||
|
|
||||||
|
if node:
|
||||||
|
node.setContent(str(memval))
|
||||||
|
return doc.serialize()
|
||||||
|
|
||||||
|
def change_mem_xml(xml, memory, maxmem):
|
||||||
|
if memory:
|
||||||
|
xml = util.xml_parse_wrapper(xml, set_mem_node, memory,
|
||||||
|
"/domain/currentMemory[1]")
|
||||||
|
if maxmem:
|
||||||
|
xml = util.xml_parse_wrapper(xml, set_mem_node, maxmem,
|
||||||
|
"/domain/memory[1]")
|
||||||
|
return xml
|
||||||
|
|
||||||
|
self.redefine(change_mem_xml, memory, maxmem)
|
||||||
|
|
||||||
def get_autostart(self):
|
def get_autostart(self):
|
||||||
return self.vm.autostart()
|
return self.vm.autostart()
|
||||||
|
Loading…
Reference in New Issue
Block a user