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 | 70 | const char *help; |
71 | 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 | 81 | struct Monitor { |
74 | 82 | CharDriverState *chr; |
75 | 83 | int flags; |
... | ... | @@ -80,6 +88,7 @@ struct Monitor { |
80 | 88 | CPUState *mon_cpu; |
81 | 89 | BlockDriverCompletionFunc *password_completion_cb; |
82 | 90 | void *password_opaque; |
91 | + LIST_HEAD(,mon_fd_t) fds; | |
83 | 92 | LIST_ENTRY(Monitor) entry; |
84 | 93 | }; |
85 | 94 | |
... | ... | @@ -1705,6 +1714,66 @@ static void do_inject_mce(Monitor *mon, |
1705 | 1714 | } |
1706 | 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 | 1777 | static const mon_cmd_t mon_cmds[] = { |
1709 | 1778 | #include "qemu-monitor.h" |
1710 | 1779 | { NULL, NULL, }, | ... | ... |
qemu-monitor.hx
... | ... | @@ -628,6 +628,24 @@ STEXI |
628 | 628 | Inject an MCE on the given CPU (x86 only). |
629 | 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 | 649 | STEXI |
632 | 650 | @end table |
633 | 651 | ETEXI | ... | ... |