[PATCH] attempt connect to sockets to determine their vitality

Michael Meeks michael.meeks at suse.com
Thu Jan 12 03:01:01 PST 2012


---
 src/tmpfiles.c |   65 ++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index 44e5c9d..b3d17a7 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -34,8 +34,10 @@
 #include <getopt.h>
 #include <stdbool.h>
 #include <time.h>
+#include <sys/un.h>
 #include <sys/types.h>
 #include <sys/param.h>
+#include <sys/socket.h>
 #include <glob.h>
 #include <fnmatch.h>
 
@@ -180,15 +182,50 @@ fail:
 }
 
 static bool unix_socket_alive(const char *fn) {
+        bool ret;
+        int sd, saddr_len, cnx;
+        struct sockaddr_un saddr;
         assert(fn);
 
+        /* We don't know, so assume yes */
+        ret = true;
+
         load_unix_sockets();
 
-        if (unix_sockets)
-                return !!set_get(unix_sockets, (char*) fn);
+        if (strlen (fn) >= sizeof (saddr.sun_path))
+                return true;
+
+        if (unix_sockets && set_get(unix_sockets, (char*) fn))
+                return true;
+
+        if ((sd = socket (AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0)
+                goto done;
+        saddr.sun_family = AF_UNIX;
+        strncpy (saddr.sun_path, fn, sizeof (saddr.sun_path));
+        saddr_len = sizeof (struct sockaddr_un) - sizeof (saddr.sun_path) +
+                    strlen (saddr.sun_path);
+        do {
+                cnx = connect (sd, &saddr, saddr_len);
+        } while (cnx < 0 && errno == EINTR);
+        if (cnx >= 0) {
+                ret = true;
+                goto done;
+        }
+        switch (errno) {
+        case ECONNREFUSED:
+                ret = false;
+                break;
+        case EAGAIN:
+        case EINPROGRESS:
+        default:
+                ret = true;
+                break;
+        }
+ done:
+        if (sd >= 0)
+                close (sd);
 
-        /* We don't know, so assume yes */
-        return true;
+        return ret;
 }
 
 static int dir_cleanup(
@@ -311,20 +348,22 @@ static int dir_cleanup(
                                         continue;
                         }
 
-                        /* Ignore sockets that are listed in /proc/net/unix */
-                        if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path))
-                                continue;
-
                         /* Ignore device nodes */
                         if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
                                 continue;
 
-                        age = MAX3(timespec_load(&s.st_mtim),
-                                   timespec_load(&s.st_atim),
-                                   timespec_load(&s.st_ctim));
+                        /* We can determine accurately whether sockets are alive */
+                        if (S_ISSOCK(s.st_mode)) {
+                                if (unix_socket_alive(sub_path))
+                                        continue;
+                        } else {
+                                age = MAX3(timespec_load(&s.st_mtim),
+                                           timespec_load(&s.st_atim),
+                                           timespec_load(&s.st_ctim));
 
-                        if (age >= cutoff)
-                                continue;
+                                if (age >= cutoff)
+                                        continue;
+                        }
 
                         log_debug("unlink '%s'\n", sub_path);
 
-- 
1.7.3.4


--=-4Xmxg4t8QhhypNXewKKn--



More information about the systemd-devel mailing list