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
# Cole Robinson <crobinso@redhat.com>
#
2018-03-20 22:00:02 +03:00
# This work is licensed under the GNU GPLv2.
# 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 ) :
2013-09-11 19:47:09 +04:00
_XML_ROOT_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 ) :
2014-02-09 22:36:12 +04:00
_XML_ROOT_NAME = " boot "
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 "
TYPES = [ ADDRESS_TYPE_PCI , ADDRESS_TYPE_DRIVE ,
ADDRESS_TYPE_VIRTIO_SERIAL , ADDRESS_TYPE_CCID ,
ADDRESS_TYPE_SPAPR_VIO ]
_XML_ROOT_NAME = " address "
_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 .
"""
2018-03-20 19:18:35 +03:00
DEVICE_DISK = " disk "
DEVICE_NET = " interface "
DEVICE_INPUT = " input "
DEVICE_GRAPHICS = " graphics "
DEVICE_AUDIO = " sound "
DEVICE_HOSTDEV = " hostdev "
DEVICE_SERIAL = " serial "
DEVICE_PARALLEL = " parallel "
DEVICE_CHANNEL = " channel "
DEVICE_CONSOLE = " console "
DEVICE_VIDEO = " video "
DEVICE_CONTROLLER = " controller "
DEVICE_WATCHDOG = " watchdog "
DEVICE_FILESYSTEM = " filesystem "
DEVICE_SMARTCARD = " smartcard "
DEVICE_REDIRDEV = " redirdev "
DEVICE_MEMBALLOON = " memballoon "
DEVICE_TPM = " tpm "
DEVICE_RNG = " rng "
DEVICE_PANIC = " panic "
DEVICE_MEMORY = " memory "
2013-03-18 01:06:52 +04:00
# Ordering in this list is important: it will be the order the
# Guest class outputs XML. So changing this may upset the test suite
2018-03-20 19:18:35 +03:00
virtual_device_types = [ DEVICE_DISK ,
DEVICE_CONTROLLER ,
DEVICE_FILESYSTEM ,
DEVICE_NET ,
DEVICE_INPUT ,
DEVICE_GRAPHICS ,
DEVICE_SERIAL ,
DEVICE_PARALLEL ,
DEVICE_CONSOLE ,
DEVICE_CHANNEL ,
DEVICE_AUDIO ,
DEVICE_VIDEO ,
DEVICE_HOSTDEV ,
DEVICE_WATCHDOG ,
DEVICE_SMARTCARD ,
DEVICE_REDIRDEV ,
DEVICE_MEMBALLOON ,
DEVICE_TPM ,
DEVICE_RNG ,
DEVICE_PANIC ,
DEVICE_MEMORY ]
2013-03-18 01:06:52 +04:00
2013-07-24 16:46:55 +04:00
virtual_device_classes = { }
@classmethod
2013-07-24 19:32:30 +04:00
def register_type ( cls ) :
2013-09-11 19:47:09 +04:00
cls . _XML_ROOT_NAME = cls . virtual_device_type
2018-03-20 19:18:35 +03:00
Device . virtual_device_classes [ cls . virtual_device_type ] = cls
2013-07-24 16:46:55 +04:00
2013-03-18 01:06:52 +04:00
# General device type (disk, interface, etc.)
2013-07-16 17:14:37 +04:00
virtual_device_type = None
2013-03-18 01:06:52 +04:00
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
2013-07-16 17:14:37 +04:00
if not self . virtual_device_type :
2013-03-18 01:06:52 +04:00
raise ValueError ( _ ( " Virtual device type must be set in subclass. " ) )
2013-07-16 17:14:37 +04:00
if self . virtual_device_type not in self . virtual_device_types :
2013-03-18 01:06:52 +04:00
raise ValueError ( _ ( " Unknown virtual device type ' %s ' . " ) %
2013-07-16 17:14:37 +04:00
self . virtual_device_type )
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
2013-03-18 01:06:52 +04:00
2013-07-06 04:14:57 +04:00
def setup ( self , meter = None ) :
2013-03-18 01:06:52 +04:00
"""
Perform potentially hazardous device initialization , like
storage creation or host device reset
2018-02-14 15:17:31 +03:00
: param meter : Optional progress meter to use
2013-03-18 01:06:52 +04:00
"""
# Will be overwritten by subclasses if necessary.
ignore = meter
return