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:
Cole Robinson 2009-07-02 10:49:06 -04:00
parent 705b50419a
commit fb7a999a81
2 changed files with 71 additions and 41 deletions

View File

@ -1545,43 +1545,37 @@ class vmmDetails(gobject.GObject):
def config_memory_apply(self, src):
self.refresh_config_memory()
exc = None
hotplug_err = False
curmem = None
maxmem = self.config_get_maxmem()
if self.window.get_widget("config-memory").get_property("sensitive"):
curmem = self.config_get_memory()
logging.info("Setting max-memory for " + self.vm.get_name() +
" to " + str(maxmem))
if curmem:
curmem = int(curmem) * 1024
if maxmem:
maxmem = int(maxmem) * 1024
actual_cur = self.vm.get_memory()
if curmem is not None:
logging.info("Setting memory for " + self.vm.get_name() +
" to " + str(curmem))
if (maxmem * 1024) < actual_cur:
# Set current first to avoid error
try:
self.vm.set_memory(curmem * 1024)
self.vm.set_max_memory(maxmem * 1024)
if self.vm.is_active():
self.vm.hotplug_both_mem(curmem, maxmem)
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
logging.debug("Memory hotplug failed: %s" % str(e))
hotplug_err = True
else:
# Change persisten config
try:
self.vm.set_max_memory(maxmem * 1024)
self.vm.define_both_mem(curmem, maxmem)
except Exception, e:
exc = e
if exc:
self.err.show_err(_("Error changing memory values: %s" % str(e)),
"".join(traceback.format_exc()))
else:
return
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):

View File

@ -1240,19 +1240,55 @@ class vmmDomain(gobject.GObject):
vcpus = int(vcpus)
self.vm.setVcpus(vcpus)
def set_memory(self, memory):
memory = int(memory)
# capture updated information due to failing to get proper maxmem setting
# 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()
def hotplug_memory(self, memory):
if memory != self.get_memory():
self.vm.setMemory(memory)
def set_max_memory(self, memory):
memory = int(memory)
self.vm.setMaxMemory(memory)
def hotplug_maxmem(self, maxmem):
if maxmem != self.maximum_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):
return self.vm.autostart()