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…
	
		Reference in New Issue