1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/magic.h>
5 #include <sys/statvfs.h>
8 #include "alloc-util.h"
10 #include "dirent-util.h"
11 #include "errno-util.h"
13 #include "filesystems.h"
15 #include "hash-funcs.h"
17 #include "mountpoint-util.h"
18 #include "path-util.h"
19 #include "siphash24.h"
20 #include "stat-util.h"
21 #include "string-util.h"
22 #include "time-util.h"
24 static int verify_stat_at(
28 int (*verify_func
)(const struct stat
*st
),
34 assert(fd
>= 0 || fd
== AT_FDCWD
);
35 assert(!isempty(path
) || !follow
);
38 if (fstatat(fd
, strempty(path
), &st
,
39 (isempty(path
) ? AT_EMPTY_PATH
: 0) | (follow
? 0 : AT_SYMLINK_NOFOLLOW
)) < 0)
43 return verify
? r
: r
>= 0;
46 int stat_verify_regular(const struct stat
*st
) {
49 /* Checks whether the specified stat() structure refers to a regular file. If not returns an
50 * appropriate error code. */
52 if (S_ISDIR(st
->st_mode
))
55 if (S_ISLNK(st
->st_mode
))
58 if (!S_ISREG(st
->st_mode
))
64 int verify_regular_at(int fd
, const char *path
, bool follow
) {
65 return verify_stat_at(fd
, path
, follow
, stat_verify_regular
, true);
68 int fd_verify_regular(int fd
) {
70 return verify_regular_at(fd
, NULL
, false);
73 int stat_verify_directory(const struct stat
*st
) {
76 if (S_ISLNK(st
->st_mode
))
79 if (!S_ISDIR(st
->st_mode
))
85 int fd_verify_directory(int fd
) {
87 return verify_stat_at(fd
, NULL
, false, stat_verify_directory
, true);
90 int is_dir_at(int fd
, const char *path
, bool follow
) {
91 return verify_stat_at(fd
, path
, follow
, stat_verify_directory
, false);
94 int is_dir(const char *path
, bool follow
) {
95 assert(!isempty(path
));
96 return is_dir_at(AT_FDCWD
, path
, follow
);
99 int stat_verify_symlink(const struct stat
*st
) {
102 if (S_ISDIR(st
->st_mode
))
105 if (!S_ISLNK(st
->st_mode
))
111 int is_symlink(const char *path
) {
112 assert(!isempty(path
));
113 return verify_stat_at(AT_FDCWD
, path
, false, stat_verify_symlink
, false);
116 int stat_verify_linked(const struct stat
*st
) {
119 if (st
->st_nlink
<= 0)
120 return -EIDRM
; /* recognizable error. */
125 int fd_verify_linked(int fd
) {
127 return verify_stat_at(fd
, NULL
, false, stat_verify_linked
, true);
130 int stat_verify_device_node(const struct stat
*st
) {
133 if (S_ISLNK(st
->st_mode
))
136 if (S_ISDIR(st
->st_mode
))
139 if (!S_ISBLK(st
->st_mode
) && !S_ISCHR(st
->st_mode
))
145 int is_device_node(const char *path
) {
146 assert(!isempty(path
));
147 return verify_stat_at(AT_FDCWD
, path
, false, stat_verify_device_node
, false);
150 int dir_is_empty_at(int dir_fd
, const char *path
, bool ignore_hidden_or_backup
) {
151 _cleanup_close_
int fd
= -EBADF
;
155 fd
= xopenat(dir_fd
, path
, O_DIRECTORY
|O_CLOEXEC
);
159 /* Allocate space for at least 3 full dirents, since every dir has at least two entries ("." +
160 * ".."), and only once we have seen if there's a third we know whether the dir is empty or not. If
161 * 'ignore_hidden_or_backup' is true we'll allocate a bit more, since we might skip over a bunch of
162 * entries that we end up ignoring. */
163 m
= (ignore_hidden_or_backup
? 16 : 3) * DIRENT_SIZE_MAX
;
170 n
= getdents64(fd
, buf
, m
);
176 assert((size_t) n
<= m
);
177 msan_unpoison(buf
, n
);
179 FOREACH_DIRENT_IN_BUFFER(de
, buf
, n
)
180 if (!(ignore_hidden_or_backup
? hidden_or_backup_file(de
->d_name
) : dot_or_dot_dot(de
->d_name
)))
187 bool stat_may_be_dev_null(struct stat
*st
) {
190 /* We don't want to hardcode the major/minor of /dev/null, hence we do a simpler "is this a character
191 * device node?" check. */
193 return S_ISCHR(st
->st_mode
);
196 bool stat_is_empty(struct stat
*st
) {
199 return S_ISREG(st
->st_mode
) && st
->st_size
<= 0;
202 int null_or_empty_path_with_root(const char *fn
, const char *root
) {
208 /* A symlink to /dev/null or an empty file?
209 * When looking under root_dir, we can't expect /dev/ to be mounted,
210 * so let's see if the path is a (possibly dangling) symlink to /dev/null. */
212 if (path_equal(path_startswith(fn
, root
?: "/"), "dev/null"))
215 r
= chase_and_stat(fn
, root
, CHASE_PREFIX_ROOT
, NULL
, &st
);
219 return null_or_empty(&st
);
222 int fd_is_read_only_fs(int fd
) {
227 if (fstatfs(fd
, &st
) < 0)
230 if (st
.f_flags
& ST_RDONLY
)
233 if (is_network_fs(&st
)) {
234 /* On NFS, fstatfs() might not reflect whether we can actually write to the remote share.
235 * Let's try again with access(W_OK) which is more reliable, at least sometimes. */
236 if (access_fd(fd
, W_OK
) == -EROFS
)
243 int path_is_read_only_fs(const char *path
) {
244 _cleanup_close_
int fd
= -EBADF
;
248 fd
= open(path
, O_CLOEXEC
| O_PATH
);
252 return fd_is_read_only_fs(fd
);
255 int inode_same_at(int fda
, const char *filea
, int fdb
, const char *fileb
, int flags
) {
256 struct stat sta
, stb
;
259 assert(fda
>= 0 || fda
== AT_FDCWD
);
260 assert(fdb
>= 0 || fdb
== AT_FDCWD
);
261 assert((flags
& ~(AT_EMPTY_PATH
|AT_SYMLINK_NOFOLLOW
|AT_NO_AUTOMOUNT
)) == 0);
263 /* Refuse an unset filea or fileb early unless AT_EMPTY_PATH is set */
264 if ((isempty(filea
) || isempty(fileb
)) && !FLAGS_SET(flags
, AT_EMPTY_PATH
))
267 /* Shortcut: comparing the same fd with itself means we can return true */
268 if (fda
>= 0 && fda
== fdb
&& isempty(filea
) && isempty(fileb
) && FLAGS_SET(flags
, AT_SYMLINK_NOFOLLOW
))
271 _cleanup_close_
int pin_a
= -EBADF
, pin_b
= -EBADF
;
272 if (!FLAGS_SET(flags
, AT_NO_AUTOMOUNT
)) {
273 /* Let's try to use the name_to_handle_at() AT_HANDLE_FID API to identify identical
274 * inodes. We have to issue multiple calls on the same file for that (first, to acquire the
275 * FID, and then to check if .st_dev is actually the same). Hence let's pin the inode in
276 * between via O_PATH, unless we already have an fd for it. */
278 if (!isempty(filea
)) {
279 pin_a
= openat(fda
, filea
, O_PATH
|O_CLOEXEC
|(FLAGS_SET(flags
, AT_SYMLINK_NOFOLLOW
) ? O_NOFOLLOW
: 0));
285 flags
|= AT_EMPTY_PATH
;
288 if (!isempty(fileb
)) {
289 pin_b
= openat(fdb
, fileb
, O_PATH
|O_CLOEXEC
|(FLAGS_SET(flags
, AT_SYMLINK_NOFOLLOW
) ? O_NOFOLLOW
: 0));
295 flags
|= AT_EMPTY_PATH
;
298 int ntha_flags
= at_flags_normalize_follow(flags
) & (AT_EMPTY_PATH
|AT_SYMLINK_FOLLOW
);
299 _cleanup_free_
struct file_handle
*ha
= NULL
, *hb
= NULL
;
300 int mntida
= -1, mntidb
= -1;
302 r
= name_to_handle_at_try_fid(
309 if (is_name_to_handle_at_fatal_error(r
))
315 r
= name_to_handle_at_try_fid(
322 if (is_name_to_handle_at_fatal_error(r
))
328 /* Now compare the two file handles */
329 if (!file_handle_equal(ha
, hb
))
332 /* If the file handles are the same and they come from the same mount ID? Great, then we are
333 * good, they are definitely the same */
334 if (mntida
== mntidb
)
337 /* File handles are the same, they are not on the same mount id. This might either be because
338 * they are on two entirely different file systems, that just happen to have the same FIDs
339 * (because they originally where created off the same disk images), or it could be because
340 * they are located on two distinct bind mounts of the same fs. To check that, let's look at
341 * .st_rdev of the inode. We simply reuse the fallback codepath for that, since it checks
342 * exactly that (it checks slightly more, but we don't care.) */
346 if (fstatat(fda
, strempty(filea
), &sta
, flags
) < 0)
347 return log_debug_errno(errno
, "Cannot stat %s: %m", strna(filea
));
349 if (fstatat(fdb
, strempty(fileb
), &stb
, flags
) < 0)
350 return log_debug_errno(errno
, "Cannot stat %s: %m", strna(fileb
));
352 return stat_inode_same(&sta
, &stb
);
355 bool is_fs_type(const struct statfs
*s
, statfs_f_type_t magic_value
) {
357 assert_cc(sizeof(statfs_f_type_t
) >= sizeof(s
->f_type
));
359 return F_TYPE_EQUAL(s
->f_type
, magic_value
);
362 int is_fs_type_at(int dir_fd
, const char *path
, statfs_f_type_t magic_value
) {
366 r
= xstatfsat(dir_fd
, path
, &s
);
370 return is_fs_type(&s
, magic_value
);
373 bool is_temporary_fs(const struct statfs
*s
) {
374 return fs_in_group(s
, FILESYSTEM_SET_TEMPORARY
);
377 bool is_network_fs(const struct statfs
*s
) {
378 return fs_in_group(s
, FILESYSTEM_SET_NETWORK
);
381 int fd_is_temporary_fs(int fd
) {
384 if (fstatfs(fd
, &s
) < 0)
387 return is_temporary_fs(&s
);
390 int fd_is_network_fs(int fd
) {
393 if (fstatfs(fd
, &s
) < 0)
396 return is_network_fs(&s
);
399 int path_is_temporary_fs(const char *path
) {
402 if (statfs(path
, &s
) < 0)
405 return is_temporary_fs(&s
);
408 int path_is_network_fs(const char *path
) {
411 if (statfs(path
, &s
) < 0)
414 return is_network_fs(&s
);
417 int proc_mounted(void) {
420 /* A quick check of procfs is properly mounted */
422 r
= path_is_fs_type("/proc/", PROC_SUPER_MAGIC
);
423 if (r
== -ENOENT
) /* not mounted at all */
429 bool stat_inode_same(const struct stat
*a
, const struct stat
*b
) {
431 /* Returns if the specified stat structure references the same (though possibly modified) inode. Does
432 * a thorough check, comparing inode nr, backing device and if the inode is still of the same type. */
434 return stat_is_set(a
) && stat_is_set(b
) &&
435 ((a
->st_mode
^ b
->st_mode
) & S_IFMT
) == 0 && /* same inode type */
436 a
->st_dev
== b
->st_dev
&&
437 a
->st_ino
== b
->st_ino
;
440 bool stat_inode_unmodified(const struct stat
*a
, const struct stat
*b
) {
442 /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to
443 * be reasonably careful when detecting changes: we check both inode and mtime, to cater for file
444 * systems where mtimes are fixed to 0 (think: ostree/nixos type installations). We also check file
445 * size, backing device, inode type and if this refers to a device not the major/minor.
447 * Note that we don't care if file attributes such as ownership or access mode change, this here is
448 * about contents of the file. The purpose here is to detect file contents changes, and nothing
451 return stat_inode_same(a
, b
) &&
452 a
->st_mtim
.tv_sec
== b
->st_mtim
.tv_sec
&&
453 a
->st_mtim
.tv_nsec
== b
->st_mtim
.tv_nsec
&&
454 (!S_ISREG(a
->st_mode
) || a
->st_size
== b
->st_size
) && /* if regular file, compare file size */
455 (!(S_ISCHR(a
->st_mode
) || S_ISBLK(a
->st_mode
)) || a
->st_rdev
== b
->st_rdev
); /* if device node, also compare major/minor, because we can */
458 bool statx_inode_same(const struct statx
*a
, const struct statx
*b
) {
460 /* Same as stat_inode_same() but for struct statx */
462 return statx_is_set(a
) && statx_is_set(b
) &&
463 FLAGS_SET(a
->stx_mask
, STATX_TYPE
|STATX_INO
) && FLAGS_SET(b
->stx_mask
, STATX_TYPE
|STATX_INO
) &&
464 ((a
->stx_mode
^ b
->stx_mode
) & S_IFMT
) == 0 &&
465 a
->stx_dev_major
== b
->stx_dev_major
&&
466 a
->stx_dev_minor
== b
->stx_dev_minor
&&
467 a
->stx_ino
== b
->stx_ino
;
470 bool statx_mount_same(const struct statx
*a
, const struct statx
*b
) {
471 if (!statx_is_set(a
) || !statx_is_set(b
))
474 /* if we have the mount ID, that's all we need */
475 if (FLAGS_SET(a
->stx_mask
, STATX_MNT_ID
) && FLAGS_SET(b
->stx_mask
, STATX_MNT_ID
))
476 return a
->stx_mnt_id
== b
->stx_mnt_id
;
478 /* Otherwise, major/minor of backing device must match */
479 return a
->stx_dev_major
== b
->stx_dev_major
&&
480 a
->stx_dev_minor
== b
->stx_dev_minor
;
483 int xstatfsat(int dir_fd
, const char *path
, struct statfs
*ret
) {
484 _cleanup_close_
int fd
= -EBADF
;
486 assert(dir_fd
>= 0 || dir_fd
== AT_FDCWD
);
489 if (!isempty(path
)) {
490 fd
= xopenat(dir_fd
, path
, O_PATH
|O_CLOEXEC
|O_NOCTTY
);
496 return RET_NERRNO(fstatfs(dir_fd
, ret
));
499 usec_t
statx_timestamp_load(const struct statx_timestamp
*ts
) {
500 return timespec_load(&(const struct timespec
) { .tv_sec
= ts
->tv_sec
, .tv_nsec
= ts
->tv_nsec
});
502 nsec_t
statx_timestamp_load_nsec(const struct statx_timestamp
*ts
) {
503 return timespec_load_nsec(&(const struct timespec
) { .tv_sec
= ts
->tv_sec
, .tv_nsec
= ts
->tv_nsec
});
506 void inode_hash_func(const struct stat
*q
, struct siphash
*state
) {
507 siphash24_compress_typesafe(q
->st_dev
, state
);
508 siphash24_compress_typesafe(q
->st_ino
, state
);
511 int inode_compare_func(const struct stat
*a
, const struct stat
*b
) {
514 r
= CMP(a
->st_dev
, b
->st_dev
);
518 return CMP(a
->st_ino
, b
->st_ino
);
521 DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(inode_hash_ops
, struct stat
, inode_hash_func
, inode_compare_func
, free
);
523 const char* inode_type_to_string(mode_t m
) {
525 /* Returns a short string for the inode type. We use the same name as the underlying macros for each
528 switch (m
& S_IFMT
) {
545 /* Note anonymous inodes in the kernel will have a zero type. Hence fstat() of an eventfd() will
546 * return an .st_mode where we'll return NULL here! */
550 mode_t
inode_type_from_string(const char *s
) {
564 if (streq(s
, "fifo"))
566 if (streq(s
, "sock"))