Skip to content
  • Luiz Capitulino's avatar
    qemu-ga: become_daemon(): reopen standard fds to /dev/null · 226a4894
    Luiz Capitulino authored
    
    
    This fixes a bug where qemu-ga doesn't suspend the guest because it
    fails to detect suspend support even when the guest does support
    suspend. This happens because of the way qemu-ga fds are managed in
    daemon mode.
    
    When starting qemu-ga with --daemon, become_daemon() will close all
    standard fds. This will cause qemu-ga to end up with the following
    fds (if started with 'qemu-ga --daemon'):
    
        0 -> /dev/vport0p1
        3 -> /run/qemu-ga.pid
    
    Then a guest-suspend-* function is issued. They call bios_supports_mode(),
    which will call pipe(), and qemu-ga's fd will be:
    
        0 -> /dev/vport0p1
        1 -> pipe:[16247]
        2 -> pipe:[16247]
        3 -> /run/qemu-ga.pid
    
    bios_supports_mode() forks off a child and blocks waiting for the child
    to write something to the pipe. The child, however, closes its reading
    end of the pipe _and_ reopen all standard fds to /dev/null. This will
    cause the child's fds to be:
    
        0 -> /dev/null
        1 -> /dev/null
        2 -> /dev/null
        3 -> /run/qemu-ga.pid
    
    In other words, the child's writing end of the pipe is now /dev/null.
    It writes there and exits. The parent process (blocked on read()) will
    get an EOF and interpret this as "something unexpected happened in
    the child, let's assume the guest doesn't support suspend". And suspend
    will fail.
    
    To solve this problem we have to reopen standard fds to /dev/null
    in become_daemon(), instead of closing them.
    
    Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
    Reviewed-by: default avatarEric Blake <eblake@redhat.com>
    Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
    226a4894