From: "Daniel P. Berrange" <berrange@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: qemu-devel@nongnu.org,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v1 2/2] char: allow passing pre-opened socket file descriptor at startup
Date: Thu, 21 Dec 2017 16:53:32 +0000 [thread overview]
Message-ID: <20171221165332.GK30327@redhat.com> (raw)
In-Reply-To: <87mv2cuiut.fsf@dusky.pond.sub.org>
On Thu, Dec 21, 2017 at 05:49:14PM +0100, Markus Armbruster wrote:
> QAPI schema review only.
>
> "Daniel P. Berrange" <berrange@redhat.com> writes:
>
> > When starting QEMU management apps will usually setup a monitor socket, and
> > then open it immediately after startup. If not using QEMU's own -daemonize
> > arg, this process can be troublesome to handle correctly. The mgmt app will
> > need to repeatedly call connect() until it succeeds, because it does not
> > know when QEMU has created the listener socket. If can't retry connect()
> > forever though, because an error might have caused QEMU to exit before it
> > even creates the monitor.
> >
> > The obvious way to fix this kind of problem is to just pass in a pre-opened
> > socket file descriptor for the QEMU monitor to listen on. The management app
> > can now immediately call connect() just once. If connect() fails it knows
> > that QEMU has exited with an error.
> >
> > The SocketAddress(Legacy) structs allow for FD passing via the monitor, using
> > the 'getfd' command, but only when using QMP JSON syntax. The HMP syntax has
> > no way to initialize the SocketAddress(Legacy) 'fd' variant. So this patch
> > first wires up the 'fd' parameter to refer to a monitor file descriptor,
> > allowing HMP to use
> >
> > getfd myfd
> > chardev-add socket,fd=myfd
> >
> > The SocketAddress 'fd' variant is currently tied to the use of the monitor
> > 'getfd' command, so we have a chicken & egg problem with reusing that at
> > startup wher no monitor connection is available. We could define that the
>
> s/wher/where/
>
> > special fd name prefix '/dev/fdset' refers to a FD passed via the CLI, but
> > magic strings feel unpleasant.
> >
> > Instead we define a SocketAddress 'fdset' variant that takes an fd set number
> > that works in combination with the 'add-fd' command line argument. e.g.
> >
> > -add-fd fd=3,set=1
> > -chardev socket,fdset=1,id=mon
> > -mon chardev=mon,mode=control
> >
> > Note that we do not wire this up in the legacy chardev syntax, so you cannot
> > use FD passing with '-qmp', you must use the modern '-mon' + '-chardev' pair
> >
> > An illustrative example of usage is:
> >
> > #!/usr/bin/perl
> >
> > use IO::Socket::UNIX;
> > use Fcntl;
> >
> > unlink "/tmp/qmp";
> > my $srv = IO::Socket::UNIX->new(
> > Type => SOCK_STREAM(),
> > Local => "/tmp/qmp",
> > Listen => 1,
> > );
> >
> > my $flags = fcntl $srv, F_GETFD, 0;
> > fcntl $srv, F_SETFD, $flags & ~FD_CLOEXEC;
> >
> > my $fd = $srv->fileno();
> >
> > exec "qemu-system-x86_64", \
> > "-add-fd", "fd=$fd,set=1", \
> > "-chardev", "socket,fdset=1,server,nowait,id=mon", \
> > "-mon", "chardev=mon,mode=control";
> >
> > Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> [...]
> > diff --git a/qapi/common.json b/qapi/common.json
> > index 6eb01821ef..a15cdc36e9 100644
> > --- a/qapi/common.json
> > +++ b/qapi/common.json
> > @@ -74,6 +74,17 @@
> > { 'enum': 'OnOffSplit',
> > 'data': [ 'on', 'off', 'split' ] }
> >
> > +##
> > +# @Int:
> > +#
> > +# A fat type wrapping 'int', to be embedded in lists.
>
> I figure you got the "to be embedded in lists" part from @String. That
> one's occasionally used as list element type, but there are other uses.
> @Int has only such other uses so far. Let's drop this line from both types.
>
> > +#
> > +# Since: 2.12
> > +##
> > +{ 'struct': 'Int',
> > + 'data': {
> > + 'i': 'int' } }
> > +
> > ##
> > # @String:
> > #
> > diff --git a/qapi/sockets.json b/qapi/sockets.json
> > index ac022c6ad0..f3cac02166 100644
> > --- a/qapi/sockets.json
> > +++ b/qapi/sockets.json
> > @@ -112,7 +112,8 @@
> > 'inet': 'InetSocketAddress',
> > 'unix': 'UnixSocketAddress',
> > 'vsock': 'VsockSocketAddress',
> > - 'fd': 'String' } }
> > + 'fd': 'String',
> > + 'fdset': 'Int' } }
> >
> > ##
> > # @SocketAddressType:
> > @@ -123,10 +124,16 @@
> > #
> > # @unix: Unix domain socket
> > #
> > +# @vsock: VSOCK socket
> > +#
> > +# @fd: socket file descriptor passed over monitor
> > +#
>
> Indepedent doc fix. I'd put it in a separate patch.
>
> One inaccuracy: @fd is *not* a file descriptor, it's the *name* of a
> file descriptor. Please fix.
>
> > +# @fdset: socket file descriptor passed via CLI (since 2.12)
> > +#
>
> I gather we have to ways to pass file descriptors. One way identifies
> them by name (member @fd), the other by numeric ID (member @fdset).
>
> 0. This is disgusting. Is there any way to unify the two, and deprecate
> the loser (hopefully the numeric one)?
Checkout my v2 which takes a different, less disgusting approach.
> 1. What makes the second one a *set*?
Just that the API i used was called fdset.
> 2. What ties the second one to the CLI? Accidents of implementation or
> something deeper?
Nothing strict - just convention of usage. You could technically (ab)use
it from the monitor too. My v2 approach enforces the distinct usage
more strictly.
>
> > # Since: 2.9
> > ##
> > { 'enum': 'SocketAddressType',
> > - 'data': [ 'inet', 'unix', 'vsock', 'fd' ] }
> > + 'data': [ 'inet', 'unix', 'vsock', 'fd', 'fdset' ] }
> >
> > ##
> > # @SocketAddress:
> > @@ -144,4 +151,5 @@
> > 'data': { 'inet': 'InetSocketAddress',
> > 'unix': 'UnixSocketAddress',
> > 'vsock': 'VsockSocketAddress',
> > - 'fd': 'String' } }
> > + 'fd': 'String',
> > + 'fdset': 'Int' } }
> [...]
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2017-12-21 16:53 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-21 13:27 [Qemu-devel] [PATCH v1 0/2] Enable passing pre-opened chardev socket FDs Daniel P. Berrange
2017-12-21 13:27 ` [Qemu-devel] [PATCH v1 1/2] io: move fd_is_socket() into common sockets code Daniel P. Berrange
2017-12-21 13:49 ` Marc-André Lureau
2017-12-21 13:27 ` [Qemu-devel] [PATCH v1 2/2] char: allow passing pre-opened socket file descriptor at startup Daniel P. Berrange
2017-12-21 13:48 ` Marc-André Lureau
2017-12-21 14:18 ` Eric Blake
2017-12-21 14:20 ` Daniel P. Berrange
2017-12-21 16:49 ` Markus Armbruster
2017-12-21 16:53 ` Daniel P. Berrange [this message]
2017-12-21 19:05 ` Eric Blake
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=20171221165332.GK30327@redhat.com \
--to=berrange@redhat.com \
--cc=armbru@redhat.com \
--cc=dgilbert@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.