|
14 | 14 |
|
15 | 15 | import itertools |
16 | 16 |
|
| 17 | +from oslo_log import log as logging |
17 | 18 | from oslo_serialization import jsonutils |
18 | 19 | from oslo_utils import versionutils |
19 | 20 |
|
|
24 | 25 | from nova.objects import fields as obj_fields |
25 | 26 | from nova.virt import hardware |
26 | 27 |
|
| 28 | +LOG = logging.getLogger(__name__) |
| 29 | + |
27 | 30 |
|
28 | 31 | # TODO(berrange): Remove NovaObjectDictCompat |
29 | 32 | @base.NovaObjectRegistry.register |
@@ -61,6 +64,11 @@ def obj_make_compatible(self, primitive, target_version): |
61 | 64 | obj_fields.CPUAllocationPolicy.DEDICATED): |
62 | 65 | primitive['cpuset'] = primitive['pcpuset'] |
63 | 66 | primitive.pop('pcpuset', None) |
| 67 | + LOG.warning( |
| 68 | + f'Downgrading InstanceNUMACell to version {target_version} ' |
| 69 | + f'may cause the loss of pinned CPUs if mixing different ' |
| 70 | + f'verisons of nova on different hosts. This should not ' |
| 71 | + f'happen on any supported version after Victoria.') |
64 | 72 |
|
65 | 73 | if target_version < (1, 4): |
66 | 74 | primitive.pop('cpuset_reserved', None) |
@@ -188,15 +196,79 @@ def _migrate_legacy_dedicated_instance_cpuset(cls, obj): |
188 | 196 | # come from instance_extra or request_spec too. |
189 | 197 | update_db = False |
190 | 198 | for cell in obj.cells: |
191 | | - if len(cell.cpuset) == 0: |
| 199 | + version = versionutils.convert_version_to_tuple(cell.VERSION) |
| 200 | + |
| 201 | + if version < (1, 4): |
| 202 | + LOG.warning( |
| 203 | + "InstanceNUMACell %s with version %s for instance %s has " |
| 204 | + "too old version in the DB, don't know how to update, " |
| 205 | + "ignoring.", cell, cell.VERSION, obj.instance_uuid) |
192 | 206 | continue |
193 | 207 |
|
194 | | - if cell.cpu_policy != obj_fields.CPUAllocationPolicy.DEDICATED: |
| 208 | + if (version >= (1, 5) and |
| 209 | + cell.cpu_policy == obj_fields.CPUAllocationPolicy.DEDICATED and |
| 210 | + (cell.cpuset or not cell.pcpuset) |
| 211 | + ): |
| 212 | + LOG.warning( |
| 213 | + "InstanceNUMACell %s with version %s is inconsistent as " |
| 214 | + "the version is 1.5 or greater, cpu_policy is dedicated, " |
| 215 | + "but cpuset is not empty or pcpuset is empty.", |
| 216 | + cell, cell.VERSION) |
195 | 217 | continue |
196 | 218 |
|
197 | | - cell.pcpuset = cell.cpuset |
198 | | - cell.cpuset = set() |
199 | | - update_db = True |
| 219 | + # NOTE(gibi): The data migration between 1.4. and 1.5 populates the |
| 220 | + # pcpuset field that is new in version 1.5. However below we update |
| 221 | + # the object version to 1.6 directly. This is intentional. The |
| 222 | + # version 1.6 introduced a new possible value 'mixed' for the |
| 223 | + # cpu_policy field. As that is a forward compatible change we don't |
| 224 | + # have a specific data migration for it. But we also don't have an |
| 225 | + # automated way to update old object versions from 1.5 to 1.6. So |
| 226 | + # we do it here just to avoid inconsistency between data and |
| 227 | + # version in the DB. |
| 228 | + if version < (1, 6): |
| 229 | + if cell.cpu_policy == obj_fields.CPUAllocationPolicy.DEDICATED: |
| 230 | + if "pcpuset" not in cell or not cell.pcpuset: |
| 231 | + # this cell was never migrated to 1.6, migrate it. |
| 232 | + cell.pcpuset = cell.cpuset |
| 233 | + cell.cpuset = set() |
| 234 | + cell.VERSION = '1.6' |
| 235 | + update_db = True |
| 236 | + else: |
| 237 | + # This data was already migrated to 1.6 format but the |
| 238 | + # version string wasn't updated to 1.6. This happened |
| 239 | + # before the fix |
| 240 | + # https://bugs.launchpad.net/nova/+bug/2097360 |
| 241 | + # Only update the version string. |
| 242 | + cell.VERSION = '1.6' |
| 243 | + update_db = True |
| 244 | + elif cell.cpu_policy in ( |
| 245 | + None, obj_fields.CPUAllocationPolicy.SHARED): |
| 246 | + # no data migration needed just add the new field and |
| 247 | + # stamp the new version in the DB |
| 248 | + cell.pcpuset = set() |
| 249 | + cell.VERSION = '1.6' |
| 250 | + update_db = True |
| 251 | + else: # obj_fields.CPUAllocationPolicy.MIXED |
| 252 | + # This means the cell data already got updated to the 1.6 |
| 253 | + # content as MIXED only supported with 1.6 but the version |
| 254 | + # was not updated to 1.6. |
| 255 | + # We should not do the data migration as that would trample |
| 256 | + # the pcpuset field. Just stamp the 1.6 version in the DB |
| 257 | + # and hope for the best. |
| 258 | + LOG.warning( |
| 259 | + "InstanceNUMACell %s with version %s for instance %s " |
| 260 | + "has older than 1.6 version in the DB but using the " |
| 261 | + "1.6 feature CPUAllocationPolicy.MIXED. So nova " |
| 262 | + "assumes that the data is in 1.6 format and only the " |
| 263 | + "version string is old. Correcting the version string " |
| 264 | + "in the DB.", cell, cell.VERSION, obj.instance_uuid) |
| 265 | + cell.VERSION = '1.6' |
| 266 | + update_db = True |
| 267 | + |
| 268 | + # When the next ovo version 1.7 is added it needs to be handed |
| 269 | + # here to do any migration if needed and to ensure the version in |
| 270 | + # the DB is stamped to 1.7 |
| 271 | + |
200 | 272 | return update_db |
201 | 273 |
|
202 | 274 | # TODO(huaqiang): Remove after Yoga once we are sure these objects have |
|
0 commit comments