#include <rdma/rdma_cma.h>
#include "trace.h"
#include "qom/object.h"
+#include <poll.h>
/*
* Print and error on both the Monitor and the Log file.
return -1;
}
-static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
+static int qemu_get_cm_event_timeout(RDMAContext *rdma,
+ struct rdma_cm_event **cm_event,
+ long msec, Error **errp)
+{
+ int ret;
+ struct pollfd poll_fd = {
+ .fd = rdma->channel->fd,
+ .events = POLLIN,
+ .revents = 0
+ };
+
+ do {
+ ret = poll(&poll_fd, 1, msec);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret == 0) {
+ ERROR(errp, "poll cm event timeout");
+ return -1;
+ } else if (ret < 0) {
+ ERROR(errp, "failed to poll cm event, errno=%i", errno);
+ return -1;
+ } else if (poll_fd.revents & POLLIN) {
+ return rdma_get_cm_event(rdma->channel, cm_event);
+ } else {
+ ERROR(errp, "no POLLIN event, revent=%x", poll_fd.revents);
+ return -1;
+ }
+}
+
+static int qemu_rdma_connect(RDMAContext *rdma, Error **errp, bool return_path)
{
RDMACapabilities cap = {
.version = RDMA_CONTROL_VERSION_CURRENT,
goto err_rdma_source_connect;
}
- ret = rdma_get_cm_event(rdma->channel, &cm_event);
+ if (return_path) {
+ ret = qemu_get_cm_event_timeout(rdma, &cm_event, 5000, errp);
+ } else {
+ ret = rdma_get_cm_event(rdma->channel, &cm_event);
+ }
if (ret) {
perror("rdma_get_cm_event after rdma_connect");
ERROR(errp, "connecting to destination!");
}
trace_rdma_start_outgoing_migration_after_rdma_source_init();
- ret = qemu_rdma_connect(rdma, errp);
+ ret = qemu_rdma_connect(rdma, errp, false);
if (ret) {
goto err;
goto return_path_err;
}
- ret = qemu_rdma_connect(rdma_return_path, errp);
+ ret = qemu_rdma_connect(rdma_return_path, errp, true);
if (ret) {
goto return_path_err;