introduce set_rate_limit function for QEMUFile

This patch converts the current callers of qemu_fopen_ops().

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/buffered_file.c b/buffered_file.c
index ec4f664..364b912 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -198,6 +198,19 @@
     return 0;
 }
 
+static size_t buffered_set_rate_limit(void *opaque, size_t new_rate)
+{
+    QEMUFileBuffered *s = opaque;
+
+    if (s->has_error)
+        goto out;
+
+    s->xfer_limit = new_rate / 10;
+    
+out:
+    return s->xfer_limit;
+}
+
 static void buffered_rate_tick(void *opaque)
 {
     QEMUFileBuffered *s = opaque;
@@ -237,7 +250,8 @@
     s->close = close;
 
     s->file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
-                             buffered_close, buffered_rate_limit);
+                             buffered_close, buffered_rate_limit,
+                             buffered_set_rate_limit);
 
     s->timer = qemu_new_timer(rt_clock, buffered_rate_tick, s);
 
diff --git a/hw/hw.h b/hw/hw.h
index c990d1a..dd11f0a 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -36,10 +36,17 @@
  */
 typedef int (QEMUFileRateLimit)(void *opaque);
 
+/* Called to change the current bandwidth allocation. This function must return
+ * the new actual bandwidth. It should be new_rate if everything goes ok, and
+ * the old rate otherwise
+ */
+typedef size_t (QEMUFileSetRateLimit)(void *opaque, size_t new_rate);
+
 QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
                          QEMUFileGetBufferFunc *get_buffer,
                          QEMUFileCloseFunc *close,
-                         QEMUFileRateLimit *rate_limit);
+                         QEMUFileRateLimit *rate_limit,
+                         QEMUFileSetRateLimit *set_rate_limit);
 QEMUFile *qemu_fopen(const char *filename, const char *mode);
 QEMUFile *qemu_fopen_socket(int fd);
 QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
@@ -73,6 +80,7 @@
 unsigned int qemu_get_be32(QEMUFile *f);
 uint64_t qemu_get_be64(QEMUFile *f);
 int qemu_file_rate_limit(QEMUFile *f);
+size_t qemu_file_set_rate_limit(QEMUFile *f, size_t new_rate);
 int qemu_file_has_error(QEMUFile *f);
 void qemu_file_set_error(QEMUFile *f);
 
diff --git a/savevm.c b/savevm.c
index 774305d..68ffd03 100644
--- a/savevm.c
+++ b/savevm.c
@@ -159,6 +159,7 @@
     QEMUFileGetBufferFunc *get_buffer;
     QEMUFileCloseFunc *close;
     QEMUFileRateLimit *rate_limit;
+    QEMUFileSetRateLimit *set_rate_limit;
     void *opaque;
     int is_write;
 
@@ -239,9 +240,9 @@
     s->popen_file = popen_file;
 
     if(mode[0] == 'r') {
-        s->file = qemu_fopen_ops(s, NULL, popen_get_buffer, popen_close, NULL);
+        s->file = qemu_fopen_ops(s, NULL, popen_get_buffer, popen_close, NULL, NULL);
     } else {
-        s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL);
+        s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL, NULL);
     }
     fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n");
     return s->file;
@@ -264,7 +265,7 @@
     QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
 
     s->fd = fd;
-    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, NULL);
+    s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, NULL, NULL);
     return s->file;
 }
 
@@ -308,9 +309,9 @@
         goto fail;
 
     if (!strcmp(mode, "wb"))
-        return qemu_fopen_ops(s, file_put_buffer, NULL, file_close, NULL);
+        return qemu_fopen_ops(s, file_put_buffer, NULL, file_close, NULL, NULL);
     else if (!strcmp(mode, "rb"))
-        return qemu_fopen_ops(s, NULL, file_get_buffer, file_close, NULL);
+        return qemu_fopen_ops(s, NULL, file_get_buffer, file_close, NULL, NULL);
 
 fail:
     if (s->outfile)
@@ -356,15 +357,16 @@
     s->base_offset = offset;
 
     if (is_writable)
-        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL);
+        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
 
-    return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL);
+    return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
 }
 
 QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
                          QEMUFileGetBufferFunc *get_buffer,
                          QEMUFileCloseFunc *close,
-                         QEMUFileRateLimit *rate_limit)
+                         QEMUFileRateLimit *rate_limit,
+                         QEMUFileSetRateLimit *set_rate_limit)
 {
     QEMUFile *f;
 
@@ -375,6 +377,7 @@
     f->get_buffer = get_buffer;
     f->close = close;
     f->rate_limit = rate_limit;
+    f->set_rate_limit = set_rate_limit;
     f->is_write = 0;
 
     return f;
@@ -552,6 +555,14 @@
     return 0;
 }
 
+size_t qemu_file_set_rate_limit(QEMUFile *f, size_t new_rate)
+{
+    if (f->set_rate_limit)
+        return f->set_rate_limit(f->opaque, new_rate);
+
+    return 0;
+}
+
 void qemu_put_be16(QEMUFile *f, unsigned int v)
 {
     qemu_put_byte(f, v >> 8);