mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Read-only mirror. Please submit merge requests / issues to https://gitlab.com/libvirt/libvirt
In certain rare occasions qemu can transition a block job which was already 'ready' into 'standby' and then back. If this happens in the following order libvirt will get confused about the actual job state: 1) the block copy job is 'ready' (job->state == QEMU_BLOCKJOB_STATE_READY) 2) user calls qemuDomainBlockJobAbort with VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT flag but without VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC 3) the block job is switched to synchronous event handling 4) the block job blips to 'standby' and back to 'ready', the event is not processed since the blockjob is in sync mode for now 5) qemuDomainBlockJobPivot is called: 5.1) 'job-complete' QMP command is issued 5.2) job->state is set to QEMU_BLOCKJOB_STATE_PIVOTING 6) code for synchronous-wait for the job completion in qemuDomainBlockJobAbort is invoked 7) the waiting loop calls qemuBlockJobUpdate: 7.1) job->newstate is QEMU_BLOCKJOB_STATE_READY due to 4) 7.2) qemuBlockJobEventProcess is called 7.3) the handler for QEMU_BLOCKJOB_STATE_READY overwrites job->state from QEMU_BLOCKJOB_STATE_PIVOTING to QEMU_BLOCKJOB_STATE_READY 8) qemuDomainBlockJobAbort is looking for a finished job, so waits again 9) qemu finishes the blockjob and transitions it into 'concluded' state 10) qemuBlockJobUpdate is triggered again, this time finalizing the job. 10.1) job->newstate is = QEMU_BLOCKJOB_STATE_CONCLUDED job->state is = QEMU_BLOCKJOB_STATE_READY 10.2) qemuBlockJobEventProcessConcluded is called, the function checks whether there was an error with the blockjob. Since there was no error job->newstate becomes QEMU_BLOCKJOB_STATE_COMPLETED. 10.3) qemuBlockJobEventProcessConcludedTransition selects the action for the appropriate block job type where we have: case QEMU_BLOCKJOB_TYPE_COPY: if (job->state == QEMU_BLOCKJOB_STATE_PIVOTING && success) qemuBlockJobProcessEventConcludedCopyPivot(driver, vm, job, asyncJob); else qemuBlockJobProcessEventConcludedCopyAbort(driver, vm, job, asyncJob); break; Since job->state is QEMU_BLOCKJOB_STATE_READY, qemuBlockJobProcessEventConcludedCopyAbort is called. This patch forbids transitions to QEMU_BLOCKJOB_STATE_READY if the previous job state isn't QEMU_BLOCKJOB_STATE_RUNNING or QEMU_BLOCKJOB_STATE_NEW. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1951507 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> |
||
---|---|---|
.ctags.d | ||
.github | ||
.gitlab/issue_templates | ||
build-aux | ||
ci | ||
docs | ||
examples | ||
include | ||
po | ||
scripts | ||
src | ||
tests | ||
tools | ||
.color_coded.in | ||
.ctags | ||
.dir-locals.el | ||
.editorconfig | ||
.gitignore | ||
.gitlab-ci.yml | ||
.gitmodules | ||
.gitpublish | ||
.mailmap | ||
.ycm_extra_conf.py.in | ||
AUTHORS.rst.in | ||
config.h | ||
configmake.h.in | ||
CONTRIBUTING.rst | ||
COPYING | ||
COPYING.LESSER | ||
gitdm.config | ||
libvirt-admin.pc.in | ||
libvirt-lxc.pc.in | ||
libvirt-qemu.pc.in | ||
libvirt.pc.in | ||
libvirt.spec.in | ||
meson_options.txt | ||
meson.build | ||
mingw-libvirt.spec.in | ||
NEWS.rst | ||
README.rst | ||
run.in |
.. image:: https://gitlab.com/libvirt/libvirt/badges/master/pipeline.svg :target: https://gitlab.com/libvirt/libvirt/pipelines :alt: GitLab CI Build Status .. image:: https://bestpractices.coreinfrastructure.org/projects/355/badge :target: https://bestpractices.coreinfrastructure.org/projects/355 :alt: CII Best Practices .. image:: https://translate.fedoraproject.org/widgets/libvirt/-/libvirt/svg-badge.svg :target: https://translate.fedoraproject.org/engage/libvirt/ :alt: Translation status ============================== Libvirt API for virtualization ============================== Libvirt provides a portable, long term stable C API for managing the virtualization technologies provided by many operating systems. It includes support for QEMU, KVM, Xen, LXC, bhyve, Virtuozzo, VMware vCenter and ESX, VMware Desktop, Hyper-V, VirtualBox and the POWER Hypervisor. For some of these hypervisors, it provides a stateful management daemon which runs on the virtualization host allowing access to the API both by non-privileged local users and remote users. Layered packages provide bindings of the libvirt C API into other languages including Python, Perl, PHP, Go, Java, OCaml, as well as mappings into object systems such as GObject, CIM and SNMP. Further information about the libvirt project can be found on the website: https://libvirt.org License ======= The libvirt C API is distributed under the terms of GNU Lesser General Public License, version 2.1 (or later). Some parts of the code that are not part of the C library may have the more restrictive GNU General Public License, version 2.0 (or later). See the files ``COPYING.LESSER`` and ``COPYING`` for full license terms & conditions. Installation ============ Instructions on building and installing libvirt can be found on the website: https://libvirt.org/compiling.html Contributing ============ The libvirt project welcomes contributions in many ways. For most components the best way to contribute is to send patches to the primary development mailing list. Further guidance on this can be found on the website: https://libvirt.org/contribute.html Contact ======= The libvirt project has two primary mailing lists: * libvirt-users@redhat.com (**for user discussions**) * libvir-list@redhat.com (**for development only**) Further details on contacting the project are available on the website: https://libvirt.org/contact.html