From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Peter Xu <peterx@redhat.com>
Cc: Steve Sistare <steven.sistare@oracle.com>,
qemu-devel@nongnu.org, Fabiano Rosas <farosas@suse.de>,
David Hildenbrand <david@redhat.com>,
Marcel Apfelbaum <marcel.apfelbaum@gmail.com>,
Eduardo Habkost <eduardo@habkost.net>,
Philippe Mathieu-Daude <philmd@linaro.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Markus Armbruster <armbru@redhat.com>
Subject: Re: [PATCH V2 07/13] migration: SCM_RIGHTS for QEMUFile
Date: Mon, 7 Oct 2024 17:35:37 +0100 [thread overview]
Message-ID: <ZwQN2YoMWNTMdop3@redhat.com> (raw)
In-Reply-To: <ZwQG_dvmTFFA2Xom@x1n>
On Mon, Oct 07, 2024 at 12:06:21PM -0400, Peter Xu wrote:
> On Mon, Sep 30, 2024 at 12:40:38PM -0700, Steve Sistare wrote:
> > Define functions to put/get file descriptors to/from a QEMUFile, for qio
> > channels that support SCM_RIGHTS. Maintain ordering such that
> > put(A), put(fd), put(B)
> > followed by
> > get(A), get(fd), get(B)
> > always succeeds. Other get orderings may succeed but are not guaranteed.
> >
> > Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> > ---
> > migration/qemu-file.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++---
> > migration/qemu-file.h | 2 ++
> > migration/trace-events | 2 ++
> > 3 files changed, 83 insertions(+), 4 deletions(-)
> >
> > diff --git a/migration/qemu-file.c b/migration/qemu-file.c
> > index b6d2f58..7f951ab 100644
> > --- a/migration/qemu-file.c
> > +++ b/migration/qemu-file.c
> > @@ -37,6 +37,11 @@
> > #define IO_BUF_SIZE 32768
> > #define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64)
> >
> > +typedef struct FdEntry {
> > + QTAILQ_ENTRY(FdEntry) entry;
> > + int fd;
> > +} FdEntry;
> > +
> > struct QEMUFile {
> > QIOChannel *ioc;
> > bool is_writable;
> > @@ -51,6 +56,9 @@ struct QEMUFile {
> >
> > int last_error;
> > Error *last_error_obj;
> > +
> > + bool fd_pass;
> > + QTAILQ_HEAD(, FdEntry) fds;
> > };
> >
> > /*
> > @@ -109,6 +117,8 @@ static QEMUFile *qemu_file_new_impl(QIOChannel *ioc, bool is_writable)
> > object_ref(ioc);
> > f->ioc = ioc;
> > f->is_writable = is_writable;
> > + f->fd_pass = qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS);
> > + QTAILQ_INIT(&f->fds);
> >
> > return f;
> > }
> > @@ -310,6 +320,10 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
> > int len;
> > int pending;
> > Error *local_error = NULL;
> > + g_autofree int *fds = NULL;
> > + size_t nfd = 0;
> > + int **pfds = f->fd_pass ? &fds : NULL;
> > + size_t *pnfd = f->fd_pass ? &nfd : NULL;
> >
> > assert(!qemu_file_is_writable(f));
> >
> > @@ -325,10 +339,9 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
> > }
> >
> > do {
> > - len = qio_channel_read(f->ioc,
> > - (char *)f->buf + pending,
> > - IO_BUF_SIZE - pending,
> > - &local_error);
> > + struct iovec iov = { f->buf + pending, IO_BUF_SIZE - pending };
> > + len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd, 0,
> > + &local_error);
> > if (len == QIO_CHANNEL_ERR_BLOCK) {
> > if (qemu_in_coroutine()) {
> > qio_channel_yield(f->ioc, G_IO_IN);
> > @@ -348,9 +361,65 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f)
> > qemu_file_set_error_obj(f, len, local_error);
> > }
> >
> > + for (int i = 0; i < nfd; i++) {
> > + FdEntry *fde = g_new0(FdEntry, 1);
> > + fde->fd = fds[i];
> > + QTAILQ_INSERT_TAIL(&f->fds, fde, entry);
> > + }
> > +
> > return len;
> > }
> >
> > +int qemu_file_put_fd(QEMUFile *f, int fd)
> > +{
> > + int ret = 0;
> > + QIOChannel *ioc = qemu_file_get_ioc(f);
> > + Error *err = NULL;
> > + struct iovec iov = { (void *)" ", 1 };
> > +
> > + /*
> > + * Send a dummy byte so qemu_fill_buffer on the receiving side does not
> > + * fail with a len=0 error. Flush first to maintain ordering wrt other
> > + * data.
> > + */
> > +
> > + qemu_fflush(f);
> > + if (qio_channel_writev_full(ioc, &iov, 1, &fd, 1, 0, &err) < 1) {
> > + error_report_err(error_copy(err));
> > + qemu_file_set_error_obj(f, -EIO, err);
> > + ret = -1;
> > + }
> > + trace_qemu_file_put_fd(f->ioc->name, fd, ret);
> > + return ret;
> > +}
> > +
> > +int qemu_file_get_fd(QEMUFile *f)
> > +{
> > + int fd = -1;
> > + FdEntry *fde;
> > +
> > + if (!f->fd_pass) {
> > + Error *err = NULL;
> > + error_setg(&err, "%s does not support fd passing", f->ioc->name);
> > + error_report_err(error_copy(err));
> > + qemu_file_set_error_obj(f, -EIO, err);
> > + goto out;
> > + }
> > +
> > + /* Force the dummy byte and its fd passenger to appear. */
> > + qemu_peek_byte(f, 0);
> > +
> > + fde = QTAILQ_FIRST(&f->fds);
> > + if (fde) {
> > + qemu_get_byte(f); /* Drop the dummy byte */
>
> Can we still try to get rid of this magical byte?
>
> Ideally this function should check for no byte but f->fds bening non-empty,
> if it is it could invoke qemu_fill_buffer(). OTOH, qemu_fill_buffer() needs
> to take len==0&&nfds!=0 as legal. Would that work?
When passing ancilliary data with sendmsg/recvmsg, on Linux at least,
it is required that there is at least 1 byte of data present.
See 'man 7 unix':
[quote]
At least one byte of real data should be sent when
sending ancillary data. On Linux, this is required to
successfully send ancillary data over a UNIX domain
stream socket. When sending ancillary data over a
UNIX domain datagram socket, it is not necessary on
Linux to send any accompanying real data. However,
portable applications should also include at least one
byte of real data when sending ancillary data over a
datagram socket.
[/quote]
So if your protocol doesn't already have a convenient bit of real data to
attach the SCM_RIGHTS data to, it is common practice to send a single dummy
data byte that is discarded.
With 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:[~2024-10-07 16:37 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-30 19:40 [PATCH V2 00/13] Live update: cpr-transfer Steve Sistare
2024-09-30 19:40 ` [PATCH V2 01/13] machine: alloc-anon option Steve Sistare
2024-10-03 16:14 ` Peter Xu
2024-10-04 10:14 ` David Hildenbrand
2024-10-04 12:33 ` Peter Xu
2024-10-04 12:54 ` David Hildenbrand
2024-10-04 13:24 ` Peter Xu
2024-10-07 16:23 ` David Hildenbrand
2024-10-07 19:05 ` Peter Xu
2024-10-07 15:36 ` Peter Xu
2024-10-07 19:30 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 02/13] migration: cpr-state Steve Sistare
2024-10-07 14:14 ` Peter Xu
2024-10-07 19:30 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 03/13] migration: save cpr mode Steve Sistare
2024-10-07 15:18 ` Peter Xu
2024-10-07 19:31 ` Steven Sistare
2024-10-07 20:10 ` Peter Xu
2024-10-08 15:57 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 04/13] migration: stop vm earlier for cpr Steve Sistare
2024-10-07 15:27 ` Peter Xu
2024-10-07 20:52 ` Steven Sistare
2024-10-08 15:35 ` Peter Xu
2024-10-08 19:13 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 05/13] physmem: preserve ram blocks " Steve Sistare
2024-10-07 15:49 ` Peter Xu
2024-10-07 16:28 ` Peter Xu
2024-10-08 15:17 ` Steven Sistare
2024-10-08 16:26 ` Peter Xu
2024-10-08 21:05 ` Steven Sistare
2024-10-08 21:32 ` Peter Xu
2024-10-31 20:32 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 06/13] hostmem-memfd: preserve " Steve Sistare
2024-10-07 15:52 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 07/13] migration: SCM_RIGHTS for QEMUFile Steve Sistare
2024-10-07 16:06 ` Peter Xu
2024-10-07 16:35 ` Daniel P. Berrangé [this message]
2024-10-07 18:12 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 08/13] migration: VMSTATE_FD Steve Sistare
2024-10-07 16:36 ` Peter Xu
2024-10-07 19:31 ` Steven Sistare
2024-09-30 19:40 ` [PATCH V2 09/13] migration: cpr-transfer save and load Steve Sistare
2024-10-07 16:47 ` Peter Xu
2024-10-07 19:31 ` Steven Sistare
2024-10-08 15:36 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 10/13] migration: cpr-uri parameter Steve Sistare
2024-10-07 16:49 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 11/13] migration: cpr-uri option Steve Sistare
2024-10-07 16:50 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 12/13] migration: split qmp_migrate Steve Sistare
2024-10-07 19:18 ` Peter Xu
2024-09-30 19:40 ` [PATCH V2 13/13] migration: cpr-transfer mode Steve Sistare
2024-10-07 19:44 ` Peter Xu
2024-10-07 20:39 ` Steven Sistare
2024-10-08 15:45 ` Peter Xu
2024-10-08 19:12 ` Steven Sistare
2024-10-08 19:38 ` Peter Xu
2024-10-08 18:28 ` Fabiano Rosas
2024-10-08 18:47 ` Peter Xu
2024-10-08 19:11 ` Fabiano Rosas
2024-10-08 19:33 ` Steven Sistare
2024-10-08 19:48 ` Peter Xu
2024-10-09 18:43 ` Steven Sistare
2024-10-09 19:06 ` Peter Xu
2024-10-09 19:59 ` Peter Xu
2024-10-09 20:18 ` Steven Sistare
2024-10-09 20:57 ` Peter Xu
2024-10-09 22:08 ` Fabiano Rosas
2024-10-10 20:05 ` Steven Sistare
2024-10-09 20:09 ` Steven Sistare
2024-10-09 20:36 ` Peter Xu
2024-10-10 20:06 ` Steven Sistare
2024-10-10 21:23 ` Peter Xu
2024-10-24 21:12 ` Steven Sistare
2024-10-25 13:55 ` Peter Xu
2024-10-25 15:04 ` Steven Sistare
2024-10-08 19:29 ` Steven Sistare
2024-10-08 14:33 ` [PATCH V2 00/13] Live update: cpr-transfer Vladimir Sementsov-Ogievskiy
2024-10-08 21:13 ` Steven Sistare
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=ZwQN2YoMWNTMdop3@redhat.com \
--to=berrange@redhat.com \
--cc=armbru@redhat.com \
--cc=david@redhat.com \
--cc=eduardo@habkost.net \
--cc=farosas@suse.de \
--cc=marcel.apfelbaum@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=steven.sistare@oracle.com \
/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).