qemu-ga: become_daemon(): reopen standard fds to /dev/null

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: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
1 file changed
tree: 6defdf6b0758336042ee7079c5ae53925b3c8456
  1. audio/
  2. block/
  3. bsd-user/
  4. default-configs/
  5. docs/
  6. fpu/
  7. fsdev/
  8. gdb-xml/
  9. hw/
  10. include/
  11. libcacard/
  12. linux-headers/
  13. linux-user/
  14. net/
  15. pc-bios/
  16. qapi/
  17. qga/
  18. QMP/
  19. qom/
  20. roms/
  21. scripts/
  22. slirp/
  23. sysconfigs/
  24. target-alpha/
  25. target-arm/
  26. target-cris/
  27. target-i386/
  28. target-lm32/
  29. target-m68k/
  30. target-microblaze/
  31. target-mips/
  32. target-ppc/
  33. target-s390x/
  34. target-sh4/
  35. target-sparc/
  36. target-unicore32/
  37. target-xtensa/
  38. tcg/
  39. tests/
  40. trace/
  41. ui/
  42. .gitignore
  43. .gitmodules
  44. .mailmap
  45. a.out.h
  46. acl.c
  47. acl.h
  48. aes.c
  49. aes.h
  50. aio.c
  51. alpha-dis.c
  52. alpha.ld
  53. arch_init.c
  54. arch_init.h
  55. arm-dis.c
  56. arm-semi.c
  57. arm.ld
  58. async.c
  59. balloon.c
  60. balloon.h
  61. bitmap.c
  62. bitmap.h
  63. bitops.c
  64. bitops.h
  65. block-migration.c
  66. block-migration.h
  67. block.c
  68. block.h
  69. block_int.h
  70. blockdev.c
  71. blockdev.h
  72. bswap.h
  73. bt-host.c
  74. bt-host.h
  75. bt-vhci.c
  76. buffered_file.c
  77. buffered_file.h
  78. cache-utils.c
  79. cache-utils.h
  80. Changelog
  81. cmd.c
  82. cmd.h
  83. CODING_STYLE
  84. compatfd.c
  85. compatfd.h
  86. compiler.h
  87. config.h
  88. configure
  89. console.c
  90. console.h
  91. COPYING
  92. COPYING.LIB
  93. coroutine-gthread.c
  94. coroutine-sigaltstack.c
  95. coroutine-ucontext.c
  96. coroutine-win32.c
  97. cpu-all.h
  98. cpu-common.h
  99. cpu-defs.h
  100. cpu-exec.c
  101. cpus.c
  102. cpus.h
  103. cputlb.c
  104. cputlb.h
  105. cris-dis.c
  106. cursor.c
  107. cursor_hidden.xpm
  108. cursor_left_ptr.xpm
  109. cutils.c
  110. def-helper.h
  111. device_tree.c
  112. device_tree.h
  113. dis-asm.h
  114. disas.c
  115. disas.h
  116. dma-helpers.c
  117. dma.h
  118. dyngen-exec.h
  119. elf.h
  120. envlist.c
  121. envlist.h
  122. error.c
  123. error.h
  124. error_int.h
  125. event_notifier.c
  126. event_notifier.h
  127. exec-all.h
  128. exec-memory.h
  129. exec-obsolete.h
  130. exec.c
  131. gdbstub.c
  132. gdbstub.h
  133. gen-icount.h
  134. HACKING
  135. hmp-commands.hx
  136. hmp.c
  137. hmp.h
  138. host-utils.c
  139. host-utils.h
  140. hppa-dis.c
  141. hppa.ld
  142. i386-dis.c
  143. i386.ld
  144. ia64-dis.c
  145. ia64.ld
  146. input.c
  147. int128.h
  148. iohandler.c
  149. ioport-user.c
  150. ioport.c
  151. ioport.h
  152. iorange.h
  153. iov.c
  154. iov.h
  155. json-lexer.c
  156. json-lexer.h
  157. json-parser.c
  158. json-parser.h
  159. json-streamer.c
  160. json-streamer.h
  161. kvm-all.c
  162. kvm-stub.c
  163. kvm.h
  164. libfdt_env.h
  165. LICENSE
  166. linux-aio.c
  167. lm32-dis.c
  168. m68k-dis.c
  169. m68k-semi.c
  170. m68k.ld
  171. main-loop.c
  172. main-loop.h
  173. MAINTAINERS
  174. Makefile
  175. Makefile.dis
  176. Makefile.hw
  177. Makefile.objs
  178. Makefile.target
  179. Makefile.user
  180. memory.c
  181. memory.h
  182. microblaze-dis.c
  183. migration-exec.c
  184. migration-fd.c
  185. migration-tcp.c
  186. migration-unix.c
  187. migration.c
  188. migration.h
  189. mips-dis.c
  190. mips.ld
  191. module.c
  192. module.h
  193. monitor.c
  194. monitor.h
  195. nbd.c
  196. nbd.h
  197. net.c
  198. net.h
  199. notify.c
  200. notify.h
  201. os-posix.c
  202. os-win32.c
  203. osdep.c
  204. osdep.h
  205. oslib-posix.c
  206. oslib-win32.c
  207. path.c
  208. pci-ids.txt
  209. pflib.c
  210. pflib.h
  211. poison.h
  212. posix-aio-compat.c
  213. ppc-dis.c
  214. ppc.ld
  215. ppc64.ld
  216. qapi-schema-guest.json
  217. qapi-schema-test.json
  218. qapi-schema.json
  219. qbool.c
  220. qbool.h
  221. qdict-test-data.txt
  222. qdict.c
  223. qdict.h
  224. qemu-aio.h
  225. qemu-barrier.h
  226. qemu-bridge-helper.c
  227. qemu-char.c
  228. qemu-char.h
  229. qemu-common.h
  230. qemu-config.c
  231. qemu-config.h
  232. qemu-coroutine-int.h
  233. qemu-coroutine-io.c
  234. qemu-coroutine-lock.c
  235. qemu-coroutine-sleep.c
  236. qemu-coroutine.c
  237. qemu-coroutine.h
  238. qemu-doc.texi
  239. qemu-error.c
  240. qemu-error.h
  241. qemu-file.h
  242. qemu-ga.c
  243. qemu-img-cmds.hx
  244. qemu-img.c
  245. qemu-img.texi
  246. qemu-io.c
  247. qemu-lock.h
  248. qemu-log.h
  249. qemu-nbd.c
  250. qemu-nbd.texi
  251. qemu-objects.h
  252. qemu-option.c
  253. qemu-option.h
  254. qemu-options-wrapper.h
  255. qemu-options.h
  256. qemu-options.hx
  257. qemu-os-posix.h
  258. qemu-os-win32.h
  259. qemu-progress.c
  260. qemu-queue.h
  261. qemu-sockets.c
  262. qemu-tech.texi
  263. qemu-thread-posix.c
  264. qemu-thread-posix.h
  265. qemu-thread-win32.c
  266. qemu-thread-win32.h
  267. qemu-thread.h
  268. qemu-timer-common.c
  269. qemu-timer.c
  270. qemu-timer.h
  271. qemu-tls.h
  272. qemu-tool.c
  273. qemu-user.c
  274. qemu-x509.h
  275. qemu-xattr.h
  276. qemu.sasl
  277. qemu_socket.h
  278. qerror.c
  279. qerror.h
  280. qfloat.c
  281. qfloat.h
  282. qint.c
  283. qint.h
  284. qjson.c
  285. qjson.h
  286. qlist.c
  287. qlist.h
  288. qmp-commands.hx
  289. qmp.c
  290. qobject.h
  291. qstring.c
  292. qstring.h
  293. qtest.c
  294. qtest.h
  295. range.h
  296. readline.c
  297. readline.h
  298. README
  299. rules.mak
  300. s390-dis.c
  301. s390.ld
  302. savevm.c
  303. sh4-dis.c
  304. softmmu-semi.h
  305. softmmu_defs.h
  306. softmmu_exec.h
  307. softmmu_header.h
  308. softmmu_template.h
  309. sparc-dis.c
  310. sparc.ld
  311. sparc64.ld
  312. spice-qemu-char.c
  313. sysemu.h
  314. targphys.h
  315. tcg-runtime.c
  316. tci-dis.c
  317. tci.c
  318. thunk.c
  319. thunk.h
  320. TODO
  321. trace-events
  322. translate-all.c
  323. uboot_image.h
  324. user-exec.c
  325. VERSION
  326. version.rc
  327. vgafont.h
  328. vl.c
  329. vmstate.h
  330. x86_64.ld
  331. xen-all.c
  332. xen-mapcache.c
  333. xen-mapcache.h
  334. xen-stub.c
  335. xtensa-semi.c