Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix recreating VM defined by devices issue:1331 #1348

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions virttest/env_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def preprocess_vm(test, params, env, name):
if vm.needs_restart(name=name,
params=params,
basedir=test.bindir):
vm.devices = None
start_vm = True
old_vm.destroy(gracefully=gracefully_kill,
free_mac_addresses=False)
Expand Down
21 changes: 19 additions & 2 deletions virttest/qemu_devices/qcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,23 @@ def get_by_properties(self, filt):
out.append(device)
return out

def get_by_params(self, filt):
"""
Return list of matching devices
:param filt: filter {'param': 'value', ...}
:type filt: dict
"""
out = []
for device in self.__devices:
for key, value in filt.iteritems():
if not key in device.params:
break
if device.params[key] != value:
break
else:
out.append(device)
return out

def __delitem__(self, item):
"""
Delete specified item from devices list
Expand Down Expand Up @@ -656,14 +673,14 @@ def idx_of_next_named_bus(self, bus_pattern):
return i
i += 1

def cmdline(self):
def cmdline(self, dynamic=True):
"""
Creates cmdline arguments for creating all defined devices
:return: cmdline of all devices (without qemu-cmd itself)
"""
out = ""
for device in self.__devices:
_out = device.cmdline()
_out = device.cmdline() if dynamic else device.cmdline_nd()
if _out:
out += " %s" % _out
if out:
Expand Down
94 changes: 89 additions & 5 deletions virttest/qemu_devices/qdevices.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from virttest import qemu_monitor
from virttest import utils_misc
import qbuses
import traceback

try:
# pylint: disable=E0611
Expand Down Expand Up @@ -81,6 +82,7 @@ def __init__(self, dev_type="QBaseDevice", params=None, aobject=None,
else:
for bus in child_bus:
self.add_child_bus(bus)
self.dynamic_params = []
self.params = OrderedDict() # various device params (id, name, ...)
if params:
for key, value in params.iteritems():
Expand All @@ -104,13 +106,21 @@ def rm_child_bus(self, bus):
self.child_bus.remove(bus)
bus.set_device(None)

def set_param(self, option, value, option_type=None):
def set_param(self, option, value, option_type=None, dynamic=False):
"""
Set device param using qemu notation ("on", "off" instead of bool...)
:param option: which option's value to set
:param value: new value
:param option_type: type of the option (bool)
:param dynamic: if true value is changed to DYN for not_dynamic compare
"""
if dynamic:
if option not in self.dynamic_params:
self.dynamic_params.append(option)
else:
if option in self.dynamic_params:
self.dynamic_params.remove(option)

if option_type is bool or isinstance(value, bool):
if value in ['yes', 'on', True]:
self.params[option] = "on"
Expand All @@ -123,6 +133,8 @@ def set_param(self, option, value, option_type=None):
self.params[option] = value
elif value is None and option in self.params:
del(self.params[option])
if option in self.dynamic_params:
self.dynamic_params.remove(option)

def get_param(self, option, default=None):
""" :return: object param """
Expand Down Expand Up @@ -152,11 +164,11 @@ def __str__(self):
""" :return: Short string representation of this object. """
return self.str_short()

def __eq__(self, dev2):
def __eq__(self, dev2, dynamic=True):
""" :return: True when devs are similar, False when different. """
check_attrs = ['cmdline_nd', 'hotplug_hmp_nd', 'hotplug_qmp_nd']
try:
for check_attr in ('cmdline', 'hotplug_hmp',
'hotplug_qmp'):
for check_attr in check_attrs:
try:
_ = getattr(self, check_attr)()
except (DeviceError, NotImplementedError, AttributeError):
Expand All @@ -168,6 +180,7 @@ def __eq__(self, dev2):
if _ != getattr(dev2, check_attr)():
return False
except Exception:
logging.error(traceback.format_exc())
return False
return True

Expand Down Expand Up @@ -227,6 +240,13 @@ def cmdline(self):
""" :return: cmdline command to define this device """
raise NotImplementedError

def cmdline_nd(self):
"""
:return: cmdline command to define this device
without dynamic parameters
"""
self.cmdline()

# pylint: disable=E0202
def hotplug(self, monitor):
""" :return: the output of monitor.cmd() hotplug command """
Expand Down Expand Up @@ -306,7 +326,7 @@ class QStringDevice(QBaseDevice):
"""

def __init__(self, dev_type="dummy", params=None, aobject=None,
parent_bus=None, child_bus=None, cmdline=""):
parent_bus=None, child_bus=None, cmdline="", cmdline_nd=None):
"""
:param dev_type: type of this component
:param params: component's parameters
Expand All @@ -318,6 +338,9 @@ def __init__(self, dev_type="dummy", params=None, aobject=None,
super(QStringDevice, self).__init__(dev_type, params, aobject,
parent_bus, child_bus)
self._cmdline = cmdline
self._cmdline_nd = cmdline_nd
if cmdline_nd is None:
self._cmdline_nd = cmdline

def cmdline(self):
""" :return: cmdline command to define this device """
Expand All @@ -329,6 +352,19 @@ def cmdline(self):
% (details, self.str_long()))


def cmdline_nd(self):
"""
:return: cmdline command to define this device
without dynamic parameters
"""
try:
if self._cmdline_nd:
return self._cmdline_nd % self.params
except KeyError, details:
raise KeyError("Param %s required for cmdline is not present in %s"
% (details, self.str_long()))


class QCustomDevice(QBaseDevice):

"""
Expand Down Expand Up @@ -366,6 +402,30 @@ def cmdline(self):
out = out[:-1]
return out

def cmdline_nd(self):
"""
:return: cmdline command to define this device
without dynamic parameters
"""
if self.__backend and self.params.get(self.__backend):
out = "-%s %s," % (self.type, self.params.get(self.__backend))
params = self.params.copy()
del params[self.__backend]
else:
out = "-%s " % self.type
params = self.params
for key, value in params.iteritems():
if value != "NO_EQUAL_STRING":
if key in self.dynamic_params:
out += "%s=DYN," % (key,)
else:
out += "%s=%s," % (key, value)
else:
out += "%s," % key
if out[-1] == ',':
out = out[:-1]
return out


class QDrive(QCustomDevice):

Expand Down Expand Up @@ -599,6 +659,30 @@ def hotplug_qmp(self):
""" :return: the hotplug monitor command """
return "device_add", self.params

def hotplug_hmp_nd(self):
""" :return: the hotplug monitor command without dynamic parameters"""
if self.params.get('driver'):
params = self.params.copy()
out = "device_add %s" % params.pop('driver')
for key in self.dynamic_params:
params[key] = "DYN"
params = _convert_args(params)
if params:
out += ",%s" % params
else:
params = self.params.copy()
for key in self.dynamic_params:
params[key] = "DYN"
out = "device_add %s" % _convert_args(params)
return out

def hotplug_qmp_nd(self):
""" :return: the hotplug monitor command without dynamic parameters"""
params = self.params.copy()
for key in self.dynamic_params:
params[key] = "DYN"
return "device_add", params

def get_children(self):
""" Device bus should be removed too """
devices = super(QDevice, self).get_children()
Expand Down
Loading