When qrexec-agent crashes for any reason (for example
QubesOS/qubes-issues#1389), it will never connect back and qrexec-client
will wait forever. In worst case it may happen while holding qubes.xml
write lock (in case of DispVM startup) effectively locking the whole
system.
FixesQubesOS/qubes-issues#1636
Otherwise if the child process isn't reading its stdin at that time, it
would deadlock the whole qrexec connection (for example preventing
reading the data from the child, which may be a cause of that deadlock).
QubesOS/qubes-issues#1347
Make sure that all the data from local process is sent (including final
EOF), before handling its exit code - which would include terminating
qrexec-client process.
This reverts commit 79abec9038.
The problem will not be applicable in new protocol, where vchan
connection is directly between VMs, so there is no longer two connected
qrexec-clients - always one end of data flow in qrexec-client is vchan,
which provide information about amount of data to read or buffer
space to write (lack of the later in case of pipes was a cause of the
original problem).
When VM-VM qrexec service is called, two qrexec-clients are connected in
dom0. If both VMs are sending data simultaneously it can happen that
both qrexec-client processes will call write(2) and none of them will be
reading -> deadlock.
Solve it by handling I/O in two separate threads (one for reading from
VM, another for writing), at any time qrexec-client is ready to accept
data from either direction.