summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2016-11-08 01:50:35 -0500
committerJeff Cody <jcody@redhat.com>2016-11-14 22:47:34 -0500
commite8a40bf71d606f9f87866fb2461eaed52814b38e (patch)
tree4474066f2b85abd51936afb6e2bde28d3866a8ee /include
parent1e93b9fba2e0e23105e91574fcfc193f899d8e74 (diff)
downloadqemu-e8a40bf71d606f9f87866fb2461eaed52814b38e.tar.gz
blockjob: add .clean property
Cleaning up after we have deferred to the main thread but before the transaction has converged can be dangerous and result in deadlocks if the job cleanup invokes any BH polling loops. A job may attempt to begin cleaning up, but may induce another job to enter its cleanup routine. The second job, part of our same transaction, will block waiting for the first job to finish, so neither job may now make progress. To rectify this, allow jobs to register a cleanup operation that will always run regardless of if the job was in a transaction or not, and if the transaction job group completed successfully or not. Move sensitive cleanup to this callback instead which is guaranteed to be run only after the transaction has converged, which removes sensitive timing constraints from said cleanup. Furthermore, in future patches these cleanup operations will be performed regardless of whether or not we actually started the job. Therefore, cleanup callbacks should essentially confine themselves to undoing create operations, e.g. setup actions taken in what is now backup_start. Reported-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1478587839-9834-3-git-send-email-jsnow@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/block/blockjob_int.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index 40275e4437..60d91a0678 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -74,6 +74,14 @@ struct BlockJobDriver {
void (*abort)(BlockJob *job);
/**
+ * If the callback is not NULL, it will be invoked after a call to either
+ * .commit() or .abort(). Regardless of which callback is invoked after
+ * completion, .clean() will always be called, even if the job does not
+ * belong to a transaction group.
+ */
+ void (*clean)(BlockJob *job);
+
+ /**
* If the callback is not NULL, it will be invoked when the job transitions
* into the paused state. Paused jobs must not perform any asynchronous
* I/O or event loop activity. This callback is used to quiesce jobs.