diff options
author | Mark McLoughlin <markmc@redhat.com> | 2009-07-22 09:11:40 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-07-27 08:39:28 -0500 |
commit | f07918fdff76ace82b1ca3e53bbcddef069eb314 (patch) | |
tree | 3328e81b61bb0e1cc4144d840bf179a205af7733 /monitor.c | |
parent | 7d1740590b6550b2b8ab4901e4f0b704d9733383 (diff) |
Add getfd and closefd monitor commands
Add monitor commands to support passing file descriptors via
SCM_RIGHTS.
getfd assigns the passed file descriptor a name for use with other
monitor commands.
closefd allows passed file descriptors to be closed. If a monitor
command actually uses a named file descriptor, closefd will not be
required.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 69 |
1 files changed, 69 insertions, 0 deletions
@@ -70,6 +70,14 @@ typedef struct mon_cmd_t { const char *help; } mon_cmd_t; +/* file descriptors passed via SCM_RIGHTS */ +typedef struct mon_fd_t mon_fd_t; +struct mon_fd_t { + char *name; + int fd; + LIST_ENTRY(mon_fd_t) next; +}; + struct Monitor { CharDriverState *chr; int flags; @@ -80,6 +88,7 @@ struct Monitor { CPUState *mon_cpu; BlockDriverCompletionFunc *password_completion_cb; void *password_opaque; + LIST_HEAD(,mon_fd_t) fds; LIST_ENTRY(Monitor) entry; }; @@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon, } #endif +static void do_getfd(Monitor *mon, const char *fdname) +{ + mon_fd_t *monfd; + int fd; + + fd = qemu_chr_get_msgfd(mon->chr); + if (fd == -1) { + monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n"); + return; + } + + if (qemu_isdigit(fdname[0])) { + monitor_printf(mon, "getfd: monitor names may not begin with a number\n"); + return; + } + + fd = dup(fd); + if (fd == -1) { + monitor_printf(mon, "Failed to dup() file descriptor: %s\n", + strerror(errno)); + return; + } + + LIST_FOREACH(monfd, &mon->fds, next) { + if (strcmp(monfd->name, fdname) != 0) { + continue; + } + + close(monfd->fd); + monfd->fd = fd; + return; + } + + monfd = qemu_mallocz(sizeof(mon_fd_t)); + monfd->name = qemu_strdup(fdname); + monfd->fd = fd; + + LIST_INSERT_HEAD(&mon->fds, monfd, next); +} + +static void do_closefd(Monitor *mon, const char *fdname) +{ + mon_fd_t *monfd; + + LIST_FOREACH(monfd, &mon->fds, next) { + if (strcmp(monfd->name, fdname) != 0) { + continue; + } + + LIST_REMOVE(monfd, next); + close(monfd->fd); + qemu_free(monfd->name); + qemu_free(monfd); + return; + } + + monitor_printf(mon, "Failed to find file descriptor named %s\n", + fdname); +} + static const mon_cmd_t mon_cmds[] = { #include "qemu-monitor.h" { NULL, NULL, }, |