Commit f07918fdff76ace82b1ca3e53bbcddef069eb314

Authored by Mark McLoughlin
Committed by Anthony Liguori
1 parent 7d174059

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>
Showing 2 changed files with 87 additions and 0 deletions
monitor.c
@@ -70,6 +70,14 @@ typedef struct mon_cmd_t { @@ -70,6 +70,14 @@ typedef struct mon_cmd_t {
70 const char *help; 70 const char *help;
71 } mon_cmd_t; 71 } mon_cmd_t;
72 72
  73 +/* file descriptors passed via SCM_RIGHTS */
  74 +typedef struct mon_fd_t mon_fd_t;
  75 +struct mon_fd_t {
  76 + char *name;
  77 + int fd;
  78 + LIST_ENTRY(mon_fd_t) next;
  79 +};
  80 +
73 struct Monitor { 81 struct Monitor {
74 CharDriverState *chr; 82 CharDriverState *chr;
75 int flags; 83 int flags;
@@ -80,6 +88,7 @@ struct Monitor { @@ -80,6 +88,7 @@ struct Monitor {
80 CPUState *mon_cpu; 88 CPUState *mon_cpu;
81 BlockDriverCompletionFunc *password_completion_cb; 89 BlockDriverCompletionFunc *password_completion_cb;
82 void *password_opaque; 90 void *password_opaque;
  91 + LIST_HEAD(,mon_fd_t) fds;
83 LIST_ENTRY(Monitor) entry; 92 LIST_ENTRY(Monitor) entry;
84 }; 93 };
85 94
@@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon, @@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon,
1705 } 1714 }
1706 #endif 1715 #endif
1707 1716
  1717 +static void do_getfd(Monitor *mon, const char *fdname)
  1718 +{
  1719 + mon_fd_t *monfd;
  1720 + int fd;
  1721 +
  1722 + fd = qemu_chr_get_msgfd(mon->chr);
  1723 + if (fd == -1) {
  1724 + monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n");
  1725 + return;
  1726 + }
  1727 +
  1728 + if (qemu_isdigit(fdname[0])) {
  1729 + monitor_printf(mon, "getfd: monitor names may not begin with a number\n");
  1730 + return;
  1731 + }
  1732 +
  1733 + fd = dup(fd);
  1734 + if (fd == -1) {
  1735 + monitor_printf(mon, "Failed to dup() file descriptor: %s\n",
  1736 + strerror(errno));
  1737 + return;
  1738 + }
  1739 +
  1740 + LIST_FOREACH(monfd, &mon->fds, next) {
  1741 + if (strcmp(monfd->name, fdname) != 0) {
  1742 + continue;
  1743 + }
  1744 +
  1745 + close(monfd->fd);
  1746 + monfd->fd = fd;
  1747 + return;
  1748 + }
  1749 +
  1750 + monfd = qemu_mallocz(sizeof(mon_fd_t));
  1751 + monfd->name = qemu_strdup(fdname);
  1752 + monfd->fd = fd;
  1753 +
  1754 + LIST_INSERT_HEAD(&mon->fds, monfd, next);
  1755 +}
  1756 +
  1757 +static void do_closefd(Monitor *mon, const char *fdname)
  1758 +{
  1759 + mon_fd_t *monfd;
  1760 +
  1761 + LIST_FOREACH(monfd, &mon->fds, next) {
  1762 + if (strcmp(monfd->name, fdname) != 0) {
  1763 + continue;
  1764 + }
  1765 +
  1766 + LIST_REMOVE(monfd, next);
  1767 + close(monfd->fd);
  1768 + qemu_free(monfd->name);
  1769 + qemu_free(monfd);
  1770 + return;
  1771 + }
  1772 +
  1773 + monitor_printf(mon, "Failed to find file descriptor named %s\n",
  1774 + fdname);
  1775 +}
  1776 +
1708 static const mon_cmd_t mon_cmds[] = { 1777 static const mon_cmd_t mon_cmds[] = {
1709 #include "qemu-monitor.h" 1778 #include "qemu-monitor.h"
1710 { NULL, NULL, }, 1779 { NULL, NULL, },
qemu-monitor.hx
@@ -628,6 +628,24 @@ STEXI @@ -628,6 +628,24 @@ STEXI
628 Inject an MCE on the given CPU (x86 only). 628 Inject an MCE on the given CPU (x86 only).
629 ETEXI 629 ETEXI
630 630
  631 + { "getfd", "s", do_getfd, "getfd name",
  632 + "receive a file descriptor via SCM rights and assign it a name" },
  633 +STEXI
  634 +@item getfd @var{fdname}
  635 +If a file descriptor is passed alongside this command using the SCM_RIGHTS
  636 +mechanism on unix sockets, it is stored using the name @var{fdname} for
  637 +later use by other monitor commands.
  638 +ETEXI
  639 +
  640 + { "closefd", "s", do_closefd, "closefd name",
  641 + "close a file descriptor previously passed via SCM rights" },
  642 +STEXI
  643 +@item closefd @var{fdname}
  644 +Close the file descriptor previously assigned to @var{fdname} using the
  645 +@code{getfd} command. This is only needed if the file descriptor was never
  646 +used by another monitor command.
  647 +ETEXI
  648 +
631 STEXI 649 STEXI
632 @end table 650 @end table
633 ETEXI 651 ETEXI