diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 060e091cbde6e8b8f5f7e20f6881657291c7223d..de15c9e0ba4d54be658b359053b936c93bcdc7d4 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3754,9 +3754,11 @@ qemuProcessKill(struct qemud_driver *driver, VIR_DEBUG("vm=%s pid=%d flags=%x", vm->def->name, vm->pid, flags); - if (!virDomainObjIsActive(vm)) { - VIR_DEBUG("VM '%s' not active", vm->def->name); - return 0; + if (!(flags & VIR_QEMU_PROCESS_KILL_NOCHECK)) { + if (!virDomainObjIsActive(vm)) { + VIR_DEBUG("VM '%s' not active", vm->def->name); + return 0; + } } /* This loop sends SIGTERM (or SIGKILL if flags has @@ -3860,6 +3862,13 @@ void qemuProcessStop(struct qemud_driver *driver, return; } + /* + * We may unlock the driver and vm in qemuProcessKill(), and another thread + * can lock driver and vm, and then call qemuProcessStop(). So we should + * set vm->def->id to -1 here to avoid qemuProcessStop() to be called twice. + */ + vm->def->id = -1; + if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) { /* To not break the normal domain shutdown process, skip the * timestamp log writing if failed on opening log file. */ @@ -3922,7 +3931,8 @@ void qemuProcessStop(struct qemud_driver *driver, } /* shut it off for sure */ - ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE)); + ignore_value(qemuProcessKill(driver, vm, VIR_QEMU_PROCESS_KILL_FORCE| + VIR_QEMU_PROCESS_KILL_NOCHECK)); qemuDomainCleanupRun(driver, vm); @@ -4015,7 +4025,6 @@ retry: vm->taint = 0; vm->pid = -1; - vm->def->id = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); VIR_FREE(priv->vcpupids); priv->nvcpupids = 0; diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 761db6f9c69fe6a26bcad10a3e335d7827ee5fb5..5cb5ffcbe547e57577785f2a285a86c4bf84a793 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -72,6 +72,7 @@ int qemuProcessAttach(virConnectPtr conn, typedef enum { VIR_QEMU_PROCESS_KILL_FORCE = 1 << 0, VIR_QEMU_PROCESS_KILL_NOWAIT = 1 << 1, + VIR_QEMU_PROCESS_KILL_NOCHECK = 1 << 2, /* bypass the running vm check */ } virQemuProcessKillMode; int qemuProcessKill(struct qemud_driver *driver,