From: Jagannathan Raman <jag.ra...@oracle.com>

Extend block_resize QMP/HMP commands to resize block devices on a remote
process.

Signed-off-by: John G Johnson <john.g.john...@oracle.com>
Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com>
Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com>
---
 Changes in v2:
  - removed separate QMP/HMP command.
  - extended existing QMP command
  - refactor code to send messages to remote
---
 blockdev.c                | 15 +++++++++++++++
 hmp.c                     |  8 ++++++++
 hmp.h                     |  1 +
 hw/proxy/monitor.c        | 39 +++++++++++++++++++++++++++++++++++++++
 include/io/proxy-link.h   |  2 ++
 include/sysemu/blockdev.h |  4 ++++
 remote/remote-main.c      | 36 ++++++++++++++++++++++++++++++++++++
 stubs/monitor.c           |  5 +++++
 8 files changed, 110 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index d554b1802f..6e1ad12a95 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3115,12 +3115,27 @@ void qmp_block_resize(bool has_device, const char 
*device,
                       bool has_node_name, const char *node_name,
                       int64_t size, Error **errp)
 {
+    MachineState *ms = MACHINE(current_machine);
     Error *local_err = NULL;
     BlockBackend *blk = NULL;
     BlockDriverState *bs;
     AioContext *aio_context;
     int ret;
 
+#ifdef CONFIG_MPQEMU
+    /*
+     * TODO: Assumes "device" for remote drive. Add support for
+     * "nodename" as well
+     */
+    if (has_device && g_hash_table_lookup(ms->remote_devs, device)) {
+        qmp_rblock_resize(device, device, size, errp);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        }
+        return;
+    }
+#endif
+
     bs = bdrv_lookup_bs(has_device ? device : NULL,
                         has_node_name ? node_name : NULL,
                         &local_err);
diff --git a/hmp.c b/hmp.c
index 89cdaebfde..e56b3b1f96 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1339,10 +1339,18 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
 
 void hmp_block_resize(Monitor *mon, const QDict *qdict)
 {
+    MachineState *ms = MACHINE(current_machine);
     const char *device = qdict_get_str(qdict, "device");
     int64_t size = qdict_get_int(qdict, "size");
     Error *err = NULL;
 
+#ifdef CONFIG_MPQEMU
+    if (g_hash_table_lookup(ms->remote_devs, device)) {
+        hmp_rblock_resize(mon, qdict, &err);
+        return;
+    }
+#endif
+
     qmp_block_resize(true, device, false, NULL, size, &err);
     hmp_handle_error(mon, &err);
 }
diff --git a/hmp.h b/hmp.h
index 6919f99218..5f46783d25 100644
--- a/hmp.h
+++ b/hmp.h
@@ -151,5 +151,6 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict 
*qdict);
 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
 void hmp_info_sev(Monitor *mon, const QDict *qdict);
 void hmp_info_remote(Monitor *mon, const QDict *qdict);
+void hmp_rblock_resize(Monitor *mon, const QDict *qdict, Error **errp);
 
 #endif
diff --git a/hw/proxy/monitor.c b/hw/proxy/monitor.c
index e48b7f05d7..90f66aec6a 100644
--- a/hw/proxy/monitor.c
+++ b/hw/proxy/monitor.c
@@ -255,3 +255,42 @@ void hmp_rdrive_del(Monitor *mon, const QDict *qdict)
         (void)g_hash_table_remove(ms->remote_devs, (gpointer)id);
     }
 }
+
+void qmp_rblock_resize(const char *id, const char *device, int64_t size,
+                       Error **errp)
+{
+    MachineState *ms = MACHINE(current_machine);
+    PCIProxyDev *pdev = NULL;
+    QString *json;
+    QDict *qdict;
+
+    pdev = (PCIProxyDev *)g_hash_table_lookup(ms->remote_devs, id);
+    if (!pdev) {
+        error_setg(errp, "No remote device named %s", device);
+        return;
+    }
+
+    qdict = qdict_new();
+    qdict_put_str(qdict, "device", device);
+    qdict_put_int(qdict, "size", size);
+
+    json = qobject_to_json(QOBJECT(qdict));
+
+    (void)send_monitor_msg(pdev, BLOCK_RESIZE, strlen(qstring_get_str(json)),
+                           (uint8_t *)qstring_get_str(json));
+}
+
+void hmp_rblock_resize(Monitor *mon, const QDict *qdict, Error **errp)
+{
+    Error *local_err = NULL;
+    const char *device;
+    int64_t size;
+
+    device = qdict_get_str(qdict, "device");
+    size = qdict_get_int(qdict, "size");
+
+    qmp_rblock_resize(device, device, size, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+}
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index bcec97d615..fea9fe5ae1 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -64,6 +64,7 @@ typedef struct ProxyLinkState ProxyLinkState;
  * DEVICE_DEL       QMP/HMP command to hot-unplug device
  * DRIVE_ADD        HMP command to hotplug drive
  * DRIVE_DEL        HMP command to hot-unplug drive
+ * BLOCK_RESIZE     QMP/HMP command to resize block backend
  *
  */
 typedef enum {
@@ -81,6 +82,7 @@ typedef enum {
     DRIVE_ADD,
     DRIVE_DEL,
     PROXY_PING,
+    BLOCK_RESIZE,
     MAX,
 } proc_cmd_t;
 
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index e6a9780025..975ecae54f 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -62,4 +62,8 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType 
block_default_type,
 void hmp_commit(Monitor *mon, const QDict *qdict);
 void hmp_drive_del(Monitor *mon, const QDict *qdict);
 void hmp_rdrive_del(Monitor *mon, const QDict *qdict);
+
+void qmp_rblock_resize(const char *id, const char *device, int64_t size,
+                       Error **errp);
+
 #endif
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 4866322b7e..fbaae8bf3a 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -64,6 +64,7 @@
 #include "qapi/qmp/qlist.h"
 #include "qemu/log.h"
 #include "qemu/cutils.h"
+#include "qapi/qapi-commands-block-core.h"
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
@@ -272,6 +273,38 @@ static void process_drive_del_msg(ProcMsg *msg)
     PUT_REMOTE_WAIT(wait);
 }
 
+static void process_block_resize_msg(ProcMsg *msg)
+{
+    const char *json = (const char *)msg->data2;
+    Error *local_err = NULL;
+    int wait = msg->fds[0];
+    const char *device;
+    int64_t size;
+    QObject *qobj = NULL;
+    QDict *qdict = NULL;
+
+    qobj = qobject_from_json(json, &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+        return;
+    }
+
+    qdict = qobject_to(QDict, qobj);
+    assert(qdict);
+
+    device = qdict_get_str(qdict, "device");
+    size = qdict_get_int(qdict, "size");
+
+    qmp_block_resize(true, device, false, NULL, size, &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+    }
+
+    notify_proxy(wait, 1);
+
+    PUT_REMOTE_WAIT(wait);
+}
+
 static int init_drive(QDict *rqdict, Error **errp)
 {
     QemuOpts *opts;
@@ -482,6 +515,9 @@ static void process_msg(GIOCondition cond)
         notify_proxy(wait, (uint32_t)getpid());
         PUT_REMOTE_WAIT(wait);
         break;
+    case BLOCK_RESIZE:
+        process_block_resize_msg(msg);
+        break;
     default:
         error_setg(&err, "Unknown command");
         goto finalize_loop;
diff --git a/stubs/monitor.c b/stubs/monitor.c
index 653c308934..79e008df41 100644
--- a/stubs/monitor.c
+++ b/stubs/monitor.c
@@ -60,3 +60,8 @@ void qmp_rdevice_del(const char *id, Error **errp)
 void hmp_rdrive_del(Monitor *mon, const QDict *qdict)
 {
 }
+
+void qmp_rblock_resize(const char *id, const char *device, int64_t size,
+                       Error **errp)
+{
+}
-- 
2.17.1


Reply via email to