diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index f01599f656..730a7d0d06 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -175,7 +175,9 @@ source path, destination path and option string, where the latter two are optional. If only a source path is specified the source and destination is taken to be the same. The option string may be either rbind or norbind for configuring a recursive or non-recursive bind - mount. If the destination path is omitted, the option string must be omitted too. + mount. If the destination path is omitted, the option string must be omitted too. + Each bind mount definition may be prefixed with -, in which case it will be ignored + when its source path does not exist. BindPaths= creates regular writable bind mounts (unless the source file system mount is already marked read-only), while BindReadOnlyPaths= creates read-only bind mounts. These diff --git a/src/core/execute.c b/src/core/execute.c index 06cbb57af4..18ad92c3d9 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -4173,13 +4173,13 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { } if (c->n_bind_mounts > 0) - for (i = 0; i < c->n_bind_mounts; i++) { - fprintf(f, "%s%s: %s:%s:%s\n", prefix, + for (i = 0; i < c->n_bind_mounts; i++) + fprintf(f, "%s%s: %s%s:%s:%s\n", prefix, c->bind_mounts[i].read_only ? "BindReadOnlyPaths" : "BindPaths", + c->bind_mounts[i].ignore_enoent ? "-": "", c->bind_mounts[i].source, c->bind_mounts[i].destination, c->bind_mounts[i].recursive ? "rbind" : "norbind"); - } if (c->utmp_id) fprintf(f, diff --git a/src/core/namespace.c b/src/core/namespace.c index a5782ece7a..a42220ebe0 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -262,6 +262,7 @@ static int append_bind_mounts(MountEntry **p, const BindMount *binds, unsigned n .mode = b->recursive ? BIND_MOUNT_RECURSIVE : BIND_MOUNT, .read_only = b->read_only, .source_const = b->source, + .ignore = b->ignore_enoent, }; } @@ -728,11 +729,11 @@ static int mount_entry_chase( const char *root_directory, const MountEntry *m, const char *path, + bool chase_nonexistent, char **location) { char *chased; int r; - unsigned flags = 0; assert(m); @@ -740,18 +741,7 @@ static int mount_entry_chase( * chase the symlinks on our own first. This is called for the destination path, as well as the source path (if * that applies). The result is stored in "location". */ - if (IN_SET(m->mode, - BIND_MOUNT, - BIND_MOUNT_RECURSIVE, - PRIVATE_TMP, - PRIVATE_DEV, - BIND_DEV, - EMPTY_DIR, - SYSFS, - PROCFS)) - flags |= CHASE_NONEXISTENT; - - r = chase_symlinks(path, root_directory, flags, &chased); + r = chase_symlinks(path, root_directory, chase_nonexistent ? CHASE_NONEXISTENT : 0, &chased); if (r == -ENOENT && m->ignore) { log_debug_errno(r, "Path %s does not exist, ignoring.", path); return 0; @@ -777,7 +767,7 @@ static int apply_mount( assert(m); - r = mount_entry_chase(root_directory, m, mount_entry_path(m), &m->path_malloc); + r = mount_entry_chase(root_directory, m, mount_entry_path(m), !IN_SET(m->mode, INACCESSIBLE, READONLY, READWRITE), &m->path_malloc); if (r <= 0) return r; @@ -822,7 +812,7 @@ static int apply_mount( case BIND_MOUNT_RECURSIVE: /* Also chase the source mount */ - r = mount_entry_chase(root_directory, m, mount_entry_source(m), &m->source_malloc); + r = mount_entry_chase(root_directory, m, mount_entry_source(m), false, &m->source_malloc); if (r <= 0) return r;