2013-03-18 01:06:52 +04:00
#
# Base class for all VM devices
#
2013-10-28 00:59:47 +04:00
# Copyright 2008, 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2013-03-18 01:06:52 +04:00
2018-03-20 19:27:37 +03:00
from . . xmlbuilder import XMLBuilder , XMLChildProperty , XMLProperty
2013-09-11 19:47:09 +04:00
2018-03-20 19:18:35 +03:00
class DeviceAlias ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " alias "
2013-09-19 21:27:30 +04:00
name = XMLProperty ( " ./@name " )
2013-09-11 19:47:09 +04:00
2018-03-20 19:18:35 +03:00
class DeviceBoot ( XMLBuilder ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " boot "
2014-02-09 22:36:12 +04:00
order = XMLProperty ( " ./@order " , is_int = True )
2018-03-20 19:18:35 +03:00
class DeviceAddress ( XMLBuilder ) :
2013-09-11 19:47:09 +04:00
"""
Examples :
< address type = ' pci ' domain = ' 0x0000 ' bus = ' 0x00 ' slot = ' 0x04 ' function = ' 0x0 ' / >
< address type = ' drive ' controller = ' 0 ' bus = ' 0 ' unit = ' 0 ' / >
< address type = ' ccid ' controller = ' 0 ' slot = ' 0 ' / >
< address type = ' virtio-serial ' controller = ' 1 ' bus = ' 0 ' port = ' 4 ' / >
"""
ADDRESS_TYPE_PCI = " pci "
ADDRESS_TYPE_DRIVE = " drive "
ADDRESS_TYPE_VIRTIO_SERIAL = " virtio-serial "
ADDRESS_TYPE_CCID = " ccid "
ADDRESS_TYPE_SPAPR_VIO = " spapr-vio "
2018-03-21 17:53:34 +03:00
XML_NAME = " address "
2013-09-11 19:47:09 +04:00
_XML_PROP_ORDER = [ " type " , " domain " , " controller " , " bus " , " slot " ,
" function " , " target " , " unit " , " multifunction " ]
def set_addrstr ( self , addrstr ) :
if addrstr is None :
return
2018-02-14 03:04:08 +03:00
if addrstr . count ( " : " ) in [ 1 , 2 ] and " . " in addrstr :
2013-09-11 19:47:09 +04:00
self . type = self . ADDRESS_TYPE_PCI
addrstr , self . function = addrstr . split ( " . " , 1 )
addrstr , self . slot = addrstr . rsplit ( " : " , 1 )
self . domain = " 0 "
2018-02-14 03:04:08 +03:00
if " : " in addrstr :
2013-09-11 19:47:09 +04:00
self . domain , self . bus = addrstr . split ( " : " , 1 )
elif addrstr == " spapr-vio " :
self . type = self . ADDRESS_TYPE_SPAPR_VIO
else :
raise ValueError ( _ ( " Could not determine or unsupported "
" format of ' %s ' " ) % addrstr )
2017-11-23 12:32:46 +03:00
def pretty_desc ( self ) :
pretty_desc = None
if self . type == self . ADDRESS_TYPE_DRIVE :
pretty_desc = _ ( " %s : %s : %s : %s " %
( self . controller , self . bus , self . target , self . unit ) )
return pretty_desc
2017-11-23 12:32:45 +03:00
def compare_controller ( self , controller , dev_bus ) :
if ( controller . type == dev_bus and
controller . index == self . controller ) :
return True
return False
2013-09-11 19:47:09 +04:00
2013-09-19 21:27:30 +04:00
type = XMLProperty ( " ./@type " )
2016-06-11 19:36:45 +03:00
# type=pci
2013-09-19 21:27:30 +04:00
domain = XMLProperty ( " ./@domain " , is_int = True )
bus = XMLProperty ( " ./@bus " , is_int = True )
slot = XMLProperty ( " ./@slot " , is_int = True )
function = XMLProperty ( " ./@function " , is_int = True )
2016-06-11 19:36:45 +03:00
multifunction = XMLProperty ( " ./@multifunction " , is_onoff = True )
# type=drive
2013-09-19 21:27:30 +04:00
controller = XMLProperty ( " ./@controller " , is_int = True )
unit = XMLProperty ( " ./@unit " , is_int = True )
port = XMLProperty ( " ./@port " , is_int = True )
target = XMLProperty ( " ./@target " , is_int = True )
2016-06-11 19:36:45 +03:00
# type=spapr-vio
reg = XMLProperty ( " ./@reg " )
# type=ccw
cssid = XMLProperty ( " ./@cssid " )
ssid = XMLProperty ( " ./@ssid " )
devno = XMLProperty ( " ./@devno " )
# type=isa
iobase = XMLProperty ( " ./@iobase " )
irq = XMLProperty ( " ./@irq " )
# type=dimm
base = XMLProperty ( " ./@base " )
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class Device ( XMLBuilder ) :
2013-03-18 01:06:52 +04:00
"""
Base class for all domain xml device objects .
"""
2013-09-11 19:47:09 +04:00
def __init__ ( self , * args , * * kwargs ) :
2013-03-18 01:06:52 +04:00
"""
Initialize device state
2018-02-14 15:17:31 +03:00
: param conn : libvirt connection to validate device against
2013-03-18 01:06:52 +04:00
"""
2013-09-11 19:47:09 +04:00
XMLBuilder . __init__ ( self , * args , * * kwargs )
2013-07-18 01:58:24 +04:00
self . _XML_PROP_ORDER = self . _XML_PROP_ORDER + [ " alias " , " address " ]
2013-03-18 01:06:52 +04:00
2018-03-20 19:18:35 +03:00
alias = XMLChildProperty ( DeviceAlias , is_single = True )
address = XMLChildProperty ( DeviceAddress , is_single = True )
boot = XMLChildProperty ( DeviceBoot , is_single = True )
2013-09-11 19:47:09 +04:00
2018-03-21 01:59:14 +03:00
@property
def DEVICE_TYPE ( self ) :
2018-03-21 17:53:34 +03:00
return self . XML_NAME
2019-02-08 01:42:25 +03:00
def compare_device ( self , newdev , idx ) :
"""
Attempt to compare this device against the passed @newdev ,
using various heuristics . For example , when removing a device
from both active and inactive XML , the device XML my be very
different or the devices may appear in different orders , so
we have to do some fuzzy matching to determine if the devices
are a ' match '
"""
devprops = {
" disk " : [ " target " , " bus " ] ,
" interface " : [ " macaddr " , " xmlindex " ] ,
" input " : [ " bus " , " type " , " xmlindex " ] ,
" sound " : [ " model " , " xmlindex " ] ,
" video " : [ " model " , " xmlindex " ] ,
" watchdog " : [ " xmlindex " ] ,
" hostdev " : [ " type " , " managed " , " xmlindex " ,
" product " , " vendor " ,
" function " , " domain " , " slot " ] ,
" serial " : [ " type " , " target_port " ] ,
" parallel " : [ " type " , " target_port " ] ,
" console " : [ " type " , " target_type " , " target_port " ] ,
" graphics " : [ " type " , " xmlindex " ] ,
" controller " : [ " type " , " index " ] ,
" channel " : [ " type " , " target_name " ] ,
" filesystem " : [ " target " , " xmlindex " ] ,
" smartcard " : [ " mode " , " xmlindex " ] ,
" redirdev " : [ " bus " , " type " , " xmlindex " ] ,
" tpm " : [ " type " , " xmlindex " ] ,
" rng " : [ " type " , " xmlindex " ] ,
" panic " : [ " type " , " xmlindex " ] ,
" vsock " : [ " xmlindex " ] ,
}
if id ( self ) == id ( newdev ) :
return True
if not isinstance ( self , type ( newdev ) ) :
return False
for devprop in devprops [ self . DEVICE_TYPE ] :
if devprop == " xmlindex " :
origval = self . get_xml_idx ( )
newval = idx
else :
origval = getattr ( self , devprop )
newval = getattr ( newdev , devprop )
if origval != newval :
return False
return True