9ae3a8
From 6270aec1271880bb5f12db46d40f51671c548f59 Mon Sep 17 00:00:00 2001
9ae3a8
From: Jeff Cody <jcody@redhat.com>
9ae3a8
Date: Thu, 7 Nov 2013 07:28:56 +0100
9ae3a8
Subject: [PATCH 57/81] block: optionally disable live block jobs
9ae3a8
9ae3a8
RH-Author: Jeff Cody <jcody@redhat.com>
9ae3a8
Message-id: <5b15ff37a1f28a76e2b66c07df996d3a7c37d6e9.1383712781.git.jcody@redhat.com>
9ae3a8
Patchwork-id: 55478
9ae3a8
O-Subject: [RHEL7 qemu-kvm PATCH 1/3] block: optionally disable live block jobs
9ae3a8
Bugzilla: 987582
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
RH-Acked-by: Eric Blake <eblake@redhat.com>
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
9ae3a8
This disables all block job operations that are part of the virt
9ae3a8
differentiation features.
9ae3a8
9ae3a8
This includes:
9ae3a8
    * live snapshots (single and group)
9ae3a8
    * block stream
9ae3a8
    * block commit
9ae3a8
    * block mirror
9ae3a8
    * block transactions
9ae3a8
9ae3a8
All of these are disabled via the CONFIG_LIVE_BLOCK_OPS config option.
9ae3a8
9ae3a8
In RHEL6, block job differentiation grew from live snapshot disablement,
9ae3a8
which was used to encompass many operations that were not live
9ae3a8
snapshots.  CONFIG_LIVE_SNAPSHOTS was used for disablement of multiple
9ae3a8
features.
9ae3a8
9ae3a8
For RHEL7, let's use naming that is more accurate:
9ae3a8
CONFIG_LIVE_BLOCK_OPS, to denote live block operations.
9ae3a8
9ae3a8
RHEL and RHEV have different binaries, where RHEV qemu-kvm binaries
9ae3a8
support live snapshots.
9ae3a8
9ae3a8
The JSON files qapi-schema-rhel.json and qapi-schema-rhev.json are
9ae3a8
automatically generated from the qapi-schema.json, by looking for
9ae3a8
'_rhev_only' comments in the 'master' JSON file.
9ae3a8
9ae3a8
For RHEL6, the JSON file had makeshift 'ifdef' statements.  This was
9ae3a8
changed to '_rhev_only' and '_end_rhev-only' blocks, because calling
9ae3a8
them 'ifdef' was misleading - it did not depend on the actual state
9ae3a8
of that variable itself.
9ae3a8
9ae3a8
The Makefile variable RHEV_CONFIGS can be appended with additional
9ae3a8
config items that may appear in the qapi-schema.json file.  For
9ae3a8
instance, to have features CONFIG_LIVE_BLOCK_OPS and CONFIG_SOME_FEATURE
9ae3a8
both be RHEV only, set the variable like so:
9ae3a8
9ae3a8
RHEV_CONFIGS = CONFIG_LIVE_BLOCK_OPS CONFIG_SOME_FEATURE
9ae3a8
9ae3a8
RHEV_CONFIGS is then turned into a regex. For the example above, the
9ae3a8
following pattern is matched when generating the RHEL/RHEV JSON files:
9ae3a8
^#_rhev-only +(\bCONFIG_LIVE_BLOCK_OPS\b|\bCONFIG_SOME_FEATURE\b)
9ae3a8
9ae3a8
Unlike the RHEL6 counterpart, this one uses original qmp-commands.h,
9ae3a8
qapi-types.h, qapi-visit.c, etc.. filenames, simplifying the Makefile a
9ae3a8
bit.
9ae3a8
9ae3a8
BZ: 987582
9ae3a8
9ae3a8
The Makefile changes were derived from
9ae3a8
RHEL6 commit bb5bd75dd86a6d05c9df4c2d271f98744d6c90b7, but this was not
9ae3a8
a cherry-pick as the actual changes differed significantly.
9ae3a8
9ae3a8
Signed-off-by: Jeff Cody <jcody@redhat.com>
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 Makefile            |   48 ++++++++++++++++++++++++++++++++++++++++++------
9ae3a8
 block/Makefile.objs |    2 ++
9ae3a8
 blockdev.c          |    7 +++++++
9ae3a8
 configure           |   14 +++++++++++++-
9ae3a8
 hmp-commands.hx     |    5 ++++-
9ae3a8
 hmp.c               |    4 ++++
9ae3a8
 qapi-schema.json    |    6 ++++++
9ae3a8
 qmp-commands.hx     |    4 ++++
9ae3a8
 8 files changed, 82 insertions(+), 8 deletions(-)
9ae3a8
9ae3a8
diff --git a/Makefile b/Makefile
9ae3a8
index dcd31c6..45048a3 100644
9ae3a8
--- a/Makefile
9ae3a8
+++ b/Makefile
9ae3a8
@@ -2,6 +2,11 @@
9ae3a8
 
9ae3a8
 # Always point to the root of the build tree (needs GNU make).
9ae3a8
 BUILD_DIR=$(CURDIR)
9ae3a8
+# useful for passing ' ' and ',' into Makefile functional calls,
9ae3a8
+# as these characters cannot be passed otherwise
9ae3a8
+_empty :=  
9ae3a8
+_space := $(_empty) $(_empty)
9ae3a8
+_comma := ,
9ae3a8
 
9ae3a8
 # All following code might depend on configuration variables
9ae3a8
 ifneq ($(wildcard config-host.mak),)
9ae3a8
@@ -213,15 +218,45 @@ qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
9ae3a8
 $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
9ae3a8
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, "  GEN   $@")
9ae3a8
 
9ae3a8
+# if there are multiple config items to be RHEV-only, simply add it to
9ae3a8
+# RHEV_CONFIGS, like so: RHEV_CONFIGS = CONFIG_LIVE_BLOCK_OPS CONFIG_SOME_FEATURE
9ae3a8
+RHEV_CONFIGS = CONFIG_LIVE_BLOCK_OPS
9ae3a8
+# Turn $(RHEV_CONFIGS) into a regex with logical OR, and whole word matching
9ae3a8
+RHEV_ONLY_CONFIG_ITEMS = (\b$(subst $(_space),\b|\b,$(strip $(RHEV_CONFIGS)))\b)
9ae3a8
+
9ae3a8
+GENERATED_JSON_FILES = $(addprefix $(SRC_PATH)/, qapi-schema-rhel.json qapi-schema-rhev.json)
9ae3a8
+
9ae3a8
+$(SRC_PATH)/qapi-schema-rhev.json: $(SRC_PATH)/qapi-schema.json
9ae3a8
+	-@echo "# THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY" > $@
9ae3a8
+	-@echo "#" >> $@
9ae3a8
+	$(call quiet-command,sed -r "/^#_rhev-only +$(RHEV_ONLY_CONFIG_ITEMS)/d;/^#_end-rhev-only/d" $< >> $@, "  GEN   $@")
9ae3a8
+
9ae3a8
+$(SRC_PATH)/qapi-schema-rhel.json: $(SRC_PATH)/qapi-schema.json
9ae3a8
+	-@echo "# THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY" > $@
9ae3a8
+	-@echo "#" >> $@
9ae3a8
+	$(call quiet-command,sed -r "/^#_rhev-only +$(RHEV_ONLY_CONFIG_ITEMS)/$(_comma)/^#_end-rhev-only/d" $< >> $@, "  GEN   $@")
9ae3a8
+
9ae3a8
+ifeq ($(CONFIG_LIVE_BLOCK_OPS),y)
9ae3a8
 qapi-types.c qapi-types.h :\
9ae3a8
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
9ae3a8
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, "  GEN   $@")
9ae3a8
+$(SRC_PATH)/qapi-schema-rhev.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
9ae3a8
 qapi-visit.c qapi-visit.h :\
9ae3a8
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
9ae3a8
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
9ae3a8
+$(SRC_PATH)/qapi-schema-rhev.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
9ae3a8
 qmp-commands.h qmp-marshal.c :\
9ae3a8
-$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
9ae3a8
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, "  GEN   $@")
9ae3a8
+$(SRC_PATH)/qapi-schema-rhev.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "."  < $<, "  GEN   $@")
9ae3a8
+else
9ae3a8
+qapi-types.c qapi-types.h :\
9ae3a8
+$(SRC_PATH)/qapi-schema-rhel.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
9ae3a8
+qapi-visit.c qapi-visit.h :\
9ae3a8
+$(SRC_PATH)/qapi-schema-rhel.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "."  < $<, "  GEN   $@")
9ae3a8
+qmp-commands.h qmp-marshal.c :\
9ae3a8
+$(SRC_PATH)/qapi-schema-rhel.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
9ae3a8
+	$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "."  < $<, "  GEN   $@")
9ae3a8
+endif
9ae3a8
 
9ae3a8
 QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
9ae3a8
 $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
9ae3a8
@@ -243,6 +278,7 @@ clean:
9ae3a8
 	rm -f trace/generated-tracers-dtrace.h*
9ae3a8
 	rm -f $(foreach f,$(GENERATED_HEADERS),$(f) $(f)-timestamp)
9ae3a8
 	rm -f $(foreach f,$(GENERATED_SOURCES),$(f) $(f)-timestamp)
9ae3a8
+	rm -f $(foreach f,$(GENERATED_JSON_FILES),$(f) $(f)-timestamp)
9ae3a8
 	rm -rf qapi-generated
9ae3a8
 	rm -rf qga/qapi-generated
9ae3a8
 	$(MAKE) -C tests/tcg clean
9ae3a8
diff --git a/block/Makefile.objs b/block/Makefile.objs
9ae3a8
index 6b8d5ec..f355271 100644
9ae3a8
--- a/block/Makefile.objs
9ae3a8
+++ b/block/Makefile.objs
9ae3a8
@@ -17,8 +17,10 @@ block-obj-$(CONFIG_GLUSTERFS) += gluster.o
9ae3a8
 block-obj-$(CONFIG_LIBSSH2) += ssh.o
9ae3a8
 endif
9ae3a8
 
9ae3a8
+ifeq ($(CONFIG_LIVE_BLOCK_OPS),y)
9ae3a8
 common-obj-y += stream.o
9ae3a8
 common-obj-y += commit.o
9ae3a8
 common-obj-y += mirror.o
9ae3a8
+endif
9ae3a8
 
9ae3a8
 $(obj)/curl.o: QEMU_CFLAGS+=$(CURL_CFLAGS)
9ae3a8
diff --git a/blockdev.c b/blockdev.c
9ae3a8
index f65aff4..6710f61 100644
9ae3a8
--- a/blockdev.c
9ae3a8
+++ b/blockdev.c
9ae3a8
@@ -237,6 +237,8 @@ typedef struct {
9ae3a8
     DriveInfo *dinfo;
9ae3a8
 } DrivePutRefBH;
9ae3a8
 
9ae3a8
+/* right now, this is only used from block_job_cb() */
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
 static void drive_put_ref_bh(void *opaque)
9ae3a8
 {
9ae3a8
     DrivePutRefBH *s = opaque;
9ae3a8
@@ -262,6 +264,7 @@ static void drive_put_ref_bh_schedule(DriveInfo *dinfo)
9ae3a8
     s->dinfo = dinfo;
9ae3a8
     qemu_bh_schedule(s->bh);
9ae3a8
 }
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 static int parse_block_error_action(const char *buf, bool is_read)
9ae3a8
 {
9ae3a8
@@ -806,6 +809,7 @@ void do_commit(Monitor *mon, const QDict *qdict)
9ae3a8
     }
9ae3a8
 }
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
 static void blockdev_do_action(int kind, void *data, Error **errp)
9ae3a8
 {
9ae3a8
     BlockdevAction action;
9ae3a8
@@ -1051,6 +1055,7 @@ exit:
9ae3a8
         g_free(states);
9ae3a8
     }
9ae3a8
 }
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 
9ae3a8
 static void eject_device(BlockDriverState *bs, int force, Error **errp)
9ae3a8
@@ -1286,6 +1291,7 @@ void qmp_block_resize(const char *device, int64_t size, Error **errp)
9ae3a8
     }
9ae3a8
 }
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
 static void block_job_cb(void *opaque, int ret)
9ae3a8
 {
9ae3a8
     BlockDriverState *bs = opaque;
9ae3a8
@@ -1547,6 +1553,7 @@ void qmp_drive_mirror(const char *device, const char *target,
9ae3a8
      */
9ae3a8
     drive_get_ref(drive_get_by_blockdev(bs));
9ae3a8
 }
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 static BlockJob *find_block_job(const char *device)
9ae3a8
 {
9ae3a8
diff --git a/configure b/configure
9ae3a8
index 4830f7e..9260d3c 100755
9ae3a8
--- a/configure
9ae3a8
+++ b/configure
9ae3a8
@@ -240,6 +240,7 @@ gtk=""
9ae3a8
 gtkabi="2.0"
9ae3a8
 tpm="no"
9ae3a8
 libssh2=""
9ae3a8
+live_block_ops="yes"
9ae3a8
 
9ae3a8
 # parse CC options first
9ae3a8
 for opt do
9ae3a8
@@ -927,7 +928,11 @@ for opt do
9ae3a8
   ;;
9ae3a8
   --enable-libssh2) libssh2="yes"
9ae3a8
   ;;
9ae3a8
-  *) echo "ERROR: unknown option $opt"; show_help="yes"
9ae3a8
+  --disable-live-block-ops) live_block_ops="no"
9ae3a8
+  ;;
9ae3a8
+  --enable-live-block-ops) live_block_ops="yes"
9ae3a8
+  ;;
9ae3a8
+*) echo "ERROR: unknown option $opt"; show_help="yes"
9ae3a8
   ;;
9ae3a8
   esac
9ae3a8
 done
9ae3a8
@@ -1195,6 +1200,8 @@ echo "  --gcov=GCOV              use specified gcov [$gcov_tool]"
9ae3a8
 echo "  --enable-tpm             enable TPM support"
9ae3a8
 echo "  --disable-libssh2        disable ssh block device support"
9ae3a8
 echo "  --enable-libssh2         enable ssh block device support"
9ae3a8
+echo "  --disable-live-block-ops disable live block operations support"
9ae3a8
+echo "  --enable-live-block-ops  enable live block operations support"
9ae3a8
 echo ""
9ae3a8
 echo "NOTE: The object files are built at the place where configure is launched"
9ae3a8
 exit 1
9ae3a8
@@ -3556,6 +3563,7 @@ echo "TPM support       $tpm"
9ae3a8
 echo "libssh2 support   $libssh2"
9ae3a8
 echo "TPM passthrough   $tpm_passthrough"
9ae3a8
 echo "QOM debugging     $qom_cast_debug"
9ae3a8
+echo "Live block operations $live_block_ops"
9ae3a8
 
9ae3a8
 if test "$sdl_too_old" = "yes"; then
9ae3a8
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
9ae3a8
@@ -3940,6 +3948,10 @@ if test "$virtio_blk_data_plane" = "yes" ; then
9ae3a8
   echo 'CONFIG_VIRTIO_BLK_DATA_PLANE=$(CONFIG_VIRTIO)' >> $config_host_mak
9ae3a8
 fi
9ae3a8
 
9ae3a8
+if test "$live_block_ops" = "yes" ; then
9ae3a8
+  echo "CONFIG_LIVE_BLOCK_OPS=y" >> $config_host_mak
9ae3a8
+fi
9ae3a8
+
9ae3a8
 # USB host support
9ae3a8
 if test "$libusb" = "yes"; then
9ae3a8
   echo "HOST_USB=libusb legacy" >> $config_host_mak
9ae3a8
diff --git a/hmp-commands.hx b/hmp-commands.hx
9ae3a8
index 5cd6368..2fc2c0b 100644
9ae3a8
--- a/hmp-commands.hx
9ae3a8
+++ b/hmp-commands.hx
9ae3a8
@@ -68,7 +68,7 @@ action to see the updated size.  Resize to a lower size is supported,
9ae3a8
 but should be used with extreme caution.  Note that this command only
9ae3a8
 resizes image files, it can not resize block devices like LVM volumes.
9ae3a8
 ETEXI
9ae3a8
-
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
     {
9ae3a8
         .name       = "block_stream",
9ae3a8
         .args_type  = "device:B,speed:o?,base:s?",
9ae3a8
@@ -76,6 +76,7 @@ ETEXI
9ae3a8
         .help       = "copy data from a backing file into a block device",
9ae3a8
         .mhandler.cmd = hmp_block_stream,
9ae3a8
     },
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 STEXI
9ae3a8
 @item block_stream
9ae3a8
@@ -1024,6 +1025,7 @@ gdb.
9ae3a8
 ETEXI
9ae3a8
 #endif
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
     {
9ae3a8
         .name       = "snapshot_blkdev",
9ae3a8
         .args_type  = "reuse:-n,device:B,snapshot-file:s?,format:s?",
9ae3a8
@@ -1066,6 +1068,7 @@ STEXI
9ae3a8
 Start mirroring a block device's writes to a new destination,
9ae3a8
 using the specified target.
9ae3a8
 ETEXI
9ae3a8
+#endif
9ae3a8
 
9ae3a8
     {
9ae3a8
         .name       = "drive_add",
9ae3a8
diff --git a/hmp.c b/hmp.c
9ae3a8
index 3b3e7c7..29990d2 100644
9ae3a8
--- a/hmp.c
9ae3a8
+++ b/hmp.c
9ae3a8
@@ -838,6 +838,7 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
9ae3a8
     hmp_handle_error(mon, &errp);
9ae3a8
 }
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
 void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
9ae3a8
 {
9ae3a8
     const char *device = qdict_get_str(qdict, "device");
9ae3a8
@@ -889,6 +890,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
9ae3a8
                                true, mode, &errp);
9ae3a8
     hmp_handle_error(mon, &errp);
9ae3a8
 }
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
9ae3a8
 {
9ae3a8
@@ -1030,6 +1032,7 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
9ae3a8
     hmp_handle_error(mon, &err;;
9ae3a8
 }
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
 void hmp_block_stream(Monitor *mon, const QDict *qdict)
9ae3a8
 {
9ae3a8
     Error *error = NULL;
9ae3a8
@@ -1043,6 +1046,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
9ae3a8
 
9ae3a8
     hmp_handle_error(mon, &error);
9ae3a8
 }
9ae3a8
+#endif
9ae3a8
 
9ae3a8
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
9ae3a8
 {
9ae3a8
diff --git a/qapi-schema.json b/qapi-schema.json
9ae3a8
index b779458..12a360a 100644
9ae3a8
--- a/qapi-schema.json
9ae3a8
+++ b/qapi-schema.json
9ae3a8
@@ -1617,6 +1617,7 @@
9ae3a8
 ##
9ae3a8
 { 'command': 'block_resize', 'data': { 'device': 'str', 'size': 'int' }}
9ae3a8
 
9ae3a8
+#_rhev-only CONFIG_LIVE_BLOCK_OPS
9ae3a8
 ##
9ae3a8
 # @NewImageMode
9ae3a8
 #
9ae3a8
@@ -1697,6 +1698,7 @@
9ae3a8
 ##
9ae3a8
 { 'command': 'blockdev-snapshot-sync',
9ae3a8
   'data': 'BlockdevSnapshot' }
9ae3a8
+#_end-rhev-only
9ae3a8
 
9ae3a8
 ##
9ae3a8
 # @human-monitor-command:
9ae3a8
@@ -1726,6 +1728,7 @@
9ae3a8
   'data': {'command-line': 'str', '*cpu-index': 'int'},
9ae3a8
   'returns': 'str' }
9ae3a8
 
9ae3a8
+#_rhev-only CONFIG_LIVE_BLOCK_OPS
9ae3a8
 ##
9ae3a8
 # @block-commit
9ae3a8
 #
9ae3a8
@@ -1811,6 +1814,7 @@
9ae3a8
             '*speed': 'int', '*granularity': 'uint32',
9ae3a8
             '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',
9ae3a8
             '*on-target-error': 'BlockdevOnError' } }
9ae3a8
+#_end-rhev-only
9ae3a8
 
9ae3a8
 ##
9ae3a8
 # @migrate_cancel
9ae3a8
@@ -2123,6 +2127,7 @@
9ae3a8
   'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
9ae3a8
             'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int' } }
9ae3a8
 
9ae3a8
+#_rhev-only CONFIG_LIVE_BLOCK_OPS
9ae3a8
 ##
9ae3a8
 # @block-stream:
9ae3a8
 #
9ae3a8
@@ -2160,6 +2165,7 @@
9ae3a8
 { 'command': 'block-stream',
9ae3a8
   'data': { 'device': 'str', '*base': 'str', '*speed': 'int',
9ae3a8
             '*on-error': 'BlockdevOnError' } }
9ae3a8
+#_end-rhev-only
9ae3a8
 
9ae3a8
 ##
9ae3a8
 # @block-job-set-speed:
9ae3a8
diff --git a/qmp-commands.hx b/qmp-commands.hx
9ae3a8
index de5f394..e40d54d 100644
9ae3a8
--- a/qmp-commands.hx
9ae3a8
+++ b/qmp-commands.hx
9ae3a8
@@ -904,6 +904,7 @@ Example:
9ae3a8
 
9ae3a8
 EQMP
9ae3a8
 
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
     {
9ae3a8
         .name       = "block-stream",
9ae3a8
         .args_type  = "device:B,base:s?,speed:o?,on-error:s?",
9ae3a8
@@ -915,6 +916,7 @@ EQMP
9ae3a8
         .args_type  = "device:B,base:s?,top:s,speed:o?",
9ae3a8
         .mhandler.cmd_new = qmp_marshal_input_block_commit,
9ae3a8
     },
9ae3a8
+#endif
9ae3a8
 
9ae3a8
     {
9ae3a8
         .name       = "block-job-set-speed",
9ae3a8
@@ -942,6 +944,7 @@ EQMP
9ae3a8
         .args_type  = "device:B",
9ae3a8
         .mhandler.cmd_new = qmp_marshal_input_block_job_complete,
9ae3a8
     },
9ae3a8
+#ifdef CONFIG_LIVE_BLOCK_OPS
9ae3a8
     {
9ae3a8
         .name       = "transaction",
9ae3a8
         .args_type  = "actions:q",
9ae3a8
@@ -1085,6 +1088,7 @@ Example:
9ae3a8
 <- { "return": {} }
9ae3a8
 
9ae3a8
 EQMP
9ae3a8
+#endif
9ae3a8
 
9ae3a8
     {
9ae3a8
         .name       = "balloon",
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8