aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2018-04-12 17:29:59 +0200
committerKevin Wolf <kwolf@redhat.com>2018-05-23 14:30:49 +0200
commit33e9e9bd62d9ae00880d9e12ad8a5b7d2c00e8a5 (patch)
treeeacaf4579f55de26f5a3ca8c45fa0faa60a19ba3 /blockjob.c
parenta81e0a825e3b89039a427bca037112f461b95fec (diff)
job: Create Job, JobDriver and job_create()
This is the first step towards creating an infrastructure for generic background jobs that aren't tied to a block device. For now, Job only stores its ID and JobDriver, the rest stays in BlockJob. The following patches will move over more parts of BlockJob to Job if they are meaningful outside the context of a block job. BlockJob.driver is now redundant, but this patch leaves it around to avoid unnecessary churn. The next patches will get rid of almost all of its uses anyway so that it can be removed later with much less churn. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: John Snow <jsnow@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/blockjob.c b/blockjob.c
index 112672a68b..1464856eb5 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -34,7 +34,6 @@
#include "qapi/qapi-events-block-core.h"
#include "qapi/qmp/qerror.h"
#include "qemu/coroutine.h"
-#include "qemu/id.h"
#include "qemu/timer.h"
/* Right now, this mutex is only needed to synchronize accesses to job->busy
@@ -92,7 +91,8 @@ static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
return 0;
}
error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
- job->id, BlockJobStatus_str(job->status), BlockJobVerb_str(bv));
+ job->job.id, BlockJobStatus_str(job->status),
+ BlockJobVerb_str(bv));
return -EPERM;
}
@@ -159,7 +159,7 @@ BlockJob *block_job_get(const char *id)
BlockJob *job;
QLIST_FOREACH(job, &block_jobs, job_list) {
- if (job->id && !strcmp(id, job->id)) {
+ if (job->job.id && !strcmp(id, job->job.id)) {
return job;
}
}
@@ -261,7 +261,7 @@ void block_job_unref(BlockJob *job)
block_job_detach_aio_context, job);
blk_unref(job->blk);
error_free(job->blocker);
- g_free(job->id);
+ g_free(job->job.id);
assert(!timer_pending(&job->sleep_timer));
g_free(job);
}
@@ -311,7 +311,7 @@ static char *child_job_get_parent_desc(BdrvChild *c)
BlockJob *job = c->opaque;
return g_strdup_printf("%s job '%s'",
BlockJobType_str(job->driver->job_type),
- job->id);
+ job->job.id);
}
static void child_job_drained_begin(BdrvChild *c)
@@ -365,7 +365,7 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
bool block_job_is_internal(BlockJob *job)
{
- return (job->id == NULL);
+ return (job->job.id == NULL);
}
static bool block_job_started(BlockJob *job)
@@ -705,13 +705,13 @@ int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
void block_job_complete(BlockJob *job, Error **errp)
{
/* Should not be reachable via external interface for internal jobs */
- assert(job->id);
+ assert(job->job.id);
if (block_job_apply_verb(job, BLOCK_JOB_VERB_COMPLETE, errp)) {
return;
}
if (job->pause_count || job->cancelled || !job->driver->complete) {
error_setg(errp, "The active block job '%s' cannot be completed",
- job->id);
+ job->job.id);
return;
}
@@ -720,7 +720,7 @@ void block_job_complete(BlockJob *job, Error **errp)
void block_job_finalize(BlockJob *job, Error **errp)
{
- assert(job && job->id);
+ assert(job && job->job.id);
if (block_job_apply_verb(job, BLOCK_JOB_VERB_FINALIZE, errp)) {
return;
}
@@ -731,7 +731,7 @@ void block_job_dismiss(BlockJob **jobptr, Error **errp)
{
BlockJob *job = *jobptr;
/* similarly to _complete, this is QMP-interface only. */
- assert(job->id);
+ assert(job->job.id);
if (block_job_apply_verb(job, BLOCK_JOB_VERB_DISMISS, errp)) {
return;
}
@@ -848,7 +848,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
}
info = g_new0(BlockJobInfo, 1);
info->type = g_strdup(BlockJobType_str(job->driver->job_type));
- info->device = g_strdup(job->id);
+ info->device = g_strdup(job->job.id);
info->len = job->len;
info->busy = atomic_read(&job->busy);
info->paused = job->pause_count > 0;
@@ -879,7 +879,7 @@ static void block_job_event_cancelled(BlockJob *job)
}
qapi_event_send_block_job_cancelled(job->driver->job_type,
- job->id,
+ job->job.id,
job->len,
job->offset,
job->speed,
@@ -893,7 +893,7 @@ static void block_job_event_completed(BlockJob *job, const char *msg)
}
qapi_event_send_block_job_completed(job->driver->job_type,
- job->id,
+ job->job.id,
job->len,
job->offset,
job->speed,
@@ -907,7 +907,7 @@ static int block_job_event_pending(BlockJob *job)
block_job_state_transition(job, BLOCK_JOB_STATUS_PENDING);
if (!job->auto_finalize && !block_job_is_internal(job)) {
qapi_event_send_block_job_pending(job->driver->job_type,
- job->id,
+ job->job.id,
&error_abort);
}
return 0;
@@ -945,12 +945,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
error_setg(errp, "Cannot specify job ID for internal block job");
return NULL;
}
-
- 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;
@@ -964,9 +958,13 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
return NULL;
}
- job = g_malloc0(driver->instance_size);
+ job = job_create(job_id, &driver->job_driver, errp);
+ if (job == NULL) {
+ blk_unref(blk);
+ return NULL;
+ }
+
job->driver = driver;
- job->id = g_strdup(job_id);
job->blk = blk;
job->cb = cb;
job->opaque = opaque;
@@ -1187,7 +1185,7 @@ void block_job_event_ready(BlockJob *job)
}
qapi_event_send_block_job_ready(job->driver->job_type,
- job->id,
+ job->job.id,
job->len,
job->offset,
job->speed, &error_abort);
@@ -1217,7 +1215,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
abort();
}
if (!block_job_is_internal(job)) {
- qapi_event_send_block_job_error(job->id,
+ qapi_event_send_block_job_error(job->job.id,
is_read ? IO_OPERATION_TYPE_READ :
IO_OPERATION_TYPE_WRITE,
action, &error_abort);