This repository has been archived by the owner on Oct 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
mntns.go
129 lines (108 loc) · 2.42 KB
/
mntns.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Note: this file is unused right now, but it describes how we could
// auto-correct our mountns. The problem is with the `atomfs mount` command, we
// need to propagate the mount to the right place, back outside of the atomfs
// mountns. Need better ideas on how to do this.
package atomfs
/*
#define _GNU_SOURCE
#include <stdio.h>
#include <syscall.h>
#include <sched.h>
#include <linux/kcmp.h>
int create_atomfs_mntns(char *base_path)
{
int ret;
char buf[PATH_MAX];
if (unshare(CLONE_NEWNS) < 0) {
perror("unshare");
return -1;
}
if (mkdir(base_path, 0755) < 0 && errno != EEXIST) {
perror("mkdir");
return -1;
}
snprintf(path, sizeof(path), "%s/ns", base_dir);
ret = open(path, O_CREAT | O_WRONLY);
if (ret < 0) {
perror("create ns mount target");
return -1;
}
close(ret);
if (mount("/proc/self/ns/mnt", path, NULL, MS_BIND, NULL) < 0) {
perror("mount");
return -1;
}
return 0;
}
__attribute__((constructor)) void fixup_mntns(void)
{
int ret, size, my_mnts, atomfs_mnts;
char buf[4096], path[PATH_MAX], *base_dir = NULL;
snprintf(buf, sizeof(buf), "/proc/self/ns/mnt")
ret = open("/proc/self/cmdline", O_RDONLY);
if (ret < 0) {
perror("error: open");
exit(96);
}
if ((size = read(ret, buf, sizeof(buf)-1)) < 0) {
close(ret);
perror("error: read");
exit(96);
}
close(ret);
#define ADVANCE_ARG \
do { \
while (*cur) { \
cur++; \
} \
cur++; \
} while (0)
// skip to base-dir
while (1) {
ADVANCE_ARG;
if (cur - buf >= size) {
base_dir = "/var/lib/atomfs";
break;
}
if (strcmp(cur, "--base-dir"))
continue;
// skip --base-dir itself, and if the next arg is still valid,
// use it as base-dir.
ADVANCE_ARG;
if (cur - buf >= size)
base_dir = cur;
else
base_dir = "/var/lib/atomfs";
break;
}
my_mntns = open("/proc/self/ns/mnt", O_RDONLY);
if (my_mntns < 0) {
perror("opening my mntns");
exit(96);
}
snprintf(path, sizeof(path), "%s/ns", base_dir);
atomfs_mntns = open(path, O_RDONLY);
if (atomfs_mntns < 0) {
if (errno == ENOENT) {
if (create_atomfs_mntns(base_dir) < 0)
exit(96)
return;
} else {
perror("opening atomfs mntns");
exit(96);
}
}
ret = syscall(__NR_kcmp, getpid(), getpid(), KCMP_FILE, my_mntns, atomfs_mntns);
close(my_mntns);
close(atomfs_mntns);
if (ret < 0) {
perror("kcmp failed");
exit(96);
}
// the namespaces match
if (!ret)
return;
if (create_atomfs_mntns(base_dir) < 0)
exit(96);
}
*/