hmp: add NBD server commands
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
17b6be4a7f
commit
4057725f35
@ -1310,6 +1310,51 @@ Remove all matches from the access control list, and set the default
|
|||||||
policy back to @code{deny}.
|
policy back to @code{deny}.
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "nbd_server_start",
|
||||||
|
.args_type = "all:-a,writable:-w,uri:s",
|
||||||
|
.params = "nbd_server_start [-a] [-w] host:port",
|
||||||
|
.help = "serve block devices on the given host and port",
|
||||||
|
.mhandler.cmd = hmp_nbd_server_start,
|
||||||
|
},
|
||||||
|
STEXI
|
||||||
|
@item nbd_server_start @var{host}:@var{port}
|
||||||
|
@findex nbd_server_start
|
||||||
|
Start an NBD server on the given host and/or port. If the @option{-a}
|
||||||
|
option is included, all of the virtual machine's block devices that
|
||||||
|
have an inserted media on them are automatically exported; in this case,
|
||||||
|
the @option{-w} option makes the devices writable too.
|
||||||
|
ETEXI
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "nbd_server_add",
|
||||||
|
.args_type = "writable:-w,device:B",
|
||||||
|
.params = "nbd_server_add [-w] device",
|
||||||
|
.help = "export a block device via NBD",
|
||||||
|
.mhandler.cmd = hmp_nbd_server_add,
|
||||||
|
},
|
||||||
|
STEXI
|
||||||
|
@item nbd_server_add @var{device}
|
||||||
|
@findex nbd_server_add
|
||||||
|
Export a block device through QEMU's NBD server, which must be started
|
||||||
|
beforehand with @command{nbd_server_start}. The @option{-w} option makes the
|
||||||
|
exported device writable too.
|
||||||
|
ETEXI
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "nbd_server_stop",
|
||||||
|
.args_type = "",
|
||||||
|
.params = "nbd_server_stop",
|
||||||
|
.help = "stop serving block devices using the NBD protocol",
|
||||||
|
.mhandler.cmd = hmp_nbd_server_stop,
|
||||||
|
},
|
||||||
|
STEXI
|
||||||
|
@item nbd_server_stop
|
||||||
|
@findex nbd_server_stop
|
||||||
|
Stop the QEMU embedded NBD server.
|
||||||
|
ETEXI
|
||||||
|
|
||||||
|
|
||||||
#if defined(TARGET_I386)
|
#if defined(TARGET_I386)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
76
hmp.c
76
hmp.c
@ -18,6 +18,7 @@
|
|||||||
#include "qemu-option.h"
|
#include "qemu-option.h"
|
||||||
#include "qemu-timer.h"
|
#include "qemu-timer.h"
|
||||||
#include "qmp-commands.h"
|
#include "qmp-commands.h"
|
||||||
|
#include "qemu_socket.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
@ -1259,3 +1260,78 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
|
|||||||
qmp_screendump(filename, &err);
|
qmp_screendump(filename, &err);
|
||||||
hmp_handle_error(mon, &err);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *uri = qdict_get_str(qdict, "uri");
|
||||||
|
int writable = qdict_get_try_bool(qdict, "writable", 0);
|
||||||
|
int all = qdict_get_try_bool(qdict, "all", 0);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
BlockInfoList *block_list, *info;
|
||||||
|
SocketAddress *addr;
|
||||||
|
|
||||||
|
if (writable && !all) {
|
||||||
|
error_setg(&local_err, "-w only valid together with -a");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First check if the address is valid and start the server. */
|
||||||
|
addr = socket_parse(uri, &local_err);
|
||||||
|
if (local_err != NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_nbd_server_start(addr, &local_err);
|
||||||
|
qapi_free_SocketAddress(addr);
|
||||||
|
if (local_err != NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!all) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then try adding all block devices. If one fails, close all and
|
||||||
|
* exit.
|
||||||
|
*/
|
||||||
|
block_list = qmp_query_block(NULL);
|
||||||
|
|
||||||
|
for (info = block_list; info; info = info->next) {
|
||||||
|
if (!info->value->has_inserted) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_nbd_server_add(info->value->device, true, writable, &local_err);
|
||||||
|
|
||||||
|
if (local_err != NULL) {
|
||||||
|
qmp_nbd_server_stop(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qapi_free_BlockInfoList(block_list);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
hmp_handle_error(mon, &local_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
|
int writable = qdict_get_try_bool(qdict, "writable", 0);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
qmp_nbd_server_add(device, true, writable, &local_err);
|
||||||
|
|
||||||
|
if (local_err != NULL) {
|
||||||
|
hmp_handle_error(mon, &local_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
Error *errp = NULL;
|
||||||
|
|
||||||
|
qmp_nbd_server_stop(&errp);
|
||||||
|
hmp_handle_error(mon, &errp);
|
||||||
|
}
|
||||||
|
3
hmp.h
3
hmp.h
@ -77,5 +77,8 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
|
|||||||
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_send_key(Monitor *mon, const QDict *qdict);
|
void hmp_send_key(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_screen_dump(Monitor *mon, const QDict *qdict);
|
void hmp_screen_dump(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user