qemu-ga: guest-shutdown: use only async-signal-safe functions
POSIX mandates[1] that a child process of a multi-thread program uses only async-signal-safe functions before exec(). We consider qemu-ga to be multi-thread, because it uses glib. However, qmp_guest_shutdown() uses functions that are not async-signal-safe. Fix it the following way: - fclose() -> reopen_fd_to_null() - execl() -> execle() - exit() -> _exit() - drop slog() usage (which is not safe) [1] http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
parent
d5dd3498eb
commit
3674838cd0
@ -126,8 +126,7 @@
|
||||
# @guest-shutdown:
|
||||
#
|
||||
# Initiate guest-activated shutdown. Note: this is an asynchronous
|
||||
# shutdown request, with no guaruntee of successful shutdown. Errors
|
||||
# will be logged to guest's syslog.
|
||||
# shutdown request, with no guarantee of successful shutdown.
|
||||
#
|
||||
# @mode: #optional "halt", "powerdown" (default), or "reboot"
|
||||
#
|
||||
|
@ -37,8 +37,8 @@
|
||||
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
|
||||
{
|
||||
const char *shutdown_flag;
|
||||
int ret, status;
|
||||
pid_t rpid, pid;
|
||||
int status;
|
||||
|
||||
slog("guest-shutdown called, mode: %s", mode);
|
||||
if (!has_mode || strcmp(mode, "powerdown") == 0) {
|
||||
@ -57,16 +57,13 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
|
||||
if (pid == 0) {
|
||||
/* child, start the shutdown */
|
||||
setsid();
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
reopen_fd_to_null(0);
|
||||
reopen_fd_to_null(1);
|
||||
reopen_fd_to_null(2);
|
||||
|
||||
ret = execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
|
||||
"hypervisor initiated shutdown", (char*)NULL);
|
||||
if (ret) {
|
||||
slog("guest-shutdown failed: %s", strerror(errno));
|
||||
}
|
||||
exit(!!ret);
|
||||
execle("/sbin/shutdown", "shutdown", shutdown_flag, "+0",
|
||||
"hypervisor initiated shutdown", (char*)NULL, environ);
|
||||
_exit(EXIT_FAILURE);
|
||||
} else if (pid < 0) {
|
||||
goto exit_err;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user