tmpfiles: silently ignore any path that passes through autofs (#6506)
If a path passes though an autofs filesystem, then accessing the path might trigger and automount. As systemd-tmpfiles is run before the network is up, and as automounts are often used for networked filesystems, this can cause a deadlock. So chase_symlinks is enhance to accept a new flag which tells it to check for autofs, and return -EREMOTE if autofs is found. tmpfiles is changed to check just before acting on a path so that it can avoid autofs even if a symlink was created earlier by tmpfiles that would send this path through an autofs. This fixes a deadlock that happens when /home is listed in /etc/fstab as x-systemd.automount for an NFS directory.
This commit is contained in:
parent
ee905de0d6
commit
655f2da079
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/magic.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -721,6 +722,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
|
||||
if (fstat(child, &st) < 0)
|
||||
return -errno;
|
||||
if ((flags & CHASE_NO_AUTOFS) &&
|
||||
fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
|
||||
return -EREMOTE;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
char *joined;
|
||||
|
|
|
@ -81,6 +81,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
|||
enum {
|
||||
CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
|
||||
CHASE_NONEXISTENT = 2, /* If set, it's OK if the path doesn't actually exist. */
|
||||
CHASE_NO_AUTOFS = 4, /* If set, return -EREMOTE if autofs mount point found */
|
||||
};
|
||||
|
||||
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
|
||||
|
|
|
@ -1664,6 +1664,9 @@ static int process_item(Item *i) {
|
|||
}
|
||||
}
|
||||
|
||||
if (chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS, NULL) == -EREMOTE)
|
||||
return t;
|
||||
|
||||
r = arg_create ? create_item(i) : 0;
|
||||
q = arg_remove ? remove_item(i) : 0;
|
||||
p = arg_clean ? clean_item(i) : 0;
|
||||
|
|
Loading…
Reference in New Issue