1
0
mirror of https://github.com/systemd/systemd synced 2025-10-09 21:54:44 +02:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Lennart Poettering
0ae2ac9759
Two follow-ups for recent PRs (#38062) 2025-07-06 22:06:52 +02:00
Mike Yuan
1320e56283
chase: introduce openat_opath_with_automount() helper
Follow-up for c5de7b14ae2e08d267d8d75bc88934ac6aa7dcd6

chase() is arguably a hot path in our code, hence it deserves
some caching whether open_tree() is available. Moreover,
the manual set of r to -EPERM feels kinda ugly. Let's
instead extract this bit into its own function.
2025-07-05 12:18:55 +02:00
Mike Yuan
d75219711f
journal-file: const and _pure_'ify journal_file_writable()
Follow-up for 1543c2385c0a1afbdc59b50c8ecd132a0d60bbef
2025-07-05 11:45:18 +02:00
3 changed files with 34 additions and 18 deletions

View File

@ -77,6 +77,34 @@ static int log_prohibited_symlink(int fd, ChaseFlags flags) {
strna(n1)); strna(n1));
} }
static int openat_opath_with_automount(int dir_fd, const char *path, bool automount) {
static bool can_open_tree = true;
int r;
/* Pin an inode via O_PATH semantics. Sounds pretty obvious to do this, right? You just do open()
* with O_PATH, and there you go. But uh, it's not that easy. open() via O_PATH does not trigger
* automounts, but we usually want that (except if CHASE_NO_AUTOFS is used). But thankfully there's
* a way out: the newer open_tree() call, when specified without OPEN_TREE_CLONE actually is fully
* equivalent to open() with O_PATH except for one thing: it triggers automounts.
*
* As it turns out some sandboxes prohibit open_tree(), and return EPERM or ENOSYS if we call it.
* But since autofs does not work inside of mount namespace anyway, let's simply handle this
* as gracefully as we can, and fall back to classic openat() if we see EPERM/ENOSYS. */
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
if (automount && can_open_tree) {
r = RET_NERRNO(open_tree(dir_fd, path, AT_SYMLINK_NOFOLLOW|OPEN_TREE_CLOEXEC));
if (r >= 0 || (r != -EPERM && !ERRNO_IS_NEG_NOT_SUPPORTED(r)))
return r;
can_open_tree = false;
}
return RET_NERRNO(openat(dir_fd, path, O_PATH|O_NOFOLLOW|O_CLOEXEC));
}
static int chaseat_needs_absolute(int dir_fd, const char *path) { static int chaseat_needs_absolute(int dir_fd, const char *path) {
if (dir_fd < 0) if (dir_fd < 0)
return path_is_absolute(path); return path_is_absolute(path);
@ -371,22 +399,8 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
continue; continue;
} }
/* Otherwise let's pin it by file descriptor, via O_PATH. Sounds pretty obvious to do this, /* Otherwise let's pin it by file descriptor, via O_PATH. */
* right? You just do open() with O_PATH, and there you go. But uh, it's not that child = r = openat_opath_with_automount(fd, first, /* automount = */ !FLAGS_SET(flags, CHASE_NO_AUTOFS));
* easy. open() via O_PATH does not trigger automounts, but we usually want that (except if
* CHASE_NO_AUTOFS is used). But thankfully there's a way out: the newer open_tree() call,
* when specified without OPEN_TREE_CLONE actually is fully equivalent to open() with O_PATH
* except for one thing: it triggers automounts.
*
* As it turns out some sandboxes prohibit open_tree(), and return EPERM or ENOSYS if we call
* it. But since autofs does not work inside of mount namespace anyway, let's simply handle
* this as gracefully as we can, and fall back to classic openat() if we see EPERM/ENOSYS. */
if (FLAGS_SET(flags, CHASE_NO_AUTOFS))
r = -EPERM;
else
child = r = RET_NERRNO(open_tree(fd, first, AT_SYMLINK_NOFOLLOW|OPEN_TREE_CLOEXEC));
if (r == -EPERM || ERRNO_IS_NEG_NOT_SUPPORTED(r))
child = r = RET_NERRNO(openat(fd, first, O_CLOEXEC|O_NOFOLLOW|O_PATH));
if (r < 0) { if (r < 0) {
if (r != -ENOENT) if (r != -ENOENT)
return r; return r;
@ -417,6 +431,7 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
return r; return r;
} }
/* ... and then check what it actually is. */
if (fstat(child, &st_child) < 0) if (fstat(child, &st_child) < 0)
return -errno; return -errno;

View File

@ -4694,8 +4694,9 @@ bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec, int log
return false; return false;
} }
bool journal_file_writable(JournalFile *f) { bool journal_file_writable(const JournalFile *f) {
assert(f); assert(f);
return (f->open_flags & O_ACCMODE_STRICT) != O_RDONLY; return (f->open_flags & O_ACCMODE_STRICT) != O_RDONLY;
} }

View File

@ -378,4 +378,4 @@ static inline uint32_t COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(Compression c) {
} }
} }
bool journal_file_writable(JournalFile *f); bool journal_file_writable(const JournalFile *f) _pure_;