]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: split out helper to open a directory
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 7 Dec 2023 11:56:44 +0000 (12:56 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 9 Feb 2024 16:57:41 +0000 (17:57 +0100)
In preparation for future commits.

src/tmpfiles/tmpfiles.c

index c174d2b6d5834b8e1dbd56b871731ed5b0bb531f..e877a5117aa4782e6d980ad98290ffb65adf866e 100644 (file)
@@ -557,6 +557,63 @@ static DIR* opendir_nomod(const char *path) {
         return xopendirat_nomod(AT_FDCWD, path);
 }
 
+static int opendir_and_stat(
+                const char *path,
+                DIR **ret,
+                struct statx *ret_sx,
+                bool *ret_mountpoint) {
+
+        _cleanup_closedir_ DIR *d = NULL;
+        STRUCT_STATX_DEFINE(sx);
+        int r;
+
+        assert(path);
+        assert(ret);
+        assert(ret_sx);
+        assert(ret_mountpoint);
+
+        /* Do opendir() and statx() on the directory.
+         * Return 1 if successful, 0 if file doesn't exist or is not a directory,
+         * negative errno otherwise.
+         */
+
+        d = opendir_nomod(path);
+        if (!d) {
+                bool ignore = IN_SET(errno, ENOENT, ENOTDIR);
+                r = log_full_errno(ignore ? LOG_DEBUG : LOG_ERR,
+                                   errno, "Failed to open directory %s: %m", path);
+                if (!ignore)
+                        return r;
+
+                *ret = NULL;
+                *ret_sx = (struct statx) {};
+                *ret_mountpoint = NULL;
+                return 0;
+        }
+
+        r = statx_fallback(dirfd(d), "", AT_EMPTY_PATH, STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, &sx);
+        if (r < 0)
+                return log_error_errno(r, "statx(%s) failed: %m", path);
+
+        if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT))
+                *ret_mountpoint = FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT);
+        else {
+                struct stat ps;
+
+                if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0)
+                        return log_error_errno(errno, "stat(%s/..) failed: %m", path);
+
+                *ret_mountpoint =
+                        sx.stx_dev_major != major(ps.st_dev) ||
+                        sx.stx_dev_minor != minor(ps.st_dev) ||
+                        sx.stx_ino != ps.st_ino;
+        }
+
+        *ret = TAKE_PTR(d);
+        *ret_sx = sx;
+        return 1;
+}
+
 static bool needs_cleanup(
                 nsec_t atime,
                 nsec_t btime,
@@ -2963,49 +3020,25 @@ static int clean_item_instance(
                 const char* instance,
                 CreationMode creation) {
 
-        _cleanup_closedir_ DIR *d = NULL;
-        STRUCT_STATX_DEFINE(sx);
-        int mountpoint, r;
-        usec_t cutoff, n;
-
         assert(i);
 
         if (!i->age_set)
                 return 0;
 
-        n = now(CLOCK_REALTIME);
+        usec_t n = now(CLOCK_REALTIME);
         if (n < i->age)
                 return 0;
 
-        cutoff = n - i->age;
-
-        d = opendir_nomod(instance);
-        if (!d) {
-                if (IN_SET(errno, ENOENT, ENOTDIR)) {
-                        log_debug_errno(errno, "Directory \"%s\": %m", instance);
-                        return 0;
-                }
-
-                return log_error_errno(errno, "Failed to open directory %s: %m", instance);
-        }
-
-        r = statx_fallback(dirfd(d), "", AT_EMPTY_PATH, STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, &sx);
-        if (r < 0)
-                return log_error_errno(r, "statx(%s) failed: %m", instance);
-
-        if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT))
-                mountpoint = FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT);
-        else {
-                struct stat ps;
+        usec_t cutoff = n - i->age;
 
-                if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0)
-                        return log_error_errno(errno, "stat(%s/..) failed: %m", i->path);
+        _cleanup_closedir_ DIR *d = NULL;
+        STRUCT_STATX_DEFINE(sx);
+        bool mountpoint;
+        int r;
 
-                mountpoint =
-                        sx.stx_dev_major != major(ps.st_dev) ||
-                        sx.stx_dev_minor != minor(ps.st_dev) ||
-                        sx.stx_ino != ps.st_ino;
-        }
+        r = opendir_and_stat(instance, &d, &sx, &mountpoint);
+        if (r <= 0)
+                return r;
 
         if (DEBUG_LOGGING) {
                 _cleanup_free_ char *ab_f = NULL, *ab_d = NULL;
@@ -3029,7 +3062,8 @@ static int clean_item_instance(
                            statx_timestamp_load_nsec(&sx.stx_atime),
                            statx_timestamp_load_nsec(&sx.stx_mtime),
                            cutoff * NSEC_PER_USEC,
-                           sx.stx_dev_major, sx.stx_dev_minor, mountpoint,
+                           sx.stx_dev_major, sx.stx_dev_minor,
+                           mountpoint,
                            MAX_DEPTH, i->keep_first_level,
                            i->age_by_file, i->age_by_dir);
 }