#include "qemu/id.h"
#include "qemu/main-loop.h"
#include "trace-root.h"
+#include "qapi/qapi-events-job.h"
static QLIST_HEAD(, Job) jobs = QLIST_HEAD_INITIALIZER(jobs);
return rc;
}
+bool job_is_internal(Job *job)
+{
+ return (job->id == NULL);
+}
+
static void job_state_transition(Job *job, JobStatus s1)
{
JobStatus s0 = job->status;
JobStatus_str(s0), JobStatus_str(s1));
assert(JobSTT[s0][s1]);
job->status = s1;
+
+ if (!job_is_internal(job) && s1 != s0) {
+ qapi_event_send_job_status_change(job->id, job->status, &error_abort);
+ }
}
int job_apply_verb(Job *job, JobVerb verb, Error **errp)
QLIST_REMOVE(job, job_list);
+ g_free(job->error);
g_free(job->id);
g_free(job);
}
job->progress_total = job->progress_current + remaining;
}
+void job_progress_increase_remaining(Job *job, uint64_t delta)
+{
+ job->progress_total += delta;
+}
+
void job_event_cancelled(Job *job)
{
notifier_list_notify(&job->on_finalize_cancelled, job);
job->ret = -ECANCELED;
}
if (job->ret) {
+ if (!job->error) {
+ job->error = g_strdup(strerror(-job->ret));
+ }
job_state_transition(job, JOB_STATUS_ABORTING);
}
}
{
if (job->ret == 0 && job->driver->prepare) {
job->ret = job->driver->prepare(job);
+ job_update_rc(job);
}
return job->ret;
}
}
}
-void job_completed(Job *job, int ret)
+void job_completed(Job *job, int ret, Error *error)
{
assert(job && job->txn && !job_is_completed(job));
+
job->ret = ret;
+ if (error) {
+ assert(job->ret < 0);
+ job->error = g_strdup(error_get_pretty(error));
+ error_free(error);
+ }
+
job_update_rc(job);
trace_job_completed(job, ret, job->ret);
if (job->ret) {
}
job_cancel_async(job, force);
if (!job_started(job)) {
- job_completed(job, -ECANCELED);
+ job_completed(job, -ECANCELED, NULL);
} else if (job->deferred_to_main_loop) {
job_completed_txn_abort(job);
} else {