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>
This commit is contained in:
Mark McLoughlin 2009-07-22 09:11:40 +01:00 committed by Anthony Liguori
parent 7d1740590b
commit f07918fdff
2 changed files with 87 additions and 0 deletions

View File

@ -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, },

View File

@ -626,6 +626,24 @@ ETEXI
STEXI
@item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
Inject an MCE on the given CPU (x86 only).
ETEXI
{ "getfd", "s", do_getfd, "getfd name",
"receive a file descriptor via SCM rights and assign it a name" },
STEXI
@item getfd @var{fdname}
If a file descriptor is passed alongside this command using the SCM_RIGHTS
mechanism on unix sockets, it is stored using the name @var{fdname} for
later use by other monitor commands.
ETEXI
{ "closefd", "s", do_closefd, "closefd name",
"close a file descriptor previously passed via SCM rights" },
STEXI
@item closefd @var{fdname}
Close the file descriptor previously assigned to @var{fdname} using the
@code{getfd} command. This is only needed if the file descriptor was never
used by another monitor command.
ETEXI
STEXI