chiark / gitweb /
Classify processes from sessions into cgroups
[elogind.git] / src / shared / path-util.c
index 8be479cd7fcab6b4ee6d03695127abda1fb780bf..8f49d652664fcf2b63aa29740da6c61f741e350f 100644 (file)
@@ -528,7 +528,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
          *
          * If that didn't work we will try to read the mount id from
          * /proc/self/fdinfo/<fd>. This is almost as good as
-         * name_to_handle_at(), however, does not return the the
+         * name_to_handle_at(), however, does not return the
          * opaque file handle. The opaque file handle is pretty useful
          * to detect the root directory, which we should always
          * consider a mount point. Hence we use this only as
@@ -637,9 +637,10 @@ fallback_fstat:
         return check_st_dev && (a.st_dev != b.st_dev);
 }
 
-int path_is_mount_point(const char *t, bool allow_symlink) {
+/* flags can be AT_SYMLINK_FOLLOW or 0 */
+int path_is_mount_point(const char *t, int flags) {
         _cleanup_close_ int fd = -1;
-        _cleanup_free_ char *parent = NULL;
+        _cleanup_free_ char *canonical = NULL, *parent = NULL;
         int r;
 
         assert(t);
@@ -647,7 +648,17 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
         if (path_equal(t, "/"))
                 return 1;
 
-        r = path_get_parent(t, &parent);
+        /* we need to resolve symlinks manually, we can't just rely on
+         * fd_is_mount_point() to do that for us; if we have a structure like
+         * /bin -> /usr/bin/ and /usr is a mount point, then the parent that we
+         * look at needs to be /usr, not /. */
+        if (flags & AT_SYMLINK_FOLLOW) {
+                canonical = canonicalize_file_name(t);
+                if (!canonical)
+                        return -errno;
+        }
+
+        r = path_get_parent(canonical ?: t, &parent);
         if (r < 0)
                 return r;
 
@@ -655,7 +666,7 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
         if (fd < 0)
                 return -errno;
 
-        return fd_is_mount_point(fd, basename(t), (allow_symlink ? AT_SYMLINK_FOLLOW : 0));
+        return fd_is_mount_point(fd, basename(canonical ?: t), flags);
 }
 
 int path_is_read_only_fs(const char *path) {