Shouldn't qemu_migration.c get the same fix, since peer2peer and
tunneled migration basically re-implement the same migration driver
function?

It's reimplementing the same thing but in a different context. The code in
libvirt.c runs on a client, while qemu_migration.c runs within the qemu driver
in libvirtd. The virDomainMigratePrform3 API called from libvirt.c cleans up
after itself; it resumes a domain and finishes the migration job in case of
error. On the other hand, everything in doPeer2PeerMigrate3 is run within a
single public API and the function called to do the Perform phase is an
internal function which doesn't clean up after itself in the same way as the
public API has to. Hence, we need to call qemuMigrationConfirm to actually
resume the domain even if the Perform phase failed.

Ping. Did I manage to convince you this patch is complete? :-)

Yes. ACK, although since I just pushed Alex' patch, you might have a
merge conflict to fix when you rebase.