Decentralized source ghost-record cleanup

Decentralized source ghost-record cleanup A workflow diagram generated by Archify. 01 / Target + sync controller 02 / virt-controller (lifecycle.go) EX / 1.9 without 3cf15d5f80 04 / Source virt-handler Completion reaches the source IsFinal guard + cleanup Target done · EndTimestamp set · Target + sync controller › Completion reaches the source Target done EndTimestamp set Copy state · onto source VMI · Target + sync controller › Completion reaches the source · sync ctrl Copy state onto source VMI sync ctrl Source pod · launcher exits · virt-controller (lifecycle.go) › Completion reaches the source Source pod launcher exits Succeeded · or Failed · virt-controller (lifecycle.go) › IsFinal guard + cleanup Succeeded or Failed Stays Running · record leaks · 1.9 without 3cf15d5f80 › IsFinal guard + cleanup Stays Running record leaks Sees window · domainMigrated() · Source virt-handler › Completion reaches the source Sees window domainMigrated() IsFinal guard · execute() · Source virt-handler › IsFinal guard + cleanup IsFinal guard execute() sync() runs · DeleteIfUID · Source virt-handler › IsFinal guard + cleanup sync() runs DeleteIfUID status sync Completed IsFinal sets Succeeded Completed false Legend virt-handler step guard / leak ghost record cluster-side controller External system

Why IsFinal matters

  • • A decentralized source keeps IsMigrationSource() true
  • • #18988 lets it into sync() only once Phase is Succeeded or Failed
  • • sync() is what deletes the source ghost record

Who makes it final

  • • virt-handler, only if it sees Shutoff+Migrated
  • • Otherwise the sync controller sets Completed
  • • virt-controller then sets Succeeded (or Failed if the pod is gone)

1.9 gap (plan task 3a)

  • • 3cf15d5f80 adds the EndTimestamp fallback; 1.9 likely lacks it
  • • Without it, a link closed early leaves Completed false
  • • Then B passes its unit tests but the record still leaks