Dear All,

I continue my work on the tunnelled selective block disks migration and the next step is to implement Tunnelled NBD block disk migration.

As far as I see libvirt uses the following algorithm for tunnelling the QEMU migration stream that is unidirectional:
1. The qemuMigrationStartTunnel (src/qemu/qemu_migration.c) starts a thread that reads the data from the local QEMU pipe and writes it to the virStream using virStreamSend.
2. The stream used by virStreamSend is embedded in the remote protocol messaging by the remoteDomainMigratePrepareTunnel3{,Params} (src/remote/remote_driver.c).
3. Remote links the daemonStream with the virFDStream connected  to the write end of a pipe linked with the QEMU.
4. Overall stream path is then: QEMU -(pipe)> virStreamSend -> (message passing to the remote) -> TCP -> (message received by deamon/*.c code) -> virStreamSend -> virFDStreamWrite -(pipe)> QEMU.

Given that I wonder what should be the changes required to implement a bidirectional QEMU tunnelled connection for the NBD device disk migration.

The way I see implementation details at the moment:
0. The `virStream` and corresponding `daemon/*.c` must be modified in a way that multiple streams can be multiplexed through the only one remote connection.
1. `Pipe`s used to interconnect to the QEMU on the both sides are obviously to be replaced by the UNIX sockets since the pipes cannot support bidirectional output due to the design. This is to be made *one for each* block device, requiring the above change.
2. The `qemuMigrationIOFunc` must be rewritten in such a way it polls for both read and write on the UNIX sockets *and* VM migration pipe and tunnells these to the appropriate `virStream`.
3. The receiving code must be modified in such a way to tunnel each of the opened UNIX socket to the according virFDStream.

Of the mentioned above the most intriguing for me is the zero-th item which will require some changes to the binary remote messaging protocol.

Is my vision on the problem is correct? Are there any other difficulties I'm going to face but not aware of due to the lack of the familiarity with the code?

Pavel