From: "Dr. David Alan Gilbert" <[email protected]> The existing 'getfd' command imports an fd from the monitor via SCM rights. This command allows qemu to open the file for itself; this is convenient primarily in testing, or with simple QMP clients.
Signed-off-by: Dr. David Alan Gilbert <[email protected]> --- monitor/misc.c | 48 ++++++++++++++++++++++++++++++++++++++---------- qapi/misc.json | 23 ++++++++++++++++++++++- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/monitor/misc.c b/monitor/misc.c index f5207cd242..d538af592a 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -1230,22 +1230,20 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict) } } -void qmp_getfd(const char *fdname, Error **errp) +/* + * Add a named fd to the monitor list. + * Returns true on success. + */ +static bool addfd(const char *fdname, int fd, Error **errp) { mon_fd_t *monfd; - int fd, tmp_fd; - - fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); - if (fd == -1) { - error_setg(errp, QERR_FD_NOT_SUPPLIED); - return; - } + int tmp_fd; if (qemu_isdigit(fdname[0])) { close(fd); error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "fdname", "a name not starting with a digit"); - return; + return false; } qemu_mutex_lock(&cur_mon->mon_lock); @@ -1259,7 +1257,7 @@ void qmp_getfd(const char *fdname, Error **errp) qemu_mutex_unlock(&cur_mon->mon_lock); /* Make sure close() is outside critical section */ close(tmp_fd); - return; + return true; } monfd = g_malloc0(sizeof(mon_fd_t)); @@ -1268,6 +1266,36 @@ void qmp_getfd(const char *fdname, Error **errp) QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next); qemu_mutex_unlock(&cur_mon->mon_lock); + + return true; +} + +void qmp_getfd(const char *fdname, Error **errp) +{ + int fd = qemu_chr_fe_get_msgfd(&cur_mon->chr); + if (fd == -1) { + error_setg(errp, QERR_FD_NOT_SUPPLIED); + return; + } + + if (!addfd(fdname, fd, errp)) { + close(fd); + } +} + +void qmp_openfd(const char *fdname, const char *filename, Error **errp) +{ + int fd; + + fd = open(filename, O_RDWR | O_CREAT, S_IRWXU); + if (fd == -1) { + error_setg_errno(errp, errno, "Cannot open file '%s'", filename); + return; + } + + if (!addfd(fdname, fd, errp)) { + close(fd); + } } void qmp_closefd(const char *fdname, Error **errp) diff --git a/qapi/misc.json b/qapi/misc.json index 99b90ac80b..baec07358e 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -952,7 +952,7 @@ ## # @closefd: # -# Close a file descriptor previously passed via SCM rights +# Close a named file descriptor # # @fdname: file descriptor name # @@ -968,6 +968,27 @@ ## { 'command': 'closefd', 'data': {'fdname': 'str'} } +## +# @openfd: +# +# Open a file descriptor. The file is opened read-write. +# +# @fdname: file descriptor name +# @filename: file name +# +# Returns: Nothing on success +# +# Since: 5.1 +# +# Example: +# +# -> { "execute": "openfd", "arguments": { "fdname": "null", +# "filename": "/dev/null" } } +# <- { "return": {} } +# +## +{ 'command': 'openfd', 'data': {'fdname': 'str', 'filename': 'str'} } + ## # @MemoryInfo: # -- 2.26.2
