diff mbox series

[v3,06/11] qapi: add x-blockdev-replace transaction action

Message ID 20220225234308.1754763-7-vsementsov@virtuozzo.com (mailing list archive)
State New, archived
Headers show
Series blockdev-replace | expand

Commit Message

Vladimir Sementsov-Ogievskiy Feb. 25, 2022, 11:43 p.m. UTC
Support blockdev-replace in a transaction.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 qapi/transaction.json | 14 +++++++++++++-
 blockdev.c            | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/qapi/transaction.json b/qapi/transaction.json
index a938dc7d10..48dd2db1ed 100644
--- a/qapi/transaction.json
+++ b/qapi/transaction.json
@@ -54,10 +54,12 @@ 
 # @blockdev-snapshot-sync: since 1.1
 # @drive-backup: Since 1.6
 # @blockdev-add: since 7.0
+# @x-blockdev-replace: since 7.0
 #
 # Features:
 # @deprecated: Member @drive-backup is deprecated.  Use member
 #              @blockdev-backup instead.
+# @unstable: Member @x-blockdev-replace is experimental
 #
 # Since: 1.1
 ##
@@ -68,6 +70,7 @@ 
             'blockdev-backup', 'blockdev-snapshot',
             'blockdev-snapshot-internal-sync', 'blockdev-snapshot-sync',
             'blockdev-add',
+            { 'name': 'x-blockdev-replace', 'features': [ 'unstable' ] },
             { 'name': 'drive-backup', 'features': [ 'deprecated' ] } ] }
 
 ##
@@ -150,6 +153,14 @@ 
 { 'struct': 'BlockdevAddWrapper',
   'data': { 'data': 'BlockdevOptions' } }
 
+##
+# @BlockdevReplaceWrapper:
+#
+# Since: 7.0
+##
+{ 'struct': 'BlockdevReplaceWrapper',
+  'data': { 'data': 'BlockdevReplace' } }
+
 ##
 # @TransactionAction:
 #
@@ -174,7 +185,8 @@ 
        'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternalWrapper',
        'blockdev-snapshot-sync': 'BlockdevSnapshotSyncWrapper',
        'blockdev-add': 'BlockdevAddWrapper',
-       'drive-backup': 'DriveBackupWrapper'
+       'drive-backup': 'DriveBackupWrapper',
+       'x-blockdev-replace': 'BlockdevReplaceWrapper'
    } }
 
 ##
diff --git a/blockdev.c b/blockdev.c
index 9fd1783be2..8ff0e2afe8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2294,6 +2294,34 @@  void qmp_x_blockdev_replace(BlockdevReplace *repl, Error **errp)
     tran_finalize(tran, ret);
 }
 
+typedef struct TranObjState {
+    BlkActionState common;
+    Transaction *tran;
+} TranObjState;
+
+static void tran_obj_commit(BlkActionState *common)
+{
+    TranObjState *s = DO_UPCAST(TranObjState, common, common);
+
+    tran_commit(s->tran);
+}
+
+static void tran_obj_abort(BlkActionState *common)
+{
+    TranObjState *s = DO_UPCAST(TranObjState, common, common);
+
+    tran_abort(s->tran);
+}
+
+static void blockdev_replace_prepare(BlkActionState *common, Error **errp)
+{
+    TranObjState *s = DO_UPCAST(TranObjState, common, common);
+
+    s->tran = tran_new();
+
+    blockdev_replace(common->action->u.x_blockdev_replace.data, s->tran, errp);
+}
+
 static const BlkActionOps actions[] = {
     [TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT] = {
         .instance_size = sizeof(ExternalSnapshotState),
@@ -2372,6 +2400,12 @@  static const BlkActionOps actions[] = {
         .prepare = blockdev_add_prepare,
         .abort = blockdev_add_abort,
     },
+    [TRANSACTION_ACTION_KIND_X_BLOCKDEV_REPLACE] = {
+        .instance_size = sizeof(TranObjState),
+        .prepare = blockdev_replace_prepare,
+        .commit = tran_obj_commit,
+        .abort = tran_obj_abort,
+    },
     /* Where are transactions for MIRROR, COMMIT and STREAM?
      * Although these blockjobs use transaction callbacks like the backup job,
      * these jobs do not necessarily adhere to transaction semantics.