#include "qapi/qapi-events-block-core.h"
#include "qapi/qmp/qerror.h"
#include "qemu/coroutine.h"
+#include "qemu/main-loop.h"
#include "qemu/timer.h"
/*
void block_job_free(Job *job)
{
BlockJob *bjob = container_of(job, BlockJob, job);
- BlockDriverState *bs = blk_bs(bjob->blk);
- bs->job = NULL;
block_job_remove_all_bdrv(bjob);
blk_unref(bjob->blk);
error_free(bjob->blocker);
}
}
-static void child_job_drained_end(BdrvChild *c)
+static void child_job_drained_end(BdrvChild *c, int *drained_end_counter)
{
BlockJob *job = c->opaque;
job_resume(&job->job);
BlockJob *job;
int ret;
- if (bs->job) {
- error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
- return NULL;
- }
-
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
job_id = bdrv_get_device_name(bs);
}
error_setg(&job->blocker, "block device is in use by block job: %s",
job_type_str(&job->job));
block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
- bs->job = job;
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
+ /* Disable request queuing in the BlockBackend to avoid deadlocks on drain:
+ * The job reports that it's busy until it reaches a pause point. */
+ blk_set_disable_request_queuing(blk, true);
blk_set_allow_aio_context_change(blk, true);
/* Only set speed when necessary to avoid NotSupported error */