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