[PATCH v3 0/3] More graceful handling of migration without passt-repair
From Red Hat internal testing we've had some reports that if attempting to migrate without passt-repair, the failure mode is uglier than we'd like. The migration fails, which is somewhat expected, but we don't correctly roll things back on the source, so it breaks network there as well. Handle this more gracefully allowing the migration to proceed in this case, but allow TCP connections to break I've test patches 1..2/3 reasonably: * I get a clean migration if there are now active flows * Migration completes, although connections are broken if passt-repair isn't connected * Basic test suite (minus perf) Patch 3 I've run the basic test suite on, but haven't tested the specific functionality of. Alas, I've spent most of today battling with RHEL, virt-install, unshare and various other things trying to create a test environment simulating two hosts with (possibly) different addresses. Despite the example given by Stefano in reply to the previous version, I haven't really succeeded yet. There are more fragile cases that I'm looking to fix, particularly the die()s in flow_migrate_source_rollback() and elsewhere, however I ran into various complications that I didn't manage to sort out today. I'll continue looking at those tomorrow. David Gibson (3): migrate, flow: Trivially succeed if migrating with no flows migrate, flow: Don't attempt to migrate TCP flows without passt-repair migrate, tcp: Don't attempt to carry on migration after flow_alloc_cancel() flow.c | 17 +++++++++++++++-- tcp.c | 5 ++++- 2 files changed, 19 insertions(+), 3 deletions(-) -- 2.48.1
We could get a migration request when we have no active flows; or at least
none that we need or are able to migrate. In this case after sending or
receiving the number of flows we continue to step through various lists.
In the target case, this could include communication with passt-repair. If
passt-repair wasn't started that could cause further errors, but of course
they shouldn't matter if we have nothing to repair.
Make it more obvious that there's nothing to do and avoid such errors by
short-circuiting flow_migrate_{source,target}() if there are no migratable
flows.
Signed-off-by: David Gibson
Migrating TCP flows requires passt-repair in order to use TCP_REPAIR. If
passt-repair is not started, our failure mode is pretty ugly though: we'll
attempt the migration, hitting various problems when we can't enter repair
mode. In some cases we may not roll back these changes properly, meaning
we break network connections on the source.
Our general approach is not to completely block migration if there are
problems, but simply to break any flows we can't migrate. So, if we have
no connection from passt-repair carry on with the migration, but don't
attempt to migrate any TCP connections.
Signed-off-by: David Gibson
In tcp_flow_migrate_target(), if we're unable to create and bind the new
socket, we print an error, cancel the flow and carry on. This seems to
make sense based on our policy of generally letting the migration complete
even if some or all flows are lost in the process. However, it can't
quite work: the flow_alloc_cancel() means that the flows in the target's
flow table are no longer one to one match to the flows which the source
is sending data for. This means that data for later flows will be
mismatched to a different flow. Most likely that will cause some nasty
error later, but even worse it might appear to succeed but lead to data
corruption due to incorrectly restoring one of the flows.
Instead, we should leave the flow in the table until we've read all the
data for it, *then* discard it. Technically removing the
flow_alloc_cancel() would be enough for this: if tcp_flow_repair_socket()
fails it leaves conn->sock == -1, which will cause the restore functions
in tcp_flow_migrate_target_ext() to fail, discarding the flow. To make
what's going on clearer, though, put an explicit test for a bad socket fd
in tcp_flow_migrate_target_ext() and discard at that point.
Signed-off-by: David Gibson
On Wed, 26 Feb 2025 17:04:19 +1100
David Gibson
From Red Hat internal testing we've had some reports that if attempting to migrate without passt-repair, the failure mode is uglier than we'd like. The migration fails, which is somewhat expected, but we don't correctly roll things back on the source, so it breaks network there as well.
Handle this more gracefully allowing the migration to proceed in this case, but allow TCP connections to break
I've test patches 1..2/3 reasonably: * I get a clean migration if there are now active flows * Migration completes, although connections are broken if passt-repair isn't connected * Basic test suite (minus perf)
Patch 3 I've run the basic test suite on, but haven't tested the specific functionality of. Alas, I've spent most of today battling with RHEL, virt-install, unshare and various other things trying to create a test environment simulating two hosts with (possibly) different addresses.
Sorry, I've been busy with other stuff most of the day and I didn't manage to test the specific functionality of 3/3 either. :( I reviewed this and it all looks good to me but I'm not sure if I should merge this now or wait until we manage to test the 3/3 case. Let me know your preference. I can also merge up to 2/3 if it makes things more convenient. -- Stefano
On Wed, Feb 26, 2025 at 08:01:13PM +0100, Stefano Brivio wrote:
On Wed, 26 Feb 2025 17:04:19 +1100 David Gibson
wrote: From Red Hat internal testing we've had some reports that if attempting to migrate without passt-repair, the failure mode is uglier than we'd like. The migration fails, which is somewhat expected, but we don't correctly roll things back on the source, so it breaks network there as well.
Handle this more gracefully allowing the migration to proceed in this case, but allow TCP connections to break
I've test patches 1..2/3 reasonably: * I get a clean migration if there are now active flows * Migration completes, although connections are broken if passt-repair isn't connected * Basic test suite (minus perf)
Patch 3 I've run the basic test suite on, but haven't tested the specific functionality of. Alas, I've spent most of today battling with RHEL, virt-install, unshare and various other things trying to create a test environment simulating two hosts with (possibly) different addresses.
Sorry, I've been busy with other stuff most of the day and I didn't manage to test the specific functionality of 3/3 either. :(
I reviewed this and it all looks good to me but I'm not sure if I should merge this now or wait until we manage to test the 3/3 case. Let me know your preference. I can also merge up to 2/3 if it makes things more convenient.
Feel free to merge 1..2/3 whenever you want. I'll probably send a new spin with some other things fixed as well today. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
participants (2)
-
David Gibson
-
Stefano Brivio