aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-05-12 15:52:53 +1000
committerStefano Brivio <sbrivio@redhat.com>2026-05-16 15:47:04 +0200
commit1254a1f9f9867a9d9022e709549388d9cdf4f7b4 (patch)
treeb65e7091fdc5e730596f09f2dad80cb2db73b25f
parenta2a2f404a7b6aa44f166006dbd85207b2727248d (diff)
downloadpasst-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar.gz
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar.bz2
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar.lz
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar.xz
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.tar.zst
passt-1254a1f9f9867a9d9022e709549388d9cdf4f7b4.zip
passt-repair: Split out inotify handling to its own function
passt-repair can operate two ways: either it can be given an explicit socket path to connect to, or it can be given a directory. In the second mode, it will wait for a socket to appear in that directory before connecting to it. That waiting involves some inotify logic that is essentially unrelated to the rest of the code. However, it's currently inline in main() making that very long. Moreover, the block handling inotify shadows several variables used in the rest of main() which will make static checkers complain once we get them running on passt-repair. Address this by moving the inotify handling into its own function. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--passt-repair.c137
1 files changed, 77 insertions, 60 deletions
diff --git a/passt-repair.c b/passt-repair.c
index c3c140f..980b0b0 100644
--- a/passt-repair.c
+++ b/passt-repair.c
@@ -47,6 +47,82 @@
#define REPAIR_EXT_LEN strlen(REPAIR_EXT)
/**
+ * wait_for_socket() - Wait for a Unix socket to appear in a directory
+ * @a: Unix domain address to update with socket's path
+ * @dir: Path to directory to wait for socket in
+ * @sb: Stat block, populated for the discovered socket on exit
+ *
+ * Return: Length of socket address
+ *
+ * #syscalls:repair close
+ * #syscalls:repair stat|statx stat64|statx statx
+ * #syscalls:repair inotify_init1 inotify_add_watch
+ */
+static int wait_for_socket(struct sockaddr_un *a, const char *dir,
+ struct stat *sb)
+{
+ char buf[sizeof(struct inotify_event) + NAME_MAX + 1]
+ __attribute__ ((aligned(__alignof__(struct inotify_event))));
+ const struct inotify_event *ev = NULL;
+ char path[PATH_MAX + 1];
+ bool found = false;
+ ssize_t n;
+ int fd;
+
+ if ((fd = inotify_init1(IN_CLOEXEC)) < 0) {
+ fprintf(stderr, "inotify_init1: %i\n", errno);
+ _exit(1);
+ }
+
+ if (inotify_add_watch(fd, dir, IN_CREATE) < 0) {
+ fprintf(stderr, "inotify_add_watch: %i\n", errno);
+ _exit(1);
+ }
+
+ do {
+ char *p;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ fprintf(stderr, "inotify read: %i\n", errno);
+ _exit(1);
+ }
+ buf[n - 1] = '\0';
+
+ if (n < (ssize_t)sizeof(*ev)) {
+ fprintf(stderr, "Short inotify read: %zi\n", n);
+ continue;
+ }
+
+ for (p = buf; p < buf + n; p += sizeof(*ev) + ev->len) {
+ ev = (const struct inotify_event *)p;
+
+ if (ev->len >= REPAIR_EXT_LEN &&
+ !memcmp(ev->name +
+ strnlen(ev->name, ev->len) -
+ REPAIR_EXT_LEN,
+ REPAIR_EXT, REPAIR_EXT_LEN)) {
+ found = true;
+ break;
+ }
+ }
+ } while (!found);
+
+ if (ev->len > NAME_MAX + 1 || ev->name[ev->len - 1] != '\0') {
+ fprintf(stderr, "Invalid filename from inotify\n");
+ _exit(1);
+ }
+
+ snprintf(path, sizeof(path), "%s/%s", dir, ev->name);
+ if ((stat(path, sb))) {
+ fprintf(stderr, "Can't stat() %s: %i\n", path, errno);
+ _exit(1);
+ }
+
+ return snprintf(a->sun_path, sizeof(a->sun_path), "%s", path);
+}
+
+/**
* main() - Entry point and whole program with loop
* @argc: Argument count, must be 2
* @argv: Argument: path of UNIX domain socket to connect to
@@ -59,7 +135,6 @@
* #syscalls:repair sendto sendmsg arm:send ppc64le:send
* #syscalls:repair stat|statx stat64|statx statx
* #syscalls:repair fstat|fstat64 newfstatat|fstatat64
- * #syscalls:repair inotify_init1 inotify_add_watch
*/
int main(int argc, char **argv)
{
@@ -112,65 +187,7 @@ int main(int argc, char **argv)
}
if ((sb.st_mode & S_IFMT) == S_IFDIR) {
- char buf[sizeof(struct inotify_event) + NAME_MAX + 1]
- __attribute__ ((aligned(__alignof__(struct inotify_event))));
- const struct inotify_event *ev = NULL;
- char path[PATH_MAX + 1];
- bool found = false;
- ssize_t n;
- int fd;
-
- if ((fd = inotify_init1(IN_CLOEXEC)) < 0) {
- fprintf(stderr, "inotify_init1: %i\n", errno);
- _exit(1);
- }
-
- if (inotify_add_watch(fd, argv[1], IN_CREATE) < 0) {
- fprintf(stderr, "inotify_add_watch: %i\n", errno);
- _exit(1);
- }
-
- do {
- char *p;
-
- n = read(fd, buf, sizeof(buf));
- if (n < 0) {
- fprintf(stderr, "inotify read: %i\n", errno);
- _exit(1);
- }
- buf[n - 1] = '\0';
-
- if (n < (ssize_t)sizeof(*ev)) {
- fprintf(stderr, "Short inotify read: %zi\n", n);
- continue;
- }
-
- for (p = buf; p < buf + n; p += sizeof(*ev) + ev->len) {
- ev = (const struct inotify_event *)p;
-
- if (ev->len >= REPAIR_EXT_LEN &&
- !memcmp(ev->name +
- strnlen(ev->name, ev->len) -
- REPAIR_EXT_LEN,
- REPAIR_EXT, REPAIR_EXT_LEN)) {
- found = true;
- break;
- }
- }
- } while (!found);
-
- if (ev->len > NAME_MAX + 1 || ev->name[ev->len - 1] != '\0') {
- fprintf(stderr, "Invalid filename from inotify\n");
- _exit(1);
- }
-
- snprintf(path, sizeof(path), "%s/%s", argv[1], ev->name);
- if ((stat(path, &sb))) {
- fprintf(stderr, "Can't stat() %s: %i\n", path, errno);
- _exit(1);
- }
-
- ret = snprintf(a.sun_path, sizeof(a.sun_path), "%s", path);
+ ret = wait_for_socket(&a, argv[1], &sb);
inotify_dir = true;
} else {
ret = snprintf(a.sun_path, sizeof(a.sun_path), "%s", argv[1]);