diff mbox series

[RFC] chardev: don't exit() straight away on C-a x

Message ID 20211018140226.838137-1-alex.bennee@linaro.org
State New
Headers show
Series [RFC] chardev: don't exit() straight away on C-a x | expand

Commit Message

Alex Bennée Oct. 18, 2021, 2:02 p.m. UTC
While there are a number of uses in the code-base of the exit(0)
pattern it gets in the way of clean exit which can do all of it's
house-keeping. In particular it was reported that you can crash
plugins this way because TCG can still be running on other threads
when the atexit callback is called.

Use qemu_system_shutdown_request() instead. I did a gentle rename of
the runstate stub seeing as it now contains two functions.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

Reported-by: Lukas Jünger <lukas.junger@greensocs.com>
---
 chardev/char-mux.c                     | 3 ++-
 stubs/{runstate-check.c => runstate.c} | 5 +++++
 stubs/meson.build                      | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)
 rename stubs/{runstate-check.c => runstate.c} (64%)

-- 
2.30.2

Comments

Marc-André Lureau Oct. 18, 2021, 2:20 p.m. UTC | #1
On Mon, Oct 18, 2021 at 6:06 PM Alex Bennée <alex.bennee@linaro.org> wrote:

> While there are a number of uses in the code-base of the exit(0)

> pattern it gets in the way of clean exit which can do all of it's

> house-keeping. In particular it was reported that you can crash

> plugins this way because TCG can still be running on other threads

> when the atexit callback is called.

>

> Use qemu_system_shutdown_request() instead. I did a gentle rename of

> the runstate stub seeing as it now contains two functions.

>

> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>


Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>


> ---

>  chardev/char-mux.c                     | 3 ++-

>  stubs/{runstate-check.c => runstate.c} | 5 +++++

>  stubs/meson.build                      | 2 +-

>  3 files changed, 8 insertions(+), 2 deletions(-)

>  rename stubs/{runstate-check.c => runstate.c} (64%)

>

> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

> index ada0c6866f..a46897fcd5 100644

> --- a/chardev/char-mux.c

> +++ b/chardev/char-mux.c

> @@ -28,6 +28,7 @@

>  #include "qemu/option.h"

>  #include "chardev/char.h"

>  #include "sysemu/block-backend.h"

> +#include "sysemu/runstate.h"

>  #include "chardev-internal.h"

>

>  /* MUX driver for serial I/O splitting */

> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d,

> int ch)

>              {

>                   const char *term =  "QEMU: Terminated\n\r";

>                   qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

> -                 exit(0);

> +

>  qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>                   break;

>              }

>          case 's':

> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

> similarity index 64%

> rename from stubs/runstate-check.c

> rename to stubs/runstate.c

> index 2ccda2b70f..f47dbcd3e0 100644

> --- a/stubs/runstate-check.c

> +++ b/stubs/runstate.c

> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>  {

>      return state == RUN_STATE_PRELAUNCH;

>  }

> +

> +void qemu_system_shutdown_request(ShutdownCause reason)

> +{

> +    return;

> +}

> diff --git a/stubs/meson.build b/stubs/meson.build

> index f6aa3aa94f..8f6a9f17e5 100644

> --- a/stubs/meson.build

> +++ b/stubs/meson.build

> @@ -35,7 +35,7 @@ stub_ss.add(files('qtest.c'))

>  stub_ss.add(files('ram-block.c'))

>  stub_ss.add(files('ramfb.c'))

>  stub_ss.add(files('replay.c'))

> -stub_ss.add(files('runstate-check.c'))

> +stub_ss.add(files('runstate.c'))

>  stub_ss.add(files('sysbus.c'))

>  stub_ss.add(files('target-get-monitor-def.c'))

>  stub_ss.add(files('target-monitor-defs.c'))

> --

> 2.30.2

>

>

>


-- 
Marc-André Lureau
<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Oct 18, 2021 at 6:06 PM Alex Bennée &lt;<a href="mailto:alex.bennee@linaro.org">alex.bennee@linaro.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">While there are a number of uses in the code-base of the exit(0)<br>
pattern it gets in the way of clean exit which can do all of it&#39;s<br>
house-keeping. In particular it was reported that you can crash<br>
plugins this way because TCG can still be running on other threads<br>
when the atexit callback is called.<br>
<br>
Use qemu_system_shutdown_request() instead. I did a gentle rename of<br>
the runstate stub seeing as it now contains two functions.<br>
<br>
Signed-off-by: Alex Bennée &lt;<a href="mailto:alex.bennee@linaro.org" target="_blank">alex.bennee@linaro.org</a>&gt;<br>

Reported-by: Lukas Jünger &lt;<a href="mailto:lukas.junger@greensocs.com" target="_blank">lukas.junger@greensocs.com</a>&gt;<br></blockquote><div><br></div><div>Reviewed-by: Marc-André Lureau &lt;<a href="mailto:marcandre.lureau@redhat.com">marcandre.lureau@redhat.com</a>&gt; <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
---<br>
 chardev/char-mux.c                     | 3 ++-<br>
 stubs/{runstate-check.c =&gt; runstate.c} | 5 +++++<br>
 stubs/meson.build                      | 2 +-<br>
 3 files changed, 8 insertions(+), 2 deletions(-)<br>
 rename stubs/{runstate-check.c =&gt; runstate.c} (64%)<br>
<br>
diff --git a/chardev/char-mux.c b/chardev/char-mux.c<br>
index ada0c6866f..a46897fcd5 100644<br>
--- a/chardev/char-mux.c<br>
+++ b/chardev/char-mux.c<br>
@@ -28,6 +28,7 @@<br>
 #include &quot;qemu/option.h&quot;<br>
 #include &quot;chardev/char.h&quot;<br>
 #include &quot;sysemu/block-backend.h&quot;<br>
+#include &quot;sysemu/runstate.h&quot;<br>
 #include &quot;chardev-internal.h&quot;<br>
<br>
 /* MUX driver for serial I/O splitting */<br>
@@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)<br>
             {<br>
                  const char *term =  &quot;QEMU: Terminated\n\r&quot;;<br>
                  qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));<br>
-                 exit(0);<br>
+                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);<br>
                  break;<br>
             }<br>
         case &#39;s&#39;:<br>
diff --git a/stubs/runstate-check.c b/stubs/runstate.c<br>
similarity index 64%<br>
rename from stubs/runstate-check.c<br>
rename to stubs/runstate.c<br>
index 2ccda2b70f..f47dbcd3e0 100644<br>
--- a/stubs/runstate-check.c<br>
+++ b/stubs/runstate.c<br>
@@ -5,3 +5,8 @@ bool runstate_check(RunState state)<br>
 {<br>
     return state == RUN_STATE_PRELAUNCH;<br>
 }<br>
+<br>
+void qemu_system_shutdown_request(ShutdownCause reason)<br>
+{<br>
+    return;<br>
+}<br>
diff --git a/stubs/meson.build b/stubs/meson.build<br>
index f6aa3aa94f..8f6a9f17e5 100644<br>
--- a/stubs/meson.build<br>
+++ b/stubs/meson.build<br>
@@ -35,7 +35,7 @@ stub_ss.add(files(&#39;qtest.c&#39;))<br>
 stub_ss.add(files(&#39;ram-block.c&#39;))<br>
 stub_ss.add(files(&#39;ramfb.c&#39;))<br>
 stub_ss.add(files(&#39;replay.c&#39;))<br>
-stub_ss.add(files(&#39;runstate-check.c&#39;))<br>
+stub_ss.add(files(&#39;runstate.c&#39;))<br>
 stub_ss.add(files(&#39;sysbus.c&#39;))<br>
 stub_ss.add(files(&#39;target-get-monitor-def.c&#39;))<br>
 stub_ss.add(files(&#39;target-monitor-defs.c&#39;))<br>
-- <br>
2.30.2<br>
<br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature">Marc-André Lureau<br></div></div>
Paolo Bonzini Oct. 18, 2021, 2:37 p.m. UTC | #2
On 18/10/21 16:02, Alex Bennée wrote:
> While there are a number of uses in the code-base of the exit(0)

> pattern it gets in the way of clean exit which can do all of it's

> house-keeping. In particular it was reported that you can crash

> plugins this way because TCG can still be running on other threads

> when the atexit callback is called.

> 

> Use qemu_system_shutdown_request() instead. I did a gentle rename of

> the runstate stub seeing as it now contains two functions.

> 

> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>


That won't work with -no-shutdown, but you can just call qmp_quit() instead.

Paolo

> ---

>   chardev/char-mux.c                     | 3 ++-

>   stubs/{runstate-check.c => runstate.c} | 5 +++++

>   stubs/meson.build                      | 2 +-

>   3 files changed, 8 insertions(+), 2 deletions(-)

>   rename stubs/{runstate-check.c => runstate.c} (64%)

> 

> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

> index ada0c6866f..a46897fcd5 100644

> --- a/chardev/char-mux.c

> +++ b/chardev/char-mux.c

> @@ -28,6 +28,7 @@

>   #include "qemu/option.h"

>   #include "chardev/char.h"

>   #include "sysemu/block-backend.h"

> +#include "sysemu/runstate.h"

>   #include "chardev-internal.h"

>   

>   /* MUX driver for serial I/O splitting */

> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)

>               {

>                    const char *term =  "QEMU: Terminated\n\r";

>                    qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

> -                 exit(0);

> +                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>                    break;

>               }

>           case 's':

> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

> similarity index 64%

> rename from stubs/runstate-check.c

> rename to stubs/runstate.c

> index 2ccda2b70f..f47dbcd3e0 100644

> --- a/stubs/runstate-check.c

> +++ b/stubs/runstate.c

> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>   {

>       return state == RUN_STATE_PRELAUNCH;

>   }

> +

> +void qemu_system_shutdown_request(ShutdownCause reason)

> +{

> +    return;

> +}

> diff --git a/stubs/meson.build b/stubs/meson.build

> index f6aa3aa94f..8f6a9f17e5 100644

> --- a/stubs/meson.build

> +++ b/stubs/meson.build

> @@ -35,7 +35,7 @@ stub_ss.add(files('qtest.c'))

>   stub_ss.add(files('ram-block.c'))

>   stub_ss.add(files('ramfb.c'))

>   stub_ss.add(files('replay.c'))

> -stub_ss.add(files('runstate-check.c'))

> +stub_ss.add(files('runstate.c'))

>   stub_ss.add(files('sysbus.c'))

>   stub_ss.add(files('target-get-monitor-def.c'))

>   stub_ss.add(files('target-monitor-defs.c'))

>
Alex Bennée Oct. 18, 2021, 2:53 p.m. UTC | #3
Paolo Bonzini <pbonzini@redhat.com> writes:

> On 18/10/21 16:02, Alex Bennée wrote:

>> While there are a number of uses in the code-base of the exit(0)

>> pattern it gets in the way of clean exit which can do all of it's

>> house-keeping. In particular it was reported that you can crash

>> plugins this way because TCG can still be running on other threads

>> when the atexit callback is called.

>> Use qemu_system_shutdown_request() instead. I did a gentle rename of

>> the runstate stub seeing as it now contains two functions.

>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

>> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>

> That won't work with -no-shutdown, but you can just call qmp_quit()

> instead.


How does calling qmp_quit() fix --no-shutdown? Isn't it just a thin
wrapper around the qemu_system_shutdown_request()?

>

> Paolo

>

>> ---

>>   chardev/char-mux.c                     | 3 ++-

>>   stubs/{runstate-check.c => runstate.c} | 5 +++++

>>   stubs/meson.build                      | 2 +-

>>   3 files changed, 8 insertions(+), 2 deletions(-)

>>   rename stubs/{runstate-check.c => runstate.c} (64%)

>> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

>> index ada0c6866f..a46897fcd5 100644

>> --- a/chardev/char-mux.c

>> +++ b/chardev/char-mux.c

>> @@ -28,6 +28,7 @@

>>   #include "qemu/option.h"

>>   #include "chardev/char.h"

>>   #include "sysemu/block-backend.h"

>> +#include "sysemu/runstate.h"

>>   #include "chardev-internal.h"

>>     /* MUX driver for serial I/O splitting */

>> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)

>>               {

>>                    const char *term =  "QEMU: Terminated\n\r";

>>                    qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

>> -                 exit(0);

>> +                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>>                    break;

>>               }

>>           case 's':

>> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

>> similarity index 64%

>> rename from stubs/runstate-check.c

>> rename to stubs/runstate.c

>> index 2ccda2b70f..f47dbcd3e0 100644

>> --- a/stubs/runstate-check.c

>> +++ b/stubs/runstate.c

>> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>>   {

>>       return state == RUN_STATE_PRELAUNCH;

>>   }

>> +

>> +void qemu_system_shutdown_request(ShutdownCause reason)

>> +{

>> +    return;

>> +}

>> diff --git a/stubs/meson.build b/stubs/meson.build

>> index f6aa3aa94f..8f6a9f17e5 100644

>> --- a/stubs/meson.build

>> +++ b/stubs/meson.build

>> @@ -35,7 +35,7 @@ stub_ss.add(files('qtest.c'))

>>   stub_ss.add(files('ram-block.c'))

>>   stub_ss.add(files('ramfb.c'))

>>   stub_ss.add(files('replay.c'))

>> -stub_ss.add(files('runstate-check.c'))

>> +stub_ss.add(files('runstate.c'))

>>   stub_ss.add(files('sysbus.c'))

>>   stub_ss.add(files('target-get-monitor-def.c'))

>>   stub_ss.add(files('target-monitor-defs.c'))

>> 



-- 
Alex Bennée
Paolo Bonzini Oct. 18, 2021, 2:59 p.m. UTC | #4
On 18/10/21 16:53, Alex Bennée wrote:
> 

> Paolo Bonzini <pbonzini@redhat.com> writes:

> 

>> On 18/10/21 16:02, Alex Bennée wrote:

>>> While there are a number of uses in the code-base of the exit(0)

>>> pattern it gets in the way of clean exit which can do all of it's

>>> house-keeping. In particular it was reported that you can crash

>>> plugins this way because TCG can still be running on other threads

>>> when the atexit callback is called.

>>> Use qemu_system_shutdown_request() instead. I did a gentle rename of

>>> the runstate stub seeing as it now contains two functions.

>>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

>>> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>>

>> That won't work with -no-shutdown, but you can just call qmp_quit()

>> instead.

> 

> How does calling qmp_quit() fix --no-shutdown? Isn't it just a thin

> wrapper around the qemu_system_shutdown_request()?


It first undoes the effect of -no-shutdown:

void qmp_quit(Error **errp)
{
     shutdown_action = SHUTDOWN_ACTION_POWEROFF;
     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
}

Paolo
Philippe Mathieu-Daudé Oct. 18, 2021, 3:04 p.m. UTC | #5
On 10/18/21 16:02, Alex Bennée wrote:
> While there are a number of uses in the code-base of the exit(0)

> pattern it gets in the way of clean exit which can do all of it's

> house-keeping. In particular it was reported that you can crash

> plugins this way because TCG can still be running on other threads

> when the atexit callback is called.

> 

> Use qemu_system_shutdown_request() instead. I did a gentle rename of

> the runstate stub seeing as it now contains two functions.

> 

> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

> ---

>  chardev/char-mux.c                     | 3 ++-

>  stubs/{runstate-check.c => runstate.c} | 5 +++++

>  stubs/meson.build                      | 2 +-

>  3 files changed, 8 insertions(+), 2 deletions(-)

>  rename stubs/{runstate-check.c => runstate.c} (64%)

> 

> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

> index ada0c6866f..a46897fcd5 100644

> --- a/chardev/char-mux.c

> +++ b/chardev/char-mux.c

> @@ -28,6 +28,7 @@

>  #include "qemu/option.h"

>  #include "chardev/char.h"

>  #include "sysemu/block-backend.h"

> +#include "sysemu/runstate.h"

>  #include "chardev-internal.h"

>  

>  /* MUX driver for serial I/O splitting */

> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)

>              {

>                   const char *term =  "QEMU: Terminated\n\r";

>                   qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

> -                 exit(0);

> +                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>                   break;

>              }

>          case 's':

> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

> similarity index 64%

> rename from stubs/runstate-check.c

> rename to stubs/runstate.c

> index 2ccda2b70f..f47dbcd3e0 100644

> --- a/stubs/runstate-check.c

> +++ b/stubs/runstate.c

> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>  {

>      return state == RUN_STATE_PRELAUNCH;

>  }

> +

> +void qemu_system_shutdown_request(ShutdownCause reason)

> +{

> +    return;

> +}


Hmm this isn't a stub anymore, this is the user-mode implementation.

I'd rather have some shared user/ or meanwhile duplicate it in
both bsd-user/linux-user (even if the implementation is empty)
instead of a stub.

> diff --git a/stubs/meson.build b/stubs/meson.build

> index f6aa3aa94f..8f6a9f17e5 100644

> --- a/stubs/meson.build

> +++ b/stubs/meson.build

> @@ -35,7 +35,7 @@ stub_ss.add(files('qtest.c'))

>  stub_ss.add(files('ram-block.c'))

>  stub_ss.add(files('ramfb.c'))

>  stub_ss.add(files('replay.c'))

> -stub_ss.add(files('runstate-check.c'))

> +stub_ss.add(files('runstate.c'))

>  stub_ss.add(files('sysbus.c'))

>  stub_ss.add(files('target-get-monitor-def.c'))

>  stub_ss.add(files('target-monitor-defs.c'))

>
Alex Bennée Oct. 18, 2021, 4:14 p.m. UTC | #6
Philippe Mathieu-Daudé <philmd@redhat.com> writes:

> On 10/18/21 16:02, Alex Bennée wrote:

>> While there are a number of uses in the code-base of the exit(0)

>> pattern it gets in the way of clean exit which can do all of it's

>> house-keeping. In particular it was reported that you can crash

>> plugins this way because TCG can still be running on other threads

>> when the atexit callback is called.

>> 

>> Use qemu_system_shutdown_request() instead. I did a gentle rename of

>> the runstate stub seeing as it now contains two functions.

>> 

>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

>> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>> ---

>>  chardev/char-mux.c                     | 3 ++-

>>  stubs/{runstate-check.c => runstate.c} | 5 +++++

>>  stubs/meson.build                      | 2 +-

>>  3 files changed, 8 insertions(+), 2 deletions(-)

>>  rename stubs/{runstate-check.c => runstate.c} (64%)

>> 

>> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

>> index ada0c6866f..a46897fcd5 100644

>> --- a/chardev/char-mux.c

>> +++ b/chardev/char-mux.c

>> @@ -28,6 +28,7 @@

>>  #include "qemu/option.h"

>>  #include "chardev/char.h"

>>  #include "sysemu/block-backend.h"

>> +#include "sysemu/runstate.h"

>>  #include "chardev-internal.h"

>>  

>>  /* MUX driver for serial I/O splitting */

>> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)

>>              {

>>                   const char *term =  "QEMU: Terminated\n\r";

>>                   qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

>> -                 exit(0);

>> +                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>>                   break;

>>              }

>>          case 's':

>> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

>> similarity index 64%

>> rename from stubs/runstate-check.c

>> rename to stubs/runstate.c

>> index 2ccda2b70f..f47dbcd3e0 100644

>> --- a/stubs/runstate-check.c

>> +++ b/stubs/runstate.c

>> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>>  {

>>      return state == RUN_STATE_PRELAUNCH;

>>  }

>> +

>> +void qemu_system_shutdown_request(ShutdownCause reason)

>> +{

>> +    return;

>> +}

>

> Hmm this isn't a stub anymore, this is the user-mode implementation.


It is? I don't think any of the chardev code touches user-mode, I had to
add this because apparently other binaries link the libchardev code.

> I'd rather have some shared user/ or meanwhile duplicate it in

> both bsd-user/linux-user (even if the implementation is empty)

> instead of a stub.

>

>> diff --git a/stubs/meson.build b/stubs/meson.build

>> index f6aa3aa94f..8f6a9f17e5 100644

>> --- a/stubs/meson.build

>> +++ b/stubs/meson.build

>> @@ -35,7 +35,7 @@ stub_ss.add(files('qtest.c'))

>>  stub_ss.add(files('ram-block.c'))

>>  stub_ss.add(files('ramfb.c'))

>>  stub_ss.add(files('replay.c'))

>> -stub_ss.add(files('runstate-check.c'))

>> +stub_ss.add(files('runstate.c'))

>>  stub_ss.add(files('sysbus.c'))

>>  stub_ss.add(files('target-get-monitor-def.c'))

>>  stub_ss.add(files('target-monitor-defs.c'))

>> 



-- 
Alex Bennée
Alex Bennée Oct. 18, 2021, 5:20 p.m. UTC | #7
Paolo Bonzini <pbonzini@redhat.com> writes:

> On 18/10/21 16:53, Alex Bennée wrote:

>> Paolo Bonzini <pbonzini@redhat.com> writes:

>> 

>>> On 18/10/21 16:02, Alex Bennée wrote:

>>>> While there are a number of uses in the code-base of the exit(0)

>>>> pattern it gets in the way of clean exit which can do all of it's

>>>> house-keeping. In particular it was reported that you can crash

>>>> plugins this way because TCG can still be running on other threads

>>>> when the atexit callback is called.

>>>> Use qemu_system_shutdown_request() instead. I did a gentle rename of

>>>> the runstate stub seeing as it now contains two functions.

>>>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

>>>> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>>>

>>> That won't work with -no-shutdown, but you can just call qmp_quit()

>>> instead.

>> How does calling qmp_quit() fix --no-shutdown? Isn't it just a thin

>> wrapper around the qemu_system_shutdown_request()?

>

> It first undoes the effect of -no-shutdown:

>

> void qmp_quit(Error **errp)

> {

>     shutdown_action = SHUTDOWN_ACTION_POWEROFF;


I guess this is it? I couldn't follow the chain of qemu_opts to find
what sort of change -no-shutdown made to the shutdown_action.

>     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);

> }

>

> Paolo



-- 
Alex Bennée
Philippe Mathieu-Daudé Oct. 18, 2021, 5:30 p.m. UTC | #8
On 10/18/21 18:14, Alex Bennée wrote:
> Philippe Mathieu-Daudé <philmd@redhat.com> writes:

>> On 10/18/21 16:02, Alex Bennée wrote:

>>> While there are a number of uses in the code-base of the exit(0)

>>> pattern it gets in the way of clean exit which can do all of it's

>>> house-keeping. In particular it was reported that you can crash

>>> plugins this way because TCG can still be running on other threads

>>> when the atexit callback is called.

>>>

>>> Use qemu_system_shutdown_request() instead. I did a gentle rename of

>>> the runstate stub seeing as it now contains two functions.

>>>

>>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

>>> Reported-by: Lukas Jünger <lukas.junger@greensocs.com>

>>> ---

>>>  chardev/char-mux.c                     | 3 ++-

>>>  stubs/{runstate-check.c => runstate.c} | 5 +++++

>>>  stubs/meson.build                      | 2 +-

>>>  3 files changed, 8 insertions(+), 2 deletions(-)

>>>  rename stubs/{runstate-check.c => runstate.c} (64%)

>>>

>>> diff --git a/chardev/char-mux.c b/chardev/char-mux.c

>>> index ada0c6866f..a46897fcd5 100644

>>> --- a/chardev/char-mux.c

>>> +++ b/chardev/char-mux.c

>>> @@ -28,6 +28,7 @@

>>>  #include "qemu/option.h"

>>>  #include "chardev/char.h"

>>>  #include "sysemu/block-backend.h"

>>> +#include "sysemu/runstate.h"

>>>  #include "chardev-internal.h"

>>>  

>>>  /* MUX driver for serial I/O splitting */

>>> @@ -157,7 +158,7 @@ static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)

>>>              {

>>>                   const char *term =  "QEMU: Terminated\n\r";

>>>                   qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));

>>> -                 exit(0);

>>> +                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);

>>>                   break;

>>>              }

>>>          case 's':

>>> diff --git a/stubs/runstate-check.c b/stubs/runstate.c

>>> similarity index 64%

>>> rename from stubs/runstate-check.c

>>> rename to stubs/runstate.c

>>> index 2ccda2b70f..f47dbcd3e0 100644

>>> --- a/stubs/runstate-check.c

>>> +++ b/stubs/runstate.c

>>> @@ -5,3 +5,8 @@ bool runstate_check(RunState state)

>>>  {

>>>      return state == RUN_STATE_PRELAUNCH;

>>>  }

>>> +

>>> +void qemu_system_shutdown_request(ShutdownCause reason)

>>> +{

>>> +    return;

>>> +}

>>

>> Hmm this isn't a stub anymore, this is the user-mode implementation.

> 

> It is? I don't think any of the chardev code touches user-mode, I had to

> add this because apparently other binaries link the libchardev code.


If it isn't then is should call g_assert_not_reached().
Paolo Bonzini Oct. 19, 2021, 10:49 a.m. UTC | #9
On 18/10/21 19:20, Alex Bennée wrote:
>>      shutdown_action = SHUTDOWN_ACTION_POWEROFF;

> I guess this is it? I couldn't follow the chain of qemu_opts to find

> what sort of change -no-shutdown made to the shutdown_action.

> 


Yes, "-no-shutdown" is short for "-action shutdown=pause".  From there 
it goes process_runstate_actions -> qmp_marshal_set_action -> 
qmp_set_action, where it sets "shutdown_action = SHUTDOWN_ACTION_PAUSE".

Paolo
diff mbox series

Patch

diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index ada0c6866f..a46897fcd5 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -28,6 +28,7 @@ 
 #include "qemu/option.h"
 #include "chardev/char.h"
 #include "sysemu/block-backend.h"
+#include "sysemu/runstate.h"
 #include "chardev-internal.h"
 
 /* MUX driver for serial I/O splitting */
@@ -157,7 +158,7 @@  static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)
             {
                  const char *term =  "QEMU: Terminated\n\r";
                  qemu_chr_write_all(chr, (uint8_t *)term, strlen(term));
-                 exit(0);
+                 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
                  break;
             }
         case 's':
diff --git a/stubs/runstate-check.c b/stubs/runstate.c
similarity index 64%
rename from stubs/runstate-check.c
rename to stubs/runstate.c
index 2ccda2b70f..f47dbcd3e0 100644
--- a/stubs/runstate-check.c
+++ b/stubs/runstate.c
@@ -5,3 +5,8 @@  bool runstate_check(RunState state)
 {
     return state == RUN_STATE_PRELAUNCH;
 }
+
+void qemu_system_shutdown_request(ShutdownCause reason)
+{
+    return;
+}
diff --git a/stubs/meson.build b/stubs/meson.build
index f6aa3aa94f..8f6a9f17e5 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -35,7 +35,7 @@  stub_ss.add(files('qtest.c'))
 stub_ss.add(files('ram-block.c'))
 stub_ss.add(files('ramfb.c'))
 stub_ss.add(files('replay.c'))
-stub_ss.add(files('runstate-check.c'))
+stub_ss.add(files('runstate.c'))
 stub_ss.add(files('sysbus.c'))
 stub_ss.add(files('target-get-monitor-def.c'))
 stub_ss.add(files('target-monitor-defs.c'))