forked from pool/systemd
123 lines
4.1 KiB
Diff
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);
|