From: "Daniel P. Berrangé" <berrange@redhat.com> To: Yury Kotov <yury-kotov@yandex-team.ru> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>, Juan Quintela <quintela@redhat.com>, qemu-devel@nongnu.org, yc-core@yandex-team.ru Subject: Re: [Qemu-devel] [PATCH] migration: Fix handling fd protocol Date: Thu, 11 Apr 2019 13:04:21 +0100 [thread overview] Message-ID: <20190411120421.GP3641@redhat.com> (raw) In-Reply-To: <20190410092652.22616-1-yury-kotov@yandex-team.ru> On Wed, Apr 10, 2019 at 12:26:52PM +0300, Yury Kotov wrote: > Currently such case is possible for incoming: > QMP: add-fd (fdset = 0, fd of some file): > adds fd to fdset 0 and returns QEMU's fd (e.g. 33) > QMP: migrate-incoming (uri = "fd:33"): fd is stored in QIOChannel *ioc > ... > Incoming migration completes and unrefs ioc -> close(33) > QMP: remove-fd (fdset = 0, fd = 33): > removes fd from fdset 0 and qemu_close() -> close(33) => double close IMHO this is user error. You've given the FD to QEMU and told it to use it for migration. Once you've done that you should not be calling remove-fd. remove-fd should only be used in some error code path. ie if you have called add-fd, and then some failure means you've decided you can't invoke 'migrate-incoming'. Now you should call "remove-fd". AFAIK, we have never documented that 'add-fd' must be paired with 'remove-fd'. IOW, I think this "fix" is in fact not a fix - it is instead changing the semantics of when "remove-fd" should be used. > For outgoing migration the case is the same but getfd instead of add-fd. > Fix it by duping client's fd. > > Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru> > --- > migration/fd.c | 39 +++++++++++++++++++++++++++++++-------- > migration/trace-events | 4 ++-- > 2 files changed, 33 insertions(+), 10 deletions(-) > > diff --git a/migration/fd.c b/migration/fd.c > index a7c13df4ad..c9ff07ac41 100644 > --- a/migration/fd.c > +++ b/migration/fd.c > @@ -15,6 +15,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qapi/error.h" > #include "channel.h" > #include "fd.h" > #include "migration.h" > @@ -26,15 +27,27 @@ > void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) > { > QIOChannel *ioc; > - int fd = monitor_get_fd(cur_mon, fdname, errp); > + int fd, dup_fd; > + > + fd = monitor_get_fd(cur_mon, fdname, errp); > if (fd == -1) { > return; > } > > - trace_migration_fd_outgoing(fd); > - ioc = qio_channel_new_fd(fd, errp); > + /* fd is previously created by qmp command 'getfd', > + * so client is responsible to close it. Dup it to save original value from > + * QIOChannel's destructor */ > + dup_fd = qemu_dup(fd); > + if (dup_fd == -1) { > + error_setg(errp, "Cannot dup fd %s: %s (%d)", fdname, strerror(errno), > + errno); > + return; > + } > + > + trace_migration_fd_outgoing(fd, dup_fd); > + ioc = qio_channel_new_fd(dup_fd, errp); > if (!ioc) { > - close(fd); > + close(dup_fd); > return; > } > > @@ -55,14 +68,24 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc, > void fd_start_incoming_migration(const char *infd, Error **errp) > { > QIOChannel *ioc; > - int fd; > + int fd, dup_fd; > > fd = strtol(infd, NULL, 0); > - trace_migration_fd_incoming(fd); > > - ioc = qio_channel_new_fd(fd, errp); > + /* fd is previously created by qmp command 'add-fd' or something else, > + * so client is responsible to close it. Dup it to save original value from > + * QIOChannel's destructor */ > + dup_fd = qemu_dup(fd); > + if (dup_fd == -1) { > + error_setg(errp, "Cannot dup fd %d: %s (%d)", fd, strerror(errno), > + errno); > + return; > + } > + > + trace_migration_fd_incoming(fd, dup_fd); > + ioc = qio_channel_new_fd(dup_fd, errp); > if (!ioc) { > - close(fd); > + close(dup_fd); > return; > } > > diff --git a/migration/trace-events b/migration/trace-events > index de2e136e57..d2d30a6b3c 100644 > --- a/migration/trace-events > +++ b/migration/trace-events > @@ -258,8 +258,8 @@ migration_exec_outgoing(const char *cmd) "cmd=%s" > migration_exec_incoming(const char *cmd) "cmd=%s" > > # fd.c > -migration_fd_outgoing(int fd) "fd=%d" > -migration_fd_incoming(int fd) "fd=%d" > +migration_fd_outgoing(int fd, int dup_fd) "fd=%d dup_fd=%d" > +migration_fd_incoming(int fd, int dup_fd) "fd=%d dup_fd=%d" > > # socket.c > migration_socket_incoming_accepted(void) "" > -- > 2.21.0 > > 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 :|
WARNING: multiple messages have this Message-ID (diff)
From: "Daniel P. Berrangé" <berrange@redhat.com> To: Yury Kotov <yury-kotov@yandex-team.ru> Cc: qemu-devel@nongnu.org, "Dr. David Alan Gilbert" <dgilbert@redhat.com>, yc-core@yandex-team.ru, Juan Quintela <quintela@redhat.com> Subject: Re: [Qemu-devel] [PATCH] migration: Fix handling fd protocol Date: Thu, 11 Apr 2019 13:04:21 +0100 [thread overview] Message-ID: <20190411120421.GP3641@redhat.com> (raw) Message-ID: <20190411120421.egnaGHxQm96bfZ8pQEEGAR9Eq51ldxSmHL4lA8WU95A@z> (raw) In-Reply-To: <20190410092652.22616-1-yury-kotov@yandex-team.ru> On Wed, Apr 10, 2019 at 12:26:52PM +0300, Yury Kotov wrote: > Currently such case is possible for incoming: > QMP: add-fd (fdset = 0, fd of some file): > adds fd to fdset 0 and returns QEMU's fd (e.g. 33) > QMP: migrate-incoming (uri = "fd:33"): fd is stored in QIOChannel *ioc > ... > Incoming migration completes and unrefs ioc -> close(33) > QMP: remove-fd (fdset = 0, fd = 33): > removes fd from fdset 0 and qemu_close() -> close(33) => double close IMHO this is user error. You've given the FD to QEMU and told it to use it for migration. Once you've done that you should not be calling remove-fd. remove-fd should only be used in some error code path. ie if you have called add-fd, and then some failure means you've decided you can't invoke 'migrate-incoming'. Now you should call "remove-fd". AFAIK, we have never documented that 'add-fd' must be paired with 'remove-fd'. IOW, I think this "fix" is in fact not a fix - it is instead changing the semantics of when "remove-fd" should be used. > For outgoing migration the case is the same but getfd instead of add-fd. > Fix it by duping client's fd. > > Signed-off-by: Yury Kotov <yury-kotov@yandex-team.ru> > --- > migration/fd.c | 39 +++++++++++++++++++++++++++++++-------- > migration/trace-events | 4 ++-- > 2 files changed, 33 insertions(+), 10 deletions(-) > > diff --git a/migration/fd.c b/migration/fd.c > index a7c13df4ad..c9ff07ac41 100644 > --- a/migration/fd.c > +++ b/migration/fd.c > @@ -15,6 +15,7 @@ > */ > > #include "qemu/osdep.h" > +#include "qapi/error.h" > #include "channel.h" > #include "fd.h" > #include "migration.h" > @@ -26,15 +27,27 @@ > void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) > { > QIOChannel *ioc; > - int fd = monitor_get_fd(cur_mon, fdname, errp); > + int fd, dup_fd; > + > + fd = monitor_get_fd(cur_mon, fdname, errp); > if (fd == -1) { > return; > } > > - trace_migration_fd_outgoing(fd); > - ioc = qio_channel_new_fd(fd, errp); > + /* fd is previously created by qmp command 'getfd', > + * so client is responsible to close it. Dup it to save original value from > + * QIOChannel's destructor */ > + dup_fd = qemu_dup(fd); > + if (dup_fd == -1) { > + error_setg(errp, "Cannot dup fd %s: %s (%d)", fdname, strerror(errno), > + errno); > + return; > + } > + > + trace_migration_fd_outgoing(fd, dup_fd); > + ioc = qio_channel_new_fd(dup_fd, errp); > if (!ioc) { > - close(fd); > + close(dup_fd); > return; > } > > @@ -55,14 +68,24 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc, > void fd_start_incoming_migration(const char *infd, Error **errp) > { > QIOChannel *ioc; > - int fd; > + int fd, dup_fd; > > fd = strtol(infd, NULL, 0); > - trace_migration_fd_incoming(fd); > > - ioc = qio_channel_new_fd(fd, errp); > + /* fd is previously created by qmp command 'add-fd' or something else, > + * so client is responsible to close it. Dup it to save original value from > + * QIOChannel's destructor */ > + dup_fd = qemu_dup(fd); > + if (dup_fd == -1) { > + error_setg(errp, "Cannot dup fd %d: %s (%d)", fd, strerror(errno), > + errno); > + return; > + } > + > + trace_migration_fd_incoming(fd, dup_fd); > + ioc = qio_channel_new_fd(dup_fd, errp); > if (!ioc) { > - close(fd); > + close(dup_fd); > return; > } > > diff --git a/migration/trace-events b/migration/trace-events > index de2e136e57..d2d30a6b3c 100644 > --- a/migration/trace-events > +++ b/migration/trace-events > @@ -258,8 +258,8 @@ migration_exec_outgoing(const char *cmd) "cmd=%s" > migration_exec_incoming(const char *cmd) "cmd=%s" > > # fd.c > -migration_fd_outgoing(int fd) "fd=%d" > -migration_fd_incoming(int fd) "fd=%d" > +migration_fd_outgoing(int fd, int dup_fd) "fd=%d dup_fd=%d" > +migration_fd_incoming(int fd, int dup_fd) "fd=%d dup_fd=%d" > > # socket.c > migration_socket_incoming_accepted(void) "" > -- > 2.21.0 > > 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:[~2019-04-11 12:04 UTC|newest] Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-10 9:26 [Qemu-devel] [PATCH] migration: Fix handling fd protocol Yury Kotov 2019-04-10 9:26 ` Yury Kotov 2019-04-10 10:13 ` no-reply 2019-04-10 10:13 ` no-reply 2019-04-10 13:57 ` Dr. David Alan Gilbert 2019-04-10 13:57 ` Dr. David Alan Gilbert 2019-04-10 14:16 ` Yury Kotov 2019-04-10 14:16 ` Yury Kotov 2019-04-11 12:04 ` Daniel P. Berrangé [this message] 2019-04-11 12:04 ` Daniel P. Berrangé 2019-04-11 12:31 ` Yury Kotov 2019-04-11 12:31 ` Yury Kotov 2019-04-11 12:39 ` Daniel P. Berrangé 2019-04-11 12:39 ` Daniel P. Berrangé 2019-04-11 12:50 ` Yury Kotov 2019-04-11 12:50 ` Yury Kotov 2019-04-15 9:50 ` Yury Kotov 2019-04-15 9:50 ` Yury Kotov 2019-04-15 10:11 ` Daniel P. Berrangé 2019-04-15 10:11 ` Daniel P. Berrangé 2019-04-15 10:17 ` Yury Kotov 2019-04-15 10:17 ` Yury Kotov 2019-04-15 10:24 ` Yury Kotov 2019-04-15 10:24 ` Yury Kotov 2019-04-15 10:25 ` Daniel P. Berrangé 2019-04-15 10:25 ` Daniel P. Berrangé 2019-04-15 10:33 ` Yury Kotov 2019-04-15 10:33 ` Yury Kotov 2019-04-15 10:47 ` Daniel P. Berrangé 2019-04-15 10:47 ` Daniel P. Berrangé 2019-04-15 11:15 ` Dr. David Alan Gilbert 2019-04-15 11:15 ` Dr. David Alan Gilbert 2019-04-15 11:19 ` Daniel P. Berrangé 2019-04-15 11:19 ` Daniel P. Berrangé 2019-04-15 11:30 ` Dr. David Alan Gilbert 2019-04-15 11:30 ` Dr. David Alan Gilbert 2019-04-15 12:20 ` Yury Kotov 2019-04-15 12:20 ` Yury Kotov 2019-04-16 9:27 ` Yury Kotov 2019-04-16 9:27 ` Yury Kotov 2019-04-16 11:01 ` Yury Kotov 2019-04-16 11:01 ` Yury Kotov 2019-04-18 14:19 ` Dr. David Alan Gilbert 2019-04-18 14:19 ` Dr. David Alan Gilbert 2019-04-18 15:36 ` Yury Kotov 2019-04-18 15:36 ` Yury Kotov 2019-04-18 16:03 ` Dr. David Alan Gilbert 2019-04-18 16:03 ` Dr. David Alan Gilbert 2019-04-18 16:25 ` Yury Kotov 2019-04-18 16:25 ` Yury Kotov 2019-04-18 17:01 ` Dr. David Alan Gilbert 2019-04-18 17:01 ` Dr. David Alan Gilbert 2019-04-18 17:46 ` Yury Kotov 2019-04-18 17:46 ` Yury Kotov 2019-05-14 9:36 ` Yury Kotov 2019-05-21 16:09 ` Yury Kotov
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=20190411120421.GP3641@redhat.com \ --to=berrange@redhat.com \ --cc=dgilbert@redhat.com \ --cc=qemu-devel@nongnu.org \ --cc=quintela@redhat.com \ --cc=yc-core@yandex-team.ru \ --cc=yury-kotov@yandex-team.ru \ /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: linkBe 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).