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:
parent
7d1740590b
commit
f07918fdff
69
monitor.c
69
monitor.c
|
@ -70,6 +70,14 @@ typedef struct mon_cmd_t {
|
||||||
const char *help;
|
const char *help;
|
||||||
} mon_cmd_t;
|
} 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 {
|
struct Monitor {
|
||||||
CharDriverState *chr;
|
CharDriverState *chr;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -80,6 +88,7 @@ struct Monitor {
|
||||||
CPUState *mon_cpu;
|
CPUState *mon_cpu;
|
||||||
BlockDriverCompletionFunc *password_completion_cb;
|
BlockDriverCompletionFunc *password_completion_cb;
|
||||||
void *password_opaque;
|
void *password_opaque;
|
||||||
|
LIST_HEAD(,mon_fd_t) fds;
|
||||||
LIST_ENTRY(Monitor) entry;
|
LIST_ENTRY(Monitor) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon,
|
||||||
}
|
}
|
||||||
#endif
|
#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[] = {
|
static const mon_cmd_t mon_cmds[] = {
|
||||||
#include "qemu-monitor.h"
|
#include "qemu-monitor.h"
|
||||||
{ NULL, NULL, },
|
{ NULL, NULL, },
|
||||||
|
|
|
@ -626,6 +626,24 @@ ETEXI
|
||||||
STEXI
|
STEXI
|
||||||
@item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
|
@item mce @var{cpu} @var{bank} @var{status} @var{mcgstatus} @var{addr} @var{misc}
|
||||||
Inject an MCE on the given CPU (x86 only).
|
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
|
ETEXI
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
|
|
Loading…
Reference in New Issue