systemd/0002-namespace-when-setting-up-an-inaccessible-mount-poin.patch

123 lines
4.1 KiB
Diff

Based on 6d313367d9ef780560e117e886502a99fa220eac Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 5 Jun 2014 21:35:35 +0200
Subject: [PATCH] namespace: when setting up an inaccessible mount point,
unmounting everything below
This has the benefit of not triggering any autofs mount points
unnecessarily.
---
src/core/namespace.c | 6 ++++
src/shared/util.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/shared/util.h | 2 +
3 files changed, 76 insertions(+)
--- src/core/namespace.c
+++ src/core/namespace.c 2014-06-11 00:00:00.000000000 +0000
@@ -220,6 +220,12 @@ static int apply_mount(
return mount_dev(m);
case INACCESSIBLE:
+
+ /* First, get rid of everything that is below if there
+ * is anything... Then, overmount it with an
+ * inaccessible directory. */
+ umount_recursive(m->path, 0);
+
what = "/run/systemd/inaccessible";
break;
--- src/shared/util.c
+++ src/shared/util.c 2014-06-11 00:00:00.000000000 +0000
@@ -54,6 +54,7 @@
#include <grp.h>
#include <sys/mman.h>
#include <sys/vfs.h>
+#include <sys/mount.h>
#include <linux/magic.h>
#include <limits.h>
#include <langinfo.h>
@@ -4635,6 +4636,73 @@ char *strjoin(const char *x, ...) {
return r;
}
+int umount_recursive(const char *prefix, int flags) {
+ bool again;
+ int n = 0, r;
+
+ /* Try to umount everything recursively below a
+ * directory. Also, take care of stacked mounts, and keep
+ * unmounting them until they are gone. */
+
+ do {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+ again = false;
+ r = 0;
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return -errno;
+
+ for (;;) {
+ _cleanup_free_ char *path = NULL, *p = NULL;
+ int k;
+
+ k = fscanf(proc_self_mountinfo,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%*s " /* (9) file system type */
+ "%*s" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &path);
+
+ if (k != 1) {
+ if (k == EOF)
+ break;
+
+ continue;
+ }
+
+ p = cunescape(path);
+ if (!p)
+ return -ENOMEM;
+
+ if (!path_startswith(p, prefix))
+ continue;
+
+ if (umount2(p, flags) < 0) {
+ r = -errno;
+ continue;
+ }
+
+ again = true;
+ n++;
+
+ break;
+ }
+
+ } while (again);
+
+ return r ? r : n;
+}
+
bool is_main_thread(void) {
static thread_local int cached = 0;
--- src/shared/util.h
+++ src/shared/util.h 2014-06-11 10:10:08.000000000 +0000
@@ -890,3 +890,5 @@ union file_handle_union {
struct file_handle handle;
char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
};
+
+int umount_recursive(const char *target, int flags);