aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2025-10-21 23:01:16 +0200
committerStefano Brivio <sbrivio@redhat.com>2025-10-30 15:33:58 +0100
commit57446ca9c3850b671c997674957f4ea2dfb0d0be (patch)
tree14d9dbab8e5a25276d9204ae8abf39482e67b5d4
parentaaa8f347351841fc16bd2a012b84f2b976c9dfb2 (diff)
downloadpasst-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar.gz
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar.bz2
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar.lz
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar.xz
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.tar.zst
passt-57446ca9c3850b671c997674957f4ea2dfb0d0be.zip
passt: Move main event loop processing into passt_worker()
Extract the epoll event processing logic from main() into a separate passt_worker() function. This refactoring prepares the code for future threading support where passt_worker() will be called as a worker thread callback. The new function handles: - Processing epoll events and dispatching to protocol handlers - Event statistics tracking and printing - Post-handler periodic tasks (timers, deferred work) - Migration handling No functional changes, purely a code restructuring. Signed-off-by: Laurent Vivier <lvivier@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> [sbrivio: Handle new EPOLL_TYPE_NL_NEIGH in passt_worker() as well] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--passt.c167
1 files changed, 91 insertions, 76 deletions
diff --git a/passt.c b/passt.c
index a8e06e1..dc3e114 100644
--- a/passt.c
+++ b/passt.c
@@ -231,6 +231,95 @@ static void print_stats(const struct ctx *c, const struct passt_stats *stats,
}
/**
+ * passt_worker() - Process epoll events and handle protocol operations
+ * @opaque: Pointer to execution context (struct ctx)
+ * @nfds: Number of file descriptors ready (epoll_wait return value)
+ * @events: epoll_event array of ready file descriptors
+ */
+static void passt_worker(void *opaque, int nfds, struct epoll_event *events)
+{
+ static struct passt_stats stats = { 0 };
+ struct ctx *c = opaque;
+ struct timespec now;
+ int i;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &now))
+ err_perror("Failed to get CLOCK_MONOTONIC time");
+
+ for (i = 0; i < nfds; i++) {
+ union epoll_ref ref = *((union epoll_ref *)&events[i].data.u64);
+ uint32_t eventmask = events[i].events;
+
+ trace("%s: epoll event on %s %i (events: 0x%08x)",
+ c->mode == MODE_PASTA ? "pasta" : "passt",
+ EPOLL_TYPE_STR(ref.type), ref.fd, eventmask);
+
+ switch (ref.type) {
+ case EPOLL_TYPE_TAP_PASTA:
+ tap_handler_pasta(c, eventmask, &now);
+ break;
+ case EPOLL_TYPE_TAP_PASST:
+ tap_handler_passt(c, eventmask, &now);
+ break;
+ case EPOLL_TYPE_TAP_LISTEN:
+ tap_listen_handler(c, eventmask);
+ break;
+ case EPOLL_TYPE_NSQUIT_INOTIFY:
+ pasta_netns_quit_inotify_handler(c, ref.fd);
+ break;
+ case EPOLL_TYPE_NSQUIT_TIMER:
+ pasta_netns_quit_timer_handler(c, ref);
+ break;
+ case EPOLL_TYPE_TCP:
+ tcp_sock_handler(c, ref, eventmask);
+ break;
+ case EPOLL_TYPE_TCP_SPLICE:
+ tcp_splice_sock_handler(c, ref, eventmask);
+ break;
+ case EPOLL_TYPE_TCP_LISTEN:
+ tcp_listen_handler(c, ref, &now);
+ break;
+ case EPOLL_TYPE_TCP_TIMER:
+ tcp_timer_handler(c, ref);
+ break;
+ case EPOLL_TYPE_UDP_LISTEN:
+ udp_listen_sock_handler(c, ref, eventmask, &now);
+ break;
+ case EPOLL_TYPE_UDP:
+ udp_sock_handler(c, ref, eventmask, &now);
+ break;
+ case EPOLL_TYPE_PING:
+ icmp_sock_handler(c, ref);
+ break;
+ case EPOLL_TYPE_VHOST_CMD:
+ vu_control_handler(c->vdev, c->fd_tap, eventmask);
+ break;
+ case EPOLL_TYPE_VHOST_KICK:
+ vu_kick_cb(c->vdev, ref, &now);
+ break;
+ case EPOLL_TYPE_REPAIR_LISTEN:
+ repair_listen_handler(c, eventmask);
+ break;
+ case EPOLL_TYPE_REPAIR:
+ repair_handler(c, eventmask);
+ break;
+ case EPOLL_TYPE_NL_NEIGH:
+ nl_neigh_notify_handler(c);
+ break;
+ default:
+ /* Can't happen */
+ ASSERT(0);
+ }
+ stats.events[ref.type]++;
+ print_stats(c, &stats, &now);
+ }
+
+ post_handler(c, &now);
+
+ migrate_handler(c);
+}
+
+/**
* main() - Entry point and main loop
* @argc: Argument count
* @argv: Options, plus optional target PID for pasta mode
@@ -247,8 +336,7 @@ static void print_stats(const struct ctx *c, const struct passt_stats *stats,
int main(int argc, char **argv)
{
struct epoll_event events[NUM_EPOLL_EVENTS];
- struct passt_stats stats = { 0 };
- int nfds, i, devnull_fd = -1;
+ int nfds, devnull_fd = -1;
struct ctx c = { 0 };
struct rlimit limit;
struct timespec now;
@@ -359,80 +447,7 @@ loop:
if (nfds == -1 && errno != EINTR)
die_perror("epoll_wait() failed in main loop");
- if (clock_gettime(CLOCK_MONOTONIC, &now))
- err_perror("Failed to get CLOCK_MONOTONIC time");
-
- for (i = 0; i < nfds; i++) {
- union epoll_ref ref = *((union epoll_ref *)&events[i].data.u64);
- uint32_t eventmask = events[i].events;
-
- trace("%s: epoll event on %s %i (events: 0x%08x)",
- c.mode == MODE_PASTA ? "pasta" : "passt",
- EPOLL_TYPE_STR(ref.type), ref.fd, eventmask);
-
- switch (ref.type) {
- case EPOLL_TYPE_TAP_PASTA:
- tap_handler_pasta(&c, eventmask, &now);
- break;
- case EPOLL_TYPE_TAP_PASST:
- tap_handler_passt(&c, eventmask, &now);
- break;
- case EPOLL_TYPE_TAP_LISTEN:
- tap_listen_handler(&c, eventmask);
- break;
- case EPOLL_TYPE_NSQUIT_INOTIFY:
- pasta_netns_quit_inotify_handler(&c, ref.fd);
- break;
- case EPOLL_TYPE_NSQUIT_TIMER:
- pasta_netns_quit_timer_handler(&c, ref);
- break;
- case EPOLL_TYPE_TCP:
- tcp_sock_handler(&c, ref, eventmask);
- break;
- case EPOLL_TYPE_TCP_SPLICE:
- tcp_splice_sock_handler(&c, ref, eventmask);
- break;
- case EPOLL_TYPE_TCP_LISTEN:
- tcp_listen_handler(&c, ref, &now);
- break;
- case EPOLL_TYPE_TCP_TIMER:
- tcp_timer_handler(&c, ref);
- break;
- case EPOLL_TYPE_UDP_LISTEN:
- udp_listen_sock_handler(&c, ref, eventmask, &now);
- break;
- case EPOLL_TYPE_UDP:
- udp_sock_handler(&c, ref, eventmask, &now);
- break;
- case EPOLL_TYPE_PING:
- icmp_sock_handler(&c, ref);
- break;
- case EPOLL_TYPE_VHOST_CMD:
- vu_control_handler(c.vdev, c.fd_tap, eventmask);
- break;
- case EPOLL_TYPE_VHOST_KICK:
- vu_kick_cb(c.vdev, ref, &now);
- break;
- case EPOLL_TYPE_REPAIR_LISTEN:
- repair_listen_handler(&c, eventmask);
- break;
- case EPOLL_TYPE_REPAIR:
- repair_handler(&c, eventmask);
- break;
- case EPOLL_TYPE_NL_NEIGH:
- nl_neigh_notify_handler(&c);
- break;
- default:
- /* Can't happen */
- ASSERT(0);
- }
- stats.events[ref.type]++;
- print_stats(&c, &stats, &now);
- }
-
- post_handler(&c, &now);
-
- migrate_handler(&c);
+ passt_worker(&c, nfds, events);
goto loop;
}