<div dir="ltr"><div>We can't change the host_id until after the migration or it will break l2pop other drivers that use the host as a location indicator (e.g. many top of rack drivers do this to determine which switch port should be wired up).</div><div><br></div>There is already a patch that went in to inform Neutron of the destination host here for proactive DVR wiring: <a href="https://review.openstack.org/#/c/275420/">https://review.openstack.org/#/c/275420/</a> During this port update phase, we can validate the destination host is 'bindable' with the given port info and fail it otherwise. This should block Nova from continuing.<div><br></div><div>However, we have to figure out how ML2 will know if something is 'bindable'. The only interface we have right now is bind_port. It is possible that we can do a faked bind_port attempt using what the port host_id would look like after migration. It's made clear in the ML2 driver API that bind_port results may not be committed: <a href="https://github.com/openstack/neutron/blob/4440297a2ff5a6893b748c2400048e840283c718/neutron/plugins/ml2/driver_api.py#L869">https://github.com/openstack/neutron/blob/4440297a2ff5a6893b748c2400048e840283c718/neutron/plugins/ml2/driver_api.py#L869</a></div><div><br></div><div>So the workflow would be something like:</div><div>* Nova calls Neutron port update with the destination host in the binding details</div><div>* In ML2 port update, the destination host is placed into a copy of the port in the host_id field and bind_port is called.</div><div>* If bind_port is unsuccessful, it fails the port update for Nova to prevent migration.</div><div>* If bind_port is successful, the results of the port update are committed (with the original host_id and the new host_id in the destination_host field).</div><div>* Workflow continues as normal here.</div><div><br></div><div>So this heavily exploits the fact that bind_port is supposed to be mutation-free in the ML2 driver API. We may encounter drivers that don't follow this now, but they are already exposed to other bugs if they mutate state so I think the onus would be on them to fix their driver.</div><div><br></div><div>Cheers,</div><div>Kevin Benton</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 12, 2016 at 3:33 AM, Rossella Sblendido <span dir="ltr"><<a href="mailto:rsblendido@suse.com" target="_blank">rsblendido@suse.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 04/12/2016 12:05 PM, Andreas Scheuring wrote:<br>
> Hi together,<br>
> I wanted to start discussion about Live Migration problem that currently exists in the nova neutron communication.<br>
><br>
> Basics Live Migration and Nova - Neutron communication<br>
> ------------------------------------------------------<br>
> On a high level, Nova Live Migration happens in 3 stages. (--> is what's happening from network perspective)<br>
> #1 pre_live_migration<br>
>    --> libvirtdriver: nova plugs the interface (for ovs hybrid sets up the linuxbridge + veth and connects it to br-int)<br>
> #2 live_migration_operation<br>
>    --> instance is being migrated (using libvirt with the domain.xml that is currently active on the migration source)<br>
> #3 post_live_migration<br>
>    --> binding:host_id is being updated for the port<br>
>    --> libvirtdriver: domain.xml is being regenerated<br>
> More details can be found here [1]<br>
><br>
> The problem - portbinding fails<br>
> -------------------------------<br>
> With this flow, ML2 portbinding is triggered in post_live_migration. At this point, the instance has already been migrated and is active on the migration destination.<br>
> Part of the port-binding is happening in the mechanism drivers, where the vif information for the port (vif-type, vif-details,..) is being updated.<br>
> If this portbinding fails, port will get the binding:vif_type "binding_failed".<br>
> After that the nova libvirt driver starts generating the domain xml again to persist it. Part of this generation is also generating the interface definition.<br>
> This fails as the vif_type is "binding_failed". Nova will set the instance to error state. --> There is no rollback, as it's already too late!<br>
><br>
> Just a remark: There is no explicit check for the vif_type binding_failed. I have the feeling that it (luckily) fails by accident when generating the xml.<br>
><br>
> --> Ideally we would trigger the portbinding before the migration started - in pre_live_migration. Then, if binding fails, we could abort migration before it even started. The instance would still be<br>
> active and fully functional on the source host. I have a WIP patchset out proposing this change [2]<br>
><br>
><br>
> The impact<br>
> ----------<br>
> Patchset [2] propose updating the host_id already in pre_live_migration.<br>
> During migration, the port would already be owned by the migration target (although the guest is still active on the source)<br>
> Technically this works fine for all the reference implementations, but this could be a problem for some third party mech drivers, if they shut down the port on the source and activate it on the target - although instance is still on the source<br>
><br>
> Any thoughts on this?<br>
<br>
</div></div>+1 on this anyway let's hear back from third party drivers maintainers.<br>
<span class=""><br>
><br>
><br>
> Additional use cases that would be enabled with this change<br>
> -----------------------------------------------------------<br>
> When updating the host_id in pre_live_migration, we could modify the domain.xml with the new vif information before live migration (see patch [2] and nova spec [4]).<br>
> This enables the following use cases<br>
><br>
> #1 Live Migration between nodes that run different l2 agents<br>
>    E.g. you could migrate a instance from an ovs node to an lb node and vice versa. This could be used as l2 agent transition strategy!<br>
> #2 Live Migration with macvtap agent<br>
>    It would enable the macvtap agent to live migrate instances between hosts, that use a different physical_interface_mapping. See bug [3]<br>
><br>
> --> #2 is the use case that made me thinking about this whole topic....<br>
><br>
> Potential other solutions<br>
> -------------------------<br>
> #1 Have something like simultaneous portbinding - On migration, a port is bound to 2 hosts (like a dvr port can today).<br>
> Therefore some database refactorings would be required (work has already been started in the DVR context [7])<br>
> And the Rest API would need to be changed in a way, that there's not a single binding, but a list of bindings returned. Of course also create & update that list.<br>
><br>
<br>
</span>I don't like this one. This would require lots of code changes and I am<br>
not sure it would solve the problem completely. The model of having a<br>
port bound to two hosts just because it's migrating, it's confusing.<br>
<span class=""><br>
<br>
> #2 execute portbinding without saving it to db<br>
> we could also introduce a new api( like update port, with live migration flag), that would run through the portbinding code and would return the port<br>
> information for the target node, but would not persist this information. Son on port-show you would still get the old information. Update would only happen if the migration flag is not present (in post_live_migration like today)<br>
> Alternatively the generated protbidning could be stored in the port context and be used on the final port_update be instead of running through all the code pathes again.<br>
><br>
<br>
</span>Another possible solution is to apply the same strategy we use for<br>
instance creation. Nova should wait to get a confirmation from Neutron<br>
before declaring the migration successful.<br>
<br>
cheers,<br>
<br>
Rossella<br>
<span class="im HOEnZb"><br>
><br>
> Other efforts in the area nova neutron live migration<br>
> -----------------------------------------------------<br>
> Just for reference, those are the other activities around nova-neutron live migration I'm aware of. But non of them is related to this IMO.<br>
><br>
> #1 ovs-hybrid plug wait for vi-plug event before doing live migration<br>
> see patches [5]<br>
> --> on nova plug, creates the linuxbridge and the veth pair and plugs it into the br-int. This plug is being detected by the ovs agent, which then reports the device as up<br>
> which again triggers this vif-plug event. This does not solve the problem as portbinding is not involved anyhow. This patch can also not be used for lb, ovs normal and macvtap,<br>
> as for those vif-types libvirt sets up the device that the agent is looking for. But this happens during live migration operation.<br>
><br>
> #2 Implement setup_networks_on_host for Neutron networks<br>
> Notification that Neutron sets up a DVR router attachment on the target node<br>
> see patch [6] + related patches<br>
><br>
> #3 I also know the midonet faces some challenges during nova plug<br>
> but this is also a separate topic<br>
><br>
><br>
><br>
> Any discussion / input would be helpful, thanks a lot!<br>
><br>
><br>
> [1] <a href="https://review.openstack.org/#/c/274097/6/doc/source/devref/live_migration.rst" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/274097/6/doc/source/devref/live_migration.rst</a><br>
> [2] <a href="https://review.openstack.org/297100" rel="noreferrer" target="_blank">https://review.openstack.org/297100</a><br>
> [3] <a href="https://bugs.launchpad.net/neutron/+bug/1550400" rel="noreferrer" target="_blank">https://bugs.launchpad.net/neutron/+bug/1550400</a><br>
> [4] <a href="https://review.openstack.org/301090" rel="noreferrer" target="_blank">https://review.openstack.org/301090</a><br>
> [5] <a href="https://review.openstack.org/246898" rel="noreferrer" target="_blank">https://review.openstack.org/246898</a> & <a href="https://review.openstack.org/246910" rel="noreferrer" target="_blank">https://review.openstack.org/246910</a><br>
> [6] <a href="https://review.openstack.org/275073" rel="noreferrer" target="_blank">https://review.openstack.org/275073</a><br>
> [7]  <a href="https://bugs.launchpad.net/neutron/+bug/1367391" rel="noreferrer" target="_blank">https://bugs.launchpad.net/neutron/+bug/1367391</a><br>
><br>
><br>
<br>
</span><div class="HOEnZb"><div class="h5">__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</div></div></blockquote></div><br></div>