[libvirt] [PATCH] Use PAUSED state for domains that are starting up
Jim Fehlig
jfehlig at suse.com
Wed Mar 11 20:20:02 UTC 2015
Jiri Denemark wrote:
> When libvirt is starting a domain, it reports the state as SHUTOFF until
> it's RUNNING. This is not ideal because domain startup may take a long
> time (usually because of some configuration issues, firewalls blocking
> access to network disks, etc.) and domain lists provided by libvirt look
> awkward. One can see weird shutoff domains with IDs in a list of active
> domains or even shutoff transient domains. In any case, it looks more
> like a bug in libvirt than a normal state a domain goes through.
>
I recently noticed similar behavior in the libxl driver when starting
large memory domains, which can take considerable time.
> Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
> ---
>
> After going through all hypervisor drivers it seems none of them needs
> to be updated. That is, this patch matches the one I sent as RFC for
> design discussions.
>
> include/libvirt/libvirt-domain.h | 1 +
> src/conf/domain_conf.c | 3 ++-
> src/qemu/qemu_process.c | 22 ++++++++++++++--------
> tools/virsh-domain-monitor.c | 3 ++-
> 4 files changed, 19 insertions(+), 10 deletions(-)
>
> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
> index 9487b80..d5c148b 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -116,6 +116,7 @@ typedef enum {
> VIR_DOMAIN_PAUSED_SHUTTING_DOWN = 8, /* paused during shutdown process */
> VIR_DOMAIN_PAUSED_SNAPSHOT = 9, /* paused while creating a snapshot */
> VIR_DOMAIN_PAUSED_CRASHED = 10, /* paused due to a guest crash */
> + VIR_DOMAIN_PAUSED_STARTING_UP = 11, /* the domain is being started */
>
Cool. I'll use this in libxlDomainStart() in the libxl driver.
>
> # ifdef VIR_ENUM_SENTINELS
> VIR_DOMAIN_PAUSED_LAST
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index cc8616b..783c382 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -661,7 +661,8 @@ VIR_ENUM_IMPL(virDomainPausedReason, VIR_DOMAIN_PAUSED_LAST,
> "from snapshot",
> "shutdown",
> "snapshot",
> - "panicked")
> + "panicked",
> + "starting up")
>
> VIR_ENUM_IMPL(virDomainShutdownReason, VIR_DOMAIN_SHUTDOWN_LAST,
> "unknown",
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index d1f089d..649b3df 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -3418,6 +3418,7 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
> virDomainState state;
> virDomainPausedReason reason;
> virDomainState newState = VIR_DOMAIN_NOSTATE;
> + int oldReason;
> int newReason;
> bool running;
> char *msg = NULL;
> @@ -3431,9 +3432,16 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
> if (ret < 0)
> return -1;
>
> - state = virDomainObjGetState(vm, NULL);
> + state = virDomainObjGetState(vm, &oldReason);
>
> - if (state == VIR_DOMAIN_PAUSED && running) {
> + if (running &&
> + (state == VIR_DOMAIN_SHUTOFF ||
> + (state == VIR_DOMAIN_PAUSED &&
> + oldReason == VIR_DOMAIN_PAUSED_STARTING_UP))) {
> + newState = VIR_DOMAIN_RUNNING;
> + newReason = VIR_DOMAIN_RUNNING_BOOTED;
> + ignore_value(VIR_STRDUP_QUIET(msg, "finished booting"));
> + } else if (state == VIR_DOMAIN_PAUSED && running) {
> newState = VIR_DOMAIN_RUNNING;
> newReason = VIR_DOMAIN_RUNNING_UNPAUSED;
> ignore_value(VIR_STRDUP_QUIET(msg, "was unpaused"));
> @@ -3452,10 +3460,6 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
> ignore_value(virAsprintf(&msg, "was paused (%s)",
> virDomainPausedReasonTypeToString(reason)));
> }
> - } else if (state == VIR_DOMAIN_SHUTOFF && running) {
> - newState = VIR_DOMAIN_RUNNING;
> - newReason = VIR_DOMAIN_RUNNING_BOOTED;
> - ignore_value(VIR_STRDUP_QUIET(msg, "finished booting"));
> }
>
> if (newState != VIR_DOMAIN_NOSTATE) {
> @@ -3828,7 +3832,9 @@ qemuProcessReconnect(void *opaque)
> goto error;
>
> state = virDomainObjGetState(obj, &reason);
> - if (state == VIR_DOMAIN_SHUTOFF) {
> + if (state == VIR_DOMAIN_SHUTOFF ||
> + (state == VIR_DOMAIN_PAUSED &&
> + reason == VIR_DOMAIN_PAUSED_STARTING_UP)) {
> VIR_DEBUG("Domain '%s' wasn't fully started yet, killing it",
> obj->def->name);
> goto error;
> @@ -4459,7 +4465,7 @@ int qemuProcessStart(virConnectPtr conn,
>
> vm->def->id = qemuDriverAllocateID(driver);
> qemuDomainSetFakeReboot(driver, vm, false);
> - virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_UNKNOWN);
> + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
>
> if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
> driver->inhibitCallback(true, driver->inhibitOpaque);
> diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
> index 464ac11..30ddae4 100644
> --- a/tools/virsh-domain-monitor.c
> +++ b/tools/virsh-domain-monitor.c
> @@ -199,7 +199,8 @@ VIR_ENUM_IMPL(vshDomainPausedReason,
> N_("from snapshot"),
> N_("shutting down"),
> N_("creating snapshot"),
> - N_("crashed"))
> + N_("crashed"),
> + N_("starting up"))
>
> VIR_ENUM_DECL(vshDomainShutdownReason)
>
> VIR_ENUM_IMPL(vshDomainShutdownReason,
I'm no expert in the qemu driver code, but this looks sane to me. ACK.
Regards,
Jim
More information about the libvir-list
mailing list