summaryrefslogtreecommitdiff
path: root/nova/network
diff options
context:
space:
mode:
authorBalazs Gibizer <gibi@redhat.com>2022-07-15 13:48:46 +0200
committerBalazs Gibizer <gibi@redhat.com>2022-09-08 09:19:16 +0200
commite43bf900dc8ca66578603bed333c56b215b1876e (patch)
treec23f6fc1af2445efcb0d0636d4788c89fa7c1f24 /nova/network
parentf8c91eb75fc5504a37fc3b4be1d65d33dbc9b511 (diff)
downloadnova-e43bf900dc8ca66578603bed333c56b215b1876e.tar.gz
Gracefully ERROR in _init_instance if vnic_type changed
If the vnic_type of a bound port changes from "direct" to "macvtap" and then the compute service is restarted then during _init_instance nova tries to plug the vif of the changed port. However as it now has macvtap vnic_type nova tries to look up the netdev of the parent VF. Still that VF is consumed by the instance so there is no such netdev on the host OS. This error killed the compute service at startup due to unhandled exception. This patch adds the exception handler, logs an ERROR and continue initializing other instances on the host. Also this patch adds a detailed ERROR log when nova detects that the vnic_type changed during _heal_instance_info_cache periodic. Closes-Bug: #1981813 Change-Id: I1719f8eda04e8d15a3b01f0612977164c4e55e85
Diffstat (limited to 'nova/network')
-rw-r--r--nova/network/neutron.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/nova/network/neutron.py b/nova/network/neutron.py
index 5ca7649303..27e7d06455 100644
--- a/nova/network/neutron.py
+++ b/nova/network/neutron.py
@@ -3356,6 +3356,25 @@ class API:
delegate_create=True,
)
+ def _log_error_if_vnic_type_changed(
+ self, port_id, old_vnic_type, new_vnic_type, instance
+ ):
+ if old_vnic_type and old_vnic_type != new_vnic_type:
+ LOG.error(
+ 'The vnic_type of the bound port %s has '
+ 'been changed in neutron from "%s" to '
+ '"%s". Changing vnic_type of a bound port '
+ 'is not supported by Nova. To avoid '
+ 'breaking the connectivity of the instance '
+ 'please change the port vnic_type back to '
+ '"%s".',
+ port_id,
+ old_vnic_type,
+ new_vnic_type,
+ old_vnic_type,
+ instance=instance
+ )
+
def _build_network_info_model(self, context, instance, networks=None,
port_ids=None, admin_client=None,
preexisting_port_ids=None,
@@ -3429,6 +3448,12 @@ class API:
preexisting_port_ids)
for index, vif in enumerate(nw_info):
if vif['id'] == refresh_vif_id:
+ self._log_error_if_vnic_type_changed(
+ vif['id'],
+ vif['vnic_type'],
+ refreshed_vif['vnic_type'],
+ instance,
+ )
# Update the existing entry.
nw_info[index] = refreshed_vif
LOG.debug('Updated VIF entry in instance network '
@@ -3478,6 +3503,7 @@ class API:
networks, port_ids = self._gather_port_ids_and_networks(
context, instance, networks, port_ids, client)
+ old_nw_info = instance.get_network_info()
nw_info = network_model.NetworkInfo()
for port_id in port_ids:
current_neutron_port = current_neutron_port_map.get(port_id)
@@ -3485,6 +3511,14 @@ class API:
vif = self._build_vif_model(
context, client, current_neutron_port, networks,
preexisting_port_ids)
+ for old_vif in old_nw_info:
+ if old_vif['id'] == port_id:
+ self._log_error_if_vnic_type_changed(
+ port_id,
+ old_vif['vnic_type'],
+ vif['vnic_type'],
+ instance,
+ )
nw_info.append(vif)
elif nw_info_refresh:
LOG.info('Port %s from network info_cache is no '