From: Corey Bryant <coreyb@linux.vnet.ibm.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v5] qemu-config: Add new -add-fd command line option
Date: Mon, 22 Oct 2012 11:06:59 -0400 [thread overview]
Message-ID: <50856113.6050706@linux.vnet.ibm.com> (raw)
In-Reply-To: <1350916563-15700-1-git-send-email-kwolf@redhat.com>
On 10/22/2012 10:36 AM, Kevin Wolf wrote:
> From: Corey Bryant <coreyb@linux.vnet.ibm.com>
>
> This option can be used for passing file descriptors on the
> command line. It mirrors the existing add-fd QMP command which
> allows an fd to be passed to QEMU via SCM_RIGHTS and added to an
> fd set.
>
> This can be combined with commands such as -drive to link file
> descriptors in an fd set to a drive:
>
> qemu-kvm -add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
> -add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
> -drive file=/dev/fdset/2,index=0,media=disk
>
> This example adds dups of fds 3 and 4, and the accompanying opaque
> strings to the fd set with ID=2. qemu_open() already knows how
> to handle a filename of this format. qemu_open() searches the
> corresponding fd set for an fd and when it finds a match, QEMU
> goes on to use a dup of that fd just like it would have used an
> fd that it opened itself.
>
> Signed-off-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>
> Sorry, Corey, hope you're okay with me taking over your patch... Your patch was
> against the unmodified version while I already did some changes after the v4
> review, so it didn't apply.
>
That's fine. Thanks for the hand.
> This version just completely disables fd passing on Windows as I don't think
> it works there anyway. Gives you a nice error message instead of a silently
> ignored -add-fd option.
>
> Also added the missing break for case QEMU_OPTION_add_fd.
>
> qemu-config.c | 22 +++++++++++++
> qemu-options.hx | 36 +++++++++++++++++++++
> vl.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 152 insertions(+), 0 deletions(-)
>
> diff --git a/qemu-config.c b/qemu-config.c
> index cd1ec21..601237d 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -653,6 +653,27 @@ QemuOptsList qemu_boot_opts = {
> },
> };
>
> +static QemuOptsList qemu_add_fd_opts = {
> + .name = "add-fd",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
> + .desc = {
> + {
> + .name = "fd",
> + .type = QEMU_OPT_NUMBER,
> + .help = "file descriptor of which a duplicate is added to fd set",
> + },{
> + .name = "set",
> + .type = QEMU_OPT_NUMBER,
> + .help = "ID of the fd set to add fd to",
> + },{
> + .name = "opaque",
> + .type = QEMU_OPT_STRING,
> + .help = "free-form string used to describe fd",
> + },
> + { /* end of list */ }
> + },
> +};
> +
> static QemuOptsList *vm_config_groups[32] = {
> &qemu_drive_opts,
> &qemu_chardev_opts,
> @@ -669,6 +690,7 @@ static QemuOptsList *vm_config_groups[32] = {
> &qemu_boot_opts,
> &qemu_iscsi_opts,
> &qemu_sandbox_opts,
> + &qemu_add_fd_opts,
> NULL,
> };
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 46f0539..a67a255 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -253,6 +253,14 @@ qemu-system-i386 -drive file=file,index=2,media=disk
> qemu-system-i386 -drive file=file,index=3,media=disk
> @end example
>
> +You can open an image using pre-opened file descriptors from an fd set:
> +@example
> +qemu-system-i386
> +-add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
> +-add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
> +-drive file=/dev/fdset/2,index=0,media=disk
> +@end example
> +
> You can connect a CDROM to the slave of ide0:
> @example
> qemu-system-i386 -drive file=file,if=ide,index=1,media=cdrom
> @@ -285,6 +293,34 @@ qemu-system-i386 -hda a -hdb b
> @end example
> ETEXI
>
> +DEF("add-fd", HAS_ARG, QEMU_OPTION_add_fd,
> + "-add-fd fd=fd,set=set[,opaque=opaque]\n"
> + " Add 'fd' to fd 'set'\n", QEMU_ARCH_ALL)
> +STEXI
> +@item -add-fd fd=@var{fd},set=@var{set}[,opaque=@var{opaque}]
> +@findex -add-fd
> +
> +Add a file descriptor to an fd set. Valid options are:
> +
> +@table @option
> +@item fd=@var{fd}
> +This option defines the file descriptor of which a duplicate is added to fd set.
> +The file descriptor cannot be stdin, stdout, or stderr.
> +@item set=@var{set}
> +This option defines the ID of the fd set to add the file descriptor to.
> +@item opaque=@var{opaque}
> +This option defines a free-form string that can be used to describe @var{fd}.
> +@end table
> +
> +You can open an image using pre-opened file descriptors from an fd set:
> +@example
> +qemu-system-i386
> +-add-fd fd=3,set=2,opaque="rdwr:/path/to/file"
> +-add-fd fd=4,set=2,opaque="rdonly:/path/to/file"
> +-drive file=/dev/fdset/2,index=0,media=disk
> +@end example
> +ETEXI
> +
> DEF("set", HAS_ARG, QEMU_OPTION_set,
> "-set group.id.arg=value\n"
> " set <arg> parameter for item <id> of type <group>\n"
> diff --git a/vl.c b/vl.c
> index ee3c43a..b870caf 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -790,6 +790,78 @@ static int parse_sandbox(QemuOpts *opts, void *opaque)
> return 0;
> }
>
> +#ifndef _WIN32
> +static int parse_add_fd(QemuOpts *opts, void *opaque)
> +{
> + int fd, dupfd, flags;
> + int64_t fdset_id;
> + const char *fd_opaque = NULL;
> +
> + fd = qemu_opt_get_number(opts, "fd", -1);
> + fdset_id = qemu_opt_get_number(opts, "set", -1);
> + fd_opaque = qemu_opt_get(opts, "opaque");
> +
> + if (fd < 0) {
> + qerror_report(ERROR_CLASS_GENERIC_ERROR,
> + "fd option is required and must be non-negative");
> + return -1;
> + }
> +
> + if (fd <= STDERR_FILENO) {
> + qerror_report(ERROR_CLASS_GENERIC_ERROR,
> + "fd cannot be a standard I/O stream");
> + return -1;
> + }
> +
> + /*
> + * All fds inherited across exec() necessarily have FD_CLOEXEC
> + * clear, while qemu sets FD_CLOEXEC on all other fds used internally.
> + */
> + flags = fcntl(fd, F_GETFD);
> + if (flags == -1 || (flags & FD_CLOEXEC)) {
> + qerror_report(ERROR_CLASS_GENERIC_ERROR,
> + "fd is not valid or already in use");
> + return -1;
> + }
> +
> + if (fdset_id < 0) {
> + qerror_report(ERROR_CLASS_GENERIC_ERROR,
> + "set option is required and must be non-negative");
> + return -1;
> + }
> +
> +#ifdef F_DUPFD_CLOEXEC
> + dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
> +#else
> + dupfd = dup(fd);
> + if (dupfd != -1) {
> + qemu_set_cloexec(dupfd);
> + }
> +#endif
> + if (dupfd == -1) {
> + qerror_report(ERROR_CLASS_GENERIC_ERROR,
> + "Error duplicating fd: %s", strerror(errno));
> + return -1;
> + }
> +
> + /* add the duplicate fd, and optionally the opaque string, to the fd set */
> + monitor_fdset_add_fd(dupfd, true, fdset_id, fd_opaque ? true : false,
> + fd_opaque, NULL);
> +
> + return 0;
> +}
> +
> +static int cleanup_add_fd(QemuOpts *opts, void *opaque)
> +{
> + int fd;
> +
> + fd = qemu_opt_get_number(opts, "fd", -1);
> + close(fd);
> +
> + return 0;
> +}
> +#endif
> +
> /***********************************************************/
> /* QEMU Block devices */
>
> @@ -3309,6 +3381,18 @@ int main(int argc, char **argv, char **envp)
> exit(0);
> }
> break;
> + case QEMU_OPTION_add_fd:
> +#ifndef _WIN32
> + opts = qemu_opts_parse(qemu_find_opts("add-fd"), optarg, 0);
> + if (!opts) {
> + exit(0);
> + }
> +#else
> + error_report("File descriptor passing is disabled on this "
> + "platform");
> + exit(1);
> +#endif
> + break;
> default:
> os_parse_cmd_args(popt->index, optarg);
> }
> @@ -3320,6 +3404,16 @@ int main(int argc, char **argv, char **envp)
> exit(1);
> }
>
> +#ifndef _WIN32
> + if (qemu_opts_foreach(qemu_find_opts("add-fd"), parse_add_fd, NULL, 1)) {
> + exit(1);
> + }
> +
> + if (qemu_opts_foreach(qemu_find_opts("add-fd"), cleanup_add_fd, NULL, 1)) {
> + exit(1);
> + }
> +#endif
> +
> if (machine == NULL) {
> fprintf(stderr, "No machine found.\n");
> exit(1);
>
This looks good to me.
--
Regards,
Corey Bryant
prev parent reply other threads:[~2012-10-22 15:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-18 19:19 [Qemu-devel] [PATCH v4 0/4] command line fd passing using fd sets Corey Bryant
2012-10-18 19:19 ` [Qemu-devel] [PATCH v4 1/4] monitor: Allow add-fd to any specified fd set Corey Bryant
2012-10-18 19:19 ` [Qemu-devel] [PATCH v4 2/4] monitor: Enable adding an inherited fd to an " Corey Bryant
2012-10-18 19:19 ` [Qemu-devel] [PATCH v4 3/4] monitor: Prevent removing fd from set during init Corey Bryant
2012-10-18 19:19 ` [Qemu-devel] [PATCH v4 4/4] qemu-config: Add new -add-fd command line option Corey Bryant
2012-10-18 20:43 ` Eric Blake
2012-10-18 21:37 ` Corey Bryant
2012-10-19 11:05 ` Kevin Wolf
2012-10-19 13:12 ` Corey Bryant
2012-10-18 22:09 ` Eric Blake
2012-10-22 14:36 ` [Qemu-devel] [PATCH v5] " Kevin Wolf
2012-10-22 15:06 ` Corey Bryant [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50856113.6050706@linux.vnet.ibm.com \
--to=coreyb@linux.vnet.ibm.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).