Commit f07918fdff76ace82b1ca3e53bbcddef069eb314
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 |