goto error;
}
- job = block_job_create(&backup_job_driver, bs, speed, cb, opaque, errp);
+ job = block_job_create(NULL, &backup_job_driver, bs, speed,
+ cb, opaque, errp);
if (!job) {
goto error;
}
return;
}
- s = block_job_create(&commit_job_driver, bs, speed, cb, opaque, errp);
+ s = block_job_create(NULL, &commit_job_driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}
buf_size = DEFAULT_MIRROR_BUF_SIZE;
}
- s = block_job_create(driver, bs, speed, cb, opaque, errp);
+ s = block_job_create(NULL, driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}
{
StreamBlockJob *s;
- s = block_job_create(&stream_job_driver, bs, speed, cb, opaque, errp);
+ s = block_job_create(NULL, &stream_job_driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
#include "qemu/coroutine.h"
+#include "qemu/id.h"
#include "qmp-commands.h"
#include "qemu/timer.h"
#include "qapi-event.h"
block_job_unref(job);
}
-void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
- int64_t speed, BlockCompletionFunc *cb,
- void *opaque, Error **errp)
+void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+ BlockDriverState *bs, int64_t speed,
+ BlockCompletionFunc *cb, void *opaque, Error **errp)
{
BlockBackend *blk;
BlockJob *job;
return NULL;
}
+ if (job_id == NULL) {
+ job_id = bdrv_get_device_name(bs);
+ /* Assign a default ID if the BDS does not have a device
+ * name. We'll get rid of this soon when we finish extending
+ * the API of all commands that create block jobs. */
+ if (job_id[0] == '\0') {
+ job_id = "default_job";
+ }
+ }
+
+ if (!id_wellformed(job_id)) {
+ error_setg(errp, "Invalid job ID '%s'", job_id);
+ return NULL;
+ }
+
+ if (block_job_get(job_id)) {
+ error_setg(errp, "Job ID '%s' already in use", job_id);
+ return NULL;
+ }
+
blk = blk_new();
blk_insert_bs(blk, bs);
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
job->driver = driver;
- job->id = g_strdup(bdrv_get_device_name(bs));
+ job->id = g_strdup(job_id);
job->blk = blk;
job->cb = cb;
job->opaque = opaque;
/**
* block_job_create:
+ * @job_id: The id of the newly-created job, or %NULL to have one
+ * generated automatically.
* @job_type: The class object for the newly-created job.
* @bs: The block
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
* This function is not part of the public job interface; it should be
* called from a wrapper that is specific to the job type.
*/
-void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
- int64_t speed, BlockCompletionFunc *cb,
- void *opaque, Error **errp);
+void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+ BlockDriverState *bs, int64_t speed,
+ BlockCompletionFunc *cb, void *opaque, Error **errp);
/**
* block_job_sleep_ns:
BlockDriverState *bs;
TestBlockJob *s;
TestBlockJobCBData *data;
+ static unsigned counter;
+ char job_id[24];
data = g_new0(TestBlockJobCBData, 1);
bs = bdrv_new();
- s = block_job_create(&test_block_job_driver, bs, 0, test_block_job_cb,
- data, &error_abort);
+ snprintf(job_id, sizeof(job_id), "job%u", counter++);
+ s = block_job_create(job_id, &test_block_job_driver, bs, 0,
+ test_block_job_cb, data, &error_abort);
s->iterations = iterations;
s->use_timer = use_timer;
s->rc = rc;