Add request_id in PciDevice

Added request_id in the PciDevice object and the corresponding
model. Migration script is added accordingly. Parent objects's
versions are bumped, and backleveling rules added.

Partially Implements: blueprint pci-passthrough-sriov
Change-Id: I2367339a29c0da8b526fd5105766e51ca4e8c6ab
This commit is contained in:
Robert Li 2014-09-08 14:44:32 -04:00 committed by Baodong (Robert) Li
parent d273e33b77
commit e274c45dcd
17 changed files with 132 additions and 38 deletions

View File

@ -0,0 +1,49 @@
# Copyright (c) 2014 Cisco Systems, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sqlalchemy import Column
from sqlalchemy import MetaData
from sqlalchemy import String
from sqlalchemy import Table
def upgrade(engine):
"""Function adds request_id field."""
meta = MetaData(bind=engine)
pci_devices = Table('pci_devices', meta, autoload=True)
shadow_pci_devices = Table('shadow_pci_devices', meta, autoload=True)
request_id = Column('request_id', String(36), nullable=True)
if not hasattr(pci_devices.c, 'request_id'):
pci_devices.create_column(request_id)
if not hasattr(shadow_pci_devices.c, 'request_id'):
shadow_pci_devices.create_column(request_id.copy())
def downgrade(engine):
"""Function drops request_id field."""
meta = MetaData(bind=engine)
pci_devices = Table('pci_devices', meta, autoload=True)
shadow_pci_devices = Table('shadow_pci_devices', meta, autoload=True)
if hasattr(pci_devices.c, 'request_id'):
pci_devices.c.request_id.drop()
if hasattr(shadow_pci_devices.c, 'request_id'):
shadow_pci_devices.c.request_id.drop()

View File

@ -1402,6 +1402,9 @@ class PciDevice(BASE, NovaBase):
label = Column(String(255), nullable=False)
status = Column(String(36), nullable=False)
# the request_id is used to identify a device that is allocated for a
# particular request
request_id = Column(String(36), nullable=True)
extra_info = Column(Text)

View File

@ -41,7 +41,8 @@ class BlockDeviceMapping(base.NovaPersistentObject, base.NovaObject):
# Version 1.0: Initial version
# Version 1.1: Add instance_uuid to get_by_volume_id method
# Version 1.2: Instance version 1.14
VERSION = '1.2'
# Version 1.3: Instance version 1.15
VERSION = '1.3'
fields = {
'id': fields.IntegerField(),
@ -66,9 +67,9 @@ class BlockDeviceMapping(base.NovaPersistentObject, base.NovaObject):
def obj_make_compatible(self, primitive, target_version):
target_version = utils.convert_version_to_tuple(target_version)
if target_version < (1, 2) and 'instance' in primitive:
primitive['instance'] = (
objects.Instance().object_make_compatible(
primitive['instance']['nova_object.data'], '1.13'))
self.instance.obj_make_compatible(
primitive['instance']['nova_object.data'], '1.13')
primitive['instance']['nova_object.version'] = '1.13'
@staticmethod
def _from_db_object(context, block_device_obj,
@ -199,7 +200,8 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
# Version 1.1: BlockDeviceMapping <= version 1.1
# Version 1.2: Added use_slave to get_by_instance_uuid
# Version 1.3: BlockDeviceMapping <= version 1.2
VERSION = '1.3'
# Version 1.4: BlockDeviceMapping <= version 1.3
VERSION = '1.4'
fields = {
'objects': fields.ListOfObjectsField('BlockDeviceMapping'),
@ -209,6 +211,7 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
'1.1': '1.1',
'1.2': '1.1',
'1.3': '1.2',
'1.4': '1.3',
}
@base.remotable_classmethod

View File

@ -28,7 +28,8 @@ class FixedIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
# Version 1.0: Initial version
# Version 1.1: Added virtual_interface field
# Version 1.2: Instance version 1.14
VERSION = '1.2'
# Version 1.3: Instance 1.15
VERSION = '1.3'
fields = {
'id': fields.IntegerField(),
@ -49,9 +50,9 @@ class FixedIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
def obj_make_compatible(self, primitive, target_version):
target_version = utils.convert_version_to_tuple(target_version)
if target_version < (1, 2) and 'instance' in primitive:
primitive['instance'] = (
objects.Instance().object_make_compatible(
primitive['instance']['nova_object.data'], '1.13'))
self.instance.obj_make_compatible(
primitive['instance']['nova_object.data'], '1.13')
primitive['instance']['nova_object.version'] = '1.13'
@property
def floating_ips(self):
@ -174,7 +175,8 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
# Version 1.0: Initial version
# Version 1.1: Added get_by_network()
# Version 1.2: FixedIP <= version 1.2
VERSION = '1.2'
# Version 1.3: FixedIP <= version 1.3
VERSION = '1.3'
fields = {
'objects': fields.ListOfObjectsField('FixedIP'),
@ -183,6 +185,7 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
'1.0': '1.0',
'1.1': '1.1',
'1.2': '1.2',
'1.3': '1.3',
}
@obj_base.remotable_classmethod

View File

@ -26,7 +26,8 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
# Version 1.0: Initial version
# Version 1.1: Added _get_addresses_by_instance_uuid()
# Version 1.2: FixedIP <= version 1.2
VERSION = '1.2'
# Version 1.3: FixedIP <= version 1.3
VERSION = '1.3'
fields = {
'id': fields.IntegerField(),
'address': fields.IPAddressField(),
@ -42,9 +43,9 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
def obj_make_compatible(self, primitive, target_version):
target_version = utils.convert_version_to_tuple(target_version)
if target_version < (1, 2) and 'fixed_ip' in primitive:
primitive['fixed_ip'] = (
objects.FixedIP().object_make_compatible(
primitive['fixed_ip']['nova_object.data'], '1.1'))
self.instance.obj_make_compatible(
primitive['fixed_ip']['nova_object.data'], '1.1')
primitive['fixed_ip']['nova_object.version'] = '1.1'
@staticmethod
def _from_db_object(context, floatingip, db_floatingip,
@ -160,6 +161,8 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject):
class FloatingIPList(obj_base.ObjectListBase, obj_base.NovaObject):
# Version 1.3: FloatingIP 1.2
# Version 1.4: FloatingIP 1.3
fields = {
'objects': fields.ListOfObjectsField('FloatingIP'),
}
@ -168,8 +171,9 @@ class FloatingIPList(obj_base.ObjectListBase, obj_base.NovaObject):
'1.1': '1.1',
'1.2': '1.1',
'1.3': '1.2',
'1.4': '1.3',
}
VERSION = '1.3'
VERSION = '1.4'
@obj_base.remotable_classmethod
def get_all(cls, context):

View File

@ -73,7 +73,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject):
# Version 1.12: Added ephemeral_key_uuid
# Version 1.13: Added delete_metadata_key()
# Version 1.14: Added numa_topology
VERSION = '1.14'
# Version 1.15: PciDeviceList 1.1
VERSION = '1.15'
fields = {
'id': fields.IntegerField(),
@ -222,6 +223,11 @@ class Instance(base.NovaPersistentObject, base.NovaObject):
for field in [x for x in unicode_attributes if x in primitive
and primitive[x] is not None]:
primitive[field] = primitive[field].encode('ascii', 'replace')
if target_version < (1, 15) and 'pci_devices' in primitive:
# NOTE(baoli): Instance <= 1.14 (icehouse) had PciDeviceList 1.0
self.pci_devices.obj_make_compatible(
primitive['pci_devices']['nova_object.data'], '1.0')
primitive['pci_devices']['nova_object.version'] = '1.0'
if target_version < (1, 6):
# NOTE(danms): Before 1.6 there was no pci_devices list
if 'pci_devices' in primitive:
@ -652,7 +658,8 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
# Version 1.6: Instance <= version 1.13
# Version 1.7: Added use_slave to get_active_by_window_joined
# Version 1.8: Instance <= version 1.14
VERSION = '1.8'
# Version 1.9: Instance <= version 1.15
VERSION = '1.9'
fields = {
'objects': fields.ListOfObjectsField('Instance'),
@ -667,6 +674,7 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
'1.6': '1.13',
'1.7': '1.13',
'1.8': '1.14',
'1.9': '1.15',
}
@base.remotable_classmethod

View File

@ -19,6 +19,7 @@ from nova.objects import base
from nova.objects import fields
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova import utils
LOG = logging.getLogger(__name__)
@ -66,7 +67,8 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject):
# Version 1.0: Initial version
# Version 1.1: String attributes updated to support unicode
VERSION = '1.1'
# Version 1.2: added request_id field
VERSION = '1.2'
fields = {
'id': fields.IntegerField(),
@ -81,9 +83,15 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject):
'dev_id': fields.StringField(nullable=True),
'label': fields.StringField(nullable=True),
'instance_uuid': fields.StringField(nullable=True),
'request_id': fields.StringField(nullable=True),
'extra_info': fields.DictOfStringsField(),
}
def obj_make_compatible(self, primitive, target_version):
target_version = utils.convert_version_to_tuple(target_version)
if target_version < (1, 2) and 'request_id' in primitive:
del primitive['request_id']
def update_device(self, dev_dict):
"""Sync the content from device dictionary to device object.
@ -167,7 +175,8 @@ class PciDevice(base.NovaPersistentObject, base.NovaObject):
class PciDeviceList(base.ObjectListBase, base.NovaObject):
# Version 1.0: Initial version
# PciDevice <= 1.1
VERSION = '1.0'
# Version 1.1: PciDevice 1.2
VERSION = '1.1'
fields = {
'objects': fields.ListOfObjectsField('PciDevice'),
@ -175,6 +184,7 @@ class PciDeviceList(base.ObjectListBase, base.NovaObject):
child_versions = {
'1.0': '1.1',
# NOTE(danms): PciDevice was at 1.1 before we added this
'1.1': '1.2',
}
def __init__(self, *args, **kwargs):

View File

@ -72,6 +72,7 @@ def allocate(devobj, instance):
def remove(devobj):
devobj.status = 'removed'
devobj.instance_uuid = None
devobj.request_id = None
@check_device_status(dev_status=['claimed', 'allocated'])
@ -84,6 +85,7 @@ def free(devobj, instance=None):
old_status = devobj.status
devobj.status = 'available'
devobj.instance_uuid = None
devobj.request_id = None
if old_status == 'allocated' and instance:
# Notes(yjiang5): remove this check when instance object for
# compute manager is finished

View File

@ -7089,6 +7089,7 @@ class PciDeviceDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin):
'label': 'label_8086_1520',
'status': 'available',
'instance_uuid': '00000000-0000-0000-0000-000000000010',
'request_id': None,
}, {'id': 3356,
'compute_node_id': 1,
'address': '0000:0f:03.7',
@ -7100,6 +7101,7 @@ class PciDeviceDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin):
'label': 'label_8086_1520',
'status': 'available',
'instance_uuid': '00000000-0000-0000-0000-000000000010',
'request_id': None,
}
def _create_fake_pci_devs(self):

View File

@ -35,6 +35,7 @@ fake_db_dev_1 = {
'dev_id': 'pci_0000_04_10_0',
'label': 'label_8086_1520',
'instance_uuid': '69ba1044-0766-4ec0-b60d-09595de034a1',
'request_id': None,
'extra_info': '{"key1": "value1", "key2": "value2"}'
}
@ -53,6 +54,7 @@ fake_db_dev_2 = {
'dev_id': 'pci_0000_04_10_1',
'label': 'label_8086_1520',
'instance_uuid': 'd5b446a6-a1b4-4d01-b4f0-eac37b3a62fc',
'request_id': None,
'extra_info': '{"key3": "value3", "key4": "value4"}'
}

View File

@ -72,7 +72,7 @@ class _TestInstanceObject(object):
primitive = inst.obj_to_primitive()
expected = {'nova_object.name': 'Instance',
'nova_object.namespace': 'nova',
'nova_object.version': '1.14',
'nova_object.version': '1.15',
'nova_object.data':
{'uuid': 'fake-uuid',
'launched_at': '1955-11-05T00:00:00Z'},
@ -88,7 +88,7 @@ class _TestInstanceObject(object):
primitive = inst.obj_to_primitive()
expected = {'nova_object.name': 'Instance',
'nova_object.namespace': 'nova',
'nova_object.version': '1.14',
'nova_object.version': '1.15',
'nova_object.data':
{'uuid': 'fake-uuid',
'access_ip_v4': '1.2.3.4',
@ -568,6 +568,7 @@ class _TestInstanceObject(object):
'dev_id': 'i',
'label': 'l',
'instance_uuid': fake_uuid,
'request_id': None,
'extra_info': '{}'},
{
'created_at': None,
@ -584,6 +585,7 @@ class _TestInstanceObject(object):
'dev_id': 'i',
'label': 'l',
'instance_uuid': fake_uuid,
'request_id': None,
'extra_info': '{}'},
]
self.mox.StubOutWithMock(db, 'instance_get_by_uuid')

View File

@ -935,8 +935,8 @@ object_data = {
'AggregateList': '1.2-4b02a285b8612bfb86a96ff80052fb0a',
'BandwidthUsage': '1.1-bdab751673947f0ac7de108540a1a8ce',
'BandwidthUsageList': '1.1-76898106a9db393cd5f42c557389c507',
'BlockDeviceMapping': '1.2-9968ffe513e7672484b0f528b034cd0f',
'BlockDeviceMappingList': '1.3-de607d5ae2f379c75c49a125bb3b4515',
'BlockDeviceMapping': '1.3-9968ffe513e7672484b0f528b034cd0f',
'BlockDeviceMappingList': '1.4-388b059a9d47ce71d4e8f3cc4f4b760c',
'ComputeNode': '1.5-57ce5a07c727ffab6c51723bb8dccbfe',
'ComputeNodeList': '1.5-a1641ab314063538470d57daaa5c7831',
'DNSDomain': '1.0-5bdc288d7c3b723ce86ede998fd5c9ba',
@ -944,13 +944,13 @@ object_data = {
'EC2InstanceMapping': '1.0-627baaf4b12c9067200979bdc4558a99',
'EC2SnapshotMapping': '1.0-26cf315be1f8abab4289d4147671c836',
'EC2VolumeMapping': '1.0-2f8c3bf077c65a425294ec2b361c9143',
'FixedIP': '1.2-082fb26772ce2db783ce4934edca4652',
'FixedIPList': '1.2-d073a985508addd78b35ea421eb8da7c',
'FixedIP': '1.3-082fb26772ce2db783ce4934edca4652',
'FixedIPList': '1.3-859ecd7b5ab338c2e18db4a7352dc80e',
'Flavor': '1.1-096cfd023c35d07542cf732fb29b45e4',
'FlavorList': '1.1-a3d5551267cb8f62ff38ded125900721',
'FloatingIP': '1.2-27eb68b7c9c620dd5f0561b5a3be0e82',
'FloatingIPList': '1.3-bbc671d6259032ee362ff6ee3600d749',
'Instance': '1.14-1154dc29398bc3c57f053b8e449bb03d',
'FloatingIP': '1.3-27eb68b7c9c620dd5f0561b5a3be0e82',
'FloatingIPList': '1.4-f77140acae46312d2d9f54dc4edab517',
'Instance': '1.15-1154dc29398bc3c57f053b8e449bb03d',
'InstanceAction': '1.1-6b1d0a6dbd522b5a83c20757ec659663',
'InstanceActionEvent': '1.1-42dbdba74bd06e0619ca75cd3397cd1b',
'InstanceActionEventList': '1.0-1d5cc958171d6ce07383c2ad6208318e',
@ -961,7 +961,7 @@ object_data = {
'InstanceGroup': '1.7-b31ea31fdb452ab7810adbe789244f91',
'InstanceGroupList': '1.2-a474822eebc3e090012e581adcc1fa09',
'InstanceInfoCache': '1.5-ef64b604498bfa505a8c93747a9d8b2f',
'InstanceList': '1.8-16db4c93fe5b80564413b9a4f547e0d1',
'InstanceList': '1.9-6f290799b0ac19eb9e72ed580520b883',
'InstanceNUMACell': '1.0-17e6ee0a24cb6651d1b084efa3027bda',
'InstanceNUMATopology': '1.0-86b95d263c4c68411d44c6741b8d2bb0',
'KeyPair': '1.1-3410f51950d052d861c11946a6ae621a',
@ -972,8 +972,8 @@ object_data = {
'MyOwnedObject': '1.0-0f3d6c028543d7f3715d121db5b8e298',
'Network': '1.2-2ea21ede5e45bb80e7b7ac7106915c4e',
'NetworkList': '1.2-aa4ad23f035b97a41732ea8b3445fc5e',
'PciDevice': '1.1-523c46f960d93f78db55f0280b09441e',
'PciDeviceList': '1.0-43d6c4ea0dd77955e97b23d937a3f925',
'PciDevice': '1.2-29e35c3199f3b98ce66e5d1212612818',
'PciDeviceList': '1.1-2896df4f5b06579e5f35adba5fcae9db',
'Quotas': '1.1-7897deef00e6cd3095c8916f68d24418',
'QuotasNoOp': '1.1-4b06fd721c586b907ddd6543a00d6c2f',
'S3ImageMapping': '1.0-9225943a44a91ad0349b9fd8bd3f3ce2',
@ -990,14 +990,14 @@ object_data = {
object_relationships = {
'BlockDeviceMapping': {'Instance': '1.14'},
'FixedIP': {'Instance': '1.14', 'Network': '1.2',
'BlockDeviceMapping': {'Instance': '1.15'},
'FixedIP': {'Instance': '1.15', 'Network': '1.2',
'VirtualInterface': '1.0'},
'FloatingIP': {'FixedIP': '1.2'},
'FloatingIP': {'FixedIP': '1.3'},
'Instance': {'InstanceFault': '1.2',
'InstanceInfoCache': '1.5',
'InstanceNUMATopology': '1.0',
'PciDeviceList': '1.0',
'PciDeviceList': '1.1',
'SecurityGroupList': '1.0'},
'MyObj': {'MyOwnedObject': '1.0'},
'SecurityGroupRule': {'SecurityGroup': '1.1'},

View File

@ -45,6 +45,7 @@ fake_db_dev = {
'label': 'l',
'instance_uuid': None,
'extra_info': '{}',
'request_id': None,
}
@ -64,6 +65,7 @@ fake_db_dev_1 = {
'label': 'l',
'instance_uuid': None,
'extra_info': '{}',
'request_id': None,
}

View File

@ -37,6 +37,7 @@ dev_dict = {
'label': 'l',
'instance_uuid': None,
'extra_info': '{}',
'request_id': None,
}

View File

@ -34,6 +34,7 @@ fake_pci = {
'address': '0000:00:00.1',
'product_id': 'p',
'vendor_id': 'v',
'request_id': None,
'status': 'available'}
fake_pci_1 = dict(fake_pci, address='0000:00:00.2',
product_id='p1', vendor_id='v1')
@ -56,6 +57,7 @@ fake_db_dev = {
'label': 'l',
'instance_uuid': None,
'extra_info': '{}',
'request_id': None,
}
fake_db_dev_1 = dict(fake_db_dev, vendor_id='v1',
product_id='p1', id=2,

View File

@ -26,6 +26,7 @@ fake_pci_1 = {
'vendor_id': 'v1',
'status': 'available',
'extra_k1': 'v1',
'request_id': None,
}

View File

@ -712,14 +712,14 @@ class SessionBase(object):
"""
# Driver is not pciback
dev_bad1 = ["Slot:\t86:10.0", "Class:\t0604", "Vendor:\t10b5",
dev_bad1 = ["Slot:\t0000:86:10.0", "Class:\t0604", "Vendor:\t10b5",
"Device:\t8747", "Rev:\tba", "Driver:\tpcieport", "\n"]
# Driver is pciback but vendor and device are bad
dev_bad2 = ["Slot:\t88:00.0", "Class:\t0300", "Vendor:\t0bad",
dev_bad2 = ["Slot:\t0000:88:00.0", "Class:\t0300", "Vendor:\t0bad",
"Device:\tcafe", "SVendor:\t10de", "SDevice:\t100d",
"Rev:\ta1", "Driver:\tpciback", "\n"]
# Driver is pciback and vendor, device are used for matching
dev_good = ["Slot:\t87:00.0", "Class:\t0300", "Vendor:\t10de",
dev_good = ["Slot:\t0000:87:00.0", "Class:\t0300", "Vendor:\t10de",
"Device:\t11bf", "SVendor:\t10de", "SDevice:\t100d",
"Rev:\ta1", "Driver:\tpciback", "\n"]