Commit bdd0294a authored by Alain Takoudjou's avatar Alain Takoudjou

qmp: reboot if try to reduce memory size

parent 81d58495
......@@ -53,7 +53,7 @@ def parseArgument():
parser.add_argument('--device-options', dest='device_options',
help="Option used for update-device:\n" \
'"device=cpu,amount=VALUE_INT[,model=MODEL]"\n OR '\
'"device=memory,mem=VALUE_MB[,slot=VALUE_MB],nslot=VALUE_INT"')
'"device=memory,mem=VALUE_MB[,slot=VALUE_MB],nslot=VALUE_INT[,canreboot=0|1]"')
parser.add_argument('--socket', dest='unix_socket_location', required=True)
parser.add_argument('remainding_argument_list', nargs=argparse.REMAINDER)
......@@ -374,7 +374,7 @@ class QemuQMPWrapper(object):
}
})
def _updateMemory(self, mem_size, slot_size, slot_amount):
def _updateMemory(self, mem_size, slot_size, slot_amount, allow_reboot=False):
"""
Update memory size according to the current value. option_dict contains:
......@@ -423,8 +423,9 @@ class QemuQMPWrapper(object):
if num_slot_used > 0 and slot_size != memory_id_list[0]['size']:
# XXX - we won't change the defined size of RAM on slots on live,
# restart qemu will allow to change the value
self.powerdown()
raise ValueError("The Size of RAM Slot changed. Rebooting...")
if allow_reboot:
self.powerdown()
raise ValueError("The Size of RAM Slot changed. Rebooting...")
if (mem_size % slot_size) != 0:
raise ValueError("Memory size %r is not a multiple of %r" % (mem_size,
......@@ -441,6 +442,11 @@ class QemuQMPWrapper(object):
raise ValueError("Memory size is not valid: %s" % option_dict)
elif current_size > mem_size:
# Request to remove memory
if allow_reboot:
# reboot so new memory size will be configured safely
self.powerdown()
raise ValueError("Rebooting because memory size was reduced...")
slot_remove = (current_size - mem_size) / slot_size
print "Removing %s memory slots of %s MB..." % (slot_remove, slot_size)
......@@ -494,7 +500,8 @@ class QemuQMPWrapper(object):
return self._updateMemory(
mem_size=int(option_dict['mem']),
slot_size=int(option_dict['slot']),
slot_amount=int(option_dict['nslot'])
slot_amount=int(option_dict['nslot']),
allow_reboot=int(option_dict.get('canreboot', 0)) in [1, True]
)
else:
raise ValueError("Unknown device type: %s" % option_dict)
......
......@@ -502,5 +502,30 @@ class TestQemuQMPWrapper(unittest.TestCase):
self.assertEquals(len(self.call_stack_list), 2)
self.assertEquals(self.call_stack_list, expected_result)
def test_updateDevice_memory_will_reboot(self):
qmpwrapper = QemuQMPWrapper(self.socket_file, auto_connect=False)
qmpwrapper._send = self.fake_send
self.hotplugged_memory_amount = 3072
# slot of 1G
self.memory_slot_size = 1024
# decrease memory to 1G, expext remove slot 3 and 2.
cpu_option = {
'device': 'memory',
'nslot': 4,
'mem': 1024,
'slot': self.memory_slot_size,
'canreboot': True
}
with self.assertRaises(ValueError):
qmpwrapper.updateDevice(cpu_option)
expected_result = [
{'execute': 'query-memory-devices'},
{'execute': 'query-memdev'},
{'execute': 'system_powerdown'}
]
self.assertEquals(len(self.call_stack_list), 3)
self.assertEquals(self.call_stack_list, expected_result)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment