)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a43ac980e4667eb258389ca2b8b280e6e50132bb","unresolved":false,"context_lines":[{"line_number":13,"context_line":"  needs to generate correct instance XML. The hash and eq methods will"},{"line_number":14,"context_line":"  be useful in unit tests in subsequent patches."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Implements blueprint bp/numa-aware-live-migration"},{"line_number":17,"context_line":"Change-Id: I7c7f54ab142f01808ee4b46d27b4a336e476cc77"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":33,"id":"7faddb67_12d96982","line":16,"range":{"start_line":16,"start_character":21,"end_line":16,"end_character":24},"updated":"2019-07-04 10:22:35.000000000","message":"Drop this or you break linking from Gerrit","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"1f3bceff2eb62929fe2ae69eb8d32df385ca5b28","unresolved":false,"context_lines":[{"line_number":13,"context_line":"  needs to generate correct instance XML. The hash and eq methods will"},{"line_number":14,"context_line":"  be useful in unit tests in subsequent patches."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Implements blueprint bp/numa-aware-live-migration"},{"line_number":17,"context_line":"Change-Id: I7c7f54ab142f01808ee4b46d27b4a336e476cc77"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":33,"id":"7faddb67_14e63618","line":16,"range":{"start_line":16,"start_character":21,"end_line":16,"end_character":24},"in_reply_to":"7faddb67_12d96982","updated":"2019-07-04 11:29:21.000000000","message":"Done","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch contains the Nova object modifications that will eventually"},{"line_number":10,"context_line":"enable NUMA live migration:"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"* src_suports_numa_live_migration is added to LibvirtLiveMigrateData."},{"line_number":13,"context_line":"The source host will use it to indicate to the destination that it can"},{"line_number":14,"context_line":"perform a NUMA-aware live migration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"7faddb67_82cf6b26","line":12,"updated":"2019-09-05 19:28:02.000000000","message":"From an earlier comment later in the series where the source/dest handshake stuff happens [1] I asked about why there isn\u0027t a corresponding dst_suports_numa_live_migration since you\u0027ve changed the rpc interface for check_can_live_migrate_source to pass a numa_live_migration flag but it seems like that is very specific to change the entire check_can_live_migrate_source interface and would be better hidden within the LibvirtLiveMigrateData object since it doesn\u0027t mean that, for example, hyper-v supports numa live migration. I guess I\u0027ll figure that out why you did it that way later when I get into that change.\n\n[1] https://review.opendev.org/#/c/634606/71/nova/compute/manager.py@6486","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d06400ca9a5812e910ac22dca5c0d2ebf16d4e1c","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch contains the Nova object modifications that will eventually"},{"line_number":10,"context_line":"enable NUMA live migration:"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"* src_suports_numa_live_migration is added to LibvirtLiveMigrateData."},{"line_number":13,"context_line":"The source host will use it to indicate to the destination that it can"},{"line_number":14,"context_line":"perform a NUMA-aware live migration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"5faad753_e8906b51","line":12,"in_reply_to":"5faad753_657a6689","updated":"2019-09-05 22:56:23.000000000","message":"OK, let\u0027s do this. The func tests should tell us fairly quickly if it causes problems having the dest pinned to 5.2.","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"5078d6dffcbf938a506c92bc0dd876e0af00397a","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch contains the Nova object modifications that will eventually"},{"line_number":10,"context_line":"enable NUMA live migration:"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"* src_suports_numa_live_migration is added to LibvirtLiveMigrateData."},{"line_number":13,"context_line":"The source host will use it to indicate to the destination that it can"},{"line_number":14,"context_line":"perform a NUMA-aware live migration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"5faad753_657a6689","line":12,"in_reply_to":"7faddb67_2e946043","updated":"2019-09-05 21:19:32.000000000","message":"tl;dr (and I think I said this better elsewhere later in the series), dst_supports_numa_live_migration would mean the dest is telling the source it\u0027s cool to do numa live migration if the source is, and the source sets src_suports_numa_live_migration if it\u0027s also cool with it, and if we\u0027re doing flags for this, let\u0027s be consistent and put them both in the migrate data object.","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"9f10a121003d6a21008100bb0bb52884734a91b2","unresolved":false,"context_lines":[{"line_number":9,"context_line":"This patch contains the Nova object modifications that will eventually"},{"line_number":10,"context_line":"enable NUMA live migration:"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"* src_suports_numa_live_migration is added to LibvirtLiveMigrateData."},{"line_number":13,"context_line":"The source host will use it to indicate to the destination that it can"},{"line_number":14,"context_line":"perform a NUMA-aware live migration."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"7faddb67_2e946043","line":12,"in_reply_to":"7faddb67_82cf6b26","updated":"2019-09-05 20:30:22.000000000","message":"That\u0027s actually a good point. Thinking about this again (with only my phone, so hard to look up code), I don\u0027t think the destination needs to be able to *send* RPC 5.3. The conductor does, because it needs to pass migration and limits to the destination, and the source does, because on rollback it needs to call drop_move_claim_at_destination, but from memory, the destination only needs to receive 5.3, not send it, so it\u0027d be reasonable to move the numa_live_migration parameter into a dst_supports_numa_live_migration field in the migrate data. Dan, keep me honest?","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":19,"context_line":"emulator thread pins."},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"* dst_numa_info is added to LibvirtLiveMigrateData. It contains a"},{"line_number":22,"context_line":"LibvirtLiveMigrateNUMAInfo object. It will be set by the destination"},{"line_number":23,"context_line":"and will be used by the source to update the intance\u0027s XML."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Implements blueprint numa-aware-live-migration"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"7faddb67_82120b60","line":22,"range":{"start_line":22,"start_character":57,"end_line":22,"end_character":68},"updated":"2019-09-05 19:28:02.000000000","message":"ack: https://review.opendev.org/#/c/635229/58/nova/virt/libvirt/driver.py@7323","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"* dst_numa_info is added to LibvirtLiveMigrateData. It contains a"},{"line_number":22,"context_line":"LibvirtLiveMigrateNUMAInfo object. It will be set by the destination"},{"line_number":23,"context_line":"and will be used by the source to update the intance\u0027s XML."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Implements blueprint numa-aware-live-migration"},{"line_number":26,"context_line":"Change-Id: I7c7f54ab142f01808ee4b46d27b4a336e476cc77"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"7faddb67_8281abc4","line":23,"range":{"start_line":23,"start_character":45,"end_line":23,"end_character":52},"updated":"2019-09-05 19:28:02.000000000","message":"instances","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d06400ca9a5812e910ac22dca5c0d2ebf16d4e1c","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"* dst_numa_info is added to LibvirtLiveMigrateData. It contains a"},{"line_number":22,"context_line":"LibvirtLiveMigrateNUMAInfo object. It will be set by the destination"},{"line_number":23,"context_line":"and will be used by the source to update the intance\u0027s XML."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Implements blueprint numa-aware-live-migration"},{"line_number":26,"context_line":"Change-Id: I7c7f54ab142f01808ee4b46d27b4a336e476cc77"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":57,"id":"5faad753_c8932f5c","line":23,"range":{"start_line":23,"start_character":45,"end_line":23,"end_character":52},"in_reply_to":"7faddb67_8281abc4","updated":"2019-09-05 22:56:23.000000000","message":"Done","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"}],"nova/objects/migrate_data.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"71521dc94e914626f5e9d9983ae1fe732b5d59b5","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class NUMAMigrateData(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9fdfeff1_6609eadb","line":99,"range":{"start_line":99,"start_character":6,"end_line":99,"end_character":21},"updated":"2019-02-06 17:51:01.000000000","message":"super small nit but it\nmight be nice to add an __repr__\nfucntion to pretty print this\nfor debuging but the default form should be fine too.","commit_id":"9bab5bae1cf98b80fbd125c6e1c91641b83ac718"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"bbea0999b4a6b586e2aa40ff2992c243fa0631bc","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class NUMAMigrateData(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9fdfeff1_fa7322b0","line":99,"range":{"start_line":99,"start_character":6,"end_line":99,"end_character":21},"in_reply_to":"9fdfeff1_6609eadb","updated":"2019-02-07 00:19:29.000000000","message":"Yeah, I\u0027ll see what we need as I continue.","commit_id":"9bab5bae1cf98b80fbd125c6e1c91641b83ac718"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"71521dc94e914626f5e9d9983ae1fe732b5d59b5","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfIntegersField(),"},{"line_number":105,"context_line":"        \u0027cell_pins\u0027: fields.DictOfIntegersField(),"},{"line_number":106,"context_line":"        \u0027emulator_pins\u0027: fields.ListOfIntegersField(),"},{"line_number":107,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":4,"id":"9fdfeff1_a6ecb2f3","line":104,"range":{"start_line":104,"start_character":21,"end_line":104,"end_character":49},"updated":"2019-02-06 17:51:01.000000000","message":"can you add a doc string stating that cpu_pins is a\ndict of guest cpu id to host cpu id mapping so that the order\nof key vs value being guest to host is clear.\n\nsame for the other fields","commit_id":"9bab5bae1cf98b80fbd125c6e1c91641b83ac718"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"bbea0999b4a6b586e2aa40ff2992c243fa0631bc","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfIntegersField(),"},{"line_number":105,"context_line":"        \u0027cell_pins\u0027: fields.DictOfIntegersField(),"},{"line_number":106,"context_line":"        \u0027emulator_pins\u0027: fields.ListOfIntegersField(),"},{"line_number":107,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":4,"id":"9fdfeff1_9a68d6ba","line":104,"range":{"start_line":104,"start_character":21,"end_line":104,"end_character":49},"in_reply_to":"9fdfeff1_a6ecb2f3","updated":"2019-02-07 00:19:29.000000000","message":"Done","commit_id":"9bab5bae1cf98b80fbd125c6e1c91641b83ac718"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"5034021077756734e6d06715959d8c45301d954c","unresolved":false,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        # Guest to host CPU pins"},{"line_number":105,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":106,"context_line":"        # Guest to host NUMA node pins"},{"line_number":107,"context_line":"        \u0027cell_pins\u0027: fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":108,"context_line":"        # List of host CPUs for emulator threads"}],"source_content_type":"text/x-python","patch_set":6,"id":"9fdfeff1_adc001e2","line":105,"range":{"start_line":105,"start_character":20,"end_line":105,"end_character":62},"updated":"2019-02-07 11:16:37.000000000","message":"i realised last night that this needs to be a \"dict of set of ints\" field.\n\nthe reason being when we request a numa topolgoy without cpu pinning we do not pin vcpus to a singel core we pin vcpus to a set of host cpus corresponding to the numa node.\n\nso the host pinning is not a single value but is a set of host cpus.","commit_id":"83dc7cb807ca59fb4f0b3072c818f7361bfa79c7"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"b9b9b184a1803a8383a1800bfb4749161ac87693","unresolved":false,"context_lines":[{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        # Guest to host CPU pins"},{"line_number":105,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":106,"context_line":"        # Guest to host NUMA node pins"},{"line_number":107,"context_line":"        \u0027cell_pins\u0027: fields.DictOfIntegersField(nullable\u003dTrue),"},{"line_number":108,"context_line":"        # List of host CPUs for emulator threads"}],"source_content_type":"text/x-python","patch_set":6,"id":"9fdfeff1_49f4e087","line":105,"range":{"start_line":105,"start_character":20,"end_line":105,"end_character":62},"in_reply_to":"9fdfeff1_adc001e2","updated":"2019-02-07 18:09:02.000000000","message":"Done","commit_id":"83dc7cb807ca59fb4f0b3072c818f7361bfa79c7"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"6e4cb533137abc54cb29e05e0e31032ada9dac63","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        # default for the config option may change in the future"},{"line_number":165,"context_line":"        \u0027wait_for_vif_plugged\u0027: fields.BooleanField(),"},{"line_number":166,"context_line":"        \u0027vifs\u0027: fields.ListOfObjectsField(\u0027VIFMigrateData\u0027),"},{"line_number":167,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027)"},{"line_number":168,"context_line":"    }"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9fdfeff1_d9d52c1d","line":167,"range":{"start_line":167,"start_character":0,"end_line":167,"end_character":64},"updated":"2019-02-19 16:59:35.000000000","message":"Why are we making this an attribute of the base object rather than the libvirt implementation? No other drive supports CPU pinning nor has expressed any interest in gaining this functionality, so I wonder if we\u0027re putting the cart before the horse here. Also, trailing comma would be helpful","commit_id":"91ad446181e17581dc078bc123c3164abef92a40"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d9dd074f2f1bba2a3624eea1361e58c1f98beb29","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        # default for the config option may change in the future"},{"line_number":165,"context_line":"        \u0027wait_for_vif_plugged\u0027: fields.BooleanField(),"},{"line_number":166,"context_line":"        \u0027vifs\u0027: fields.ListOfObjectsField(\u0027VIFMigrateData\u0027),"},{"line_number":167,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027)"},{"line_number":168,"context_line":"    }"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9fdfeff1_1a4934b6","line":167,"range":{"start_line":167,"start_character":0,"end_line":167,"end_character":64},"in_reply_to":"9fdfeff1_d9d52c1d","updated":"2019-02-21 16:17:30.000000000","message":"Done","commit_id":"91ad446181e17581dc078bc123c3164abef92a40"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"7bb13c2d5ecf574481c62320c82c77e28010f6fe","unresolved":false,"context_lines":[{"line_number":164,"context_line":"        # default for the config option may change in the future"},{"line_number":165,"context_line":"        \u0027wait_for_vif_plugged\u0027: fields.BooleanField(),"},{"line_number":166,"context_line":"        \u0027vifs\u0027: fields.ListOfObjectsField(\u0027VIFMigrateData\u0027),"},{"line_number":167,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027)"},{"line_number":168,"context_line":"    }"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"9fdfeff1_99e9e4b8","line":167,"range":{"start_line":167,"start_character":0,"end_line":167,"end_character":64},"in_reply_to":"9fdfeff1_d9d52c1d","updated":"2019-02-19 17:06:51.000000000","message":"I\u0027d sorta wondered about that as well - but not too much, because I then blindly copied Sean\u0027s work for the new port binding API series. If we\u0027re confident nothing outside of libvirt will care about this in the foreseeable future, I\u0027ll happily put this in LibvirtLiveMigrateData and not bother with the rest.","commit_id":"91ad446181e17581dc078bc123c3164abef92a40"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"edff823e37e47636ab373f204c3a52615b3cd463","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_1501e604","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"updated":"2019-02-23 06:07:37.000000000","message":"So we already have instance.migration_context, that include the claimed instance numa obj. And then we can pass the dest host numa topo obj back to the source host in the migration data obj. Then we use claimed instance numa obj and dest host numa topo obj to build the xml. I feel that is better than hacking the xml directly https://review.openstack.org/#/c/635229/21/nova/virt/libvirt/migration.py@102, and we needn\u0027t those new objects also. I just want to know why we want to do this way? (I know there some existed code hacking the xml now...but I want to know whether people prefer that way)\n\nSo I\u0027m not following all the discussion for this feature, apologize if I asked something people already discussed.","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"e4a72bb3863b900d68928af781dec0e0d46fd0d7","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_896dbf9a","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"in_reply_to":"9fdfeff1_1501e604","updated":"2019-02-23 21:36:18.000000000","message":"It\u0027s a valid concern, and while we have sort of talked about this before, it\u0027s worth going over again.\n\nEssentially, the NUMA objects are an imcomplete model: they are *almost* enough for the source to update the XML, but not quite. For example, emulator threads get placed on CONF.compute.cpu_shared_set if the emulator threads policy is `share`. Only the destination host knows what its cpu_shared_set is, and that information only exists as a config option.\n\nI\u0027ve left a TODOO to this effect in another patch [1]. It\u0027d be good to improve this, but maybe let\u0027s start with a baseline that\u0027s easier to implement by re-using as much existing code as possible?\n\n[1] https://review.openstack.org/#/c/634828/24/nova/virt/libvirt/driver.py@6752","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d032367517a5cea22b08be7ec7c85126aa6a997c","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_940aa223","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"in_reply_to":"9fdfeff1_32de73da","updated":"2019-02-25 15:53:37.000000000","message":"\u003e * reusing existed libvifg config generation code\n\nWouldn\u0027t that be the main advantage of doing the config generation on the dest? Looking at _get_guest_numa_config(), there\u0027s a whole bunch of places where it depends on the host it\u0027s running on:\n\n[1] calls [2], and just in _get_host_numa_topology() there\u0027s [3], [4], [5], [6] and [7] that are dest-specific.\n\nI\u0027m not saying we need all of those for live migration, so we could conceivably have the dest send its host topology, its vcpu_pin_set, and anything else that might be necessary, to the source, and the source can update the XML from that.\n\nHowever, it\u0027s just so much safer to use the existing _get_guest_numa_config() on the dest by giving it what it needs to know about the instance.\n\nThe alternative would be to reproduce parts of the logic of _get_guest_numa_config() on the source with information sent from the dest, but that would be new fragile code.\n\n[1] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L4452\n[2] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6274\n[3] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6285\n[4] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6286\n[5] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6293\n[6] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6293\n[7] https://github.com/openstack/nova/blob/a90c8e1a359a236e06f3a78df74f55808bbef31b/nova/virt/libvirt/driver.py#L6298","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2662ba3b70b615ebc8166f3c0f4e68340db46eff","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_32de73da","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"in_reply_to":"9fdfeff1_896dbf9a","updated":"2019-02-25 05:44:21.000000000","message":"Yes, actually I mean we put the dest host numa obj and dest host cpu shared set and etc all we need in the NUMAMigrateData obj.\n\nThen we use the libvirt config building code of source node to generate the XML with those dest host info.\n\nPros:\n  * avoid to hack xml\n  * reusing existed libvifg config generation code\n  * reusing existed obj, avoid to add new obj\nCons:\n  * more data transfer between dest and src host\n  * If the source host and dest host are running in different version, they may have different way to build libvirt config. Then the src node may build a wrong libvirt config for dest node, but I don\u0027t think it will happy, since libvirt probably need same libvirt config on two nodes to make the LM successful.","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"d2947dbf1c689e69ac19ef5b85373bed4bb76bc3","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_b02228a2","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"in_reply_to":"9fdfeff1_940aa223","updated":"2019-02-27 05:19:59.000000000","message":"Yea, I see, the host info is more than I thought. I agree this is safest way to do that. Thanks for collecting all those code to reply my comment","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"edff823e37e47636ab373f204c3a52615b3cd463","unresolved":false,"context_lines":[{"line_number":129,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"    fields \u003d {"},{"line_number":132,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":133,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":135,"context_line":"    }"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_b507ba18","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":61},"updated":"2019-02-23 06:07:37.000000000","message":"so....sounds like ObjectsOfIntegers is enough...What is reason we introduce this new obj?","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2662ba3b70b615ebc8166f3c0f4e68340db46eff","unresolved":false,"context_lines":[{"line_number":129,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"    fields \u003d {"},{"line_number":132,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":133,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":135,"context_line":"    }"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_f2bf8b5d","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":61},"in_reply_to":"9fdfeff1_a90d23e9","updated":"2019-02-25 05:44:21.000000000","message":"sorry :) DictOfIntegers","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"e4a72bb3863b900d68928af781dec0e0d46fd0d7","unresolved":false,"context_lines":[{"line_number":129,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"    fields \u003d {"},{"line_number":132,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":133,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":135,"context_line":"    }"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_a90d23e9","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":61},"in_reply_to":"9fdfeff1_b507ba18","updated":"2019-02-23 21:36:18.000000000","message":"I\u0027m not sure I understand what an ObjectsOfIntegers is :)","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d032367517a5cea22b08be7ec7c85126aa6a997c","unresolved":false,"context_lines":[{"line_number":129,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"    fields \u003d {"},{"line_number":132,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":133,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":135,"context_line":"    }"},{"line_number":136,"context_line":""}],"source_content_type":"text/x-python","patch_set":23,"id":"9fdfeff1_b47ec6e0","line":133,"range":{"start_line":132,"start_character":8,"end_line":133,"end_character":61},"in_reply_to":"9fdfeff1_f2bf8b5d","updated":"2019-02-25 15:53:37.000000000","message":"So DictOfIntegers is 1:1, right? That won\u0027t work because a pin could be 1:many.","commit_id":"62253421edaf5b0298815e1396afc9bfe1b9a55a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"815be96aafde2d7971af3f068351d6d0f392341a","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        \u0027guest_id\u0027: fields.IntegerField(),"},{"line_number":105,"context_line":"        \u0027host_ids\u0027: fields.SetOfIntegersField(),"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_aad6434e","line":104,"updated":"2019-02-26 16:55:18.000000000","message":"Maybe I\u0027ll figure this out after further reading, but is guest_id is the integer libvirt \"domain number\" from the source, yeah? Is this just intended to be an identifier used by the remote to correlate multiple pinning objects?\n\nEr, wait. Maybe guest_id is the id of the resource as visible to the guest (i.e. core 0) to map to host resource (i.e. core 6) ?\n\nProbably worth some extra comments around here to make sure that\u0027s clear.","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"3f15251f13c0c2bf95eae41f76d3553c7508902e","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    fields \u003d {"},{"line_number":104,"context_line":"        \u0027guest_id\u0027: fields.IntegerField(),"},{"line_number":105,"context_line":"        \u0027host_ids\u0027: fields.SetOfIntegersField(),"},{"line_number":106,"context_line":"    }"},{"line_number":107,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_303882d1","line":104,"in_reply_to":"9fdfeff1_aad6434e","updated":"2019-02-26 18:39:29.000000000","message":"\u003e Maybe I\u0027ll figure this out after further reading, but is guest_id\n \u003e is the integer libvirt \"domain number\" from the source, yeah? Is\n \u003e this just intended to be an identifier used by the remote to\n \u003e correlate multiple pinning objects?\n \u003e \n \u003e Er, wait. Maybe guest_id is the id of the resource as visible to\n \u003e the guest (i.e. core 0) to map to host resource (i.e. core 6) ?\n\nThis one.\n\n \u003e Probably worth some extra comments around here to make sure that\u0027s\n \u003e clear.\n\nDone.","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"815be96aafde2d7971af3f068351d6d0f392341a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        sorted_host_ids \u003d list(self.host_ids)"},{"line_number":121,"context_line":"        sorted_host_ids.sort()"},{"line_number":122,"context_line":"        return hash(str(self.guest_id) +"},{"line_number":123,"context_line":"                    \u0027\u0027.join([str(host_id) for host_id in sorted_host_ids]))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"@obj_base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_4a5557c1","line":123,"updated":"2019-02-26 16:55:18.000000000","message":"What happens if I have things like:\n\n guest_id\u003d1, host_id\u003d10\n guest_id\u003d11, host_id\u003d0\n\n? Pretty sure that your hash string will look the same for both of those and thus potentially fool whatever is testing for equality.\n\nProbably need to include delimiters between (all) the fields to avoid that.","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"3f15251f13c0c2bf95eae41f76d3553c7508902e","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        sorted_host_ids \u003d list(self.host_ids)"},{"line_number":121,"context_line":"        sorted_host_ids.sort()"},{"line_number":122,"context_line":"        return hash(str(self.guest_id) +"},{"line_number":123,"context_line":"                    \u0027\u0027.join([str(host_id) for host_id in sorted_host_ids]))"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"@obj_base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_904cce76","line":123,"in_reply_to":"9fdfeff1_4a5557c1","updated":"2019-02-26 18:39:29.000000000","message":"Done","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"815be96aafde2d7971af3f068351d6d0f392341a","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":259,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":260,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":261,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027),"},{"line_number":262,"context_line":"    }"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_eafa0bb8","line":261,"updated":"2019-02-26 16:55:18.000000000","message":"Should this be nullable too? Since the NUMAMigrateData doesn\u0027t let the *_pins fields be null, this implies that all guests will have dst_numa_config set, and within that, there will be cpu and cell pins set to something.","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"3f15251f13c0c2bf95eae41f76d3553c7508902e","unresolved":false,"context_lines":[{"line_number":258,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":259,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":260,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":261,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027),"},{"line_number":262,"context_line":"    }"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":27,"id":"9fdfeff1_70284a32","line":261,"in_reply_to":"9fdfeff1_eafa0bb8","updated":"2019-02-26 18:39:29.000000000","message":"Done","commit_id":"f7ff49ddec263ff17888de9a89414e67095b6a51"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a43ac980e4667eb258389ca2b8b280e6e50132bb","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"9fdfeff1_de9c32c1","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"updated":"2019-07-04 10:22:35.000000000","message":"The more I think about this, the more it seems unnecessary. We already have this information (and much more) available in the InstanceNUMATopology/InstanceNUMACell objects. Any reason we can\u0027t use that?","commit_id":"8e9f3f42010d1ba1bcb4046eb622ce99948c1b9d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"e8e763cbc98f8e87fa1f789890c17d596869d3f6","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        return vif"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":99,"context_line":"class PinMapping(obj_base.NovaObject):"},{"line_number":100,"context_line":"    # Version 1.0: Initial version"},{"line_number":101,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"7faddb67_72d1bd57","line":99,"range":{"start_line":98,"start_character":0,"end_line":99,"end_character":38},"in_reply_to":"9fdfeff1_de9c32c1","updated":"2019-07-04 10:22:48.000000000","message":"Ignore this - super old comment","commit_id":"8e9f3f42010d1ba1bcb4046eb622ce99948c1b9d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a43ac980e4667eb258389ca2b8b280e6e50132bb","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_1294098b","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"updated":"2019-07-04 10:22:35.000000000","message":"Any reason we\u0027re not using DictOfIntegers for this instead? I feel like someone might have asked this but a quick browse didn\u0027t reveal the answer (maybe stick it in the commit message if so)","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"a9ad7d4a250e61b3550b6d23693cf5a3f2f7c328","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_99dbe8eb","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_03f836c2","updated":"2019-07-10 18:16:13.000000000","message":"OTOH, it\u0027s kinda nice keeping the semantic meaning with PinMapping, and allows us to have __hash__ and __eq__ methods, which make testing much easier.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"1f3bceff2eb62929fe2ae69eb8d32df385ca5b28","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_54834e05","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_1294098b","updated":"2019-07-04 11:29:21.000000000","message":"https://review.opendev.org/#/c/634827/23/nova/objects/migrate_data.py@133 :)","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"030d7f24cab8bb265cd4bfae3885ab841eaaf366","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_833666b4","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_54834e05","updated":"2019-07-04 15:21:12.000000000","message":"I knew I couldn\u0027t be the only one :D However, as noted in a later patch, we have \u0027DictOfListOfStringsField\u0027. Could we just add \u0027DictOfListOfIntegersField\u0027 (or \u0027DictOfSetOfIntegersField\u0027). It\u0027s a mouthful but it should be simpler to grok in the long run.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"2c2467b1c0066c1addfd49de084ae0c5fe279e4b","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_e00569c3","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_7574e068","updated":"2019-07-11 16:01:12.000000000","message":"For something like this object (NUMAMigrateData), sure. For a simple pin mapping, it\u0027s total overkill.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"27dbc371a08e36e5d79e771efa232411f1a200f7","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_03f836c2","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_833666b4","updated":"2019-07-04 15:25:24.000000000","message":"Ah yeah, I\u0027d be on board with adding a DictOfSetOfIntegersField.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"d499210952cbe1955449e2f66b186dc2940e03c5","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_d581144c","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_99dbe8eb","updated":"2019-07-11 12:49:53.000000000","message":"OTSH (on the same hand), using an actual o.vo brings a whole load of versioning baggage that we\u0027re not likely to need - just look at the repr for this object with \u0027DictOfSetOfIntegersField\u0027 vs. \u0027PinMapping\u0027. If __eq__ doesn\u0027t work, we can/should fix that.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"8e0e43f2f7d03d72a14dee002884571e3963cc8e","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_7574e068","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_d581144c","updated":"2019-07-11 12:57:15.000000000","message":"personally i like using types to model things in my domain instad fo have everything be dicts","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"96851acfe5809c5346c6fffeec492bcb2823c7f3","unresolved":false,"context_lines":[{"line_number":130,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"    fields \u003d {"},{"line_number":133,"context_line":"        \u0027cpu_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":134,"context_line":"        \u0027cell_pins\u0027: fields.ListOfObjectsField(\u0027PinMapping\u0027),"},{"line_number":135,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":136,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_ea946aea","line":133,"range":{"start_line":133,"start_character":20,"end_line":133,"end_character":60},"in_reply_to":"7faddb67_e00569c3","updated":"2019-07-29 21:24:12.000000000","message":"Right, removed PinMapping entirely and used a newly-created DictOfSetsOfIntegersField.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a43ac980e4667eb258389ca2b8b280e6e50132bb","unresolved":false,"context_lines":[{"line_number":276,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":277,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":278,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":279,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":280,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":281,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027,"},{"line_number":282,"context_line":"                                              nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_32f26508","line":279,"range":{"start_line":279,"start_character":9,"end_line":279,"end_character":18},"updated":"2019-07-04 10:22:35.000000000","message":"nit: This seems superfluous since most of the fields here refer to the instance or some metadata about the instance. Could we drop it?","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"1f3bceff2eb62929fe2ae69eb8d32df385ca5b28","unresolved":false,"context_lines":[{"line_number":276,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":277,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":278,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":279,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":280,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":281,"context_line":"        \u0027dst_numa_config\u0027: fields.ObjectField(\u0027NUMAMigrateData\u0027,"},{"line_number":282,"context_line":"                                              nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":33,"id":"7faddb67_54e6eeea","line":279,"range":{"start_line":279,"start_character":9,"end_line":279,"end_character":18},"in_reply_to":"7faddb67_32f26508","updated":"2019-07-04 11:29:21.000000000","message":"We could conceivably get host NUMA topologies in the future (I don\u0027t currently see how or why, but...). If you don\u0027t mind I won\u0027t address this nit, \u0027instance_numa_topology\u0027 is clearer to me than just \u0027numa_topology\u0027.","commit_id":"6c73eb6f176e4e18113726d836728269bf04badc"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"13e2c03a75b54fcb43b9d1eef8906d2cedf32d1d","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":114,"context_line":"class NUMAMigrateData(obj_base.NovaObject):"},{"line_number":115,"context_line":"    # Version 1.0: Initial version"},{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""}],"source_content_type":"text/x-python","patch_set":41,"id":"7faddb67_760b8029","line":114,"range":{"start_line":114,"start_character":6,"end_line":114,"end_character":21},"updated":"2019-07-30 09:45:31.000000000","message":"Perhaps we could use a name that better indicates the libvirt\u0027y-ness of this? Something like \u0027LibvirtLiveMigrateNUMAInfo\u0027, to match up with the BDM variant below?","commit_id":"5ed66102a2febaf0ab14c55819919fc8c72e3b3f"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"92e25d3814d85ba94e2fc927cf23eaf607f70f79","unresolved":false,"context_lines":[{"line_number":111,"context_line":""},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"@obj_base.NovaObjectRegistry.register"},{"line_number":114,"context_line":"class NUMAMigrateData(obj_base.NovaObject):"},{"line_number":115,"context_line":"    # Version 1.0: Initial version"},{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""}],"source_content_type":"text/x-python","patch_set":41,"id":"7faddb67_bece0d2b","line":114,"range":{"start_line":114,"start_character":6,"end_line":114,"end_character":21},"in_reply_to":"7faddb67_760b8029","updated":"2019-08-09 15:41:57.000000000","message":"Done","commit_id":"5ed66102a2febaf0ab14c55819919fc8c72e3b3f"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"13e2c03a75b54fcb43b9d1eef8906d2cedf32d1d","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":123,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":41,"id":"7faddb67_162b2c95","line":120,"range":{"start_line":119,"start_character":0,"end_line":120,"end_character":47},"updated":"2019-07-30 09:45:31.000000000","message":"Maybe unnecessary?","commit_id":"5ed66102a2febaf0ab14c55819919fc8c72e3b3f"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"92e25d3814d85ba94e2fc927cf23eaf607f70f79","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":123,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":41,"id":"7faddb67_9ed551ba","line":120,"range":{"start_line":119,"start_character":0,"end_line":120,"end_character":47},"in_reply_to":"7faddb67_162b2c95","updated":"2019-08-09 15:41:57.000000000","message":"Both you and Alex asked the question, I know we know longer have the confusing PinMapping object, but I\u0027d rather not have to answer that again :D","commit_id":"5ed66102a2febaf0ab14c55819919fc8c72e3b3f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"b2b6c48f5a806fc9c60213968c6ae6b06bf15e35","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":123,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":124,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":43,"id":"7faddb67_156697ee","line":121,"updated":"2019-08-16 17:57:52.000000000","message":"I don\u0027t really understand why this is not nullable but some of the things like sched_vcpus is. You know that nullable\u003dTrue means \"can be set to None\" right? Can you justify (here or in a comment) the nullability of each of these so I can understand?","commit_id":"8e9a9cc8d045f0b700eac69a8d6586400a2d0ab1"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"c595b4f2b802cd86decbecfb827e5b0bb83be62f","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":123,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":124,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":43,"id":"7faddb67_f2936da3","line":121,"in_reply_to":"7faddb67_156697ee","updated":"2019-08-22 20:23:02.000000000","message":"I was just being inconsistent, there\u0027s no reason for any of these to not be nullable.","commit_id":"8e9a9cc8d045f0b700eac69a8d6586400a2d0ab1"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d864b58deeb25076002572f454e05c6c545ee626","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":123,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"},{"line_number":124,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":43,"id":"7faddb67_b203b510","line":121,"in_reply_to":"7faddb67_f2936da3","updated":"2019-08-22 21:01:21.000000000","message":"Actually, reading your feedback in [1], they should all be *not* nullable - they can be unset, or set to something, but None makes no sense.\n\n[1] https://review.opendev.org/#/c/635229/41/nova/virt/libvirt/migration.py@92","commit_id":"8e9a9cc8d045f0b700eac69a8d6586400a2d0ab1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4feba862520ebf401037df2709234b7e3a28b574","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":244,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":245,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":246,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":247,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027,"},{"line_number":248,"context_line":"                                            nullable\u003dTrue),"},{"line_number":249,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_ca38eaa0","line":246,"updated":"2019-08-23 14:09:44.000000000","message":"I think I looked this up last time, but I don\u0027t remember the answer. Is this the *current* instance numa topology? If so, can\u0027t we just get it on the other side from the instance itself?\n\nAlso, Stephen is on a rampage to s/_topology// on all of these, so you should probably get ahead of the curve on the naming.","commit_id":"87c8c1121e86697e54b4032a26bd1ea0c9f7ae9f"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d7f3c4aee6be29faaf5987415bf8306acdf92345","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":244,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":245,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":246,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":247,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027,"},{"line_number":248,"context_line":"                                            nullable\u003dTrue),"},{"line_number":249,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_ea3363c3","line":246,"in_reply_to":"7faddb67_ca38eaa0","updated":"2019-08-23 16:29:01.000000000","message":"Done","commit_id":"87c8c1121e86697e54b4032a26bd1ea0c9f7ae9f"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4073e1e37f218527f51c6f53d1256b6a7e656e55","unresolved":false,"context_lines":[{"line_number":245,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":246,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":247,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027,"},{"line_number":248,"context_line":"                                            nullable\u003dTrue),"},{"line_number":249,"context_line":"    }"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_6a245661","line":248,"updated":"2019-08-23 14:12:55.000000000","message":"Why is this nullable? It looks to me like you always set this as of the next patch, even if the instance has no numa topology. If so, it will be unset when coming from older clients, and never None.","commit_id":"87c8c1121e86697e54b4032a26bd1ea0c9f7ae9f"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d7f3c4aee6be29faaf5987415bf8306acdf92345","unresolved":false,"context_lines":[{"line_number":245,"context_line":"        \u0027instance_numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027,"},{"line_number":246,"context_line":"                                                     nullable\u003dTrue),"},{"line_number":247,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027,"},{"line_number":248,"context_line":"                                            nullable\u003dTrue),"},{"line_number":249,"context_line":"    }"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def obj_make_compatible(self, primitive, target_version):"}],"source_content_type":"text/x-python","patch_set":44,"id":"7faddb67_8a442f1b","line":248,"in_reply_to":"7faddb67_6a245661","updated":"2019-08-23 16:29:01.000000000","message":"I think I\u0027ve *finally* (yes, after many years) understood what nullable means here. So yeah, they don\u0027t need to be nullable. They\u0027re either unset, or set to something not-null.","commit_id":"87c8c1121e86697e54b4032a26bd1ea0c9f7ae9f"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ef0d4148325803ef6103b9e0a32c4b9f9459d596","unresolved":false,"context_lines":[{"line_number":243,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":244,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":245,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":246,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in U."},{"line_number":247,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027),"},{"line_number":248,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"},{"line_number":249,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":50,"id":"7faddb67_e41a8b7a","line":246,"range":{"start_line":246,"start_character":64,"end_line":246,"end_character":76},"updated":"2019-08-27 14:07:28.000000000","message":"You can\u0027t really just remove a field - it\u0027s not that simple. It\u0027s an RPC versioned object so you\u0027d need a major bump to do this removal.\n\nIf you need to know if one side or the other is new enough, you can do that by checking the nova-compute service version, which is what the file-backed memory live migration stuff did here:\n\nhttps://github.com/openstack/nova/blob/18.0.0/nova/virt/libvirt/driver.py#L6612","commit_id":"aa14c3e5b778bc6d4fd2a1faa003fc5ef8d9a52c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"4adb27ea6fbe0979d72d9bd3d558d3396b49682e","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":245,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":246,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in U."},{"line_number":247,"context_line":"        \u0027numa_topology\u0027: fields.ObjectField(\u0027InstanceNUMATopology\u0027),"},{"line_number":248,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"},{"line_number":249,"context_line":"    }"},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":50,"id":"7faddb67_44f6ffda","line":247,"updated":"2019-08-27 13:43:49.000000000","message":"Can you answer my question from an earlier patch set? Is this the *current* instance numa_topology, and if so, can you explain why you\u0027re stuffing it in here instead of fetching it from the db on the other side and/or passing the instance itself with it attached?","commit_id":"aa14c3e5b778bc6d4fd2a1faa003fc5ef8d9a52c"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"e0303b21ac1ec64c9ce685a5814b39fe5da0f310","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":245,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":246,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":247,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in RPC"},{"line_number":248,"context_line":"        # 6.0"},{"line_number":249,"context_line":"        \u0027src_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":250,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"},{"line_number":251,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":54,"id":"7faddb67_e70ecde2","line":248,"range":{"start_line":247,"start_character":64,"end_line":248,"end_character":13},"updated":"2019-08-30 14:11:36.000000000","message":"This is not correct. You can remove this in version 2.0 of this object, but no sooner. It\u0027s not (directly) tied to the RPC version.","commit_id":"ecd784e30bd83a1a26902a72dece2319ea0adafd"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"dca3c8275d9161482ef17079efde976b02a1a787","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":245,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":246,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":247,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in RPC"},{"line_number":248,"context_line":"        # 6.0"},{"line_number":249,"context_line":"        \u0027src_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":250,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"},{"line_number":251,"context_line":"    }"}],"source_content_type":"text/x-python","patch_set":54,"id":"7faddb67_c4ff0c32","line":248,"range":{"start_line":247,"start_character":64,"end_line":248,"end_character":13},"in_reply_to":"7faddb67_e70ecde2","updated":"2019-08-30 16:09:03.000000000","message":"Done","commit_id":"ecd784e30bd83a1a26902a72dece2319ea0adafd"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":57,"id":"7faddb67_a2ef0785","line":119,"range":{"start_line":119,"start_character":72,"end_line":119,"end_character":78},"updated":"2019-09-05 19:28:02.000000000","message":"? cell_pins? just say that, otherwise I\u0027m just having a hard time grokking what this is saying.","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":57,"id":"7faddb67_e2df3fd4","line":119,"range":{"start_line":119,"start_character":22,"end_line":119,"end_character":26},"updated":"2019-09-05 19:28:02.000000000","message":"cpu_pins","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d06400ca9a5812e910ac22dca5c0d2ebf16d4e1c","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) This cannot be a DictOfIntegers field because the latter"},{"line_number":120,"context_line":"        # is 1:1, while cpu_pins can be 1:many."},{"line_number":121,"context_line":"        \u0027cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":122,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":57,"id":"5faad753_c8024f3f","line":119,"range":{"start_line":119,"start_character":22,"end_line":119,"end_character":26},"in_reply_to":"7faddb67_e2df3fd4","updated":"2019-09-05 22:56:23.000000000","message":"Done","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c0e406d1623a8e5c6fbc1395318e2f8eb162a744","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) allocation_cpu_pins and tuning_cpu_pins are mutually"},{"line_number":120,"context_line":"        # exclusive and should not be set at the same time!"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        # Represents CPU pinning via CPU allocation [1]. This case happens when"},{"line_number":123,"context_line":"        # a guest with no NUMA topology lands on a host with"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_693ea12a","line":120,"range":{"start_line":120,"start_character":20,"end_line":120,"end_character":59},"updated":"2019-09-07 18:22:07.000000000","message":"Hmm, is this something we\u0027d want to enforce by overriding __setattr__ and failing if both get set? Or is this more a thing that should be validated in the libvirt driver and fail if there is some kind of misconfiguration?","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"7b68c048ee62ba6a06f4c00fca045c0ebb12fbab","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) allocation_cpu_pins and tuning_cpu_pins are mutually"},{"line_number":120,"context_line":"        # exclusive and should not be set at the same time!"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        # Represents CPU pinning via CPU allocation [1]. This case happens when"},{"line_number":123,"context_line":"        # a guest with no NUMA topology lands on a host with"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_ec4b7f84","line":120,"range":{"start_line":120,"start_character":20,"end_line":120,"end_character":59},"in_reply_to":"5faad753_693ea12a","updated":"2019-09-07 22:52:43.000000000","message":"It\u0027s already \"enforced\" in the driver when it\u0027s created: [1]. I\u0027m wondering whether being more defensive inside the object itself is over-engineering.\n\n[1] https://review.opendev.org/#/c/635229/60/nova/virt/libvirt/driver.py@7348","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"c7c599e7f869351d633bba1e5d5140b128f90e6d","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # NOTE(artom) allocation_cpu_pins and tuning_cpu_pins are mutually"},{"line_number":120,"context_line":"        # exclusive and should not be set at the same time!"},{"line_number":121,"context_line":""},{"line_number":122,"context_line":"        # Represents CPU pinning via CPU allocation [1]. This case happens when"},{"line_number":123,"context_line":"        # a guest with no NUMA topology lands on a host with"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_af081928","line":120,"range":{"start_line":120,"start_character":20,"end_line":120,"end_character":59},"in_reply_to":"5faad753_ec4b7f84","updated":"2019-09-07 23:10:49.000000000","message":"I clarified the NOTE.","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c0e406d1623a8e5c6fbc1395318e2f8eb162a744","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        # Represents CPU pinning via CPU tuning [2]. This case happens when a"},{"line_number":129,"context_line":"        # guest has a NUMA topology. This cannot be a DictOfIntegers field"},{"line_number":130,"context_line":"        # because the latter is 1:1, while tuning_cpu_can have a single guest"},{"line_number":131,"context_line":"        # CPU pinned to multiple host CPUs."},{"line_number":132,"context_line":"        # [2] https://libvirt.org/formatdomain.html#elementsCPUTuning"},{"line_number":133,"context_line":"        \u0027tuning_cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_a90d7991","line":130,"range":{"start_line":130,"start_character":43,"end_line":130,"end_character":57},"updated":"2019-09-07 18:22:07.000000000","message":"Is this a typo?","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c0e406d1623a8e5c6fbc1395318e2f8eb162a744","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        # Represents CPU pinning via CPU tuning [2]. This case happens when a"},{"line_number":129,"context_line":"        # guest has a NUMA topology. This cannot be a DictOfIntegers field"},{"line_number":130,"context_line":"        # because the latter is 1:1, while tuning_cpu_can have a single guest"},{"line_number":131,"context_line":"        # CPU pinned to multiple host CPUs."},{"line_number":132,"context_line":"        # [2] https://libvirt.org/formatdomain.html#elementsCPUTuning"},{"line_number":133,"context_line":"        \u0027tuning_cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_4945e5b2","line":130,"range":{"start_line":130,"start_character":22,"end_line":130,"end_character":28},"updated":"2019-09-07 18:22:07.000000000","message":"What is the latter here?","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"7b68c048ee62ba6a06f4c00fca045c0ebb12fbab","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        # Represents CPU pinning via CPU tuning [2]. This case happens when a"},{"line_number":129,"context_line":"        # guest has a NUMA topology. This cannot be a DictOfIntegers field"},{"line_number":130,"context_line":"        # because the latter is 1:1, while tuning_cpu_can have a single guest"},{"line_number":131,"context_line":"        # CPU pinned to multiple host CPUs."},{"line_number":132,"context_line":"        # [2] https://libvirt.org/formatdomain.html#elementsCPUTuning"},{"line_number":133,"context_line":"        \u0027tuning_cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_0c513b37","line":130,"range":{"start_line":130,"start_character":22,"end_line":130,"end_character":28},"in_reply_to":"5faad753_4945e5b2","updated":"2019-09-07 22:52:43.000000000","message":"DictOfIntegers, I should indeed clarify in the comment.","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"7b68c048ee62ba6a06f4c00fca045c0ebb12fbab","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"        # Represents CPU pinning via CPU tuning [2]. This case happens when a"},{"line_number":129,"context_line":"        # guest has a NUMA topology. This cannot be a DictOfIntegers field"},{"line_number":130,"context_line":"        # because the latter is 1:1, while tuning_cpu_can have a single guest"},{"line_number":131,"context_line":"        # CPU pinned to multiple host CPUs."},{"line_number":132,"context_line":"        # [2] https://libvirt.org/formatdomain.html#elementsCPUTuning"},{"line_number":133,"context_line":"        \u0027tuning_cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_ac458772","line":130,"range":{"start_line":130,"start_character":43,"end_line":130,"end_character":57},"in_reply_to":"5faad753_a90d7991","updated":"2019-09-07 22:52:43.000000000","message":"Yep :(","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c0e406d1623a8e5c6fbc1395318e2f8eb162a744","unresolved":false,"context_lines":[{"line_number":259,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":260,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":261,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":262,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":263,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in"},{"line_number":264,"context_line":"        # version 2.0."},{"line_number":265,"context_line":"        \u0027src_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":266,"context_line":"        \u0027dst_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":267,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_a9ffb965","line":264,"range":{"start_line":262,"start_character":8,"end_line":264,"end_character":22},"updated":"2019-09-07 18:22:07.000000000","message":"Should have something like this for dst_supports_numa_live_migration as well but can deal with it in a follow up.","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"c7c599e7f869351d633bba1e5d5140b128f90e6d","unresolved":false,"context_lines":[{"line_number":259,"context_line":"        # file_backed_memory_discard is ignored unless"},{"line_number":260,"context_line":"        # dst_wants_file_backed_memory is set"},{"line_number":261,"context_line":"        \u0027file_backed_memory_discard\u0027: fields.BooleanField(),"},{"line_number":262,"context_line":"        # TODO(artom) This is only used as a flag to indicate that the source"},{"line_number":263,"context_line":"        # is new enough to perform a NUMA-aware live migration. Remove in"},{"line_number":264,"context_line":"        # version 2.0."},{"line_number":265,"context_line":"        \u0027src_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":266,"context_line":"        \u0027dst_supports_numa_live_migration\u0027: fields.BooleanField(),"},{"line_number":267,"context_line":"        \u0027dst_numa_info\u0027: fields.ObjectField(\u0027LibvirtLiveMigrateNUMAInfo\u0027),"}],"source_content_type":"text/x-python","patch_set":58,"id":"5faad753_6c246fc7","line":264,"range":{"start_line":262,"start_character":8,"end_line":264,"end_character":22},"in_reply_to":"5faad753_a9ffb965","updated":"2019-09-07 23:10:49.000000000","message":"Done","commit_id":"36686edb11792fae8449ff3d877a96ca1ea77abe"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"7a20aa49bf18579a44125fadc444bd8fe44f92ff","unresolved":false,"context_lines":[{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # Represents CPU pinning via CPU allocation [1]. This case happens when"},{"line_number":120,"context_line":"        # a guest with no NUMA topology lands on a host with"},{"line_number":121,"context_line":"        # CONF.libvirt.vcpu_pin_set configured."},{"line_number":122,"context_line":"        # https://libvirt.org/formatdomain.html#elementsCPUAllocation"},{"line_number":123,"context_line":"        \u0027allocation_cpu_pins\u0027: fields.SetOfIntegersField(),"}],"source_content_type":"text/x-python","patch_set":59,"id":"5faad753_d4aab383","line":120,"updated":"2019-09-09 21:46:43.000000000","message":"\"no NUMA topology\" so why are we munging this into an object called LibvirtLiveMigrateNUMAInfo? Seems confusing. Why wouldn\u0027t we handle the non-numa live migration issue with a separate field in the LibvirtLiveMigrateData object?","commit_id":"dec25631b8af11faf04d16a8fe67bd33997eca8b"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"11684bf03e4b3e403db6589808857108ebd9fbf6","unresolved":false,"context_lines":[{"line_number":116,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    fields \u003d {"},{"line_number":119,"context_line":"        # Represents CPU pinning via CPU allocation [1]. This case happens when"},{"line_number":120,"context_line":"        # a guest with no NUMA topology lands on a host with"},{"line_number":121,"context_line":"        # CONF.libvirt.vcpu_pin_set configured."},{"line_number":122,"context_line":"        # https://libvirt.org/formatdomain.html#elementsCPUAllocation"},{"line_number":123,"context_line":"        \u0027allocation_cpu_pins\u0027: fields.SetOfIntegersField(),"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"        # Represents CPU pinning via CPU tuning [2]. This case happens when a"},{"line_number":126,"context_line":"        # guest has a NUMA topology. We need a 1:many cardinality here, so"}],"source_content_type":"text/x-python","patch_set":59,"id":"5faad753_c038b1d4","line":123,"range":{"start_line":119,"start_character":8,"end_line":123,"end_character":59},"updated":"2019-09-09 18:17:26.000000000","message":"tl;dr +1\n\nnote that today when using vcpu_pin_set for non numa instances the operator is expected to use host aggreates to group host with the same vcpu_pin_set to ensure that you dont need to regenerate teh xml on live migration.\n\nincluding this allows use to remove that restriction by updating the xml for non numa guest.\n\nusing vcpu_pin_set for reserving cpu for host use has several advandages the primary one being the ability to partition which cpus are reserved for the host which allows you to configure systemd or other services to run on just those cores.\n\nsince this can vary per host we in principal need to update the cpu set on migration, in practice by requiring operators to set the same value across all host we have avoided that.\n\nbefore this change set floating instance would not be updated on migration. if the source set was contined cpu not on the dest node libvirt would reject the migration\n\nif libvirt allowed the migration because all cpus were present on the dest then the vm would float over incorrect cpus until it was hard rebooted at which point it will use the correct cores. \n\n\nthis will remove the need for operators to understand this bit of tribal knowadge as it was pointed out that this behavior is not commonly known or documented upstream.","commit_id":"dec25631b8af11faf04d16a8fe67bd33997eca8b"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"11684bf03e4b3e403db6589808857108ebd9fbf6","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        # [2] https://libvirt.org/formatdomain.html#elementsCPUTuning"},{"line_number":131,"context_line":"        \u0027tuning_cpu_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"        # NOTE(artom) allocation_cpu_pins and tuning_cpu_pins represent"},{"line_number":134,"context_line":"        # different ways of pinning guest CPUs to host CPUs in the libvirt XML."},{"line_number":135,"context_line":"        # In Nova we never generate XML that contains both, so we expect them"},{"line_number":136,"context_line":"        # to never be set at the same time. Libvirt itself however supports"},{"line_number":137,"context_line":"        # both existing in the XML, in which case tuning-style pinning will"},{"line_number":138,"context_line":"        # override allocation-style pinning."},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"        # NOTE(artom) Currently we never pin a guest cell to more than a single"},{"line_number":141,"context_line":"        # host cell, so cell_pins could be a DictOfIntegers, but"}],"source_content_type":"text/x-python","patch_set":59,"id":"5faad753_001489f4","line":138,"range":{"start_line":133,"start_character":9,"end_line":138,"end_character":44},"updated":"2019-09-09 18:17:26.000000000","message":"the \u003cvcpu cpuset\u003dX-Y\u003e is a shorthand for the \u003cvcpupin .. \u003e form in the cputune ellement. \n\ne.g.\n\u003cvcpu placement\u003d\u0027static\u0027 cpuset\u003d\"1-4,^3,6\" current\u003d\"2\"\u003e2\u003c/vcpu\u003e\n\nis the same as \n\n\u003ccputune\u003e\n    \u003cvcpupin vcpu\u003d\"0\" cpuset\u003d\"1-4,^3,6\"/\u003e\n    \u003cvcpupin vcpu\u003d\"1\" cpuset\u003d\"1-4,^3,6\"/\u003e\n\u003c/cputune\u003e\n\n\n\nboth get translated to the same  cgroups.\n\n\u003cvcpu placement\u003d\u0027static\u0027 cpuset\u003d\"1-4,^3,6\" current\u003d\"2\"\u003e2\u003c/vcpu\u003e\n\nis the more potable form however it does not allow you to pin indivgual guest cpus to spefic host cpus. that mapping is left to the kernel.\n\n\u003cvcpu placement\u003d\u0027static\u0027 cpuset\u003d\"1-4,^3,6\" current\u003d\"2\"\u003e2\u003c/vcpu\u003e\n\nwill work for kvm, qemu xen lxc and more.\n\n\u003cvcpupin vcpu\u003d\"0\" cpuset\u003d\"1-4,^3,6\"/\u003e\n\nrequired the hyperviors to support per core pinning with does not work with qemu and the singel tread tcg backend but does work with qemu and the multi thread tcg backed mttcg, kvm and xen.\n\nwe use the most generic form when the guest does not have a numa toplogy to allow it to work with the majority fo libvir  t backends.","commit_id":"dec25631b8af11faf04d16a8fe67bd33997eca8b"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"11684bf03e4b3e403db6589808857108ebd9fbf6","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        # DictOfSetOfIntegers is more future-proof."},{"line_number":143,"context_line":"        \u0027cell_pins\u0027: fields.DictOfSetOfIntegersField(),"},{"line_number":144,"context_line":"        \u0027emulator_pins\u0027: fields.SetOfIntegersField(),"},{"line_number":145,"context_line":"        \u0027sched_vcpus\u0027: fields.SetOfIntegersField(),"},{"line_number":146,"context_line":"        \u0027sched_priority\u0027: fields.IntegerField(),"},{"line_number":147,"context_line":"    }"},{"line_number":148,"context_line":""}],"source_content_type":"text/x-python","patch_set":59,"id":"5faad753_40d84152","line":145,"range":{"start_line":145,"start_character":8,"end_line":145,"end_character":51},"updated":"2019-09-09 18:17:26.000000000","message":"this is for the realtime cpus right?\na comment for this would be useful.","commit_id":"dec25631b8af11faf04d16a8fe67bd33997eca8b"}],"nova/tests/unit/objects/test_migrate_data.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"63a511c7e25f68c20cc04bd813ca4a380152d669","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        manifest \u003d ovo_base.obj_tree_get_versions(obj.obj_name())"},{"line_number":75,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.0\u0027,"},{"line_number":76,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":77,"context_line":"        self.assertEqual(primitive[\u0027guest_id\u0027], 0)"},{"line_number":78,"context_line":"        self.assertEqual(primitive[\u0027host_ids\u0027], (1,))"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_pin_mapping_hash(self):"},{"line_number":81,"context_line":"        self.assertEqual("}],"source_content_type":"text/x-python","patch_set":25,"id":"9fdfeff1_c1a07b45","line":78,"range":{"start_line":77,"start_character":8,"end_line":78,"end_character":53},"updated":"2019-02-24 22:32:25.000000000","message":"nit: should be assertEqual(expected, actual) which is useful for the MismatchError output if the assertion fails - here and elsewhere.","commit_id":"b197e5a4e5d5b7116c4e7c675c8c8d6c83990666"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d032367517a5cea22b08be7ec7c85126aa6a997c","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        manifest \u003d ovo_base.obj_tree_get_versions(obj.obj_name())"},{"line_number":75,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.0\u0027,"},{"line_number":76,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":77,"context_line":"        self.assertEqual(primitive[\u0027guest_id\u0027], 0)"},{"line_number":78,"context_line":"        self.assertEqual(primitive[\u0027host_ids\u0027], (1,))"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_pin_mapping_hash(self):"},{"line_number":81,"context_line":"        self.assertEqual("}],"source_content_type":"text/x-python","patch_set":25,"id":"9fdfeff1_94c86255","line":78,"range":{"start_line":77,"start_character":8,"end_line":78,"end_character":53},"in_reply_to":"9fdfeff1_c1a07b45","updated":"2019-02-25 15:53:37.000000000","message":"Done","commit_id":"b197e5a4e5d5b7116c4e7c675c8c8d6c83990666"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"695294c3d15b562c8f64c85002cdd67aa046128b","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        manifest \u003d ovo_base.obj_tree_get_versions(obj.obj_name())"},{"line_number":80,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.0\u0027,"},{"line_number":81,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":82,"context_line":"        self.assertEqual(primitive[\u0027cpu_pins\u0027], {\u00270\u0027: (1,)})"},{"line_number":83,"context_line":"        self.assertEqual(primitive[\u0027cell_pins\u0027], {\u00272\u0027: (3,)})"},{"line_number":84,"context_line":"        self.assertEqual(primitive[\u0027emulator_pins\u0027], (4,))"},{"line_number":85,"context_line":"        self.assertEqual(primitive[\u0027sched_vcpus\u0027], (5,))"},{"line_number":86,"context_line":"        self.assertEqual(primitive[\u0027sched_priority\u0027], 6)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_obj_make_compatible(self):"},{"line_number":89,"context_line":"        obj \u003d migrate_data.LibvirtLiveMigrateData("}],"source_content_type":"text/x-python","patch_set":57,"id":"7faddb67_5e63b2b1","line":86,"range":{"start_line":82,"start_character":0,"end_line":86,"end_character":56},"updated":"2019-09-04 14:23:09.000000000","message":"These tests are backwards.. It should be (expected, actual).","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d06400ca9a5812e910ac22dca5c0d2ebf16d4e1c","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        manifest \u003d ovo_base.obj_tree_get_versions(obj.obj_name())"},{"line_number":80,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.0\u0027,"},{"line_number":81,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":82,"context_line":"        self.assertEqual(primitive[\u0027cpu_pins\u0027], {\u00270\u0027: (1,)})"},{"line_number":83,"context_line":"        self.assertEqual(primitive[\u0027cell_pins\u0027], {\u00272\u0027: (3,)})"},{"line_number":84,"context_line":"        self.assertEqual(primitive[\u0027emulator_pins\u0027], (4,))"},{"line_number":85,"context_line":"        self.assertEqual(primitive[\u0027sched_vcpus\u0027], (5,))"},{"line_number":86,"context_line":"        self.assertEqual(primitive[\u0027sched_priority\u0027], 6)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def test_obj_make_compatible(self):"},{"line_number":89,"context_line":"        obj \u003d migrate_data.LibvirtLiveMigrateData("}],"source_content_type":"text/x-python","patch_set":57,"id":"5faad753_88c8d774","line":86,"range":{"start_line":82,"start_character":0,"end_line":86,"end_character":56},"in_reply_to":"7faddb67_5e63b2b1","updated":"2019-09-05 22:56:23.000000000","message":"Done","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ec4ef3635fa852f875f285aa7d9a66a3ff15d33b","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.9\u0027,"},{"line_number":131,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":132,"context_line":"        self.assertNotIn(\u0027dst_numa_info\u0027, primitive)"},{"line_number":133,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.9\u0027,"},{"line_number":134,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":135,"context_line":"        self.assertNotIn(\u0027src_supports_numa_live_migration\u0027, primitive)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def test_bdm_obj_make_compatible(self):"}],"source_content_type":"text/x-python","patch_set":57,"id":"7faddb67_7857825b","line":134,"range":{"start_line":133,"start_character":8,"end_line":134,"end_character":73},"updated":"2019-09-05 19:28:02.000000000","message":"nit: this is redundant","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"d06400ca9a5812e910ac22dca5c0d2ebf16d4e1c","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.9\u0027,"},{"line_number":131,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":132,"context_line":"        self.assertNotIn(\u0027dst_numa_info\u0027, primitive)"},{"line_number":133,"context_line":"        primitive \u003d data(obj.obj_to_primitive(target_version\u003d\u00271.9\u0027,"},{"line_number":134,"context_line":"                                              version_manifest\u003dmanifest))"},{"line_number":135,"context_line":"        self.assertNotIn(\u0027src_supports_numa_live_migration\u0027, primitive)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def test_bdm_obj_make_compatible(self):"}],"source_content_type":"text/x-python","patch_set":57,"id":"5faad753_28a3e351","line":134,"range":{"start_line":133,"start_character":8,"end_line":134,"end_character":73},"in_reply_to":"7faddb67_7857825b","updated":"2019-09-05 22:56:23.000000000","message":"Done","commit_id":"7f47421cd9f1d685b6c7d88022b801ef3a69028d"}]}
