Hi,
On Tue, 6 Jan 2026 at 19:17, Fabiano Rosas <[email protected]> wrote:
> If we had a linear state transition table, i.e. a DFA without any
> branching, that would be ideal. But since we have states that can reach
> (and be reached from) multiple other states, then we'll always need some
> input to migration_change_state(). Here you're making it the
> s->trigger. Where will that come from?
* The trigger or reason can come from the place where we call
migration_change_state(), there we'll know whether migration has
paused OR completed OR failed OR cancelled.
* Even with branches, the process is still linear as it goes from
start to finish. Just that we can reach the end state via different
paths.
===
$ grep -ri 'shutting' /var/log/libvirt/qemu/ | cut -d' ' -f 3- |
sort | uniq
shutting down, reason=crashed
shutting down, reason=destroyed
shutting down, reason=failed
shutting down, reason=migrated
shutting down, reason=shutdown
===
As we see, guest VM can stop/shutdown due to various reasons.
* Between [migration-start] and [migration-end], we can define
events/triggers that will lead to the next state. Ex
- START -> t:connection-established -> ACTIVE
We can reach the ACTIVE state only after connections are established,
not without that. If connection establishment fails, we reach the END.
- START -> t:connection-established -> ACTIVE -> running -> END
ACTIVE -> t:error -> END
ACTIVE -> t:cancel -> END
ACTIVE -> t:pause -> PAUSED -> t:resume -> ACTIVE
> Looking at runstate.c and job.c, it seems we could at least define a
> state transition table and do away with the second parameter to
> migrate_set_state(s, old, new).
>
> As we've been discussing, the current state-change mechanism has the
> dual purpose of emitting the state change event and also serving as
> internal tracking of the migration state. It's not clear to me whether
> you're covering both in this proposal or just one of them.
* We are not doing away with migration states, just reducing or
rationalising them to make it easier. Emitting state change to
libvirtd(8) and internal tracking should still serve the same. Just
that in migration_is_running() etc. functions we'll check only if the
state is ACTIVE, instead of 10 other states which also indicate that
the migration is running.
> I don't think we've established actually what are the goals of having
> any state changes. Do we even need state changes for internal tracking?
> We could use your s->trigger as an enum and just check it wherever
> necessary. And keep the MIGRATION_STATUS exclusive for the external API,
> in which case, it's probably better to just set it unconditionally (in
> many places migrate_set_state already takes the current state as
> argument, i.e. it doesn't care about the current state).
* Well as I see it, different states help us to
1 - know where the process is at a given time. In case of
errors/failures or other events to know what actions to take.
2 - what actions/triggers/events are possible.
ex. If an error/cancel occurs before ACTIVE state, during connection
establishment, it may not have to go through migration_cleanup(),
probably there's nothing to cleanup. Vs if an error/cancel occurs
after ACTIVE or in PAUSED state, we know migration_cleanup() is
needed. Similarly if we receive t:resume command when in ACTIVE
state, OR receive t:pause command in PAUSED state, we know there's
nothing to do and ignore it.
Thank you.
---
- Prasad