]> git.proxmox.com Git - mirror_corosync-qdevice.git/commitdiff
qdevice: Initial port to use pr-poll-loop
authorJan Friesse <jfriesse@redhat.com>
Tue, 25 Aug 2020 14:14:00 +0000 (16:14 +0200)
committerJan Friesse <jfriesse@redhat.com>
Tue, 25 Aug 2020 16:01:17 +0000 (18:01 +0200)
Only qdevice_instance_wait_for_initial_heuristics_exec_result is ported
for now.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
qdevices/Makefile.am
qdevices/corosync-qdevice.c
qdevices/qdevice-instance.c
qdevices/qdevice-instance.h
qdevices/qdevice-pr-poll-loop-cb.c [new file with mode: 0644]
qdevices/qdevice-pr-poll-loop-cb.h [new file with mode: 0644]
qdevices/qdevice-pr-poll-loop.c [new file with mode: 0644]
qdevices/qdevice-pr-poll-loop.h [new file with mode: 0644]

index 4c795ebed7c6f8113cd28d638290af4517170860..e75b90ee012c22924d45fd92fcad94f103a82aa0 100644 (file)
@@ -143,7 +143,9 @@ corosync_qdevice_SOURCES = corosync-qdevice.c \
                            process-list.h process-list.c \
                            qdevice-net-heuristics.c qdevice-net-heuristics.h \
                            qdevice-heuristics-result-notifier.c qdevice-heuristics-result-notifier.h \
-                           log.c log.h
+                           log.c log.h pr-poll-loop.c pr-poll-loop.h \
+                           qdevice-pr-poll-loop-cb.c qdevice-pr-poll-loop-cb.h \
+                           qdevice-pr-poll-loop.c qdevice-pr-poll-loop.h
 
 corosync_qdevice_tool_SOURCES = corosync-qdevice-tool.c unix-socket.c unix-socket.h dynar.c dynar.h \
                                 dynar-str.c dynar-str.h utils.c utils.h
index 54eddcf5e98d41c04ce0419279a560fa89e0f568..3cad898d2cb6f0375a641c28b3c1c17309b514b5 100644 (file)
@@ -47,6 +47,8 @@
 #include "qdevice-ipc.h"
 #include "qdevice-log.h"
 #include "qdevice-model.h"
+#include "qdevice-pr-poll-loop.h"
+#include "qdevice-pr-poll-loop-cb.h"
 #include "qdevice-votequorum.h"
 #include "utils.h"
 
@@ -257,13 +259,18 @@ main(int argc, char * const argv[])
                return (EXIT_FAILURE);
        }
 
+       log(LOG_DEBUG, "Registering main poll loop callbacks");
+       if (qdevice_pr_poll_loop_cb_register(&instance) != 0) {
+               return (EXIT_FAILURE);
+       }
+
        log(LOG_DEBUG, "Waiting for ring id");
        if (qdevice_votequorum_wait_for_ring_id(&instance) != 0) {
                return (EXIT_FAILURE);
        }
 
        log(LOG_DEBUG, "Waiting for initial heuristics exec result");
-       if (qdevice_instance_wait_for_initial_heuristics_exec_result(&instance) != 0) {
+       if (qdevice_pr_poll_loop_wait_for_initial_heuristics_exec_result(&instance) != 0) {
                return (EXIT_FAILURE);
        }
 
index f50e273dbb292f96a540e10e687d4271cb11392a..89652dcd355081e156bbde6584a576ad81ea6763 100644 (file)
 #include "qdevice-config.h"
 #include "qdevice-instance.h"
 #include "qdevice-heuristics-exec-list.h"
-/*TODO Remove this 3 line includes when porting on pr-poll-loop */
-#include "qdevice-heuristics.h"
-#include "qdevice-heuristics-cmd.h"
-#include "qdevice-votequorum.h"
 #include "qdevice-model.h"
 #include "utils.h"
 
@@ -57,6 +53,7 @@ qdevice_instance_init(struct qdevice_instance *instance,
 
        instance->vq_last_poll = ((time_t) -1);
        instance->advanced_settings = advanced_settings;
+       pr_poll_loop_init(&instance->main_poll_loop);
 
        return (0);
 }
@@ -66,6 +63,7 @@ qdevice_instance_destroy(struct qdevice_instance *instance)
 {
 
        node_list_free(&instance->config_node_list);
+       pr_poll_loop_destroy(&instance->main_poll_loop);
 
        return (0);
 }
@@ -298,155 +296,3 @@ qdevice_instance_configure_from_cmap(struct qdevice_instance *instance)
 
        return (0);
 }
-
-#define QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS               5
-
-int
-qdevice_instance_wait_for_initial_heuristics_exec_result(struct qdevice_instance *instance)
-{
-       struct pollfd pfds[QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS];
-       int no_pfds;
-       int poll_res;
-       int timeout;
-       int i;
-       int case_processed;
-       int res;
-
-       while (!instance->vq_node_list_initial_heuristics_finished) {
-               no_pfds = 0;
-
-               assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS);
-               pfds[no_pfds].fd = instance->heuristics_instance.pipe_log_recv;
-               pfds[no_pfds].events = POLLIN;
-               pfds[no_pfds].revents = 0;
-               no_pfds++;
-
-               assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS);
-               pfds[no_pfds].fd = instance->heuristics_instance.pipe_cmd_recv;
-               pfds[no_pfds].events = POLLIN;
-               pfds[no_pfds].revents = 0;
-               no_pfds++;
-
-               assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS);
-               pfds[no_pfds].fd = instance->votequorum_poll_fd;
-               pfds[no_pfds].events = POLLIN;
-               pfds[no_pfds].revents = 0;
-               no_pfds++;
-
-               if (!send_buffer_list_empty(&instance->heuristics_instance.cmd_out_buffer_list)) {
-                       assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS);
-                       pfds[no_pfds].fd = instance->heuristics_instance.pipe_cmd_send;
-                       pfds[no_pfds].events = POLLOUT;
-                       pfds[no_pfds].revents = 0;
-                       no_pfds++;
-               }
-
-               /*
-                * We know this is never larger than QDEVICE_DEFAULT_HEURISTICS_MAX_TIMEOUT * 2
-                */
-               timeout = (int)instance->heuristics_instance.sync_timeout * 2;
-
-               poll_res = poll(pfds, no_pfds, timeout);
-               if (poll_res > 0) {
-                       for (i = 0; i < no_pfds; i++) {
-                               if (pfds[i].revents & POLLIN) {
-                                       case_processed = 0;
-                                       switch (i) {
-                                       case 0:
-                                               case_processed = 1;
-
-                                               res = qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance);
-                                               if (res == -1) {
-                                                       return (-1);
-                                               }
-                                               break;
-                                       case 1:
-                                               case_processed = 1;
-                                               res = qdevice_heuristics_cmd_read_from_pipe(&instance->heuristics_instance);
-                                               if (res == -1) {
-                                                       return (-1);
-                                               }
-                                               break;
-                                       case 2:
-                                               case_processed = 1;
-                                               res = qdevice_votequorum_dispatch(instance);
-                                               if (res == -1) {
-                                                       return (-1);
-                                               }
-                                       case 3:
-                                               /*
-                                                * Read on heuristics cmd send fs shouldn't happen
-                                                */
-                                                break;
-                                       }
-
-                                       if (!case_processed) {
-                                               log(LOG_CRIT, "Unhandled read on poll descriptor %u", i);
-                                               exit(EXIT_FAILURE);
-                                       }
-                               }
-
-                               if (pfds[i].revents & POLLOUT) {
-                                       case_processed = 0;
-                                       switch (i) {
-                                       case 0:
-                                       case 1:
-                                       case 2:
-                                               /*
-                                                * Write on heuristics log, cmd recv or vq shouldn't happen
-                                                */
-                                               break;
-                                       case 3:
-                                               case_processed = 1;
-                                               res = qdevice_heuristics_cmd_write(&instance->heuristics_instance);
-                                               if (res == -1) {
-                                                       return (-1);
-                                               }
-                                               break;
-                                       }
-
-                                       if (!case_processed) {
-                                               log(LOG_CRIT, "Unhandled write on poll descriptor %u", i);
-                                               exit(EXIT_FAILURE);
-                                       }
-                               }
-
-                               if ((pfds[i].revents & (POLLERR|POLLHUP|POLLNVAL)) &&
-                                   !(pfds[i].revents & (POLLIN|POLLOUT))) {
-                                       switch (i) {
-                                       case 0:
-                                       case 1:
-                                       case 3:
-                                               /*
-                                                *  Closed pipe doesn't mean return of POLLIN. To display
-                                                * better log message, we call read log as if POLLIN would
-                                                * be set.
-                                                */
-                                               res = qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance);
-                                               if (res == -1) {
-                                                       return (-1);
-                                               }
-
-                                               log(LOG_ERR, "POLLERR (%u) on heuristics pipe. Exiting",
-                                                   pfds[i].revents);
-                                               return (-1);
-                                               break;
-                                       case 2:
-                                               log(LOG_ERR, "POLLERR (%u) on corosync socket. Exiting",
-                                                   pfds[i].revents);
-                                               return (-1);
-                                               break;
-                                       }
-                               }
-                       }
-               } else if (poll_res == 0) {
-                       log(LOG_ERR, "Timeout waiting for initial heuristics exec result");
-                       return (-1);
-               } else {
-                       log_err(LOG_ERR, "Initial heuristics exec result poll failed");
-                       return (-1);
-               }
-       }
-
-       return (0);
-}
index 129ed58a86a43645354498d75c5def8ccd093ba8..32c2e051584dcd08bf05cbc949d4b80d821f4972 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017 Red Hat, Inc.
+ * Copyright (c) 2015-2020 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -47,6 +47,7 @@
 #include "qdevice-heuristics.h"
 #include "qdevice-model-type.h"
 #include "node-list.h"
+#include "pr-poll-loop.h"
 #include "unix-socket-ipc.h"
 
 #ifdef __cplusplus
@@ -118,6 +119,17 @@ struct qdevice_instance {
        int sync_in_progress;
 
        struct qdevice_heuristics_instance heuristics_instance;
+
+       struct pr_poll_loop main_poll_loop;
+
+       /*
+        * Set by poll handler when votequorum connection is closed
+        */
+       int votequorum_closed;
+       /*
+        * Set by poll handler when one of the heuristics pipes becomes closed
+        */
+       int heuristics_closed;
 };
 
 extern int     qdevice_instance_init(struct qdevice_instance *instance,
diff --git a/qdevices/qdevice-pr-poll-loop-cb.c b/qdevices/qdevice-pr-poll-loop-cb.c
new file mode 100644 (file)
index 0000000..fe90518
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2015-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "log.h"
+#include "qdevice-heuristics-cmd.h"
+#include "qdevice-heuristics-log.h"
+#include "qdevice-pr-poll-loop-cb.h"
+#include "qdevice-votequorum.h"
+
+static int
+heuristics_pipe_log_recv_read_cb(int fd, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+       int res;
+
+       res = qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance);
+       if (res == -1) {
+               instance->heuristics_closed = 1;
+               return (-1);
+       }
+
+       return (0);
+}
+
+/*
+ * Callback is shared for all heuristics pipes
+ */
+static int
+heuristics_pipe_err_cb(int fd, short revents, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+
+       instance->heuristics_closed = 1;
+
+       /*
+        * Closed pipe doesn't mean return of PR_POLL_READ. To display
+        * better log message, we call read log as if POLLIN would
+        * be set. Ignore error code because loop closes anyway.
+        */
+       (void)qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance);
+       log(LOG_DEBUG, "POLL_ERR (%u) on heuristics pipe. "
+            "Disconnecting.",  revents);
+
+       return (-1);
+}
+
+static int
+heuristics_pipe_cmd_recv_read_cb(int fd, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+       int res;
+
+       res = qdevice_heuristics_cmd_read_from_pipe(&instance->heuristics_instance);
+       if (res == -1) {
+               instance->heuristics_closed = 1;
+               return (-1);
+       }
+
+       return (0);
+}
+
+static int
+heuristics_pipe_cmd_send_set_events_cb(int fd, short *events, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+       int res;
+
+       res = -1;
+
+       if (!send_buffer_list_empty(&instance->heuristics_instance.cmd_out_buffer_list)) {
+               *events |= POLLOUT;
+               res = 0;
+       }
+
+       return (res);
+}
+
+static int
+heuristics_pipe_cmd_send_write_cb(int fd, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+       int res;
+
+       res = qdevice_heuristics_cmd_write(&instance->heuristics_instance);
+       if (res == -1) {
+               instance->heuristics_closed = 1;
+               return (-1);
+       }
+
+       return (0);
+}
+
+static int
+votequorum_read_cb(int fd, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+       int res;
+
+       res = qdevice_votequorum_dispatch(instance);
+       if (res == -1) {
+               instance->votequorum_closed = 1;
+               return (-1);
+       }
+
+       return (0);
+}
+
+static int
+votequorum_err_cb(int fd, short revents, void *user_data1, void *user_data2)
+{
+       struct qdevice_instance *instance = (struct qdevice_instance *)user_data1;
+
+       instance->votequorum_closed = 1;
+
+       log(LOG_DEBUG, "POLL_ERR (%u) on corosync socket. "
+            "Disconnecting.",  revents);
+
+       return (-1);
+}
+
+int
+qdevice_pr_poll_loop_cb_register(struct qdevice_instance *instance)
+{
+
+       if (pr_poll_loop_add_fd(&instance->main_poll_loop, instance->heuristics_instance.pipe_log_recv,
+           POLLIN, NULL, heuristics_pipe_log_recv_read_cb, NULL, heuristics_pipe_err_cb,
+           instance, NULL) != 0) {
+               log(LOG_ERR, "Can't add heuristics log pipe to main poll loop");
+
+               return (-1);
+       }
+
+       if (pr_poll_loop_add_fd(&instance->main_poll_loop, instance->heuristics_instance.pipe_cmd_recv,
+           POLLIN, NULL, heuristics_pipe_cmd_recv_read_cb, NULL, heuristics_pipe_err_cb,
+           instance, NULL) != 0) {
+               log(LOG_ERR, "Can't add heuristics cmd recv pipe to main poll loop");
+
+               return (-1);
+       }
+
+       if (pr_poll_loop_add_fd(&instance->main_poll_loop, instance->heuristics_instance.pipe_cmd_send,
+           0, heuristics_pipe_cmd_send_set_events_cb, NULL,
+           heuristics_pipe_cmd_send_write_cb, heuristics_pipe_err_cb,
+           instance, NULL) != 0) {
+               log(LOG_ERR, "Can't add heuristics cmd send pipe to main poll loop");
+
+               return (-1);
+       }
+
+       if (pr_poll_loop_add_fd(&instance->main_poll_loop, instance->votequorum_poll_fd,
+           POLLIN, NULL, votequorum_read_cb, NULL, votequorum_err_cb,
+           instance, NULL) != 0) {
+               log(LOG_ERR, "Can't add votequorum fd to main poll loop");
+
+               return (-1);
+       }
+
+       return (0);
+}
diff --git a/qdevices/qdevice-pr-poll-loop-cb.h b/qdevices/qdevice-pr-poll-loop-cb.h
new file mode 100644 (file)
index 0000000..8ff4609
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _QDEVICE_PR_POLL_LOOP_CB_H_
+#define _QDEVICE_PR_POLL_LOOP_CB_H_
+
+#include "qdevice-instance.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int             qdevice_pr_poll_loop_cb_register(struct qdevice_instance *instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _QDEVICE_PR_POLL_LOOP_CB_H_ */
diff --git a/qdevices/qdevice-pr-poll-loop.c b/qdevices/qdevice-pr-poll-loop.c
new file mode 100644 (file)
index 0000000..ae43d13
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "log.h"
+#include "qdevice-pr-poll-loop.h"
+#include "timer-list.h"
+
+static int
+wait_for_initial_heuristics_exec_result_timeout_timer_cb(void *data1, void *data2)
+{
+       int *timeout_called = (int *)data1;
+
+       *timeout_called = 1;
+
+       return (0);
+}
+
+int
+qdevice_pr_poll_loop_wait_for_initial_heuristics_exec_result(struct qdevice_instance *instance)
+{
+       struct timer_list_entry *timeout_timer;
+       int timeout_called;
+       int poll_res;
+       PRUint32 timeout;
+
+       timeout_called = 0;
+
+       /*
+        * We know this is never larger than QDEVICE_DEFAULT_HEURISTICS_MAX_TIMEOUT * 2
+        */
+       timeout = (PRUint32)instance->heuristics_instance.sync_timeout * 2;
+
+       timeout_timer = timer_list_add(pr_poll_loop_get_timer_list(&instance->main_poll_loop),
+           timeout, wait_for_initial_heuristics_exec_result_timeout_timer_cb,
+           &timeout_called, NULL);
+
+       while ((poll_res = pr_poll_loop_exec(&instance->main_poll_loop)) == 0 &&
+           !instance->vq_node_list_initial_heuristics_finished &&
+           !timeout_called) {
+       }
+
+       if (poll_res == -2) {
+               log(LOG_CRIT, "Initial heuristics exec result poll failed - internal error");
+               return (-1);
+       } else if (poll_res == -3) {
+               log_nss(LOG_CRIT, "Initial heuristics exec result poll failed - PR_Poll error");
+               return (-1);
+       }
+
+       if (timeout_called) {
+               log(LOG_ERR, "Timeout waiting for initial heuristics exec result");
+               return (-1);
+       }
+
+       timer_list_delete(pr_poll_loop_get_timer_list(&instance->main_poll_loop), timeout_timer);
+
+       return (poll_res);
+}
diff --git a/qdevices/qdevice-pr-poll-loop.h b/qdevices/qdevice-pr-poll-loop.h
new file mode 100644 (file)
index 0000000..2a12157
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015-2020 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Jan Friesse (jfriesse@redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the Red Hat, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _QDEVICE_PR_POLL_LOOP_H_
+#define _QDEVICE_PR_POLL_LOOP_H_
+
+#include "qdevice-instance.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int             qdevice_pr_poll_loop_wait_for_initial_heuristics_exec_result(
+    struct qdevice_instance *instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _QDEVICE_PR_POLL_LOOP_H_ */