aboutgitcodebugslistschat
path: root/pasta.c
diff options
context:
space:
mode:
Diffstat (limited to 'pasta.c')
-rw-r--r--pasta.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/pasta.c b/pasta.c
index 972cbcf..e45cc92 100644
--- a/pasta.c
+++ b/pasta.c
@@ -24,6 +24,8 @@
#include <stdint.h>
#include <unistd.h>
#include <syslog.h>
+#include <sys/epoll.h>
+#include <sys/inotify.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -219,3 +221,53 @@ void pasta_ns_conf(struct ctx *c)
proto_update_l2_buf(c->mac_guest, NULL, NULL);
}
+
+/**
+ * pasta_netns_quit_init() - Watch network namespace to quit once it's gone
+ * @c: Execution context
+ *
+ * Return: inotify file descriptor, -1 on failure or if not needed/applicable
+ */
+int pasta_netns_quit_init(struct ctx *c)
+{
+ struct epoll_event ev = { .events = EPOLLIN };
+ int inotify_fd;
+
+ if (c->mode != MODE_PASTA || c->no_netns_quit || !*c->netns_base)
+ return -1;
+
+ if ((inotify_fd = inotify_init1(O_NONBLOCK)) < 0) {
+ perror("inotify_init(): won't quit once netns is gone");
+ return -1;
+ }
+
+ if (inotify_add_watch(inotify_fd, c->netns_dir, IN_DELETE) < 0) {
+ perror("inotify_add_watch(): won't quit once netns is gone");
+ return -1;
+ }
+
+ ev.data.fd = inotify_fd;
+ epoll_ctl(c->epollfd, EPOLL_CTL_ADD, inotify_fd, &ev);
+
+ return inotify_fd;
+}
+
+/**
+ * pasta_netns_quit_handler() - Handle ns directory events, exit if ns is gone
+ * @c: Execution context
+ * @inotify_fd: inotify file descriptor with watch on namespace directory
+ */
+void pasta_netns_quit_handler(struct ctx *c, int inotify_fd)
+{
+ char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
+ struct inotify_event *in_ev = (struct inotify_event *)buf;
+
+ if (read(inotify_fd, buf, sizeof(buf)) < (ssize_t)sizeof(*in_ev))
+ return;
+
+ if (strncmp(in_ev->name, c->netns_base, sizeof(c->netns_base)))
+ return;
+
+ info("Namespace %s is gone, exiting", c->netns_base);
+ exit(EXIT_SUCCESS);
+}