qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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).