This patch provides support for the getfd_file monitor command. This command will allow passing of a filename and its corresponding file descriptor to a guest via the monitor. This command could be followed, for example, by a drive_add command to hot attach a disk drive. Signed-off-by: Corey Bryant <coreyb@xxxxxxxxxxxxxxxxxx> --- hmp-commands.hx | 17 +++++++++++++ monitor.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor.h | 3 ++ qemu-tool.c | 5 ++++ qmp-commands.hx | 30 +++++++++++++++++++++++ 5 files changed, 125 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 18cb415..9cd5ed1 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1240,6 +1240,23 @@ used by another monitor command. ETEXI { + .name = "getfd_file", + .args_type = "filename:s", + .params = "getfd_file filename", + .help = "receive a file descriptor via SCM rights and assign it a filename", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_getfd_file, + }, + +STEXI +@item getfd_file @var{filename} +@findex getfd_file +If a file descriptor is passed alongside this command using the SCM_RIGHTS +mechanism on unix sockets, it is stored using the name @var{filename} for +later use by other monitor commands. +ETEXI + + { .name = "block_passwd", .args_type = "device:B,password:s", .params = "block_passwd device password", diff --git a/monitor.c b/monitor.c index 12a6fe2..bdf4dd8 100644 --- a/monitor.c +++ b/monitor.c @@ -163,6 +163,7 @@ struct Monitor { #endif QError *error; QLIST_HEAD(,mon_fd_t) fds; + QLIST_HEAD(,mon_fd_t) file_fds; QLIST_ENTRY(Monitor) entry; }; @@ -2256,6 +2257,42 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) return -1; } +static int do_getfd_file(Monitor *mon, const QDict *qdict, QObject **ret_data) +{ + const char *filename = qdict_get_str(qdict, "filename"); + mon_fd_t *monfd; + int fd; + + fd = qemu_chr_fe_get_msgfd(mon->chr); + if (fd == -1) { + qerror_report(QERR_FD_NOT_SUPPLIED); + return -1; + } + + if (qemu_isdigit(filename[0])) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "filename", + "a name not starting with a digit"); + return -1; + } + + QLIST_FOREACH(monfd, &mon->file_fds, next) { + if (strcmp(monfd->name, filename) != 0) { + continue; + } + + close(monfd->fd); + monfd->fd = fd; + return 0; + } + + monfd = g_malloc0(sizeof(mon_fd_t)); + monfd->name = g_strdup(filename); + monfd->fd = fd; + + QLIST_INSERT_HEAD(&mon->file_fds, monfd, next); + return 0; +} + static void do_loadvm(Monitor *mon, const QDict *qdict) { int saved_vm_running = runstate_is_running(); @@ -2292,6 +2329,39 @@ int monitor_get_fd(Monitor *mon, const char *fdname) return -1; } +int monitor_get_fd_file(Monitor *mon, const char *filename, + bool take_ownership) +{ + mon_fd_t *monfd; + + QLIST_FOREACH(monfd, &mon->file_fds, next) { + int fd; + + if (strcmp(monfd->name, filename) != 0) { + continue; + } + + fd = monfd->fd; + + if (take_ownership) { + /* caller takes ownership of fd */ + QLIST_REMOVE(monfd, next); + g_free(monfd->name); + g_free(monfd); + } + + return fd; + } + + return -1; +} + +int qemu_get_fd_file(const char *filename, bool take_ownership) +{ + return cur_mon ? + monitor_get_fd_file(cur_mon, filename, take_ownership) : -1; +} + /* mon_cmds and info_cmds would be sorted at runtime */ static mon_cmd_t mon_cmds[] = { #include "hmp-commands.h" diff --git a/monitor.h b/monitor.h index 0d49800..529d8a7 100644 --- a/monitor.h +++ b/monitor.h @@ -60,6 +60,9 @@ int monitor_read_block_device_key(Monitor *mon, const char *device, void *opaque); int monitor_get_fd(Monitor *mon, const char *fdname); +int monitor_get_fd_file(Monitor *mon, const char *filename, + bool take_ownership); +int qemu_get_fd_file(const char *filename, bool take_ownership); void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0); diff --git a/qemu-tool.c b/qemu-tool.c index 07fc4f2..d3d86bf 100644 --- a/qemu-tool.c +++ b/qemu-tool.c @@ -111,3 +111,8 @@ void migrate_add_blocker(Error *reason) void migrate_del_blocker(Error *reason) { } + +int qemu_get_fd_file(const char *fdname, bool take_ownership) +{ + return -1; +} diff --git a/qmp-commands.hx b/qmp-commands.hx index db980fa..1825a91 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -891,6 +891,36 @@ Example: EQMP { + .name = "getfd_file", + .args_type = "filename:s", + .params = "getfd_file filename", + .help = "receive a file descriptor via SCM rights and assign it a filename", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_getfd_file, + }, + + +SQMP + +getfd_file +-------------- + +Receive a file descriptor via SCM rights and assign it a filename. + +Arguments: + +- "filename": filename (json-string) + +Example: + +-> { "execute": "getfd_file", + "arguments": { "filename": "/var/lib/libvirt/images/tst.img" } } +<- { "return": {} } + + +EQMP + + { .name = "block_passwd", .args_type = "device:B,password:s", .mhandler.cmd_new = qmp_marshal_input_block_passwd, -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list