colo: dynamic allocate aio_requests to avoid -EBUSY error

In normal case, there are at most TAPDISK_DATA_REQUESTS request
at the same time. But in remus mode, the write requests are
forwarded from the master side, and cached in block-remus. All
cached requests will be forwarded to aio driver when syncing PVM
and SVM. In this case, The number of requests may be more than
TAPDISK_DATA_REQUESTS. So aio driver can't hanlde these requests
at the same time, it will cause tapdisk2 exit.

We don't know how many requests will be handled, so dynamic allocate
aio_requests to avoid this error.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
fix memory leak in block-remus

Fix the following two memory leak:
1. If s->ramdisk.prev is not NULL, we merge the write requests in
   s->ramdisk.h into s->ramdisk.prev, and then destroy s->ramdisk.h.
   But we forget to free hash value when destroying s->ramdisk.h.
2. When write requests is finished, replicated_write_callback() will
   be called. We forget free the buff in this function.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
pass uuid to the callback td_open

remus's callback td_open needs uuid, but it is hard coded as 0.
After commit 4b1af8, the vbd's uuid is the minor of the blktap
device, not 0.
return the correct dev path

The user uses TAPDISK_MESSAGE_OPEN to pass the devpath to tapdisk2,
and will use TAPDISK_MESSAGE_LIST to query and get the pid of the
tapdisk2.

The devpath's format is: driver:params[|driver:params[...]].
The first vbd image only contains the first params, and we will
return driver:params, not devpath. The devpath is stored in
vbd->name, so return vbd->name instead of image->name.
blktap2: use correct way to get remus_image

We set remus_image in backup_read(). If we do flush
before the first read operation, remus_image will be
NULL. Pass image to remus via the callback td_open().

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
don't call client_flush() when switching to unprotected mode

If we switch the mode from primary to unprotected, the connection
between primary and backup cannot be used.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
remus: fix bug in tdremus_close()

We close ctl_fd.fd, but we don't unregister ctl_fd.id. It will
cause select() return fails, and the user cannot talk with
tapdisk2.

This patch also does some cleanup.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: use correct way to get free event id

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: don't return negative event id

If we find some error when registering a new event, we will return
a negative value. So we should skip negative event id.

Also fix a wrong check of return value.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: use correct way to define array.

Currently, we use the following way to define an array:
type array[] = {
    [index] = xxx,
    0,
};
So array[index+1] will be NULL. If index is not the last
index, it will override another index.

tapdisk_vbd_index is not defined, but array[DISK_TYPE_VINDEX]
is overridden, so we don't find this problem when building
the source.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: connect to backup asynchronously

tapdisk2 is a single thread process. If we use remus,
we will block in primary_blocking_connect(). The
user will not have any chance to talk with tapdisk2.
So we should connect to backup asynchronously.
Before the connection is established, we queue
all I/O request, and handle it when the connection
is established.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
switch to unprotected mode before closing

If the user wants to stop tapdisk2, he will do
the following thing:
1. close the image
2. detach from blktap device

If there is some pending I/O request, close will
fail. But the I/O request is pended in remus until
the connection is established. Introduce a new
callback td_pre_close() to flush these I/O requests.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: move async connect related codes to block-replication.c

   COLO will reuse them.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
blktap2: move ramdisk related codes to block-replication.c

 COLO will reuse them

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
block-colo: implement colo disk replication

 TODO:
 update block-remus to use async io to instead
 of mread/mwrite.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
pass correct file to qemu if we use blktap2

If we use blktap2, the correct file should be blktap device
not the pdev_path.
support blktap remus in xl

With this patch, we can use blktap remus like this:
disk = [ 'format=remus,devtype=disk,access=w,vdev=hda,backendtype=tap,target=192.168.3.1:9000|aio:filename' ]
support blktap colo in xl:

With this patch, we can use blktap remus like this:
disk = [ 'format=colo,devtype=disk,access=w,vdev=hda,backendtype=tap,target=192.168.3.1:9000|aio:filename' ]

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
update libxl__device_disk_from_xs_be() to support blktap device

If the disk backend is blktap device, we store "format:pdev_path"
in tapdisk-params, and store "phy" in type. So use tapdisk-params
to set libxl_device_disk instead of params and type.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
libxl/colo: setup and control disk replication for blktap2 backends

This patch adds the machinery required for protecting a guest's
disk state, when the guest disk uses a blktap2 disk backend.
1. COLO blktap2 disk device: Implements the interfaces required by the
   checkpoint abstract device layer. A note about the implementation:
   a) setup() is called for each disk attached to the guest.
      During setup():
      i) perform the sanity check: backend type should be LIBXL_DISK_BACKEND_TAP
         and format should be LIBXL_DISK_FORMAT_COLO.
      ii) connect to the control socket: /var/run/tap/colo_xxx, xxx is
          "host:port"(The character ':/' will be changed to '_').
   b) The postsuspend callback() will write "flush" to this socket
   c) The commit callback() will wait and read "done" from this socket

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>