* [Qemu-devel] [FOR 0.12][PATCH] monitor: Accept input only byte-wise
@ 2009-12-04 13:05 Jan Kiszka
2010-04-16 11:00 ` Daniel P. Berrange
0 siblings, 1 reply; 6+ messages in thread
From: Jan Kiszka @ 2009-12-04 13:05 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
This allows to suspend command interpretation and execution
synchronously, e.g. during migration.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
monitor.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/monitor.c b/monitor.c
index 3286ba2..a3be1c8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3418,7 +3418,7 @@ static int monitor_can_read(void *opaque)
{
Monitor *mon = opaque;
- return (mon->suspend_cnt == 0) ? 128 : 0;
+ return (mon->suspend_cnt == 0) ? 1 : 0;
}
static void monitor_read(void *opaque, const uint8_t *buf, int size)
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [FOR 0.12][PATCH] monitor: Accept input only byte-wise
2009-12-04 13:05 [Qemu-devel] [FOR 0.12][PATCH] monitor: Accept input only byte-wise Jan Kiszka
@ 2010-04-16 11:00 ` Daniel P. Berrange
2010-04-16 11:14 ` [Qemu-devel] " Paolo Bonzini
0 siblings, 1 reply; 6+ messages in thread
From: Daniel P. Berrange @ 2010-04-16 11:00 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Anthony Liguori, qemu-devel
On Fri, Dec 04, 2009 at 02:05:29PM +0100, Jan Kiszka wrote:
> This allows to suspend command interpretation and execution
> synchronously, e.g. during migration.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>
> monitor.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/monitor.c b/monitor.c
> index 3286ba2..a3be1c8 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -3418,7 +3418,7 @@ static int monitor_can_read(void *opaque)
> {
> Monitor *mon = opaque;
>
> - return (mon->suspend_cnt == 0) ? 128 : 0;
> + return (mon->suspend_cnt == 0) ? 1 : 0;
> }
>
> static void monitor_read(void *opaque, const uint8_t *buf, int size)
FYI, this change seems to have broken the 'getfd' command in the monitor.
Any attempt to use this command (in both text + json modes) is currently
returning
"No file descriptor supplied via SCM_RIGHTS"
Reverting this change makes getfd work again for me.
Strace of libvirtd shows it sending the command + FD in one message:
sendmsg(18, {msg_name(0)=NULL, msg_iov(1)=[{"getfd fd-net2\r", 14}],
msg_controllen=24, {cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS,
{16}}, msg_flags=0}, 0) = 14
Strace of qemu shows that it receives the FD ok, but immediately closes it
before finishing reading the actual monitor command with which it is associated:
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"g", 1}], msg_controllen=24, {cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, {17}}, msg_flags=0}, 0) = 1
[pid 31941] close(17) = 0
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"e", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"t", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"f", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"d", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{" ", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"f", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"d", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"-", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"n", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"e", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"t", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"2", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
[pid 31941] recvmsg(16, {msg_name(0)=NULL, msg_iov(1)=[{"\r", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
The QEMU code appears to be written to assume that it will recvmsg() a
complete monitor command in one go + process that, because it closes the
FD the moment the data from any recvmsg() is dealt with.
Regards,
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] Re: [FOR 0.12][PATCH] monitor: Accept input only byte-wise
2010-04-16 11:00 ` Daniel P. Berrange
@ 2010-04-16 11:14 ` Paolo Bonzini
2010-04-16 13:17 ` Daniel P. Berrange
0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2010-04-16 11:14 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel
> The QEMU code appears to be written to assume that it will recvmsg() a
> complete monitor command in one go + process that, because it closes the
> FD the moment the data from any recvmsg() is dealt with.
This is buggy anyway. This should fix it too:
diff --git a/monitor.c b/monitor.c
index 5659991..225a922 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2408,15 +2408,6 @@
return -1;
}
- fd = dup(fd);
- if (fd == -1) {
- if (errno == EMFILE)
- qerror_report(QERR_TOO_MANY_FILES);
- else
- qerror_report(QERR_UNDEFINED_ERROR);
- return -1;
- }
-
QLIST_FOREACH(monfd, &mon->fds, next) {
if (strcmp(monfd->name, fdname) != 0) {
continue;
diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ac65a1c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2000,8 +2000,9 @@
static int tcp_get_msgfd(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
-
- return s->msgfd;
+ int fd = s->msgfd;
+ s->msgfd = -1;
+ return fd;
}
#ifndef _WIN32
@@ -2089,10 +2090,6 @@ static void tcp_chr_read(void *opaque)
tcp_chr_process_IAC_bytes(chr, s, buf, &size);
if (size > 0)
qemu_chr_read(chr, buf, size);
- if (s->msgfd != -1) {
- close(s->msgfd);
- s->msgfd = -1;
- }
}
}
Paolo
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] Re: [FOR 0.12][PATCH] monitor: Accept input only byte-wise
2010-04-16 11:14 ` [Qemu-devel] " Paolo Bonzini
@ 2010-04-16 13:17 ` Daniel P. Berrange
2010-04-16 14:57 ` Paolo Bonzini
2010-04-16 15:25 ` [Qemu-devel] [FOR 0.12] [PATCH] stash away SCM_RIGHTS fd until a getfd command arrives Paolo Bonzini
0 siblings, 2 replies; 6+ messages in thread
From: Daniel P. Berrange @ 2010-04-16 13:17 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Jan Kiszka, Anthony Liguori, qemu-devel
On Fri, Apr 16, 2010 at 01:14:11PM +0200, Paolo Bonzini wrote:
>
> >The QEMU code appears to be written to assume that it will recvmsg() a
> >complete monitor command in one go + process that, because it closes the
> >FD the moment the data from any recvmsg() is dealt with.
>
> This is buggy anyway. This should fix it too:
Yep, this makes it work too, but if a client is evil they could
pass a FD to qemu with any other non-getfd command & it'd remain
open for ever. Probably not important though.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] Re: [FOR 0.12][PATCH] monitor: Accept input only byte-wise
2010-04-16 13:17 ` Daniel P. Berrange
@ 2010-04-16 14:57 ` Paolo Bonzini
2010-04-16 15:25 ` [Qemu-devel] [FOR 0.12] [PATCH] stash away SCM_RIGHTS fd until a getfd command arrives Paolo Bonzini
1 sibling, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2010-04-16 14:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Jan Kiszka, Anthony Liguori
On 04/16/2010 03:17 PM, Daniel P. Berrange wrote:
> On Fri, Apr 16, 2010 at 01:14:11PM +0200, Paolo Bonzini wrote:
>>
>>> The QEMU code appears to be written to assume that it will recvmsg() a
>>> complete monitor command in one go + process that, because it closes the
>>> FD the moment the data from any recvmsg() is dealt with.
>>
>> This is buggy anyway. This should fix it too:
>
> Yep, this makes it work too, but if a client is evil they could
> pass a FD to qemu with any other non-getfd command& it'd remain
> open for ever. Probably not important though.
No, it wouldn't: outside the part that I patched there is this:
if (s->msgfd != -1)
close(s->msgfd);
s->msgfd = fd;
Only one file descriptor could "leak".
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [FOR 0.12] [PATCH] stash away SCM_RIGHTS fd until a getfd command arrives
2010-04-16 13:17 ` Daniel P. Berrange
2010-04-16 14:57 ` Paolo Bonzini
@ 2010-04-16 15:25 ` Paolo Bonzini
1 sibling, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2010-04-16 15:25 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aliguori, armbru
If there is already a fd in s->msgfd before recvmsg it is
closed by parts that this patch does not touch. So, only
one descriptor can be "leaked" by attaching it to a command
other than getfd.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
monitor.c | 9 ---------
qemu-char.c | 9 +++------
2 files changed, 3 insertions(+), 15 deletions(-)
Tested by Daniel, identical to the previous one except for
the Signed-off-by line.
diff --git a/monitor.c b/monitor.c
index 5659991..225a922 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2408,15 +2408,6 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
return -1;
}
- fd = dup(fd);
- if (fd == -1) {
- if (errno == EMFILE)
- qerror_report(QERR_TOO_MANY_FILES);
- else
- qerror_report(QERR_UNDEFINED_ERROR);
- return -1;
- }
-
QLIST_FOREACH(monfd, &mon->fds, next) {
if (strcmp(monfd->name, fdname) != 0) {
continue;
diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ac65a1c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2000,8 +2000,9 @@ static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
static int tcp_get_msgfd(CharDriverState *chr)
{
TCPCharDriver *s = chr->opaque;
-
- return s->msgfd;
+ int fd = s->msgfd;
+ s->msgfd = -1;
+ return fd;
}
#ifndef _WIN32
@@ -2089,10 +2090,6 @@ static void tcp_chr_read(void *opaque)
tcp_chr_process_IAC_bytes(chr, s, buf, &size);
if (size > 0)
qemu_chr_read(chr, buf, size);
- if (s->msgfd != -1) {
- close(s->msgfd);
- s->msgfd = -1;
- }
}
}
--
1.6.6.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-04-16 15:25 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-04 13:05 [Qemu-devel] [FOR 0.12][PATCH] monitor: Accept input only byte-wise Jan Kiszka
2010-04-16 11:00 ` Daniel P. Berrange
2010-04-16 11:14 ` [Qemu-devel] " Paolo Bonzini
2010-04-16 13:17 ` Daniel P. Berrange
2010-04-16 14:57 ` Paolo Bonzini
2010-04-16 15:25 ` [Qemu-devel] [FOR 0.12] [PATCH] stash away SCM_RIGHTS fd until a getfd command arrives Paolo Bonzini
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).