diff options
| author | Laurent Vivier <lvivier@redhat.com> | 2025-10-21 23:01:16 +0200 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2025-10-30 15:33:58 +0100 |
| commit | 57446ca9c3850b671c997674957f4ea2dfb0d0be (patch) | |
| tree | 14d9dbab8e5a25276d9204ae8abf39482e67b5d4 | |
| parent | aaa8f347351841fc16bd2a012b84f2b976c9dfb2 (diff) | |
| download | passt-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.c | 167 |
1 files changed, 91 insertions, 76 deletions
@@ -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; } |
