summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-06-19 11:11:06 +0900
committerGitHub <noreply@github.com>2019-06-19 11:11:06 +0900
commita057135bceef2d8e1efa52f8693bd478385d0049 (patch)
tree00a5901f38331c593a5ec637035561626105d77d
parentd9adc8a8636f48e7f33371fc97cf9388744ff3a1 (diff)
parent60bdc0ca225534c695190e24e016fea7324919d8 (diff)
downloadsystemd-a057135bceef2d8e1efa52f8693bd478385d0049.tar.gz
Merge pull request #12822 from poettering/tmpfiles-is-mount-point
tmpfiles: use common fd_is_mount_point() implementation
-rw-r--r--src/tmpfiles/tmpfiles.c66
1 files changed, 21 insertions, 45 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index eabc51101d..b859d94b92 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -461,38 +461,6 @@ static bool unix_socket_alive(const char *fn) {
return !!set_get(unix_sockets, (char*) fn);
}
-static int dir_is_mount_point(DIR *d, const char *subdir) {
-
- int mount_id_parent, mount_id;
- int r_p, r;
-
- r_p = name_to_handle_at_loop(dirfd(d), ".", NULL, &mount_id_parent, 0);
- if (r_p < 0)
- r_p = -errno;
-
- r = name_to_handle_at_loop(dirfd(d), subdir, NULL, &mount_id, 0);
- if (r < 0)
- r = -errno;
-
- /* got no handle; make no assumptions, return error */
- if (r_p < 0 && r < 0)
- return r_p;
-
- /* got both handles; if they differ, it is a mount point */
- if (r_p >= 0 && r >= 0)
- return mount_id_parent != mount_id;
-
- /* got only one handle; assume different mount points if one
- * of both queries was not supported by the filesystem */
- if (IN_SET(r_p, -ENOSYS, -EOPNOTSUPP) || IN_SET(r, -ENOSYS, -EOPNOTSUPP))
- return true;
-
- /* return error */
- if (r_p < 0)
- return r_p;
- return r;
-}
-
static DIR* xopendirat_nomod(int dirfd, const char *path) {
DIR *dir;
@@ -557,13 +525,19 @@ static int dir_cleanup(
/* Try to detect bind mounts of the same filesystem instance; they
* do not differ in device major/minors. This type of query is not
* supported on all kernels or filesystem types though. */
- if (S_ISDIR(s.st_mode) && dir_is_mount_point(d, dent->d_name) > 0) {
- log_debug("Ignoring \"%s/%s\": different mount of the same filesystem.",
- p, dent->d_name);
- continue;
+ if (S_ISDIR(s.st_mode)) {
+ int q;
+
+ q = fd_is_mount_point(dirfd(d), dent->d_name, 0);
+ if (q < 0)
+ log_debug_errno(q, "Failed to determine whether \"%s/%s\" is a mount point, ignoring: %m", p, dent->d_name);
+ else if (q > 0) {
+ log_debug("Ignoring \"%s/%s\": different mount of the same filesystem.", p, dent->d_name);
+ continue;
+ }
}
- sub_path = strjoin(p, "/", dent->d_name);
+ sub_path = path_join(p, dent->d_name);
if (!sub_path) {
r = log_oom();
goto finish;
@@ -656,14 +630,16 @@ static int dir_cleanup(
continue;
}
- if (mountpoint && S_ISREG(s.st_mode))
- if (s.st_uid == 0 && STR_IN_SET(dent->d_name,
- ".journal",
- "aquota.user",
- "aquota.group")) {
- log_debug("Skipping \"%s\".", sub_path);
- continue;
- }
+ if (mountpoint &&
+ S_ISREG(s.st_mode) &&
+ s.st_uid == 0 &&
+ STR_IN_SET(dent->d_name,
+ ".journal",
+ "aquota.user",
+ "aquota.group")) {
+ log_debug("Skipping \"%s\".", sub_path);
+ continue;
+ }
/* Ignore sockets that are listed in /proc/net/unix */
if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path)) {