From 4e83dfecc62f282d364b446ce77c8afad9ba29fa Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 21 Mar 2012 21:54:33 +0100
Subject: [PATCH 06/55] Revert "qmp: add block_stream command"

RH-Author: Jeffrey Cody <jcody@redhat.com>
Message-id: <b46c0e0284823b07c80e48ece3519a6e360ac36b.1332362400.git.jcody@redhat.com>
Patchwork-id: 38856
O-Subject: [RHEL6.3 qemu-kvm PATCH v8 06/54] Revert "qmp: add block_stream command"
Bugzilla: 582475
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

This reverts commit 23dc821a5318f6cd2c6f8f0071c2dbd6638a4812.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 blockdev.c      |  139 -------------------------------------------------------
 blockdev.h      |    1 -
 monitor.c       |    3 -
 monitor.h       |    1 -
 qemu-monitor.hx |   69 ---------------------------
 qerror.c        |    8 ---
 qerror.h        |    6 --
 7 files changed, 0 insertions(+), 227 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 blockdev.c      |  139 -------------------------------------------------------
 blockdev.h      |    1 -
 monitor.c       |    3 -
 monitor.h       |    1 -
 qemu-monitor.hx |   69 ---------------------------
 qerror.c        |    8 ---
 qerror.h        |    6 --
 7 files changed, 0 insertions(+), 227 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index f8c1111..402cd40 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -15,7 +15,6 @@
 #include "qemu-config.h"
 #include "sysemu.h"
 #include "block_int.h"
-#include "qjson.h"
 #include "qmp-commands.h"
 
 struct drivelist drives = QTAILQ_HEAD_INITIALIZER(drives);
@@ -52,137 +51,6 @@ static const int if_max_devs[IF_COUNT] = {
     [IF_SCSI] = 7,
 };
 
-typedef struct StreamState {
-    int64_t offset;             /* current position in block device */
-    BlockDriverState *bs;
-    QEMUTimer *timer;
-    QLIST_ENTRY(StreamState) list;
-} StreamState;
-
-static QLIST_HEAD(, StreamState) block_streams =
-    QLIST_HEAD_INITIALIZER(block_streams);
-
-static QObject *stream_get_qobject(StreamState *s)
-{
-    const char *name = bdrv_get_device_name(s->bs);
-    int64_t len = bdrv_getlength(s->bs);
-
-    return qobject_from_jsonf("{ 'device': %s, 'type': 'stream', "
-                              "'offset': %" PRId64 ", 'len': %" PRId64 ", "
-                              "'speed': %" PRId64 " }",
-                              name, s->offset, len, (int64_t)0);
-}
-
-static void stream_mon_event(StreamState *s, int ret)
-{
-    QObject *data = stream_get_qobject(s);
-
-    if (ret < 0) {
-        QDict *qdict = qobject_to_qdict(data);
-
-        qdict_put(qdict, "error", qstring_from_str(strerror(-ret)));
-    }
-
-    monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, data);
-    qobject_decref(data);
-}
-
-static void stream_free(StreamState *s)
-{
-    QLIST_REMOVE(s, list);
-
-    bdrv_set_in_use(s->bs, 0);
-    qemu_del_timer(s->timer);
-    qemu_free_timer(s->timer);
-    qemu_free(s);
-}
-
-static void stream_complete(StreamState *s, int ret)
-{
-    stream_mon_event(s, ret);
-    stream_free(s);
-}
-
-static void stream_cb(void *opaque, int nb_sectors)
-{
-    StreamState *s = opaque;
-
-    if (nb_sectors < 0) {
-        stream_complete(s, nb_sectors);
-        return;
-    }
-
-    s->offset += nb_sectors * BDRV_SECTOR_SIZE;
-
-    if (s->offset == bdrv_getlength(s->bs)) {
-        bdrv_change_backing_file(s->bs, NULL, NULL);
-        stream_complete(s, 0);
-    } else {
-        qemu_mod_timer(s->timer, qemu_get_clock(rt_clock));
-    }
-}
-
-/* We can't call bdrv_aio_stream() directly from the callback because that
- * makes qemu_aio_flush() not complete until the streaming is completed.
- * By delaying with a timer, we give qemu_aio_flush() a chance to complete.
- */
-static void stream_next_iteration(void *opaque)
-{
-    StreamState *s = opaque;
-
-    bdrv_aio_copy_backing(s->bs, s->offset / BDRV_SECTOR_SIZE, stream_cb, s);
-}
-
-static StreamState *stream_find(const char *device)
-{
-    StreamState *s;
-
-    QLIST_FOREACH(s, &block_streams, list) {
-        if (strcmp(bdrv_get_device_name(s->bs), device) == 0) {
-            return s;
-        }
-    }
-    return NULL;
-}
-
-static StreamState *stream_start(const char *device)
-{
-    StreamState *s;
-    BlockDriverAIOCB *acb;
-    BlockDriverState *bs;
-
-    s = stream_find(device);
-    if (s) {
-        qerror_report(QERR_DEVICE_IN_USE, device);
-        return NULL;
-    }
-
-    bs = bdrv_find(device);
-    if (!bs) {
-        qerror_report(QERR_DEVICE_NOT_FOUND, device);
-        return NULL;
-    }
-    if (bdrv_in_use(bs)) {
-        qerror_report(QERR_DEVICE_IN_USE, device);
-        return NULL;
-    }
-    bdrv_set_in_use(bs, 1);
-
-    s = qemu_mallocz(sizeof(*s));
-    s->bs = bs;
-    s->timer = qemu_new_timer(rt_clock, stream_next_iteration, s);
-    QLIST_INSERT_HEAD(&block_streams, s, list);
-
-    acb = bdrv_aio_copy_backing(s->bs, s->offset / BDRV_SECTOR_SIZE,
-                                stream_cb, s);
-    if (acb == NULL) {
-        stream_free(s);
-        qerror_report(QERR_NOT_SUPPORTED);
-        return NULL;
-    }
-    return s;
-}
-
 /*
  * We automatically delete the drive when a device using it gets
  * unplugged.  Questionable feature, but we can't just drop it.
@@ -966,13 +834,6 @@ exit:
 }
 #endif
 
-int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data)
-{
-    const char *device = qdict_get_str(params, "device");
-
-    return stream_start(device) ? 0 : -1;
-}
-
 static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
 {
     if (!bdrv_dev_has_removable_media(bs)) {
diff --git a/blockdev.h b/blockdev.h
index 5a6d9fc..171401c 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -71,6 +71,5 @@ int do_change_block(Monitor *mon, const char *device,
                     const char *filename, const char *fmt);
 int simple_drive_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
-int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 9930635..b714e99 100644
--- a/monitor.c
+++ b/monitor.c
@@ -484,9 +484,6 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
         case QEVENT_RH_SPICE_DISCONNECTED:
             event_name = RFQDN_REDHAT "SPICE_DISCONNECTED";
             break;
-        case QEVENT_BLOCK_JOB_COMPLETED:
-            event_name = "BLOCK_JOB_COMPLETED";
-            break;
         case QEVENT_SUSPEND:
             event_name = "SUSPEND";
             break;
diff --git a/monitor.h b/monitor.h
index 8db2523..b4481cf 100644
--- a/monitor.h
+++ b/monitor.h
@@ -41,7 +41,6 @@ typedef enum MonitorEvent {
     QEVENT_DEVICE_TRAY_MOVED,
     QEVENT_RH_SPICE_INITIALIZED,
     QEVENT_RH_SPICE_DISCONNECTED,
-    QEVENT_BLOCK_JOB_COMPLETED,
     QEVENT_SUSPEND,
     QEVENT_WAKEUP,
     QEVENT_MAX,
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index b974542..07d8739 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -99,75 +99,6 @@ Commit changes to the disk images (if -snapshot is used) or backing files.
 ETEXI
 
     {
-        .name       = "block_stream",
-        .args_type  = "device:B",
-        .params     = "device",
-        .help       = "Copy data from a backing file into a block device",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_block_stream,
-    },
-
-STEXI
-@item block_stream
-@findex block_stream
-Copy data from a backing file into a block device.
-ETEXI
-SQMP
-
-Copy data from a backing file into a block device.
-
-The block streaming operation is performed in the background until the entire
-backing file has been copied.  This command returns immediately once streaming
-has started.  The status of ongoing block streaming operations can be checked
-with query-block-jobs.  The operation can be stopped before it has completed
-using the block_job_cancel command.
-
-If a base file is specified then sectors are not copied from that base file and
-its backing chain.  When streaming completes the image file will have the base
-file as its backing file.  This can be used to stream a subset of the backing
-file chain instead of flattening the entire image.
-
-On successful completion the image file is updated to drop the backing file.
-
-Arguments:
-
-- device: device name (json-string)
-- base:   common backing file (json-string, optional)
-
-Errors:
-
-DeviceInUse:    streaming is already active on this device
-DeviceNotFound: device name is invalid
-NotSupported:   image streaming is not supported by this device
-
-Events:
-
-On completion the BLOCK_JOB_COMPLETED event is raised with the following
-fields:
-
-- type:     job type ("stream" for image streaming, json-string)
-- device:   device name (json-string)
-- end:      maximum progress value (json-int)
-- position: current progress value (json-int)
-- speed:    rate limit, bytes per second (json-int)
-- error:    error message (json-string, only on error)
-
-The completion event is raised both on success and on failure.  On
-success position is equal to end.  On failure position and end can be
-used to indicate at which point the operation failed.
-
-On failure the error field contains a human-readable error message.  There are
-no semantics other than that streaming has failed and clients should not try
-to interpret the error string.
-
-Examples:
-
--> { "execute": "block_stream", "arguments": { "device": "virtio0" } }
-<- { "return":  {} }
-
-EQMP
-
-    {
         .name       = "q|quit",
         .args_type  = "",
         .params     = "",
diff --git a/qerror.c b/qerror.c
index 5261552..29d6577 100644
--- a/qerror.c
+++ b/qerror.c
@@ -174,10 +174,6 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "No '%(bus)' bus found for device '%(device)'",
     },
     {
-        .error_fmt = QERR_NOT_SUPPORTED,
-        .desc      = "Operation is not supported",
-    },
-    {
         .error_fmt = QERR_OPEN_FILE_FAILED,
         .desc      = "Could not open '%(filename)'",
     },
@@ -246,10 +242,6 @@ static const QErrorStringTable qerror_table[] = {
         .error_fmt = QERR_QGA_COMMAND_FAILED,
         .desc      = "Guest agent command failed, error was '%(message)'",
     },
-    {
-        .error_fmt = QERR_STREAMING_ERROR,
-        .desc      = "An error occurred during streaming: %(msg)",
-    },
     {}
 };
 
diff --git a/qerror.h b/qerror.h
index bff2b8e..27de1da 100644
--- a/qerror.h
+++ b/qerror.h
@@ -152,9 +152,6 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_NO_BUS_FOR_DEVICE \
     "{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }"
 
-#define QERR_NOT_SUPPORTED \
-    "{ 'class': 'NotSupported', 'data': {} }"
-
 #define QERR_OPEN_FILE_FAILED \
     "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
 
@@ -200,9 +197,6 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_VNC_SERVER_FAILED \
     "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
 
-#define QERR_STREAMING_ERROR \
-    "{ 'class': 'StreamingError', 'data': { 'msg': %s } }"
-
 #define QERR_QGA_LOGGING_FAILED \
     "{ 'class': 'QgaLoggingFailed', 'data': {} }"
 
-- 
1.7.7.6

