]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-vserver-2.3.patch
- updated vserver patch to 4.4.111-vs2.3.9.1; builds (with cow and vroot) and seems...
[packages/kernel.git] / kernel-vserver-2.3.patch
CommitLineData
f19bd705
AM
1diff -NurpP --minimal linux-4.4.111/Documentation/vserver/debug.txt linux-4.4.111-vs2.3.9.1/Documentation/vserver/debug.txt
2--- linux-4.4.111/Documentation/vserver/debug.txt 1970-01-01 00:00:00.000000000 +0000
3+++ linux-4.4.111-vs2.3.9.1/Documentation/vserver/debug.txt 2018-01-09 16:36:20.000000000 +0000
d33d7b00
AM
4@@ -0,0 +1,154 @@
5+
6+debug_cvirt:
7+
8+ 2 4 "vx_map_tgid: %p/%llx: %d -> %d"
9+ "vx_rmap_tgid: %p/%llx: %d -> %d"
10+
11+debug_dlim:
12+
13+ 0 1 "ALLOC (%p,#%d)%c inode (%d)"
14+ "FREE (%p,#%d)%c inode"
15+ 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)"
16+ "FREE (%p,#%d)%c %lld bytes"
17+ 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]"
18+ 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
19+ "ext3_has_free_blocks(%p): free=%lu, root=%lu"
20+ "rcu_free_dl_info(%p)"
21+ 4 10 "alloc_dl_info(%p,%d) = %p"
22+ "dealloc_dl_info(%p)"
23+ "get_dl_info(%p[#%d.%d])"
24+ "put_dl_info(%p[#%d.%d])"
25+ 5 20 "alloc_dl_info(%p,%d)*"
26+ 6 40 "__hash_dl_info: %p[#%d]"
27+ "__unhash_dl_info: %p[#%d]"
28+ 7 80 "locate_dl_info(%p,#%d) = %p"
29+
30+debug_misc:
31+
32+ 0 1 "destroy_dqhash: %p [#0x%08x] c=%d"
33+ "new_dqhash: %p [#0x%08x]"
34+ "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
35+ "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
36+ "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
37+ "vroot_get_real_bdev not set"
927ca606
AM
38+ 1 2 "cow_break_link(?%s?)"
39+ "temp copy ?%s?"
d33d7b00
AM
40+ 2 4 "dentry_open(new): %p"
41+ "dentry_open(old): %p"
42+ "lookup_create(new): %p"
927ca606 43+ "old path ?%s?"
d33d7b00
AM
44+ "path_lookup(old): %d"
45+ "vfs_create(new): %d"
46+ "vfs_rename: %d"
47+ "vfs_sendfile: %d"
48+ 3 8 "fput(new_file=%p[#%d])"
49+ "fput(old_file=%p[#%d])"
50+ 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d"
51+ "vx_info_kill(%p[#%d],%d,%d)*"
52+ 5 20 "vs_reboot(%p[#%d],%d)"
53+ 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
54+
55+debug_net:
56+
57+ 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
58+ 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
59+ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
60+ 4 10 "ip_route_connect(%p) %p,%p;%lx"
61+ 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
62+ 6 40 "sk,egf: %p [#%d] (from %d)"
63+ "sk,egn: %p [#%d] (from %d)"
64+ "sk,req: %p [#%d] (from %d)"
65+ "sk: %p [#%d] (from %d)"
66+ "tw: %p [#%d] (from %d)"
67+ 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
68+ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
69+
70+debug_nid:
71+
72+ 0 1 "__lookup_nx_info(#%u): %p[#%u]"
73+ "alloc_nx_info(%d) = %p"
74+ "create_nx_info(%d) (dynamic rejected)"
75+ "create_nx_info(%d) = %p (already there)"
76+ "create_nx_info(%d) = %p (new)"
77+ "dealloc_nx_info(%p)"
78+ 1 2 "alloc_nx_info(%d)*"
79+ "create_nx_info(%d)*"
80+ 2 4 "get_nx_info(%p[#%d.%d])"
81+ "put_nx_info(%p[#%d.%d])"
82+ 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p"
83+ "clr_nx_info(%p[#%d.%d])"
84+ "init_nx_info(%p[#%d.%d])"
85+ "release_nx_info(%p[#%d.%d.%d]) %p"
86+ "set_nx_info(%p[#%d.%d])"
87+ 4 10 "__hash_nx_info: %p[#%d]"
88+ "__nx_dynamic_id: [#%d]"
89+ "__unhash_nx_info: %p[#%d.%d.%d]"
90+ 5 20 "moved task %p into nxi:%p[#%d]"
91+ "nx_migrate_task(%p,%p[#%d.%d.%d])"
92+ "task_get_nx_info(%p)"
93+ 6 40 "nx_clear_persistent(%p[#%d])"
94+
95+debug_quota:
96+
97+ 0 1 "quota_sync_dqh(%p,%d) discard inode %p"
98+ 1 2 "quota_sync_dqh(%p,%d)"
99+ "sync_dquots(%p,%d)"
100+ "sync_dquots_dqh(%p,%d)"
101+ 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
102+
103+debug_switch:
104+
105+ 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
106+ 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
107+ 4 10 "%s: (%s %s) returned %s with %d"
108+
109+debug_tag:
110+
927ca606 111+ 7 80 "dx_parse_tag(?%s?): %d:#%d"
d33d7b00
AM
112+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
113+
114+debug_xid:
115+
116+ 0 1 "__lookup_vx_info(#%u): %p[#%u]"
117+ "alloc_vx_info(%d) = %p"
118+ "alloc_vx_info(%d)*"
119+ "create_vx_info(%d) (dynamic rejected)"
120+ "create_vx_info(%d) = %p (already there)"
121+ "create_vx_info(%d) = %p (new)"
122+ "dealloc_vx_info(%p)"
123+ "loc_vx_info(%d) = %p (found)"
124+ "loc_vx_info(%d) = %p (new)"
125+ "loc_vx_info(%d) = %p (not available)"
126+ 1 2 "create_vx_info(%d)*"
127+ "loc_vx_info(%d)*"
128+ 2 4 "get_vx_info(%p[#%d.%d])"
129+ "put_vx_info(%p[#%d.%d])"
130+ 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p"
131+ "clr_vx_info(%p[#%d.%d])"
132+ "init_vx_info(%p[#%d.%d])"
133+ "release_vx_info(%p[#%d.%d.%d]) %p"
134+ "set_vx_info(%p[#%d.%d])"
135+ 4 10 "__hash_vx_info: %p[#%d]"
136+ "__unhash_vx_info: %p[#%d.%d.%d]"
137+ "__vx_dynamic_id: [#%d]"
138+ 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
139+ "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
140+ "moved task %p into vxi:%p[#%d]"
141+ "task_get_vx_info(%p)"
142+ "vx_migrate_task(%p,%p[#%d.%d])"
143+ 6 40 "vx_clear_persistent(%p[#%d])"
144+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
145+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
146+ "vx_set_persistent(%p[#%d])"
147+ "vx_set_reaper(%p[#%d],%p[#%d,%d])"
148+ 7 80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
149+
150+
151+debug_limit:
152+
153+ n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
154+ "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
155+
156+ m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
157+ "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
158+ "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
f19bd705
AM
159diff -NurpP --minimal linux-4.4.111/arch/alpha/Kconfig linux-4.4.111-vs2.3.9.1/arch/alpha/Kconfig
160--- linux-4.4.111/arch/alpha/Kconfig 2016-07-05 04:11:34.000000000 +0000
161+++ linux-4.4.111-vs2.3.9.1/arch/alpha/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 162@@ -745,6 +745,8 @@ config DUMMY_CONSOLE
2380c486
JR
163 depends on VGA_HOSE
164 default y
d337f35e
JR
165
166+source "kernel/vserver/Kconfig"
167+
168 source "security/Kconfig"
169
170 source "crypto/Kconfig"
f19bd705
AM
171diff -NurpP --minimal linux-4.4.111/arch/alpha/kernel/systbls.S linux-4.4.111-vs2.3.9.1/arch/alpha/kernel/systbls.S
172--- linux-4.4.111/arch/alpha/kernel/systbls.S 2015-07-06 20:41:36.000000000 +0000
173+++ linux-4.4.111-vs2.3.9.1/arch/alpha/kernel/systbls.S 2018-01-09 16:36:20.000000000 +0000
d337f35e
JR
174@@ -446,7 +446,7 @@ sys_call_table:
175 .quad sys_stat64 /* 425 */
176 .quad sys_lstat64
177 .quad sys_fstat64
178- .quad sys_ni_syscall /* sys_vserver */
179+ .quad sys_vserver /* sys_vserver */
180 .quad sys_ni_syscall /* sys_mbind */
181 .quad sys_ni_syscall /* sys_get_mempolicy */
182 .quad sys_ni_syscall /* sys_set_mempolicy */
f19bd705
AM
183diff -NurpP --minimal linux-4.4.111/arch/alpha/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/alpha/kernel/traps.c
184--- linux-4.4.111/arch/alpha/kernel/traps.c 2015-07-06 20:41:36.000000000 +0000
185+++ linux-4.4.111-vs2.3.9.1/arch/alpha/kernel/traps.c 2018-01-09 16:36:20.000000000 +0000
927ca606 186@@ -174,7 +174,8 @@ die_if_kernel(char * str, struct pt_regs
d337f35e
JR
187 #ifdef CONFIG_SMP
188 printk("CPU %d ", hard_smp_processor_id());
189 #endif
2380c486 190- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
61333608 191+ printk("%s(%d:#%u): %s %ld\n", current->comm,
2380c486 192+ task_pid_nr(current), current->xid, str, err);
d337f35e 193 dik_show_regs(regs, r9_15);
b00e13aa 194 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
d337f35e 195 dik_show_trace((unsigned long *)(regs+1));
f19bd705
AM
196diff -NurpP --minimal linux-4.4.111/arch/arm/Kconfig linux-4.4.111-vs2.3.9.1/arch/arm/Kconfig
197--- linux-4.4.111/arch/arm/Kconfig 2016-07-05 04:14:23.000000000 +0000
198+++ linux-4.4.111-vs2.3.9.1/arch/arm/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 199@@ -2159,6 +2159,8 @@ source "fs/Kconfig"
d337f35e
JR
200
201 source "arch/arm/Kconfig.debug"
202
203+source "kernel/vserver/Kconfig"
204+
205 source "security/Kconfig"
206
207 source "crypto/Kconfig"
f19bd705
AM
208diff -NurpP --minimal linux-4.4.111/arch/arm/kernel/calls.S linux-4.4.111-vs2.3.9.1/arch/arm/kernel/calls.S
209--- linux-4.4.111/arch/arm/kernel/calls.S 2016-07-05 04:14:26.000000000 +0000
210+++ linux-4.4.111-vs2.3.9.1/arch/arm/kernel/calls.S 2018-01-09 16:36:20.000000000 +0000
d337f35e
JR
211@@ -322,7 +322,7 @@
212 /* 310 */ CALL(sys_request_key)
213 CALL(sys_keyctl)
214 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
215-/* vserver */ CALL(sys_ni_syscall)
216+ CALL(sys_vserver)
217 CALL(sys_ioprio_set)
218 /* 315 */ CALL(sys_ioprio_get)
219 CALL(sys_inotify_init)
f19bd705
AM
220diff -NurpP --minimal linux-4.4.111/arch/arm/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/arm/kernel/traps.c
221--- linux-4.4.111/arch/arm/kernel/traps.c 2018-01-11 07:57:02.000000000 +0000
222+++ linux-4.4.111-vs2.3.9.1/arch/arm/kernel/traps.c 2018-01-09 16:36:20.000000000 +0000
927ca606 223@@ -258,8 +258,8 @@ static int __die(const char *str, int er
78865d5b 224
d337f35e
JR
225 print_modules();
226 __show_regs(regs);
927ca606
AM
227- pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
228- TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
229+ pr_emerg("Process %.*s (pid: %d:%u, stack limit = 0x%p)\n",
230+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), tsk->xid, end_of_stack(tsk));
d337f35e
JR
231
232 if (!user_mode(regs) || in_interrupt()) {
7e46296a 233 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
f19bd705
AM
234diff -NurpP --minimal linux-4.4.111/arch/cris/Kconfig linux-4.4.111-vs2.3.9.1/arch/cris/Kconfig
235--- linux-4.4.111/arch/cris/Kconfig 2016-07-05 04:14:27.000000000 +0000
236+++ linux-4.4.111-vs2.3.9.1/arch/cris/Kconfig 2018-01-09 16:36:20.000000000 +0000
927ca606 237@@ -581,6 +581,8 @@ source "fs/Kconfig"
d337f35e
JR
238
239 source "arch/cris/Kconfig.debug"
240
241+source "kernel/vserver/Kconfig"
242+
243 source "security/Kconfig"
244
245 source "crypto/Kconfig"
f19bd705
AM
246diff -NurpP --minimal linux-4.4.111/arch/ia64/Kconfig linux-4.4.111-vs2.3.9.1/arch/ia64/Kconfig
247--- linux-4.4.111/arch/ia64/Kconfig 2016-07-05 04:11:39.000000000 +0000
248+++ linux-4.4.111-vs2.3.9.1/arch/ia64/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 249@@ -606,6 +606,8 @@ source "fs/Kconfig"
2380c486
JR
250
251 source "arch/ia64/Kconfig.debug"
d337f35e
JR
252
253+source "kernel/vserver/Kconfig"
254+
255 source "security/Kconfig"
256
257 source "crypto/Kconfig"
f19bd705
AM
258diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/entry.S linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/entry.S
259--- linux-4.4.111/arch/ia64/kernel/entry.S 2016-07-05 04:14:27.000000000 +0000
260+++ linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/entry.S 2018-01-09 16:36:21.000000000 +0000
927ca606 261@@ -1694,7 +1694,7 @@ sys_call_table:
2380c486
JR
262 data8 sys_mq_notify
263 data8 sys_mq_getsetattr
264 data8 sys_kexec_load
265- data8 sys_ni_syscall // reserved for vserver
266+ data8 sys_vserver
267 data8 sys_waitid // 1270
268 data8 sys_add_key
269 data8 sys_request_key
f19bd705
AM
270diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/ptrace.c linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/ptrace.c
271--- linux-4.4.111/arch/ia64/kernel/ptrace.c 2015-04-12 22:12:50.000000000 +0000
272+++ linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
78865d5b 273@@ -21,6 +21,7 @@
2380c486 274 #include <linux/regset.h>
d337f35e 275 #include <linux/elf.h>
ec22aa5c 276 #include <linux/tracehook.h>
d337f35e
JR
277+#include <linux/vs_base.h>
278
279 #include <asm/pgtable.h>
280 #include <asm/processor.h>
f19bd705
AM
281diff -NurpP --minimal linux-4.4.111/arch/ia64/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/traps.c
282--- linux-4.4.111/arch/ia64/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
283+++ linux-4.4.111-vs2.3.9.1/arch/ia64/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
1e8b8f9b 284@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re
d337f35e
JR
285 put_cpu();
286
287 if (++die.lock_owner_depth < 3) {
288- printk("%s[%d]: %s %ld [%d]\n",
2380c486 289- current->comm, task_pid_nr(current), str, err, ++die_counter);
61333608 290+ printk("%s[%d:#%u]: %s %ld [%d]\n",
2380c486 291+ current->comm, task_pid_nr(current), current->xid,
d337f35e 292+ str, err, ++die_counter);
2380c486
JR
293 if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV)
294 != NOTIFY_STOP)
295 show_regs(regs);
1e8b8f9b 296@@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_
2380c486
JR
297 if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) {
298 last.time = current_jiffies + 5 * HZ;
299 printk(KERN_WARNING
300- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
301- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
61333608 302+ "%s(%d:#%u): floating-point assist fault at ip %016lx, isr %016lx\n",
2380c486
JR
303+ current->comm, task_pid_nr(current), current->xid,
304+ regs->cr_iip + ia64_psr(regs)->ri, isr);
305 }
306 }
d337f35e 307 }
f19bd705
AM
308diff -NurpP --minimal linux-4.4.111/arch/m32r/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/m32r/kernel/traps.c
309--- linux-4.4.111/arch/m32r/kernel/traps.c 2015-04-12 22:12:50.000000000 +0000
310+++ linux-4.4.111-vs2.3.9.1/arch/m32r/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
09be7631 311@@ -184,8 +184,9 @@ static void show_registers(struct pt_reg
d337f35e
JR
312 } else {
313 printk("SPI: %08lx\n", sp);
314 }
315- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
2380c486 316- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
61333608 317+ printk("Process %s (pid: %d:#%u, process nr: %d, stackpage=%08lx)",
2380c486 318+ current->comm, task_pid_nr(current), current->xid,
d337f35e
JR
319+ 0xffff & i, 4096+(unsigned long)current);
320
321 /*
322 * When in-kernel, we also print out the stack and code at the
f19bd705
AM
323diff -NurpP --minimal linux-4.4.111/arch/m68k/Kconfig linux-4.4.111-vs2.3.9.1/arch/m68k/Kconfig
324--- linux-4.4.111/arch/m68k/Kconfig 2016-07-05 04:11:39.000000000 +0000
325+++ linux-4.4.111-vs2.3.9.1/arch/m68k/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 326@@ -164,6 +164,8 @@ source "fs/Kconfig"
d337f35e
JR
327
328 source "arch/m68k/Kconfig.debug"
329
330+source "kernel/vserver/Kconfig"
331+
332 source "security/Kconfig"
333
334 source "crypto/Kconfig"
f19bd705
AM
335diff -NurpP --minimal linux-4.4.111/arch/mips/Kconfig linux-4.4.111-vs2.3.9.1/arch/mips/Kconfig
336--- linux-4.4.111/arch/mips/Kconfig 2018-01-11 07:57:04.000000000 +0000
337+++ linux-4.4.111-vs2.3.9.1/arch/mips/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 338@@ -3026,6 +3026,8 @@ source "fs/Kconfig"
d337f35e
JR
339
340 source "arch/mips/Kconfig.debug"
341
342+source "kernel/vserver/Kconfig"
343+
344 source "security/Kconfig"
345
346 source "crypto/Kconfig"
f19bd705
AM
347diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/ptrace.c linux-4.4.111-vs2.3.9.1/arch/mips/kernel/ptrace.c
348--- linux-4.4.111/arch/mips/kernel/ptrace.c 2018-01-11 07:57:05.000000000 +0000
349+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
927ca606 350@@ -30,6 +30,7 @@
2380c486
JR
351 #include <linux/audit.h>
352 #include <linux/seccomp.h>
c2e5f7c8 353 #include <linux/ftrace.h>
d337f35e
JR
354+#include <linux/vs_base.h>
355
356 #include <asm/byteorder.h>
357 #include <asm/cpu.h>
927ca606 358@@ -690,6 +691,9 @@ long arch_ptrace(struct task_struct *chi
ab30d09f
AM
359 void __user *datavp = (void __user *) data;
360 unsigned long __user *datalp = (void __user *) data;
d337f35e 361
2380c486 362+ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT))
d337f35e
JR
363+ goto out;
364+
365 switch (request) {
366 /* when I and D space are separate, these will need to be fixed. */
367 case PTRACE_PEEKTEXT: /* read word at location addr. */
f19bd705
AM
368diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall32-o32.S linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall32-o32.S
369--- linux-4.4.111/arch/mips/kernel/scall32-o32.S 2018-01-11 07:57:05.000000000 +0000
370+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall32-o32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 371@@ -512,7 +512,7 @@ EXPORT(sys_call_table)
c2e5f7c8
JR
372 PTR sys_mq_timedreceive
373 PTR sys_mq_notify /* 4275 */
374 PTR sys_mq_getsetattr
375- PTR sys_ni_syscall /* sys_vserver */
376+ PTR sys_vserver
377 PTR sys_waitid
378 PTR sys_ni_syscall /* available, was setaltroot */
379 PTR sys_add_key /* 4280 */
f19bd705
AM
380diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-64.S linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-64.S
381--- linux-4.4.111/arch/mips/kernel/scall64-64.S 2018-01-11 07:57:05.000000000 +0000
382+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-64.S 2018-01-09 16:36:21.000000000 +0000
927ca606 383@@ -349,7 +349,7 @@ EXPORT(sys_call_table)
d337f35e
JR
384 PTR sys_mq_timedreceive
385 PTR sys_mq_notify
386 PTR sys_mq_getsetattr /* 5235 */
387- PTR sys_ni_syscall /* sys_vserver */
388+ PTR sys_vserver
389 PTR sys_waitid
390 PTR sys_ni_syscall /* available, was setaltroot */
391 PTR sys_add_key
f19bd705
AM
392diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-n32.S linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-n32.S
393--- linux-4.4.111/arch/mips/kernel/scall64-n32.S 2018-01-11 07:57:05.000000000 +0000
394+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-n32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 395@@ -339,7 +339,7 @@ EXPORT(sysn32_call_table)
d337f35e
JR
396 PTR compat_sys_mq_timedreceive
397 PTR compat_sys_mq_notify
398 PTR compat_sys_mq_getsetattr
399- PTR sys_ni_syscall /* 6240, sys_vserver */
400+ PTR sys32_vserver /* 6240 */
2380c486 401 PTR compat_sys_waitid
d337f35e
JR
402 PTR sys_ni_syscall /* available, was setaltroot */
403 PTR sys_add_key
f19bd705
AM
404diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/scall64-o32.S linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-o32.S
405--- linux-4.4.111/arch/mips/kernel/scall64-o32.S 2018-01-11 07:57:05.000000000 +0000
406+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/scall64-o32.S 2018-01-09 16:36:21.000000000 +0000
927ca606 407@@ -495,7 +495,7 @@ EXPORT(sys32_call_table)
d337f35e
JR
408 PTR compat_sys_mq_timedreceive
409 PTR compat_sys_mq_notify /* 4275 */
410 PTR compat_sys_mq_getsetattr
411- PTR sys_ni_syscall /* sys_vserver */
412+ PTR sys32_vserver
b00e13aa 413 PTR compat_sys_waitid
d337f35e
JR
414 PTR sys_ni_syscall /* available, was setaltroot */
415 PTR sys_add_key /* 4280 */
f19bd705
AM
416diff -NurpP --minimal linux-4.4.111/arch/mips/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/mips/kernel/traps.c
417--- linux-4.4.111/arch/mips/kernel/traps.c 2018-01-11 07:57:05.000000000 +0000
418+++ linux-4.4.111-vs2.3.9.1/arch/mips/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 419@@ -353,9 +353,10 @@ void show_registers(struct pt_regs *regs
2380c486
JR
420
421 __show_regs(regs);
d337f35e 422 print_modules();
2380c486
JR
423- printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
424- current->comm, current->pid, current_thread_info(), current,
425- field, current_thread_info()->tp_value);
426+ printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p, tls=%0*lx)\n",
427+ current->comm, task_pid_nr(current), current->xid,
428+ current_thread_info(), current,
429+ field, current_thread_info()->tp_value);
430 if (cpu_has_userlocal) {
431 unsigned long tls;
432
f19bd705
AM
433diff -NurpP --minimal linux-4.4.111/arch/parisc/Kconfig linux-4.4.111-vs2.3.9.1/arch/parisc/Kconfig
434--- linux-4.4.111/arch/parisc/Kconfig 2016-07-05 04:14:29.000000000 +0000
435+++ linux-4.4.111-vs2.3.9.1/arch/parisc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 436@@ -341,6 +341,8 @@ config SECCOMP
d337f35e 437
bb20add7 438 If unsure, say Y. Only embedded should say N here.
d337f35e
JR
439
440+source "kernel/vserver/Kconfig"
441+
442 source "security/Kconfig"
443
444 source "crypto/Kconfig"
f19bd705
AM
445diff -NurpP --minimal linux-4.4.111/arch/parisc/kernel/syscall_table.S linux-4.4.111-vs2.3.9.1/arch/parisc/kernel/syscall_table.S
446--- linux-4.4.111/arch/parisc/kernel/syscall_table.S 2018-01-11 07:57:05.000000000 +0000
447+++ linux-4.4.111-vs2.3.9.1/arch/parisc/kernel/syscall_table.S 2018-01-09 16:36:21.000000000 +0000
b00e13aa 448@@ -358,7 +358,7 @@
d337f35e
JR
449 ENTRY_COMP(mbind) /* 260 */
450 ENTRY_COMP(get_mempolicy)
451 ENTRY_COMP(set_mempolicy)
452- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
453+ ENTRY_DIFF(vserver)
454 ENTRY_SAME(add_key)
455 ENTRY_SAME(request_key) /* 265 */
927ca606 456 ENTRY_COMP(keyctl)
f19bd705
AM
457diff -NurpP --minimal linux-4.4.111/arch/parisc/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/parisc/kernel/traps.c
458--- linux-4.4.111/arch/parisc/kernel/traps.c 2018-01-11 07:57:05.000000000 +0000
459+++ linux-4.4.111-vs2.3.9.1/arch/parisc/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 460@@ -235,8 +235,9 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
461 return; /* STFU */
462
98968f7b
JR
463 parisc_printk_ratelimited(1, regs,
464- KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
2380c486 465- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
98968f7b 466+ KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
2380c486 467+ current->comm, task_pid_nr(current), current->xid,
d337f35e 468+ str, err, regs->iaoq[0]);
98968f7b
JR
469
470 return;
471 }
927ca606 472@@ -266,8 +267,8 @@ void die_if_kernel(char *str, struct pt_
d337f35e
JR
473 pdc_console_restart();
474
2380c486
JR
475 if (err)
476- printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
477- current->comm, task_pid_nr(current), str, err);
478+ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
479+ current->comm, task_pid_nr(current), current->xid, str, err);
480
481 /* Wot's wrong wif bein' racy? */
482 if (current->thread.flags & PARISC_KERNEL_DEATH) {
f19bd705
AM
483diff -NurpP --minimal linux-4.4.111/arch/powerpc/Kconfig linux-4.4.111-vs2.3.9.1/arch/powerpc/Kconfig
484--- linux-4.4.111/arch/powerpc/Kconfig 2018-01-11 07:57:05.000000000 +0000
485+++ linux-4.4.111-vs2.3.9.1/arch/powerpc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 486@@ -1080,6 +1080,8 @@ source "lib/Kconfig"
d33d7b00
AM
487
488 source "arch/powerpc/Kconfig.debug"
489
490+source "kernel/vserver/Kconfig"
491+
492 source "security/Kconfig"
493
927ca606 494 source "crypto/Kconfig"
f19bd705
AM
495diff -NurpP --minimal linux-4.4.111/arch/powerpc/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.1/arch/powerpc/include/uapi/asm/unistd.h
496--- linux-4.4.111/arch/powerpc/include/uapi/asm/unistd.h 2016-07-05 04:14:29.000000000 +0000
497+++ linux-4.4.111-vs2.3.9.1/arch/powerpc/include/uapi/asm/unistd.h 2018-01-09 16:36:21.000000000 +0000
adc1caaa
AM
498@@ -275,7 +275,7 @@
499 #endif
500 #define __NR_rtas 255
501 #define __NR_sys_debug_setcontext 256
502-/* Number 257 is reserved for vserver */
503+#define __NR_vserver 257
504 #define __NR_migrate_pages 258
505 #define __NR_mbind 259
506 #define __NR_get_mempolicy 260
f19bd705
AM
507diff -NurpP --minimal linux-4.4.111/arch/powerpc/kernel/traps.c linux-4.4.111-vs2.3.9.1/arch/powerpc/kernel/traps.c
508--- linux-4.4.111/arch/powerpc/kernel/traps.c 2018-01-11 07:57:06.000000000 +0000
509+++ linux-4.4.111-vs2.3.9.1/arch/powerpc/kernel/traps.c 2018-01-09 16:36:21.000000000 +0000
927ca606 510@@ -1315,8 +1315,9 @@ void nonrecoverable_exception(struct pt_
d337f35e
JR
511
512 void trace_syscall(struct pt_regs *regs)
513 {
514- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
2380c486 515- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
61333608 516+ printk("Task: %p(%d:#%u), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
2380c486 517+ current, task_pid_nr(current), current->xid,
d337f35e
JR
518+ regs->nip, regs->link, regs->gpr[0],
519 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
520 }
521
f19bd705
AM
522diff -NurpP --minimal linux-4.4.111/arch/s390/Kconfig linux-4.4.111-vs2.3.9.1/arch/s390/Kconfig
523--- linux-4.4.111/arch/s390/Kconfig 2018-01-11 07:57:06.000000000 +0000
524+++ linux-4.4.111-vs2.3.9.1/arch/s390/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 525@@ -729,6 +729,8 @@ source "fs/Kconfig"
d33d7b00
AM
526
527 source "arch/s390/Kconfig.debug"
528
529+source "kernel/vserver/Kconfig"
530+
531 source "security/Kconfig"
0411181d 532
d33d7b00 533 source "crypto/Kconfig"
f19bd705
AM
534diff -NurpP --minimal linux-4.4.111/arch/s390/include/asm/tlb.h linux-4.4.111-vs2.3.9.1/arch/s390/include/asm/tlb.h
535--- linux-4.4.111/arch/s390/include/asm/tlb.h 2015-07-06 20:41:37.000000000 +0000
536+++ linux-4.4.111-vs2.3.9.1/arch/s390/include/asm/tlb.h 2018-01-09 16:36:21.000000000 +0000
dd5f3080 537@@ -24,6 +24,7 @@
0411181d 538 #include <linux/mm.h>
d33d7b00 539 #include <linux/pagemap.h>
0411181d 540 #include <linux/swap.h>
0411181d
AM
541+
542 #include <asm/processor.h>
543 #include <asm/pgalloc.h>
763640ca 544 #include <asm/tlbflush.h>
f19bd705
AM
545diff -NurpP --minimal linux-4.4.111/arch/s390/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.1/arch/s390/include/uapi/asm/unistd.h
546--- linux-4.4.111/arch/s390/include/uapi/asm/unistd.h 2016-07-05 04:14:30.000000000 +0000
547+++ linux-4.4.111-vs2.3.9.1/arch/s390/include/uapi/asm/unistd.h 2018-01-09 16:48:33.000000000 +0000
92598135 548@@ -200,7 +200,7 @@
927ca606
AM
549 #define __NR_clock_gettime 260
550 #define __NR_clock_getres 261
551 #define __NR_clock_nanosleep 262
0411181d
AM
552-/* Number 263 is reserved for vserver */
553+#define __NR_vserver 263
554 #define __NR_statfs64 265
555 #define __NR_fstatfs64 266
556 #define __NR_remap_file_pages 267
f19bd705
AM
557diff -NurpP --minimal linux-4.4.111/arch/s390/kernel/ptrace.c linux-4.4.111-vs2.3.9.1/arch/s390/kernel/ptrace.c
558--- linux-4.4.111/arch/s390/kernel/ptrace.c 2018-01-11 07:57:07.000000000 +0000
559+++ linux-4.4.111-vs2.3.9.1/arch/s390/kernel/ptrace.c 2018-01-09 16:36:21.000000000 +0000
db55b927 560@@ -21,6 +21,7 @@
ec22aa5c
AM
561 #include <linux/tracehook.h>
562 #include <linux/seccomp.h>
969f5c41 563 #include <linux/compat.h>
db55b927 564+#include <linux/vs_base.h>
ec22aa5c 565 #include <trace/syscall.h>
d337f35e 566 #include <asm/segment.h>
db55b927 567 #include <asm/page.h>
f19bd705
AM
568diff -NurpP --minimal linux-4.4.111/arch/s390/kernel/syscalls.S linux-4.4.111-vs2.3.9.1/arch/s390/kernel/syscalls.S
569--- linux-4.4.111/arch/s390/kernel/syscalls.S 2018-01-11 07:57:07.000000000 +0000
570+++ linux-4.4.111-vs2.3.9.1/arch/s390/kernel/syscalls.S 2018-01-09 16:36:21.000000000 +0000
927ca606
AM
571@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,compat_sys_clo
572 SYSCALL(sys_clock_gettime,compat_sys_clock_gettime) /* 260 */
573 SYSCALL(sys_clock_getres,compat_sys_clock_getres)
574 SYSCALL(sys_clock_nanosleep,compat_sys_clock_nanosleep)
575-NI_SYSCALL /* reserved for vserver */
d337f35e 576+SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
927ca606
AM
577 SYSCALL(sys_ni_syscall,compat_sys_s390_fadvise64_64)
578 SYSCALL(sys_statfs64,compat_sys_statfs64)
579 SYSCALL(sys_fstatfs64,compat_sys_fstatfs64)
f19bd705
AM
580diff -NurpP --minimal linux-4.4.111/arch/sh/Kconfig linux-4.4.111-vs2.3.9.1/arch/sh/Kconfig
581--- linux-4.4.111/arch/sh/Kconfig 2016-07-05 04:11:46.000000000 +0000
582+++ linux-4.4.111-vs2.3.9.1/arch/sh/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 583@@ -883,6 +883,8 @@ source "fs/Kconfig"
d337f35e
JR
584
585 source "arch/sh/Kconfig.debug"
586
587+source "kernel/vserver/Kconfig"
588+
589 source "security/Kconfig"
590
591 source "crypto/Kconfig"
f19bd705
AM
592diff -NurpP --minimal linux-4.4.111/arch/sh/kernel/irq.c linux-4.4.111-vs2.3.9.1/arch/sh/kernel/irq.c
593--- linux-4.4.111/arch/sh/kernel/irq.c 2016-07-05 04:11:46.000000000 +0000
594+++ linux-4.4.111-vs2.3.9.1/arch/sh/kernel/irq.c 2018-01-09 16:36:21.000000000 +0000
f86f0b53 595@@ -14,6 +14,7 @@
7e46296a 596 #include <linux/ftrace.h>
76514441 597 #include <linux/delay.h>
763640ca 598 #include <linux/ratelimit.h>
f86f0b53 599+// #include <linux/vs_context.h>
d337f35e 600 #include <asm/processor.h>
2380c486 601 #include <asm/machvec.h>
f86f0b53 602 #include <asm/uaccess.h>
f19bd705
AM
603diff -NurpP --minimal linux-4.4.111/arch/sparc/Kconfig linux-4.4.111-vs2.3.9.1/arch/sparc/Kconfig
604--- linux-4.4.111/arch/sparc/Kconfig 2018-01-11 07:57:07.000000000 +0000
605+++ linux-4.4.111-vs2.3.9.1/arch/sparc/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 606@@ -561,6 +561,8 @@ source "fs/Kconfig"
d33d7b00
AM
607
608 source "arch/sparc/Kconfig.debug"
609
610+source "kernel/vserver/Kconfig"
611+
612 source "security/Kconfig"
613
614 source "crypto/Kconfig"
f19bd705
AM
615diff -NurpP --minimal linux-4.4.111/arch/sparc/include/uapi/asm/unistd.h linux-4.4.111-vs2.3.9.1/arch/sparc/include/uapi/asm/unistd.h
616--- linux-4.4.111/arch/sparc/include/uapi/asm/unistd.h 2016-07-05 04:14:33.000000000 +0000
617+++ linux-4.4.111-vs2.3.9.1/arch/sparc/include/uapi/asm/unistd.h 2018-01-09 16:36:21.000000000 +0000
537831f9 618@@ -332,7 +332,7 @@
ec22aa5c
AM
619 #define __NR_timer_getoverrun 264
620 #define __NR_timer_delete 265
621 #define __NR_timer_create 266
622-/* #define __NR_vserver 267 Reserved for VSERVER */
623+#define __NR_vserver 267
624 #define __NR_io_setup 268
625 #define __NR_io_destroy 269
626 #define __NR_io_submit 270
f19bd705
AM
627diff -NurpP --minimal linux-4.4.111/arch/sparc/kernel/systbls_32.S linux-4.4.111-vs2.3.9.1/arch/sparc/kernel/systbls_32.S
628--- linux-4.4.111/arch/sparc/kernel/systbls_32.S 2016-07-05 04:14:33.000000000 +0000
629+++ linux-4.4.111-vs2.3.9.1/arch/sparc/kernel/systbls_32.S 2018-01-09 16:36:21.000000000 +0000
50e68740 630@@ -70,7 +70,7 @@ sys_call_table:
a168f21d 631 /*250*/ .long sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_ni_syscall
50e68740
JR
632 /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
633 /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
634-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
635+/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
636 /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
637 /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
638 /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
f19bd705
AM
639diff -NurpP --minimal linux-4.4.111/arch/sparc/kernel/systbls_64.S linux-4.4.111-vs2.3.9.1/arch/sparc/kernel/systbls_64.S
640--- linux-4.4.111/arch/sparc/kernel/systbls_64.S 2016-07-05 04:14:33.000000000 +0000
641+++ linux-4.4.111-vs2.3.9.1/arch/sparc/kernel/systbls_64.S 2018-01-09 16:36:21.000000000 +0000
50e68740 642@@ -71,7 +71,7 @@ sys_call_table32:
b00e13aa 643 /*250*/ .word sys_mremap, compat_sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
644 .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
645 /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
646- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
647+ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
648 /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
649 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
b00e13aa 650 /*280*/ .word sys_tee, sys_add_key, sys_request_key, compat_sys_keyctl, compat_sys_openat
927ca606 651@@ -152,7 +152,7 @@ sys_call_table:
a168f21d 652 /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nis_syscall
50e68740
JR
653 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
654 /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
655- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
656+ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
657 /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
658 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
659 /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
f19bd705
AM
660diff -NurpP --minimal linux-4.4.111/arch/um/Kconfig.rest linux-4.4.111-vs2.3.9.1/arch/um/Kconfig.rest
661--- linux-4.4.111/arch/um/Kconfig.rest 2015-04-12 22:12:50.000000000 +0000
662+++ linux-4.4.111-vs2.3.9.1/arch/um/Kconfig.rest 2018-01-09 16:36:21.000000000 +0000
f6c5ef8b 663@@ -12,6 +12,8 @@ source "arch/um/Kconfig.net"
d33d7b00
AM
664
665 source "fs/Kconfig"
666
667+source "kernel/vserver/Kconfig"
668+
669 source "security/Kconfig"
670
671 source "crypto/Kconfig"
f19bd705
AM
672diff -NurpP --minimal linux-4.4.111/arch/x86/Kconfig linux-4.4.111-vs2.3.9.1/arch/x86/Kconfig
673--- linux-4.4.111/arch/x86/Kconfig 2018-01-11 07:57:08.000000000 +0000
674+++ linux-4.4.111-vs2.3.9.1/arch/x86/Kconfig 2018-01-09 16:36:21.000000000 +0000
927ca606 675@@ -2672,6 +2672,8 @@ source "fs/Kconfig"
e03b8c3c 676
d33d7b00 677 source "arch/x86/Kconfig.debug"
e03b8c3c
AM
678
679+source "kernel/vserver/Kconfig"
680+
681 source "security/Kconfig"
682
683 source "crypto/Kconfig"
f19bd705
AM
684diff -NurpP --minimal linux-4.4.111/arch/x86/entry/syscalls/syscall_32.tbl linux-4.4.111-vs2.3.9.1/arch/x86/entry/syscalls/syscall_32.tbl
685--- linux-4.4.111/arch/x86/entry/syscalls/syscall_32.tbl 2018-01-11 07:57:08.000000000 +0000
686+++ linux-4.4.111-vs2.3.9.1/arch/x86/entry/syscalls/syscall_32.tbl 2018-01-10 01:51:14.000000000 +0000
db55b927
AM
687@@ -279,7 +279,7 @@
688 270 i386 tgkill sys_tgkill
689 271 i386 utimes sys_utimes compat_sys_utimes
690 272 i386 fadvise64_64 sys_fadvise64_64 sys32_fadvise64_64
691-273 i386 vserver
692+273 i386 vserver sys_vserver sys32_vserver
693 274 i386 mbind sys_mbind
694 275 i386 get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy
695 276 i386 set_mempolicy sys_set_mempolicy
f19bd705
AM
696diff -NurpP --minimal linux-4.4.111/arch/x86/entry/syscalls/syscall_64.tbl linux-4.4.111-vs2.3.9.1/arch/x86/entry/syscalls/syscall_64.tbl
697--- linux-4.4.111/arch/x86/entry/syscalls/syscall_64.tbl 2016-07-05 04:14:33.000000000 +0000
698+++ linux-4.4.111-vs2.3.9.1/arch/x86/entry/syscalls/syscall_64.tbl 2018-01-10 01:51:32.000000000 +0000
db55b927 699@@ -242,7 +242,7 @@
1e8b8f9b
AM
700 233 common epoll_ctl sys_epoll_ctl
701 234 common tgkill sys_tgkill
702 235 common utimes sys_utimes
db55b927
AM
703-236 64 vserver
704+236 64 vserver sys_vserver
1e8b8f9b
AM
705 237 common mbind sys_mbind
706 238 common set_mempolicy sys_set_mempolicy
707 239 common get_mempolicy sys_get_mempolicy
f19bd705
AM
708diff -NurpP --minimal linux-4.4.111/block/ioprio.c linux-4.4.111-vs2.3.9.1/block/ioprio.c
709--- linux-4.4.111/block/ioprio.c 2018-01-11 07:57:12.000000000 +0000
710+++ linux-4.4.111-vs2.3.9.1/block/ioprio.c 2018-01-09 16:36:23.000000000 +0000
bb20add7
AM
711@@ -28,6 +28,7 @@
712 #include <linux/syscalls.h>
713 #include <linux/security.h>
714 #include <linux/pid_namespace.h>
715+#include <linux/vs_base.h>
716
717 int set_task_ioprio(struct task_struct *task, int ioprio)
718 {
719@@ -105,6 +106,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which,
720 else
721 pgrp = find_vpid(who);
722 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
723+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
724+ continue;
725 ret = set_task_ioprio(p, ioprio);
726 if (ret)
727 break;
927ca606 728@@ -203,6 +206,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which,
bb20add7
AM
729 else
730 pgrp = find_vpid(who);
731 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
732+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
733+ continue;
734 tmpio = get_task_ioprio(p);
735 if (tmpio < 0)
736 continue;
f19bd705
AM
737diff -NurpP --minimal linux-4.4.111/drivers/block/Kconfig linux-4.4.111-vs2.3.9.1/drivers/block/Kconfig
738--- linux-4.4.111/drivers/block/Kconfig 2016-07-05 04:14:35.000000000 +0000
739+++ linux-4.4.111-vs2.3.9.1/drivers/block/Kconfig 2018-01-09 16:36:23.000000000 +0000
bb20add7 740@@ -283,6 +283,13 @@ config BLK_DEV_CRYPTOLOOP
2bf5ad28
AM
741
742 source "drivers/block/drbd/Kconfig"
d337f35e
JR
743
744+config BLK_DEV_VROOT
745+ tristate "Virtual Root device support"
746+ depends on QUOTACTL
747+ ---help---
748+ Saying Y here will allow you to use quota/fs ioctls on a shared
749+ partition within a virtual server without compromising security.
750+
751 config BLK_DEV_NBD
752 tristate "Network block device support"
753 depends on NET
f19bd705
AM
754diff -NurpP --minimal linux-4.4.111/drivers/block/Makefile linux-4.4.111-vs2.3.9.1/drivers/block/Makefile
755--- linux-4.4.111/drivers/block/Makefile 2016-07-05 04:14:35.000000000 +0000
756+++ linux-4.4.111-vs2.3.9.1/drivers/block/Makefile 2018-01-09 16:36:23.000000000 +0000
927ca606 757@@ -32,6 +32,7 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
bb20add7 758
d33d7b00 759 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
d33d7b00
AM
760 obj-$(CONFIG_BLK_DEV_HD) += hd.o
761+obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
762
763 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
763640ca 764 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/
f19bd705
AM
765diff -NurpP --minimal linux-4.4.111/drivers/block/loop.c linux-4.4.111-vs2.3.9.1/drivers/block/loop.c
766--- linux-4.4.111/drivers/block/loop.c 2018-01-11 07:57:13.000000000 +0000
767+++ linux-4.4.111-vs2.3.9.1/drivers/block/loop.c 2018-01-09 23:00:25.000000000 +0000
927ca606 768@@ -76,6 +76,7 @@
a168f21d 769 #include <linux/miscdevice.h>
f6c5ef8b 770 #include <linux/falloc.h>
927ca606 771 #include <linux/uio.h>
d337f35e 772+#include <linux/vs_context.h>
c2e5f7c8 773 #include "loop.h"
f6c5ef8b 774
d337f35e 775 #include <asm/uaccess.h>
927ca606 776@@ -935,6 +936,7 @@ static int loop_set_fd(struct loop_devic
d337f35e
JR
777 lo->lo_blocksize = lo_blocksize;
778 lo->lo_device = bdev;
779 lo->lo_flags = lo_flags;
780+ lo->lo_xid = vx_current_xid();
781 lo->lo_backing_file = file;
927ca606 782 lo->transfer = NULL;
d337f35e 783 lo->ioctl = NULL;
927ca606
AM
784@@ -1055,6 +1057,7 @@ static int loop_clr_fd(struct loop_devic
785 lo->lo_offset = 0;
f6c5ef8b 786 lo->lo_sizelimit = 0;
2380c486 787 lo->lo_encrypt_key_size = 0;
2380c486
JR
788+ lo->lo_xid = 0;
789 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
790 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
791 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
927ca606 792@@ -1101,7 +1104,7 @@ loop_set_status(struct loop_device *lo,
2380c486 793
ec22aa5c 794 if (lo->lo_encrypt_key_size &&
537831f9 795 !uid_eq(lo->lo_key_owner, uid) &&
d337f35e
JR
796- !capable(CAP_SYS_ADMIN))
797+ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
798 return -EPERM;
799 if (lo->lo_state != Lo_bound)
800 return -ENXIO;
927ca606 801@@ -1202,7 +1205,8 @@ loop_get_status(struct loop_device *lo,
d337f35e
JR
802 memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
803 info->lo_encrypt_type =
804 lo->lo_encryption ? lo->lo_encryption->number : 0;
805- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
806+ if (lo->lo_encrypt_key_size &&
807+ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
808 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
809 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
810 lo->lo_encrypt_key_size);
927ca606 811@@ -1563,6 +1567,11 @@ static int lo_open(struct block_device *
a168f21d
AM
812 goto out;
813 }
d337f35e 814
dd5f3080 815+ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) {
816+ err = -EACCES;
817+ goto out;
818+ }
d337f35e 819+
927ca606
AM
820 atomic_inc(&lo->lo_refcnt);
821 out:
822 mutex_unlock(&loop_index_mutex);
f19bd705
AM
823diff -NurpP --minimal linux-4.4.111/drivers/block/loop.h linux-4.4.111-vs2.3.9.1/drivers/block/loop.h
824--- linux-4.4.111/drivers/block/loop.h 2016-07-05 04:14:35.000000000 +0000
825+++ linux-4.4.111-vs2.3.9.1/drivers/block/loop.h 2018-01-09 16:36:23.000000000 +0000
927ca606 826@@ -43,6 +43,7 @@ struct loop_device {
c2e5f7c8
JR
827 struct loop_func_table *lo_encryption;
828 __u32 lo_init[2];
829 kuid_t lo_key_owner; /* Who set the key */
830+ vxid_t lo_xid;
831 int (*ioctl)(struct loop_device *, int cmd,
832 unsigned long arg);
833
f19bd705
AM
834diff -NurpP --minimal linux-4.4.111/drivers/block/vroot.c linux-4.4.111-vs2.3.9.1/drivers/block/vroot.c
835--- linux-4.4.111/drivers/block/vroot.c 1970-01-01 00:00:00.000000000 +0000
836+++ linux-4.4.111-vs2.3.9.1/drivers/block/vroot.c 2018-01-11 07:37:22.000000000 +0000
837@@ -0,0 +1,291 @@
d337f35e
JR
838+/*
839+ * linux/drivers/block/vroot.c
840+ *
927ca606
AM
841+ * written by Herbert P?tzl, 9/11/2002
842+ * ported to 2.6.10 by Herbert P?tzl, 30/12/2004
d337f35e
JR
843+ *
844+ * based on the loop.c code by Theodore Ts'o.
845+ *
927ca606 846+ * Copyright (C) 2002-2007 by Herbert P?tzl.
d337f35e
JR
847+ * Redistribution of this file is permitted under the
848+ * GNU General Public License.
849+ *
850+ */
851+
852+#include <linux/module.h>
853+#include <linux/moduleparam.h>
854+#include <linux/file.h>
855+#include <linux/major.h>
856+#include <linux/blkdev.h>
76514441 857+#include <linux/slab.h>
d337f35e
JR
858+
859+#include <linux/vroot.h>
860+#include <linux/vs_context.h>
861+
862+
863+static int max_vroot = 8;
864+
865+static struct vroot_device *vroot_dev;
866+static struct gendisk **disks;
867+
868+
869+static int vroot_set_dev(
870+ struct vroot_device *vr,
d337f35e
JR
871+ struct block_device *bdev,
872+ unsigned int arg)
873+{
874+ struct block_device *real_bdev;
875+ struct file *file;
876+ struct inode *inode;
877+ int error;
878+
879+ error = -EBUSY;
880+ if (vr->vr_state != Vr_unbound)
881+ goto out;
882+
883+ error = -EBADF;
884+ file = fget(arg);
885+ if (!file)
886+ goto out;
887+
888+ error = -EINVAL;
927ca606 889+ inode = file->f_path.dentry->d_inode;
d337f35e
JR
890+
891+
892+ if (S_ISBLK(inode->i_mode)) {
893+ real_bdev = inode->i_bdev;
894+ vr->vr_device = real_bdev;
895+ __iget(real_bdev->bd_inode);
896+ } else
897+ goto out_fput;
898+
899+ vxdprintk(VXD_CBIT(misc, 0),
900+ "vroot[%d]_set_dev: dev=" VXF_DEV,
901+ vr->vr_number, VXD_DEV(real_bdev));
902+
903+ vr->vr_state = Vr_bound;
904+ error = 0;
905+
906+ out_fput:
907+ fput(file);
908+ out:
909+ return error;
910+}
911+
912+static int vroot_clr_dev(
913+ struct vroot_device *vr,
d337f35e
JR
914+ struct block_device *bdev)
915+{
916+ struct block_device *real_bdev;
917+
918+ if (vr->vr_state != Vr_bound)
919+ return -ENXIO;
920+ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
921+ return -EBUSY;
922+
923+ real_bdev = vr->vr_device;
924+
925+ vxdprintk(VXD_CBIT(misc, 0),
926+ "vroot[%d]_clr_dev: dev=" VXF_DEV,
927+ vr->vr_number, VXD_DEV(real_bdev));
928+
929+ bdput(real_bdev);
930+ vr->vr_state = Vr_unbound;
931+ vr->vr_device = NULL;
932+ return 0;
933+}
934+
935+
ec22aa5c 936+static int vr_ioctl(struct block_device *bdev, fmode_t mode,
d337f35e
JR
937+ unsigned int cmd, unsigned long arg)
938+{
ec22aa5c 939+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
940+ int err;
941+
942+ down(&vr->vr_ctl_mutex);
943+ switch (cmd) {
944+ case VROOT_SET_DEV:
ec22aa5c 945+ err = vroot_set_dev(vr, bdev, arg);
d337f35e
JR
946+ break;
947+ case VROOT_CLR_DEV:
ec22aa5c 948+ err = vroot_clr_dev(vr, bdev);
d337f35e
JR
949+ break;
950+ default:
951+ err = -EINVAL;
952+ break;
953+ }
954+ up(&vr->vr_ctl_mutex);
955+ return err;
956+}
957+
ec22aa5c 958+static int vr_open(struct block_device *bdev, fmode_t mode)
d337f35e 959+{
ec22aa5c 960+ struct vroot_device *vr = bdev->bd_disk->private_data;
d337f35e
JR
961+
962+ down(&vr->vr_ctl_mutex);
963+ vr->vr_refcnt++;
964+ up(&vr->vr_ctl_mutex);
965+ return 0;
966+}
967+
09be7631 968+static void vr_release(struct gendisk *disk, fmode_t mode)
d337f35e 969+{
ec22aa5c 970+ struct vroot_device *vr = disk->private_data;
d337f35e
JR
971+
972+ down(&vr->vr_ctl_mutex);
973+ --vr->vr_refcnt;
974+ up(&vr->vr_ctl_mutex);
d337f35e
JR
975+}
976+
977+static struct block_device_operations vr_fops = {
978+ .owner = THIS_MODULE,
979+ .open = vr_open,
980+ .release = vr_release,
981+ .ioctl = vr_ioctl,
982+};
983+
f19bd705 984+static blk_qc_t vroot_make_request(struct request_queue *q, struct bio *bio)
b3b0d4fd
AM
985+{
986+ printk("vroot_make_request %p, %p\n", q, bio);
987+ bio_io_error(bio);
f19bd705 988+ return BLK_QC_T_NONE;
b3b0d4fd
AM
989+}
990+
d337f35e
JR
991+struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
992+{
993+ struct inode *inode = bdev->bd_inode;
994+ struct vroot_device *vr;
995+ struct block_device *real_bdev;
996+ int minor = iminor(inode);
997+
998+ vr = &vroot_dev[minor];
999+ real_bdev = vr->vr_device;
1000+
1001+ vxdprintk(VXD_CBIT(misc, 0),
1002+ "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
1003+ vr->vr_number, VXD_DEV(real_bdev));
1004+
1005+ if (vr->vr_state != Vr_bound)
1006+ return ERR_PTR(-ENXIO);
1007+
1008+ __iget(real_bdev->bd_inode);
1009+ return real_bdev;
1010+}
1011+
b3b0d4fd
AM
1012+
1013+
d337f35e
JR
1014+/*
1015+ * And now the modules code and kernel interface.
1016+ */
1017+
1018+module_param(max_vroot, int, 0);
1019+
1020+MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
1021+MODULE_LICENSE("GPL");
1022+MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
1023+
927ca606 1024+MODULE_AUTHOR ("Herbert P?tzl");
d337f35e
JR
1025+MODULE_DESCRIPTION ("Virtual Root Device Mapper");
1026+
1027+
1028+int __init vroot_init(void)
1029+{
1030+ int err, i;
1031+
1032+ if (max_vroot < 1 || max_vroot > 256) {
1033+ max_vroot = MAX_VROOT_DEFAULT;
1034+ printk(KERN_WARNING "vroot: invalid max_vroot "
1035+ "(must be between 1 and 256), "
1036+ "using default (%d)\n", max_vroot);
1037+ }
1038+
1039+ if (register_blkdev(VROOT_MAJOR, "vroot"))
1040+ return -EIO;
1041+
1042+ err = -ENOMEM;
1043+ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
1044+ if (!vroot_dev)
1045+ goto out_mem1;
1046+ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
1047+
1048+ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
1049+ if (!disks)
1050+ goto out_mem2;
1051+
1052+ for (i = 0; i < max_vroot; i++) {
1053+ disks[i] = alloc_disk(1);
1054+ if (!disks[i])
1055+ goto out_mem3;
2380c486
JR
1056+ disks[i]->queue = blk_alloc_queue(GFP_KERNEL);
1057+ if (!disks[i]->queue)
1058+ goto out_mem3;
b3b0d4fd 1059+ blk_queue_make_request(disks[i]->queue, vroot_make_request);
d337f35e
JR
1060+ }
1061+
1062+ for (i = 0; i < max_vroot; i++) {
1063+ struct vroot_device *vr = &vroot_dev[i];
1064+ struct gendisk *disk = disks[i];
1065+
1066+ memset(vr, 0, sizeof(*vr));
5a9fc8e8 1067+ sema_init(&vr->vr_ctl_mutex, 1);
d337f35e
JR
1068+ vr->vr_number = i;
1069+ disk->major = VROOT_MAJOR;
1070+ disk->first_minor = i;
1071+ disk->fops = &vr_fops;
1072+ sprintf(disk->disk_name, "vroot%d", i);
1073+ disk->private_data = vr;
1074+ }
1075+
1076+ err = register_vroot_grb(&__vroot_get_real_bdev);
1077+ if (err)
1078+ goto out_mem3;
1079+
1080+ for (i = 0; i < max_vroot; i++)
1081+ add_disk(disks[i]);
1082+ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
1083+ return 0;
1084+
1085+out_mem3:
1086+ while (i--)
1087+ put_disk(disks[i]);
1088+ kfree(disks);
1089+out_mem2:
1090+ kfree(vroot_dev);
1091+out_mem1:
1092+ unregister_blkdev(VROOT_MAJOR, "vroot");
1093+ printk(KERN_ERR "vroot: ran out of memory\n");
1094+ return err;
1095+}
1096+
1097+void vroot_exit(void)
1098+{
1099+ int i;
1100+
1101+ if (unregister_vroot_grb(&__vroot_get_real_bdev))
1102+ printk(KERN_WARNING "vroot: cannot unregister grb\n");
1103+
1104+ for (i = 0; i < max_vroot; i++) {
1105+ del_gendisk(disks[i]);
1106+ put_disk(disks[i]);
1107+ }
2380c486 1108+ unregister_blkdev(VROOT_MAJOR, "vroot");
d337f35e
JR
1109+
1110+ kfree(disks);
1111+ kfree(vroot_dev);
1112+}
1113+
1114+module_init(vroot_init);
1115+module_exit(vroot_exit);
1116+
1117+#ifndef MODULE
1118+
1119+static int __init max_vroot_setup(char *str)
1120+{
1121+ max_vroot = simple_strtol(str, NULL, 0);
1122+ return 1;
1123+}
1124+
1125+__setup("max_vroot=", max_vroot_setup);
1126+
1127+#endif
1128+
f19bd705
AM
1129diff -NurpP --minimal linux-4.4.111/drivers/infiniband/core/addr.c linux-4.4.111-vs2.3.9.1/drivers/infiniband/core/addr.c
1130--- linux-4.4.111/drivers/infiniband/core/addr.c 2018-01-11 07:57:21.000000000 +0000
1131+++ linux-4.4.111-vs2.3.9.1/drivers/infiniband/core/addr.c 2018-01-09 16:49:06.000000000 +0000
927ca606 1132@@ -283,7 +283,7 @@ static int addr6_resolve(struct sockaddr
5dd10c98 1133
763640ca 1134 if (ipv6_addr_any(&fl6.saddr)) {
927ca606 1135 ret = ipv6_dev_get_saddr(addr->net, ip6_dst_idev(dst)->dev,
763640ca
JR
1136- &fl6.daddr, 0, &fl6.saddr);
1137+ &fl6.daddr, 0, &fl6.saddr, NULL);
5dd10c98
AM
1138 if (ret)
1139 goto put;
1140
f19bd705
AM
1141diff -NurpP --minimal linux-4.4.111/drivers/md/dm-ioctl.c linux-4.4.111-vs2.3.9.1/drivers/md/dm-ioctl.c
1142--- linux-4.4.111/drivers/md/dm-ioctl.c 2018-01-11 07:57:23.000000000 +0000
1143+++ linux-4.4.111-vs2.3.9.1/drivers/md/dm-ioctl.c 2018-01-09 16:36:23.000000000 +0000
3bac966d
AM
1144@@ -16,6 +16,7 @@
1145 #include <linux/dm-ioctl.h>
1146 #include <linux/hdreg.h>
1147 #include <linux/compat.h>
1148+#include <linux/vs_context.h>
1149
1150 #include <asm/uaccess.h>
1151
c2e5f7c8 1152@@ -114,7 +115,8 @@ static struct hash_cell *__get_name_cell
3bac966d
AM
1153 unsigned int h = hash_str(str);
1154
1155 list_for_each_entry (hc, _name_buckets + h, name_list)
1156- if (!strcmp(hc->name, str)) {
1157+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1158+ !strcmp(hc->name, str)) {
1159 dm_get(hc->md);
1160 return hc;
1161 }
c2e5f7c8 1162@@ -128,7 +130,8 @@ static struct hash_cell *__get_uuid_cell
3bac966d
AM
1163 unsigned int h = hash_str(str);
1164
1165 list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
1166- if (!strcmp(hc->uuid, str)) {
1167+ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) &&
1168+ !strcmp(hc->uuid, str)) {
1169 dm_get(hc->md);
1170 return hc;
1171 }
c2e5f7c8 1172@@ -139,13 +142,15 @@ static struct hash_cell *__get_uuid_cell
a168f21d
AM
1173 static struct hash_cell *__get_dev_cell(uint64_t dev)
1174 {
1175 struct mapped_device *md;
1176- struct hash_cell *hc;
1177+ struct hash_cell *hc = NULL;
1178
1179 md = dm_get_md(huge_decode_dev(dev));
1180 if (!md)
1181 return NULL;
1182
1183- hc = dm_get_mdptr(md);
1184+ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT))
1185+ hc = dm_get_mdptr(md);
1186+
1187 if (!hc) {
1188 dm_put(md);
1189 return NULL;
c2e5f7c8 1190@@ -467,6 +472,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
3bac966d
AM
1191
1192 static int remove_all(struct dm_ioctl *param, size_t param_size)
1193 {
1194+ if (!vx_check(0, VS_ADMIN))
1195+ return -EPERM;
1196+
c2e5f7c8 1197 dm_hash_remove_all(true, !!(param->flags & DM_DEFERRED_REMOVE), false);
3bac966d
AM
1198 param->data_size = 0;
1199 return 0;
c2e5f7c8 1200@@ -514,6 +522,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1201 */
1202 for (i = 0; i < NUM_BUCKETS; i++) {
1203 list_for_each_entry (hc, _name_buckets + i, name_list) {
1204+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1205+ continue;
1206 needed += sizeof(struct dm_name_list);
1207 needed += strlen(hc->name) + 1;
1208 needed += ALIGN_MASK;
c2e5f7c8 1209@@ -537,6 +547,8 @@ static int list_devices(struct dm_ioctl
3bac966d
AM
1210 */
1211 for (i = 0; i < NUM_BUCKETS; i++) {
1212 list_for_each_entry (hc, _name_buckets + i, name_list) {
1213+ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT))
1214+ continue;
1215 if (old_nl)
1216 old_nl->next = (uint32_t) ((void *) nl -
1217 (void *) old_nl);
927ca606 1218@@ -1801,8 +1813,8 @@ static int ctl_ioctl(uint command, struc
763640ca 1219 size_t input_param_size;
b00e13aa 1220 struct dm_ioctl param_kernel;
3bac966d
AM
1221
1222- /* only root can play with this */
1223- if (!capable(CAP_SYS_ADMIN))
1224+ /* only root and certain contexts can play with this */
1225+ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
1226 return -EACCES;
1227
1228 if (_IOC_TYPE(command) != DM_IOCTL)
f19bd705
AM
1229diff -NurpP --minimal linux-4.4.111/drivers/md/dm.c linux-4.4.111-vs2.3.9.1/drivers/md/dm.c
1230--- linux-4.4.111/drivers/md/dm.c 2018-01-11 07:57:23.000000000 +0000
1231+++ linux-4.4.111-vs2.3.9.1/drivers/md/dm.c 2018-01-09 16:49:30.000000000 +0000
927ca606
AM
1232@@ -25,6 +25,7 @@
1233 #include <linux/elevator.h> /* for rq_end_sector() */
1234 #include <linux/blk-mq.h>
1235 #include <linux/pr.h>
d33d7b00
AM
1236+#include <linux/vs_base.h>
1237
1238 #include <trace/events/block.h>
1239
927ca606 1240@@ -144,6 +145,7 @@ struct mapped_device {
c2e5f7c8 1241 struct mutex suspend_lock;
d33d7b00
AM
1242 atomic_t holders;
1243 atomic_t open_count;
61333608 1244+ vxid_t xid;
d33d7b00 1245
c2e5f7c8
JR
1246 /*
1247 * The current mapping.
927ca606 1248@@ -445,6 +447,7 @@ int dm_deleting_md(struct mapped_device
d33d7b00
AM
1249 static int dm_blk_open(struct block_device *bdev, fmode_t mode)
1250 {
1251 struct mapped_device *md;
1252+ int ret = -ENXIO;
1253
1254 spin_lock(&_minor_lock);
1255
927ca606 1256@@ -453,17 +456,19 @@ static int dm_blk_open(struct block_devi
d33d7b00
AM
1257 goto out;
1258
1259 if (test_bit(DMF_FREEING, &md->flags) ||
1260- dm_deleting_md(md)) {
1261- md = NULL;
1262+ dm_deleting_md(md))
1263+ goto out;
1264+
1265+ ret = -EACCES;
1266+ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID))
1267 goto out;
1268- }
1269
1270 dm_get(md);
1271 atomic_inc(&md->open_count);
d33d7b00
AM
1272+ ret = 0;
1273 out:
1274 spin_unlock(&_minor_lock);
1275-
1276- return md ? 0 : -ENXIO;
1277+ return ret;
1278 }
1279
09be7631 1280 static void dm_blk_close(struct gendisk *disk, fmode_t mode)
927ca606 1281@@ -909,6 +914,14 @@ int dm_set_geometry(struct mapped_device
d33d7b00
AM
1282 return 0;
1283 }
1284
1285+/*
1286+ * Get the xid associated with a dm device
1287+ */
61333608 1288+vxid_t dm_get_xid(struct mapped_device *md)
d33d7b00
AM
1289+{
1290+ return md->xid;
1291+}
1292+
1293 /*-----------------------------------------------------------------
1294 * CRUD START:
1295 * A more elegant soln is in the works that uses the queue
927ca606 1296@@ -2380,6 +2393,7 @@ static struct mapped_device *alloc_dev(i
bb20add7 1297 INIT_LIST_HEAD(&md->table_devices);
d33d7b00
AM
1298 spin_lock_init(&md->uevent_lock);
1299
1300+ md->xid = vx_current_xid();
1301 md->queue = blk_alloc_queue(GFP_KERNEL);
1302 if (!md->queue)
927ca606 1303 goto bad;
f19bd705
AM
1304diff -NurpP --minimal linux-4.4.111/drivers/md/dm.h linux-4.4.111-vs2.3.9.1/drivers/md/dm.h
1305--- linux-4.4.111/drivers/md/dm.h 2016-07-05 04:12:06.000000000 +0000
1306+++ linux-4.4.111-vs2.3.9.1/drivers/md/dm.h 2018-01-09 16:36:24.000000000 +0000
927ca606 1307@@ -52,6 +52,8 @@ struct dm_dev_internal {
d33d7b00
AM
1308 struct dm_table;
1309 struct dm_md_mempools;
1310
61333608 1311+vxid_t dm_get_xid(struct mapped_device *md);
d33d7b00
AM
1312+
1313 /*-----------------------------------------------------------------
1314 * Internal table functions.
1315 *---------------------------------------------------------------*/
f19bd705
AM
1316diff -NurpP --minimal linux-4.4.111/drivers/net/tun.c linux-4.4.111-vs2.3.9.1/drivers/net/tun.c
1317--- linux-4.4.111/drivers/net/tun.c 2018-01-11 07:57:30.000000000 +0000
1318+++ linux-4.4.111-vs2.3.9.1/drivers/net/tun.c 2018-01-09 16:36:24.000000000 +0000
c2e5f7c8 1319@@ -65,6 +65,7 @@
d33d7b00
AM
1320 #include <linux/nsproxy.h>
1321 #include <linux/virtio_net.h>
1322 #include <linux/rcupdate.h>
1323+#include <linux/vs_network.h>
1324 #include <net/net_namespace.h>
1325 #include <net/netns/generic.h>
927ca606
AM
1326 #include <net/rtnetlink.h>
1327@@ -181,6 +182,7 @@ struct tun_struct {
d33d7b00 1328 unsigned int flags;
537831f9
AM
1329 kuid_t owner;
1330 kgid_t group;
61333608 1331+ vnid_t nid;
d33d7b00
AM
1332
1333 struct net_device *dev;
db55b927 1334 netdev_features_t set_features;
927ca606 1335@@ -475,6 +477,7 @@ static inline bool tun_not_capable(struc
b00e13aa
AM
1336 return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1337 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1338 !ns_capable(net->user_ns, CAP_NET_ADMIN);
1339+ /* !cap_raised(current_cap(), CAP_NET_ADMIN) */
1340 }
1341
1342 static void tun_set_real_num_queues(struct tun_struct *tun)
927ca606 1343@@ -1463,6 +1466,7 @@ static void tun_setup(struct net_device
2380c486 1344
537831f9
AM
1345 tun->owner = INVALID_UID;
1346 tun->group = INVALID_GID;
1347+ tun->nid = nx_current_nid();
2380c486 1348
ec22aa5c
AM
1349 dev->ethtool_ops = &tun_ethtool_ops;
1350 dev->destructor = tun_free_netdev;
927ca606 1351@@ -1657,7 +1661,7 @@ static int tun_set_iff(struct net *net,
b00e13aa
AM
1352 int queues = ifr->ifr_flags & IFF_MULTI_QUEUE ?
1353 MAX_TAP_QUEUES : 1;
1354
1355- if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
c2e5f7c8 1356+ if (!nx_ns_capable(net->user_ns, CAP_NET_ADMIN, NXC_TUN_CREATE))
b00e13aa
AM
1357 return -EPERM;
1358 err = security_tun_dev_create();
1359 if (err < 0)
927ca606 1360@@ -2010,6 +2014,16 @@ static long __tun_chr_ioctl(struct file
537831f9 1361 from_kgid(&init_user_ns, tun->group));
2380c486 1362 break;
d337f35e 1363
2380c486
JR
1364+ case TUNSETNID:
1365+ if (!capable(CAP_CONTEXT))
1366+ return -EPERM;
d337f35e 1367+
2380c486 1368+ /* Set nid owner of the device */
61333608 1369+ tun->nid = (vnid_t) arg;
d337f35e 1370+
763640ca 1371+ tun_debug(KERN_INFO, tun, "nid owner set to %u\n", tun->nid);
2380c486 1372+ break;
d337f35e 1373+
2380c486
JR
1374 case TUNSETLINK:
1375 /* Only allow setting the type when the interface is down */
ec22aa5c 1376 if (tun->dev->flags & IFF_UP) {
f19bd705
AM
1377diff -NurpP --minimal linux-4.4.111/drivers/scsi/cxgbi/libcxgbi.c linux-4.4.111-vs2.3.9.1/drivers/scsi/cxgbi/libcxgbi.c
1378--- linux-4.4.111/drivers/scsi/cxgbi/libcxgbi.c 2015-10-29 09:21:24.000000000 +0000
1379+++ linux-4.4.111-vs2.3.9.1/drivers/scsi/cxgbi/libcxgbi.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1380@@ -768,7 +768,8 @@ static struct cxgbi_sock *cxgbi_check_ro
bb20add7
AM
1381 struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
1382
1383 err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
1384- &daddr6->sin6_addr, 0, &pref_saddr);
1385+ &daddr6->sin6_addr, 0, &pref_saddr,
1386+ NULL);
1387 if (err) {
1388 pr_info("failed to get source address to reach %pI6\n",
1389 &daddr6->sin6_addr);
f19bd705
AM
1390diff -NurpP --minimal linux-4.4.111/drivers/tty/sysrq.c linux-4.4.111-vs2.3.9.1/drivers/tty/sysrq.c
1391--- linux-4.4.111/drivers/tty/sysrq.c 2018-01-11 07:57:38.000000000 +0000
1392+++ linux-4.4.111-vs2.3.9.1/drivers/tty/sysrq.c 2018-01-09 16:36:24.000000000 +0000
bb20add7 1393@@ -47,6 +47,7 @@
c2e5f7c8
JR
1394 #include <linux/syscalls.h>
1395 #include <linux/of.h>
bb20add7 1396 #include <linux/rcupdate.h>
ab30d09f
AM
1397+#include <linux/vserver/debug.h>
1398
1399 #include <asm/ptrace.h>
1400 #include <asm/irq_regs.h>
927ca606 1401@@ -421,6 +422,21 @@ static struct sysrq_key_op sysrq_unrt_op
ab30d09f
AM
1402 .enable_mask = SYSRQ_ENABLE_RTNICE,
1403 };
1404
1405+
1406+#ifdef CONFIG_VSERVER_DEBUG
1407+static void sysrq_handle_vxinfo(int key)
1408+{
1409+ dump_vx_info_inactive((key == 'x') ? 0 : 1);
1410+}
1411+
1412+static struct sysrq_key_op sysrq_showvxinfo_op = {
1413+ .handler = sysrq_handle_vxinfo,
1414+ .help_msg = "conteXt",
1415+ .action_msg = "Show Context Info",
1416+ .enable_mask = SYSRQ_ENABLE_DUMP,
1417+};
1418+#endif
1419+
1420 /* Key Operations table and lock */
1421 static DEFINE_SPINLOCK(sysrq_key_table_lock);
1422
927ca606
AM
1423@@ -477,7 +493,11 @@ static struct sysrq_key_op *sysrq_key_ta
1424 /* x: May be registered on mips for TLB dump */
ab30d09f 1425 /* x: May be registered on ppc/powerpc for xmon */
537831f9 1426 /* x: May be registered on sparc64 for global PMU dump */
ab30d09f
AM
1427+#ifdef CONFIG_VSERVER_DEBUG
1428+ &sysrq_showvxinfo_op, /* x */
1429+#else
4bf69007 1430 NULL, /* x */
ab30d09f
AM
1431+#endif
1432 /* y: May be registered on sparc64 for global register dump */
1433 NULL, /* y */
1434 &sysrq_ftrace_dump_op, /* z */
927ca606 1435@@ -492,6 +512,8 @@ static int sysrq_key_table_key2index(int
ab30d09f
AM
1436 retval = key - '0';
1437 else if ((key >= 'a') && (key <= 'z'))
1438 retval = key + 10 - 'a';
1439+ else if ((key >= 'A') && (key <= 'Z'))
1440+ retval = key + 10 - 'A';
1441 else
1442 retval = -1;
1443 return retval;
f19bd705
AM
1444diff -NurpP --minimal linux-4.4.111/drivers/tty/tty_io.c linux-4.4.111-vs2.3.9.1/drivers/tty/tty_io.c
1445--- linux-4.4.111/drivers/tty/tty_io.c 2018-01-11 07:57:38.000000000 +0000
1446+++ linux-4.4.111-vs2.3.9.1/drivers/tty/tty_io.c 2018-01-09 16:36:24.000000000 +0000
1e8b8f9b 1447@@ -104,6 +104,7 @@
ab30d09f
AM
1448
1449 #include <linux/kmod.h>
1450 #include <linux/nsproxy.h>
1451+#include <linux/vs_pid.h>
1452
1453 #undef TTY_DEBUG_HANGUP
927ca606
AM
1454 #ifdef TTY_DEBUG_HANGUP
1455@@ -2280,7 +2281,8 @@ static int tiocsti(struct tty_struct *tt
ab30d09f
AM
1456 char ch, mbz = 0;
1457 struct tty_ldisc *ld;
1458
1459- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
1460+ if (((current->signal->tty != tty) &&
1461+ !vx_capable(CAP_SYS_ADMIN, VXC_TIOCSTI)))
1462 return -EPERM;
1463 if (get_user(ch, p))
1464 return -EFAULT;
927ca606 1465@@ -2593,6 +2595,7 @@ static int tiocspgrp(struct tty_struct *
ab30d09f
AM
1466 return -ENOTTY;
1467 if (get_user(pgrp_nr, p))
1468 return -EFAULT;
1469+ pgrp_nr = vx_rmap_pid(pgrp_nr);
1470 if (pgrp_nr < 0)
1471 return -EINVAL;
1472 rcu_read_lock();
f19bd705
AM
1473diff -NurpP --minimal linux-4.4.111/fs/attr.c linux-4.4.111-vs2.3.9.1/fs/attr.c
1474--- linux-4.4.111/fs/attr.c 2018-01-11 07:57:43.000000000 +0000
1475+++ linux-4.4.111-vs2.3.9.1/fs/attr.c 2018-01-09 17:27:12.000000000 +0000
537831f9 1476@@ -15,6 +15,9 @@
d337f35e 1477 #include <linux/security.h>
f6c5ef8b 1478 #include <linux/evm.h>
537831f9 1479 #include <linux/ima.h>
d337f35e
JR
1480+#include <linux/proc_fs.h>
1481+#include <linux/devpts_fs.h>
2380c486 1482+#include <linux/vs_tag.h>
d337f35e 1483
93de0823
AM
1484 /**
1485 * inode_change_ok - check if attribute changes to an inode are allowed
b00e13aa 1486@@ -77,6 +80,10 @@ int inode_change_ok(const struct inode *
93de0823 1487 return -EPERM;
d337f35e 1488 }
93de0823
AM
1489
1490+ /* check for inode tag permission */
2380c486 1491+ if (dx_permission(inode, MAY_WRITE))
93de0823 1492+ return -EACCES;
2380c486 1493+
93de0823
AM
1494 return 0;
1495 }
1496 EXPORT_SYMBOL(inode_change_ok);
b00e13aa 1497@@ -147,6 +154,8 @@ void setattr_copy(struct inode *inode, c
d337f35e
JR
1498 inode->i_uid = attr->ia_uid;
1499 if (ia_valid & ATTR_GID)
1500 inode->i_gid = attr->ia_gid;
1501+ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
1502+ inode->i_tag = attr->ia_tag;
1503 if (ia_valid & ATTR_ATIME)
1504 inode->i_atime = timespec_trunc(attr->ia_atime,
1505 inode->i_sb->s_time_gran);
c2e5f7c8 1506@@ -197,7 +206,8 @@ int notify_change(struct dentry * dentry
92598135
AM
1507
1508 WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
78865d5b
AM
1509
1510- if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
1511+ if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
1512+ ATTR_TAG | ATTR_TIMES_SET)) {
1513 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
1514 return -EPERM;
1515 }
f19bd705
AM
1516diff -NurpP --minimal linux-4.4.111/fs/block_dev.c linux-4.4.111-vs2.3.9.1/fs/block_dev.c
1517--- linux-4.4.111/fs/block_dev.c 2018-01-11 07:57:43.000000000 +0000
1518+++ linux-4.4.111-vs2.3.9.1/fs/block_dev.c 2018-01-09 17:16:29.000000000 +0000
927ca606 1519@@ -29,6 +29,7 @@
2380c486 1520 #include <linux/log2.h>
db55b927 1521 #include <linux/cleancache.h>
927ca606 1522 #include <linux/dax.h>
2380c486
JR
1523+#include <linux/vs_device.h>
1524 #include <asm/uaccess.h>
1525 #include "internal.h"
1526
927ca606 1527@@ -645,6 +646,7 @@ struct block_device *bdget(dev_t dev)
2380c486
JR
1528 bdev->bd_invalidated = 0;
1529 inode->i_mode = S_IFBLK;
1530 inode->i_rdev = dev;
1531+ inode->i_mdev = dev;
1532 inode->i_bdev = bdev;
1533 inode->i_data.a_ops = &def_blk_aops;
1534 mapping_set_gfp_mask(&inode->i_data, GFP_USER);
927ca606 1535@@ -691,6 +693,11 @@ EXPORT_SYMBOL(bdput);
2380c486
JR
1536 static struct block_device *bd_acquire(struct inode *inode)
1537 {
1538 struct block_device *bdev;
1539+ dev_t mdev;
1540+
1541+ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN))
1542+ return NULL;
1543+ inode->i_mdev = mdev;
1544
1545 spin_lock(&bdev_lock);
1546 bdev = inode->i_bdev;
927ca606 1547@@ -701,7 +708,7 @@ static struct block_device *bd_acquire(s
2380c486
JR
1548 }
1549 spin_unlock(&bdev_lock);
1550
1551- bdev = bdget(inode->i_rdev);
1552+ bdev = bdget(mdev);
1553 if (bdev) {
1554 spin_lock(&bdev_lock);
1555 if (!inode->i_bdev) {
f19bd705
AM
1556diff -NurpP --minimal linux-4.4.111/fs/btrfs/ctree.h linux-4.4.111-vs2.3.9.1/fs/btrfs/ctree.h
1557--- linux-4.4.111/fs/btrfs/ctree.h 2018-01-11 07:57:43.000000000 +0000
1558+++ linux-4.4.111-vs2.3.9.1/fs/btrfs/ctree.h 2018-01-09 16:36:24.000000000 +0000
927ca606 1559@@ -731,11 +731,14 @@ struct btrfs_inode_item {
e22b5178
AM
1560 /* modification sequence number for NFS */
1561 __le64 sequence;
1562
1563+ __le16 tag;
1564 /*
1565 * a little future expansion, for more than this we can
1566 * just grow the inode item and version it
1567 */
1568- __le64 reserved[4];
1569+ __le16 reserved16;
1570+ __le32 reserved32;
1571+ __le64 reserved[3];
1572 struct btrfs_timespec atime;
1573 struct btrfs_timespec ctime;
1574 struct btrfs_timespec mtime;
927ca606 1575@@ -2189,6 +2192,8 @@ struct btrfs_ioctl_defrag_range_args {
c2e5f7c8 1576 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
bb20add7 1577 #define BTRFS_DEFAULT_MAX_INLINE (8192)
e22b5178
AM
1578
1579+#define BTRFS_MOUNT_TAGGED (1 << 24)
1580+
1581 #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1582 #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
b00e13aa 1583 #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt)
927ca606 1584@@ -2528,6 +2533,7 @@ BTRFS_SETGET_FUNCS(inode_block_group, st
e22b5178
AM
1585 BTRFS_SETGET_FUNCS(inode_nlink, struct btrfs_inode_item, nlink, 32);
1586 BTRFS_SETGET_FUNCS(inode_uid, struct btrfs_inode_item, uid, 32);
1587 BTRFS_SETGET_FUNCS(inode_gid, struct btrfs_inode_item, gid, 32);
1588+BTRFS_SETGET_FUNCS(inode_tag, struct btrfs_inode_item, tag, 16);
1589 BTRFS_SETGET_FUNCS(inode_mode, struct btrfs_inode_item, mode, 32);
1590 BTRFS_SETGET_FUNCS(inode_rdev, struct btrfs_inode_item, rdev, 64);
1591 BTRFS_SETGET_FUNCS(inode_flags, struct btrfs_inode_item, flags, 64);
927ca606 1592@@ -2575,6 +2581,10 @@ BTRFS_SETGET_FUNCS(extent_flags, struct
78865d5b
AM
1593
1594 BTRFS_SETGET_FUNCS(extent_refs_v0, struct btrfs_extent_item_v0, refs, 32);
1595
1596+#define BTRFS_INODE_IXUNLINK (1 << 24)
1597+#define BTRFS_INODE_BARRIER (1 << 25)
1598+#define BTRFS_INODE_COW (1 << 26)
1599+
1600
1601 BTRFS_SETGET_FUNCS(tree_block_level, struct btrfs_tree_block_info, level, 8);
1602
927ca606 1603@@ -4022,6 +4032,7 @@ long btrfs_ioctl(struct file *file, unsi
d4263eb0
JR
1604 void btrfs_update_iflags(struct inode *inode);
1605 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
c2e5f7c8 1606 int btrfs_is_empty_uuid(u8 *uuid);
d4263eb0 1607+int btrfs_sync_flags(struct inode *inode, int, int);
763640ca
JR
1608 int btrfs_defrag_file(struct inode *inode, struct file *file,
1609 struct btrfs_ioctl_defrag_range_args *range,
1610 u64 newer_than, unsigned long max_pages);
f19bd705
AM
1611diff -NurpP --minimal linux-4.4.111/fs/btrfs/disk-io.c linux-4.4.111-vs2.3.9.1/fs/btrfs/disk-io.c
1612--- linux-4.4.111/fs/btrfs/disk-io.c 2018-01-11 07:57:43.000000000 +0000
1613+++ linux-4.4.111-vs2.3.9.1/fs/btrfs/disk-io.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1614@@ -2736,6 +2736,9 @@ int open_ctree(struct super_block *sb,
763640ca 1615 goto fail_alloc;
e22b5178
AM
1616 }
1617
1618+ if (btrfs_test_opt(tree_root, TAGGED))
1619+ sb->s_flags |= MS_TAGGED;
1620+
1621 features = btrfs_super_incompat_flags(disk_super) &
1622 ~BTRFS_FEATURE_INCOMPAT_SUPP;
1623 if (features) {
f19bd705
AM
1624diff -NurpP --minimal linux-4.4.111/fs/btrfs/inode.c linux-4.4.111-vs2.3.9.1/fs/btrfs/inode.c
1625--- linux-4.4.111/fs/btrfs/inode.c 2018-01-11 07:57:43.000000000 +0000
1626+++ linux-4.4.111-vs2.3.9.1/fs/btrfs/inode.c 2018-01-09 16:36:24.000000000 +0000
c2e5f7c8 1627@@ -43,6 +43,7 @@
b00e13aa 1628 #include <linux/blkdev.h>
c2e5f7c8 1629 #include <linux/posix_acl_xattr.h>
927ca606 1630 #include <linux/uio.h>
e22b5178 1631+#include <linux/vs_tag.h>
e22b5178
AM
1632 #include "ctree.h"
1633 #include "disk-io.h"
c2e5f7c8 1634 #include "transaction.h"
927ca606 1635@@ -3611,6 +3612,9 @@ static void btrfs_read_locked_inode(stru
bb20add7 1636 unsigned long ptr;
e22b5178 1637 int maybe_acls;
e22b5178 1638 u32 rdev;
a4a22af8
AM
1639+ kuid_t kuid;
1640+ kgid_t kgid;
1641+ ktag_t ktag;
e22b5178 1642 int ret;
763640ca 1643 bool filled = false;
bb20add7 1644 int first_xattr_slot;
927ca606 1645@@ -3638,8 +3642,14 @@ static void btrfs_read_locked_inode(stru
a168f21d 1646 struct btrfs_inode_item);
e22b5178 1647 inode->i_mode = btrfs_inode_mode(leaf, inode_item);
f6c5ef8b 1648 set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
537831f9
AM
1649- i_uid_write(inode, btrfs_inode_uid(leaf, inode_item));
1650- i_gid_write(inode, btrfs_inode_gid(leaf, inode_item));
e22b5178 1651+
a4a22af8
AM
1652+ kuid = make_kuid(&init_user_ns, btrfs_inode_uid(leaf, inode_item));
1653+ kgid = make_kgid(&init_user_ns, btrfs_inode_gid(leaf, inode_item));
1654+ ktag = make_ktag(&init_user_ns, btrfs_inode_tag(leaf, inode_item));
1655+
1656+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
1657+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
1658+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
e22b5178
AM
1659 btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
1660
927ca606
AM
1661 inode->i_atime.tv_sec = btrfs_timespec_sec(leaf, &inode_item->atime);
1662@@ -3795,11 +3805,18 @@ static void fill_inode_item(struct btrfs
e22b5178
AM
1663 struct inode *inode)
1664 {
b00e13aa 1665 struct btrfs_map_token token;
a4a22af8
AM
1666+ uid_t uid = from_kuid(&init_user_ns,
1667+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
1668+ gid_t gid = from_kgid(&init_user_ns,
1669+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
b00e13aa
AM
1670
1671 btrfs_init_map_token(&token);
1672
1673- btrfs_set_token_inode_uid(leaf, item, i_uid_read(inode), &token);
1674- btrfs_set_token_inode_gid(leaf, item, i_gid_read(inode), &token);
1675+ btrfs_set_token_inode_uid(leaf, item, uid, &token);
1676+ btrfs_set_token_inode_gid(leaf, item, gid, &token);
e22b5178 1677+#ifdef CONFIG_TAGGING_INTERN
b00e13aa 1678+ btrfs_set_token_inode_tag(leaf, item, i_tag_read(inode), &token);
e22b5178 1679+#endif
b00e13aa
AM
1680 btrfs_set_token_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size,
1681 &token);
1682 btrfs_set_token_inode_mode(leaf, item, inode->i_mode, &token);
927ca606 1683@@ -10062,6 +10079,7 @@ static const struct inode_operations btr
d4263eb0
JR
1684 .listxattr = btrfs_listxattr,
1685 .removexattr = btrfs_removexattr,
d4263eb0
JR
1686 .permission = btrfs_permission,
1687+ .sync_flags = btrfs_sync_flags,
a168f21d 1688 .get_acl = btrfs_get_acl,
f15949f2 1689 .set_acl = btrfs_set_acl,
c2e5f7c8 1690 .update_time = btrfs_update_time,
927ca606 1691@@ -10070,6 +10088,7 @@ static const struct inode_operations btr
7e46296a 1692 static const struct inode_operations btrfs_dir_ro_inode_operations = {
d4263eb0 1693 .lookup = btrfs_lookup,
d4263eb0 1694 .permission = btrfs_permission,
d4263eb0 1695+ .sync_flags = btrfs_sync_flags,
a168f21d 1696 .get_acl = btrfs_get_acl,
f15949f2 1697 .set_acl = btrfs_set_acl,
c2e5f7c8 1698 .update_time = btrfs_update_time,
927ca606 1699@@ -10140,6 +10159,7 @@ static const struct inode_operations btr
c2e5f7c8
JR
1700 .removexattr = btrfs_removexattr,
1701 .permission = btrfs_permission,
1702 .fiemap = btrfs_fiemap,
1703+ .sync_flags = btrfs_sync_flags,
1704 .get_acl = btrfs_get_acl,
bb20add7 1705 .set_acl = btrfs_set_acl,
c2e5f7c8 1706 .update_time = btrfs_update_time,
f19bd705
AM
1707diff -NurpP --minimal linux-4.4.111/fs/btrfs/ioctl.c linux-4.4.111-vs2.3.9.1/fs/btrfs/ioctl.c
1708--- linux-4.4.111/fs/btrfs/ioctl.c 2018-01-11 07:57:43.000000000 +0000
1709+++ linux-4.4.111-vs2.3.9.1/fs/btrfs/ioctl.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1710@@ -108,10 +108,13 @@ static unsigned int btrfs_flags_to_ioctl
d4263eb0
JR
1711 {
1712 unsigned int iflags = 0;
1713
1714- if (flags & BTRFS_INODE_SYNC)
1715- iflags |= FS_SYNC_FL;
1716 if (flags & BTRFS_INODE_IMMUTABLE)
1717 iflags |= FS_IMMUTABLE_FL;
1718+ if (flags & BTRFS_INODE_IXUNLINK)
1719+ iflags |= FS_IXUNLINK_FL;
1720+
1721+ if (flags & BTRFS_INODE_SYNC)
1722+ iflags |= FS_SYNC_FL;
1723 if (flags & BTRFS_INODE_APPEND)
1724 iflags |= FS_APPEND_FL;
1725 if (flags & BTRFS_INODE_NODUMP)
927ca606 1726@@ -128,34 +131,84 @@ static unsigned int btrfs_flags_to_ioctl
763640ca
JR
1727 else if (flags & BTRFS_INODE_NOCOMPRESS)
1728 iflags |= FS_NOCOMP_FL;
d4263eb0
JR
1729
1730+ if (flags & BTRFS_INODE_BARRIER)
1731+ iflags |= FS_BARRIER_FL;
1732+ if (flags & BTRFS_INODE_COW)
1733+ iflags |= FS_COW_FL;
1734 return iflags;
1735 }
1736
1737 /*
1738- * Update inode->i_flags based on the btrfs internal flags.
1739+ * Update inode->i_(v)flags based on the btrfs internal flags.
1740 */
1741 void btrfs_update_iflags(struct inode *inode)
1742 {
1743 struct btrfs_inode *ip = BTRFS_I(inode);
bb20add7 1744 unsigned int new_fl = 0;
d4263eb0
JR
1745
1746- if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1747- new_fl |= S_SYNC;
d4263eb0 1748 if (ip->flags & BTRFS_INODE_IMMUTABLE)
bb20add7 1749 new_fl |= S_IMMUTABLE;
d4263eb0 1750+ if (ip->flags & BTRFS_INODE_IXUNLINK)
bb20add7 1751+ new_fl |= S_IXUNLINK;
d4263eb0
JR
1752+
1753+ if (ip->flags & BTRFS_INODE_SYNC)
bb20add7 1754+ new_fl |= S_SYNC;
d4263eb0 1755 if (ip->flags & BTRFS_INODE_APPEND)
bb20add7 1756 new_fl |= S_APPEND;
d4263eb0 1757 if (ip->flags & BTRFS_INODE_NOATIME)
bb20add7 1758 new_fl |= S_NOATIME;
d4263eb0 1759 if (ip->flags & BTRFS_INODE_DIRSYNC)
bb20add7
AM
1760 new_fl |= S_DIRSYNC;
1761-
1762 set_mask_bits(&inode->i_flags,
1763- S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
1764+ S_SYNC | S_APPEND | S_IMMUTABLE | S_IXUNLINK | S_NOATIME | S_DIRSYNC,
1765 new_fl);
d4263eb0 1766+
bb20add7 1767+ new_fl = 0;
d4263eb0 1768+ if (ip->flags & BTRFS_INODE_BARRIER)
bb20add7 1769+ new_fl |= V_BARRIER;
d4263eb0 1770+ if (ip->flags & BTRFS_INODE_COW)
bb20add7 1771+ new_fl |= V_COW;
d4263eb0 1772+
bb20add7
AM
1773+ set_mask_bits(&inode->i_vflags,
1774+ V_BARRIER | V_COW, new_fl);
1775 }
1776
1777 /*
d4263eb0
JR
1778+ * Update btrfs internal flags from inode->i_(v)flags.
1779+ */
1780+void btrfs_update_flags(struct inode *inode)
1781+{
1782+ struct btrfs_inode *ip = BTRFS_I(inode);
1783+
1784+ unsigned int flags = inode->i_flags;
1785+ unsigned int vflags = inode->i_vflags;
1786+
1787+ ip->flags &= ~(BTRFS_INODE_SYNC | BTRFS_INODE_APPEND |
1788+ BTRFS_INODE_IMMUTABLE | BTRFS_INODE_IXUNLINK |
1789+ BTRFS_INODE_NOATIME | BTRFS_INODE_DIRSYNC |
1790+ BTRFS_INODE_BARRIER | BTRFS_INODE_COW);
1791+
1792+ if (flags & S_IMMUTABLE)
1793+ ip->flags |= BTRFS_INODE_IMMUTABLE;
1794+ if (flags & S_IXUNLINK)
1795+ ip->flags |= BTRFS_INODE_IXUNLINK;
1796+
1797+ if (flags & S_SYNC)
1798+ ip->flags |= BTRFS_INODE_SYNC;
1799+ if (flags & S_APPEND)
1800+ ip->flags |= BTRFS_INODE_APPEND;
1801+ if (flags & S_NOATIME)
1802+ ip->flags |= BTRFS_INODE_NOATIME;
1803+ if (flags & S_DIRSYNC)
1804+ ip->flags |= BTRFS_INODE_DIRSYNC;
1805+
1806+ if (vflags & V_BARRIER)
1807+ ip->flags |= BTRFS_INODE_BARRIER;
1808+ if (vflags & V_COW)
1809+ ip->flags |= BTRFS_INODE_COW;
bb20add7
AM
1810+ }
1811+
1812+/*
1813 * Inherit flags from the parent inode.
1814 *
1815 * Currently only the compression flags and the cow flags are inherited.
927ca606 1816@@ -168,6 +221,7 @@ void btrfs_inherit_iflags(struct inode *
f6c5ef8b 1817 return;
d4263eb0 1818
f6c5ef8b
AM
1819 flags = BTRFS_I(dir)->flags;
1820+ flags &= ~BTRFS_INODE_BARRIER;
d4263eb0 1821
f6c5ef8b
AM
1822 if (flags & BTRFS_INODE_NOCOMPRESS) {
1823 BTRFS_I(inode)->flags &= ~BTRFS_INODE_COMPRESS;
927ca606 1824@@ -186,6 +240,30 @@ void btrfs_inherit_iflags(struct inode *
d4263eb0
JR
1825 btrfs_update_iflags(inode);
1826 }
1827
1828+int btrfs_sync_flags(struct inode *inode, int flags, int vflags)
1829+{
1830+ struct btrfs_inode *ip = BTRFS_I(inode);
1831+ struct btrfs_root *root = ip->root;
1832+ struct btrfs_trans_handle *trans;
1833+ int ret;
1834+
763640ca 1835+ trans = btrfs_join_transaction(root);
d4263eb0
JR
1836+ BUG_ON(!trans);
1837+
d4263eb0
JR
1838+ inode->i_flags = flags;
1839+ inode->i_vflags = vflags;
1840+ btrfs_update_flags(inode);
e22b5178
AM
1841+
1842+ ret = btrfs_update_inode(trans, root, inode);
1843+ BUG_ON(ret);
1844+
1845+ btrfs_update_iflags(inode);
d4263eb0
JR
1846+ inode->i_ctime = CURRENT_TIME;
1847+ btrfs_end_transaction(trans, root);
1848+
1849+ return 0;
1850+}
1851+
1852 static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
1853 {
b00e13aa 1854 struct btrfs_inode *ip = BTRFS_I(file_inode(file));
927ca606 1855@@ -248,21 +326,27 @@ static int btrfs_ioctl_setflags(struct f
d4263eb0
JR
1856
1857 flags = btrfs_mask_flags(inode->i_mode, flags);
1858 oldflags = btrfs_flags_to_ioctl(ip->flags);
1859- if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
1860+ if ((flags ^ oldflags) & (FS_APPEND_FL |
1861+ FS_IMMUTABLE_FL | FS_IXUNLINK_FL)) {
1862 if (!capable(CAP_LINUX_IMMUTABLE)) {
1863 ret = -EPERM;
1864 goto out_unlock;
92598135
AM
1865 }
1866 }
d4263eb0
JR
1867
1868- if (flags & FS_SYNC_FL)
1869- ip->flags |= BTRFS_INODE_SYNC;
1870- else
1871- ip->flags &= ~BTRFS_INODE_SYNC;
1872 if (flags & FS_IMMUTABLE_FL)
1873 ip->flags |= BTRFS_INODE_IMMUTABLE;
1874 else
1875 ip->flags &= ~BTRFS_INODE_IMMUTABLE;
1876+ if (flags & FS_IXUNLINK_FL)
1877+ ip->flags |= BTRFS_INODE_IXUNLINK;
1878+ else
1879+ ip->flags &= ~BTRFS_INODE_IXUNLINK;
1880+
1881+ if (flags & FS_SYNC_FL)
1882+ ip->flags |= BTRFS_INODE_SYNC;
1883+ else
1884+ ip->flags &= ~BTRFS_INODE_SYNC;
1885 if (flags & FS_APPEND_FL)
1886 ip->flags |= BTRFS_INODE_APPEND;
1887 else
f19bd705
AM
1888diff -NurpP --minimal linux-4.4.111/fs/btrfs/super.c linux-4.4.111-vs2.3.9.1/fs/btrfs/super.c
1889--- linux-4.4.111/fs/btrfs/super.c 2018-01-11 07:57:43.000000000 +0000
1890+++ linux-4.4.111-vs2.3.9.1/fs/btrfs/super.c 2018-01-09 17:25:27.000000000 +0000
927ca606
AM
1891@@ -306,7 +306,7 @@ enum {
1892 #ifdef CONFIG_BTRFS_DEBUG
1893 Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
1894 #endif
db55b927 1895- Opt_err,
f6c5ef8b 1896+ Opt_tag, Opt_notag, Opt_tagid, Opt_err,
e22b5178
AM
1897 };
1898
1899 static match_table_t tokens = {
927ca606
AM
1900@@ -363,6 +363,9 @@ static match_table_t tokens = {
1901 {Opt_fragment_metadata, "fragment=metadata"},
1902 {Opt_fragment_all, "fragment=all"},
1903 #endif
e22b5178
AM
1904+ {Opt_tag, "tag"},
1905+ {Opt_notag, "notag"},
1906+ {Opt_tagid, "tagid=%u"},
1907 {Opt_err, NULL},
1908 };
1909
927ca606
AM
1910@@ -745,6 +748,22 @@ int btrfs_parse_options(struct btrfs_roo
1911 btrfs_set_opt(info->mount_opt, FRAGMENT_DATA);
1e8b8f9b 1912 break;
927ca606 1913 #endif
e22b5178
AM
1914+#ifndef CONFIG_TAGGING_NONE
1915+ case Opt_tag:
1916+ printk(KERN_INFO "btrfs: use tagging\n");
1917+ btrfs_set_opt(info->mount_opt, TAGGED);
1918+ break;
1919+ case Opt_notag:
1920+ printk(KERN_INFO "btrfs: disabled tagging\n");
1921+ btrfs_clear_opt(info->mount_opt, TAGGED);
1922+ break;
1923+#endif
1924+#ifdef CONFIG_PROPAGATE
1925+ case Opt_tagid:
1926+ /* use args[0] */
1927+ btrfs_set_opt(info->mount_opt, TAGGED);
1928+ break;
1929+#endif
2bf5ad28 1930 case Opt_err:
bb20add7
AM
1931 btrfs_info(root->fs_info, "unrecognized mount option '%s'", p);
1932 ret = -EINVAL;
927ca606 1933@@ -1647,6 +1666,12 @@ static int btrfs_remount(struct super_bl
42bc425c
AM
1934 btrfs_resize_thread_pool(fs_info,
1935 fs_info->thread_pool_size, old_thread_pool_size);
e22b5178
AM
1936
1937+ if (btrfs_test_opt(root, TAGGED) && !(sb->s_flags & MS_TAGGED)) {
1938+ printk("btrfs: %s: tagging not permitted on remount.\n",
1939+ sb->s_id);
1940+ return -EINVAL;
1941+ }
1942+
1943 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
b00e13aa 1944 goto out;
e22b5178 1945
f19bd705
AM
1946diff -NurpP --minimal linux-4.4.111/fs/char_dev.c linux-4.4.111-vs2.3.9.1/fs/char_dev.c
1947--- linux-4.4.111/fs/char_dev.c 2016-07-05 04:12:30.000000000 +0000
1948+++ linux-4.4.111-vs2.3.9.1/fs/char_dev.c 2018-01-09 16:36:24.000000000 +0000
4744a4b1 1949@@ -21,6 +21,8 @@
2380c486
JR
1950 #include <linux/mutex.h>
1951 #include <linux/backing-dev.h>
7942c842 1952 #include <linux/tty.h>
2380c486
JR
1953+#include <linux/vs_context.h>
1954+#include <linux/vs_device.h>
1955
ec22aa5c
AM
1956 #include "internal.h"
1957
927ca606 1958@@ -350,14 +352,21 @@ static int chrdev_open(struct inode *ino
2380c486
JR
1959 struct cdev *p;
1960 struct cdev *new = NULL;
1961 int ret = 0;
1962+ dev_t mdev;
1963+
1964+ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN))
1965+ return -EPERM;
1966+ inode->i_mdev = mdev;
1967
1968 spin_lock(&cdev_lock);
1969 p = inode->i_cdev;
1970 if (!p) {
1971 struct kobject *kobj;
1972 int idx;
1973+
1974 spin_unlock(&cdev_lock);
1975- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
1976+
1977+ kobj = kobj_lookup(cdev_map, mdev, &idx);
1978 if (!kobj)
1979 return -ENXIO;
1980 new = container_of(kobj, struct cdev, kobj);
f19bd705
AM
1981diff -NurpP --minimal linux-4.4.111/fs/dcache.c linux-4.4.111-vs2.3.9.1/fs/dcache.c
1982--- linux-4.4.111/fs/dcache.c 2018-01-11 07:57:44.000000000 +0000
1983+++ linux-4.4.111-vs2.3.9.1/fs/dcache.c 2018-01-09 16:36:24.000000000 +0000
927ca606 1984@@ -39,6 +39,7 @@
f6c5ef8b 1985 #include <linux/ratelimit.h>
c2e5f7c8 1986 #include <linux/list_lru.h>
927ca606 1987 #include <linux/kasan.h>
d337f35e 1988+#include <linux/vs_limit.h>
927ca606 1989
d337f35e 1990 #include "internal.h"
db55b927 1991 #include "mount.h"
927ca606
AM
1992@@ -677,6 +678,7 @@ static inline bool fast_dput(struct dent
1993 spin_lock(&dentry->d_lock);
1994 if (dentry->d_lockref.count > 1) {
1995 dentry->d_lockref.count--;
1996+ vx_dentry_dec(dentry);
1997 spin_unlock(&dentry->d_lock);
1998 return 1;
1999 }
2000@@ -806,6 +808,7 @@ repeat:
2001 dentry_lru_add(dentry);
2002
2003 dentry->d_lockref.count--;
2004+ vx_dentry_dec(dentry);
2005 spin_unlock(&dentry->d_lock);
2006 return;
d337f35e 2007
927ca606 2008@@ -823,6 +826,7 @@ EXPORT_SYMBOL(dput);
d33d7b00 2009 static inline void __dget_dlock(struct dentry *dentry)
2380c486 2010 {
c2e5f7c8 2011 dentry->d_lockref.count++;
2380c486 2012+ vx_dentry_inc(dentry);
d337f35e 2013 }
2380c486 2014
d33d7b00 2015 static inline void __dget(struct dentry *dentry)
927ca606 2016@@ -835,6 +839,8 @@ struct dentry *dget_parent(struct dentry
bb20add7
AM
2017 int gotref;
2018 struct dentry *ret;
2019
2020+ vx_dentry_dec(dentry);
2021+
2022 /*
2023 * Do optimistic parent lookup without any
2024 * locking.
927ca606
AM
2025@@ -865,6 +871,7 @@ repeat:
2026 rcu_read_unlock();
2027 BUG_ON(!ret->d_lockref.count);
2028 ret->d_lockref.count++;
2029+ vx_dentry_inc(ret);
2030 spin_unlock(&ret->d_lock);
2031 return ret;
2032 }
2033@@ -1019,6 +1026,7 @@ static void shrink_dentry_list(struct li
2034 parent = lock_parent(dentry);
2035 if (dentry->d_lockref.count != 1) {
2036 dentry->d_lockref.count--;
2037+ vx_dentry_dec(dentry);
2038 spin_unlock(&dentry->d_lock);
2039 if (parent)
2040 spin_unlock(&parent->d_lock);
2041@@ -1581,6 +1589,9 @@ struct dentry *__d_alloc(struct super_bl
d337f35e
JR
2042 struct dentry *dentry;
2043 char *dname;
2044
2045+ if (!vx_dentry_avail(1))
2046+ return NULL;
2047+
2380c486 2048 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
d337f35e
JR
2049 if (!dentry)
2050 return NULL;
927ca606 2051@@ -1619,6 +1630,7 @@ struct dentry *__d_alloc(struct super_bl
d337f35e 2052
c2e5f7c8 2053 dentry->d_lockref.count = 1;
763640ca 2054 dentry->d_flags = 0;
ab30d09f 2055+ vx_dentry_inc(dentry);
ab30d09f 2056 spin_lock_init(&dentry->d_lock);
d33d7b00 2057 seqcount_init(&dentry->d_seq);
763640ca 2058 dentry->d_inode = NULL;
927ca606 2059@@ -2355,6 +2367,7 @@ struct dentry *__d_lookup(const struct d
d337f35e 2060 }
2380c486 2061
c2e5f7c8 2062 dentry->d_lockref.count++;
2380c486
JR
2063+ vx_dentry_inc(dentry);
2064 found = dentry;
d337f35e 2065 spin_unlock(&dentry->d_lock);
2380c486 2066 break;
927ca606
AM
2067@@ -3371,6 +3384,7 @@ static enum d_walk_ret d_genocide_kill(v
2068 if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
2069 dentry->d_flags |= DCACHE_GENOCIDE;
2070 dentry->d_lockref.count--;
2071+ vx_dentry_dec(dentry);
2072 }
2073 }
2074 return D_WALK_CONTINUE;
f19bd705
AM
2075diff -NurpP --minimal linux-4.4.111/fs/devpts/inode.c linux-4.4.111-vs2.3.9.1/fs/devpts/inode.c
2076--- linux-4.4.111/fs/devpts/inode.c 2018-01-11 07:57:44.000000000 +0000
2077+++ linux-4.4.111-vs2.3.9.1/fs/devpts/inode.c 2018-01-09 16:36:24.000000000 +0000
bb20add7 2078@@ -27,6 +27,7 @@
d337f35e 2079 #include <linux/parser.h>
2380c486
JR
2080 #include <linux/fsnotify.h>
2081 #include <linux/seq_file.h>
d337f35e
JR
2082+#include <linux/vs_base.h>
2083
2380c486 2084 #define DEVPTS_DEFAULT_MODE 0600
ec22aa5c 2085 /*
bb20add7 2086@@ -38,6 +39,21 @@
ec22aa5c
AM
2087 #define DEVPTS_DEFAULT_PTMX_MODE 0000
2088 #define PTMX_MINOR 2
2380c486 2089
a168f21d 2090+static int devpts_permission(struct inode *inode, int mask)
d337f35e
JR
2091+{
2092+ int ret = -EACCES;
2093+
2094+ /* devpts is xid tagged */
61333608 2095+ if (vx_check((vxid_t)i_tag_read(inode), VS_WATCH_P | VS_IDENT))
a168f21d 2096+ ret = generic_permission(inode, mask);
d337f35e
JR
2097+ return ret;
2098+}
2099+
2100+static struct inode_operations devpts_file_inode_operations = {
2101+ .permission = devpts_permission,
2102+};
2380c486 2103+
1e8b8f9b
AM
2104+
2105 /*
2106 * sysctl support for setting limits on the number of Unix98 ptys allocated.
2107 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
927ca606 2108@@ -353,6 +369,34 @@ static int devpts_show_options(struct se
d337f35e
JR
2109 return 0;
2110 }
2111
2112+static int devpts_filter(struct dentry *de)
2113+{
61333608 2114+ vxid_t xid = 0;
b3b0d4fd 2115+
d337f35e 2116+ /* devpts is xid tagged */
b3b0d4fd 2117+ if (de && de->d_inode)
61333608 2118+ xid = (vxid_t)i_tag_read(de->d_inode);
b3b0d4fd
AM
2119+#ifdef CONFIG_VSERVER_WARN_DEVPTS
2120+ else
2121+ vxwprintk_task(1, "devpts " VS_Q("%.*s") " without inode.",
2122+ de->d_name.len, de->d_name.name);
2123+#endif
2124+ return vx_check(xid, VS_WATCH_P | VS_IDENT);
d337f35e
JR
2125+}
2126+
c2e5f7c8 2127+static int devpts_readdir(struct file * filp, struct dir_context *ctx)
d337f35e 2128+{
c2e5f7c8 2129+ return dcache_readdir_filter(filp, ctx, devpts_filter);
d337f35e
JR
2130+}
2131+
2132+static struct file_operations devpts_dir_operations = {
2133+ .open = dcache_dir_open,
2134+ .release = dcache_dir_close,
2135+ .llseek = dcache_dir_lseek,
2136+ .read = generic_read_dir,
c2e5f7c8 2137+ .iterate = devpts_readdir,
d337f35e
JR
2138+};
2139+
2380c486 2140 static const struct super_operations devpts_sops = {
d337f35e
JR
2141 .statfs = simple_statfs,
2142 .remount_fs = devpts_remount,
927ca606 2143@@ -397,8 +441,10 @@ devpts_fill_super(struct super_block *s,
ec22aa5c 2144 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
d337f35e
JR
2145 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
2146 inode->i_op = &simple_dir_inode_operations;
2147- inode->i_fop = &simple_dir_operations;
2148+ inode->i_fop = &devpts_dir_operations;
f6c5ef8b 2149 set_nlink(inode, 2);
d337f35e 2150+ /* devpts is xid tagged */
61333608 2151+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2152
1e8b8f9b 2153 s->s_root = d_make_root(inode);
d337f35e 2154 if (s->s_root)
927ca606 2155@@ -630,6 +676,9 @@ struct inode *devpts_pty_new(struct pts_
ec22aa5c 2156 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
d337f35e 2157 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
ec22aa5c 2158 init_special_inode(inode, S_IFCHR|opts->mode, device);
d337f35e 2159+ /* devpts is xid tagged */
61333608 2160+ i_tag_write(inode, (vtag_t)vx_current_xid());
d337f35e 2161+ inode->i_op = &devpts_file_inode_operations;
b00e13aa 2162 inode->i_private = priv;
d337f35e 2163
b00e13aa 2164 sprintf(s, "%d", index);
f19bd705
AM
2165diff -NurpP --minimal linux-4.4.111/fs/ext2/balloc.c linux-4.4.111-vs2.3.9.1/fs/ext2/balloc.c
2166--- linux-4.4.111/fs/ext2/balloc.c 2015-04-12 22:12:50.000000000 +0000
2167+++ linux-4.4.111-vs2.3.9.1/fs/ext2/balloc.c 2018-01-09 16:36:24.000000000 +0000
b00e13aa 2168@@ -693,7 +693,6 @@ ext2_try_to_allocate(struct super_block
2380c486
JR
2169 start = 0;
2170 end = EXT2_BLOCKS_PER_GROUP(sb);
d337f35e 2171 }
2380c486
JR
2172-
2173 BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
2174
2175 repeat:
f19bd705
AM
2176diff -NurpP --minimal linux-4.4.111/fs/ext2/ext2.h linux-4.4.111-vs2.3.9.1/fs/ext2/ext2.h
2177--- linux-4.4.111/fs/ext2/ext2.h 2016-07-05 04:15:07.000000000 +0000
2178+++ linux-4.4.111-vs2.3.9.1/fs/ext2/ext2.h 2018-01-09 16:36:24.000000000 +0000
1e8b8f9b
AM
2179@@ -244,8 +244,12 @@ struct ext2_group_desc
2180 #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
2181 #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
2182 #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
2183+#define EXT2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
2184 #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2185
2186+#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
2187+#define EXT2_COW_FL FS_COW_FL /* Copy on Write marker */
2188+
2189 #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
2190 #define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
2191
2192@@ -329,7 +333,8 @@ struct ext2_inode {
2193 __u16 i_pad1;
2194 __le16 l_i_uid_high; /* these 2 fields */
2195 __le16 l_i_gid_high; /* were reserved2[0] */
2196- __u32 l_i_reserved2;
2197+ __le16 l_i_tag; /* Context Tag */
2198+ __u16 l_i_reserved2;
2199 } linux2;
2200 struct {
2201 __u8 h_i_frag; /* Fragment number */
2202@@ -357,6 +362,7 @@ struct ext2_inode {
2203 #define i_gid_low i_gid
2204 #define i_uid_high osd2.linux2.l_i_uid_high
2205 #define i_gid_high osd2.linux2.l_i_gid_high
2206+#define i_raw_tag osd2.linux2.l_i_tag
2207 #define i_reserved2 osd2.linux2.l_i_reserved2
2208
2209 /*
927ca606
AM
2210@@ -389,6 +395,7 @@ struct ext2_inode {
2211 #else
2212 #define EXT2_MOUNT_DAX 0
2213 #endif
2214+#define EXT2_MOUNT_TAGGED 0x200000 /* Enable Context Tags */
1e8b8f9b
AM
2215
2216
2217 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
927ca606 2218@@ -776,6 +783,7 @@ extern void ext2_set_inode_flags(struct
93de0823
AM
2219 extern void ext2_get_inode_flags(struct ext2_inode_info *);
2220 extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
2221 u64 start, u64 len);
d4263eb0
JR
2222+extern int ext2_sync_flags(struct inode *, int, int);
2223
2224 /* ioctl.c */
2225 extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
f19bd705
AM
2226diff -NurpP --minimal linux-4.4.111/fs/ext2/file.c linux-4.4.111-vs2.3.9.1/fs/ext2/file.c
2227--- linux-4.4.111/fs/ext2/file.c 2016-07-05 04:15:07.000000000 +0000
2228+++ linux-4.4.111-vs2.3.9.1/fs/ext2/file.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2229@@ -202,4 +202,5 @@ const struct inode_operations ext2_file_
a168f21d 2230 .get_acl = ext2_get_acl,
bb20add7 2231 .set_acl = ext2_set_acl,
ec22aa5c 2232 .fiemap = ext2_fiemap,
d337f35e
JR
2233+ .sync_flags = ext2_sync_flags,
2234 };
f19bd705
AM
2235diff -NurpP --minimal linux-4.4.111/fs/ext2/ialloc.c linux-4.4.111-vs2.3.9.1/fs/ext2/ialloc.c
2236--- linux-4.4.111/fs/ext2/ialloc.c 2016-07-05 04:12:30.000000000 +0000
2237+++ linux-4.4.111-vs2.3.9.1/fs/ext2/ialloc.c 2018-01-09 16:36:24.000000000 +0000
e22b5178
AM
2238@@ -17,6 +17,7 @@
2239 #include <linux/backing-dev.h>
2240 #include <linux/buffer_head.h>
2241 #include <linux/random.h>
2242+#include <linux/vs_tag.h>
2243 #include "ext2.h"
2244 #include "xattr.h"
2245 #include "acl.h"
a4a22af8 2246@@ -546,6 +547,7 @@ got:
76514441
AM
2247 inode->i_mode = mode;
2248 inode->i_uid = current_fsuid();
2249 inode->i_gid = dir->i_gid;
a4a22af8 2250+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2251 } else
76514441 2252 inode_init_owner(inode, dir, mode);
e22b5178 2253
f19bd705
AM
2254diff -NurpP --minimal linux-4.4.111/fs/ext2/inode.c linux-4.4.111-vs2.3.9.1/fs/ext2/inode.c
2255--- linux-4.4.111/fs/ext2/inode.c 2016-07-05 04:15:07.000000000 +0000
2256+++ linux-4.4.111-vs2.3.9.1/fs/ext2/inode.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2257@@ -33,6 +33,7 @@
ec22aa5c
AM
2258 #include <linux/fiemap.h>
2259 #include <linux/namei.h>
927ca606 2260 #include <linux/uio.h>
d337f35e
JR
2261+#include <linux/vs_tag.h>
2262 #include "ext2.h"
2263 #include "acl.h"
927ca606
AM
2264 #include "xattr.h"
2265@@ -1188,7 +1189,7 @@ static void ext2_truncate_blocks(struct
d337f35e
JR
2266 return;
2267 if (ext2_inode_is_fast_symlink(inode))
2268 return;
2269- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2270+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
2271 return;
927ca606
AM
2272
2273 dax_sem_down_write(EXT2_I(inode));
2274@@ -1284,39 +1285,62 @@ void ext2_set_inode_flags(struct inode *
d337f35e
JR
2275 {
2276 unsigned int flags = EXT2_I(inode)->i_flags;
2277
927ca606
AM
2278- inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME |
2279- S_DIRSYNC | S_DAX);
2280+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | S_DAX |
d337f35e
JR
2281+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2282+
2283+ if (flags & EXT2_IMMUTABLE_FL)
2284+ inode->i_flags |= S_IMMUTABLE;
2380c486
JR
2285+ if (flags & EXT2_IXUNLINK_FL)
2286+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
2287+
2288 if (flags & EXT2_SYNC_FL)
2289 inode->i_flags |= S_SYNC;
2290 if (flags & EXT2_APPEND_FL)
2291 inode->i_flags |= S_APPEND;
2292- if (flags & EXT2_IMMUTABLE_FL)
2293- inode->i_flags |= S_IMMUTABLE;
2294 if (flags & EXT2_NOATIME_FL)
2295 inode->i_flags |= S_NOATIME;
2296 if (flags & EXT2_DIRSYNC_FL)
2297 inode->i_flags |= S_DIRSYNC;
927ca606
AM
2298 if (test_opt(inode->i_sb, DAX))
2299 inode->i_flags |= S_DAX;
2380c486
JR
2300+
2301+ inode->i_vflags &= ~(V_BARRIER | V_COW);
2302+
2303+ if (flags & EXT2_BARRIER_FL)
2304+ inode->i_vflags |= V_BARRIER;
2305+ if (flags & EXT2_COW_FL)
2306+ inode->i_vflags |= V_COW;
2307 }
2308
2309 /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
2310 void ext2_get_inode_flags(struct ext2_inode_info *ei)
2311 {
2312 unsigned int flags = ei->vfs_inode.i_flags;
2313+ unsigned int vflags = ei->vfs_inode.i_vflags;
2314+
2315+ ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL |
2316+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL |
2317+ EXT2_NOATIME_FL | EXT2_DIRSYNC_FL |
2318+ EXT2_BARRIER_FL | EXT2_COW_FL);
2319+
2320+ if (flags & S_IMMUTABLE)
2321+ ei->i_flags |= EXT2_IMMUTABLE_FL;
2322+ if (flags & S_IXUNLINK)
2323+ ei->i_flags |= EXT2_IXUNLINK_FL;
2324
2325- ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
2326- EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
2327 if (flags & S_SYNC)
2328 ei->i_flags |= EXT2_SYNC_FL;
2329 if (flags & S_APPEND)
2330 ei->i_flags |= EXT2_APPEND_FL;
2331- if (flags & S_IMMUTABLE)
2332- ei->i_flags |= EXT2_IMMUTABLE_FL;
2333 if (flags & S_NOATIME)
2334 ei->i_flags |= EXT2_NOATIME_FL;
2335 if (flags & S_DIRSYNC)
2336 ei->i_flags |= EXT2_DIRSYNC_FL;
2337+
2338+ if (vflags & V_BARRIER)
2339+ ei->i_flags |= EXT2_BARRIER_FL;
2340+ if (vflags & V_COW)
2341+ ei->i_flags |= EXT2_COW_FL;
d337f35e
JR
2342 }
2343
2380c486 2344 struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
927ca606 2345@@ -1352,8 +1376,10 @@ struct inode *ext2_iget (struct super_bl
42bc425c
AM
2346 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2347 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2348 }
42bc425c
AM
2349- i_uid_write(inode, i_uid);
2350- i_gid_write(inode, i_gid);
2351+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2352+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2353+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2354+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2355 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
d337f35e 2356 inode->i_size = le32_to_cpu(raw_inode->i_size);
2380c486 2357 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
927ca606 2358@@ -1449,8 +1475,10 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2359 struct ext2_inode_info *ei = EXT2_I(inode);
2360 struct super_block *sb = inode->i_sb;
2361 ino_t ino = inode->i_ino;
42bc425c
AM
2362- uid_t uid = i_uid_read(inode);
2363- gid_t gid = i_gid_read(inode);
a4a22af8
AM
2364+ uid_t uid = from_kuid(&init_user_ns,
2365+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2366+ gid_t gid = from_kgid(&init_user_ns,
2367+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
d337f35e
JR
2368 struct buffer_head * bh;
2369 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
2370 int n;
927ca606 2371@@ -1486,6 +1514,9 @@ static int __ext2_write_inode(struct ino
d337f35e
JR
2372 raw_inode->i_uid_high = 0;
2373 raw_inode->i_gid_high = 0;
2374 }
2375+#ifdef CONFIG_TAGGING_INTERN
537831f9 2376+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2377+#endif
2378 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2379 raw_inode->i_size = cpu_to_le32(inode->i_size);
2380 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
927ca606
AM
2381@@ -1569,7 +1600,8 @@ int ext2_setattr(struct dentry *dentry,
2382 return error;
2383 }
42bc425c
AM
2384 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
2385- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
2386+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
537831f9 2387+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b 2388 error = dquot_transfer(inode, iattr);
d337f35e
JR
2389 if (error)
2390 return error;
f19bd705
AM
2391diff -NurpP --minimal linux-4.4.111/fs/ext2/ioctl.c linux-4.4.111-vs2.3.9.1/fs/ext2/ioctl.c
2392--- linux-4.4.111/fs/ext2/ioctl.c 2015-04-12 22:12:50.000000000 +0000
2393+++ linux-4.4.111-vs2.3.9.1/fs/ext2/ioctl.c 2018-01-09 16:36:24.000000000 +0000
d4263eb0
JR
2394@@ -17,6 +17,16 @@
2395 #include <asm/uaccess.h>
2396
2397
2398+int ext2_sync_flags(struct inode *inode, int flags, int vflags)
2399+{
2400+ inode->i_flags = flags;
2401+ inode->i_vflags = vflags;
2402+ ext2_get_inode_flags(EXT2_I(inode));
2403+ inode->i_ctime = CURRENT_TIME_SEC;
2404+ mark_inode_dirty(inode);
2405+ return 0;
2406+}
2407+
2408 long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2409 {
b00e13aa 2410 struct inode *inode = file_inode(filp);
d4263eb0 2411@@ -51,6 +61,11 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e 2412
ec22aa5c 2413 flags = ext2_mask_flags(inode->i_mode, flags);
d337f35e 2414
2380c486
JR
2415+ if (IS_BARRIER(inode)) {
2416+ vxwprintk_task(1, "messing with the barrier.");
2417+ return -EACCES;
2418+ }
2419+
2420 mutex_lock(&inode->i_mutex);
2421 /* Is it quota file? Do not allow user to mess with it */
2422 if (IS_NOQUOTA(inode)) {
d4263eb0 2423@@ -66,7 +81,9 @@ long ext2_ioctl(struct file *filp, unsig
d337f35e
JR
2424 *
2425 * This test looks nicer. Thanks to Pauline Middelink
2426 */
2427- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
2428+ if ((oldflags & EXT2_IMMUTABLE_FL) ||
2429+ ((flags ^ oldflags) & (EXT2_APPEND_FL |
2380c486
JR
2430+ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) {
2431 if (!capable(CAP_LINUX_IMMUTABLE)) {
2432 mutex_unlock(&inode->i_mutex);
2433 ret = -EPERM;
d4263eb0
JR
2434@@ -74,7 +91,7 @@ long ext2_ioctl(struct file *filp, unsig
2435 }
2436 }
2437
2438- flags = flags & EXT2_FL_USER_MODIFIABLE;
2439+ flags &= EXT2_FL_USER_MODIFIABLE;
2440 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
2441 ei->i_flags = flags;
db55b927 2442
f19bd705
AM
2443diff -NurpP --minimal linux-4.4.111/fs/ext2/namei.c linux-4.4.111-vs2.3.9.1/fs/ext2/namei.c
2444--- linux-4.4.111/fs/ext2/namei.c 2016-07-05 04:15:07.000000000 +0000
2445+++ linux-4.4.111-vs2.3.9.1/fs/ext2/namei.c 2018-01-09 16:36:24.000000000 +0000
78865d5b 2446@@ -32,6 +32,7 @@
d337f35e
JR
2447
2448 #include <linux/pagemap.h>
78865d5b 2449 #include <linux/quotaops.h>
d337f35e
JR
2450+#include <linux/vs_tag.h>
2451 #include "ext2.h"
2452 #include "xattr.h"
2453 #include "acl.h"
927ca606 2454@@ -72,6 +73,7 @@ static struct dentry *ext2_lookup(struct
a168f21d
AM
2455 (unsigned long) ino);
2456 return ERR_PTR(-EIO);
ec22aa5c 2457 }
a168f21d 2458+ dx_propagate_tag(nd, inode);
d337f35e 2459 }
a168f21d
AM
2460 return d_splice_alias(inode, dentry);
2461 }
927ca606 2462@@ -446,6 +448,7 @@ const struct inode_operations ext2_speci
a168f21d 2463 .removexattr = generic_removexattr,
d337f35e
JR
2464 #endif
2465 .setattr = ext2_setattr,
d337f35e 2466+ .sync_flags = ext2_sync_flags,
a168f21d 2467 .get_acl = ext2_get_acl,
bb20add7 2468 .set_acl = ext2_set_acl,
d337f35e 2469 };
f19bd705
AM
2470diff -NurpP --minimal linux-4.4.111/fs/ext2/super.c linux-4.4.111-vs2.3.9.1/fs/ext2/super.c
2471--- linux-4.4.111/fs/ext2/super.c 2016-07-05 04:15:07.000000000 +0000
2472+++ linux-4.4.111-vs2.3.9.1/fs/ext2/super.c 2018-01-09 16:36:24.000000000 +0000
927ca606 2473@@ -408,7 +408,8 @@ enum {
d337f35e
JR
2474 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
2475 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
927ca606 2476 Opt_acl, Opt_noacl, Opt_xip, Opt_dax, Opt_ignore, Opt_err, Opt_quota,
2380c486
JR
2477- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
2478+ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation,
2479+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2480 };
2481
ec22aa5c 2482 static const match_table_t tokens = {
927ca606 2483@@ -436,6 +437,9 @@ static const match_table_t tokens = {
d337f35e
JR
2484 {Opt_acl, "acl"},
2485 {Opt_noacl, "noacl"},
2486 {Opt_xip, "xip"},
2487+ {Opt_tag, "tag"},
2488+ {Opt_notag, "notag"},
2489+ {Opt_tagid, "tagid=%u"},
927ca606 2490 {Opt_dax, "dax"},
d337f35e
JR
2491 {Opt_grpquota, "grpquota"},
2492 {Opt_ignore, "noquota"},
927ca606 2493@@ -520,6 +524,20 @@ static int parse_options(char *options,
d337f35e
JR
2494 case Opt_nouid32:
2495 set_opt (sbi->s_mount_opt, NO_UID32);
2496 break;
2497+#ifndef CONFIG_TAGGING_NONE
2498+ case Opt_tag:
2499+ set_opt (sbi->s_mount_opt, TAGGED);
2500+ break;
2501+ case Opt_notag:
2502+ clear_opt (sbi->s_mount_opt, TAGGED);
2503+ break;
2504+#endif
2505+#ifdef CONFIG_PROPAGATE
2506+ case Opt_tagid:
2507+ /* use args[0] */
2508+ set_opt (sbi->s_mount_opt, TAGGED);
2509+ break;
2510+#endif
2511 case Opt_nocheck:
2512 clear_opt (sbi->s_mount_opt, CHECK);
2513 break;
927ca606 2514@@ -884,6 +902,8 @@ static int ext2_fill_super(struct super_
2bf5ad28 2515 if (!parse_options((char *) data, sb))
d337f35e
JR
2516 goto failed_mount;
2517
2518+ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
2519+ sb->s_flags |= MS_TAGGED;
2520 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2521 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
2522 MS_POSIXACL : 0);
927ca606 2523@@ -1294,6 +1314,14 @@ static int ext2_remount (struct super_bl
537831f9 2524 err = -EINVAL;
d337f35e
JR
2525 goto restore_opts;
2526 }
537831f9 2527+
d337f35e
JR
2528+ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
2529+ !(sb->s_flags & MS_TAGGED)) {
2530+ printk("EXT2-fs: %s: tagging not permitted on remount.\n",
2531+ sb->s_id);
d4263eb0
JR
2532+ err = -EINVAL;
2533+ goto restore_opts;
d337f35e 2534+ }
537831f9 2535
d337f35e
JR
2536 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
2537 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
f19bd705
AM
2538diff -NurpP --minimal linux-4.4.111/fs/ext4/ext4.h linux-4.4.111-vs2.3.9.1/fs/ext4/ext4.h
2539--- linux-4.4.111/fs/ext4/ext4.h 2018-01-11 07:57:44.000000000 +0000
2540+++ linux-4.4.111-vs2.3.9.1/fs/ext4/ext4.h 2018-01-09 17:33:10.000000000 +0000
927ca606 2541@@ -375,8 +375,11 @@ struct flex_groups {
2380c486 2542 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
78865d5b
AM
2543 #define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
2544 #define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
b00e13aa 2545+#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 2546+#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
b00e13aa 2547 #define EXT4_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */
927ca606
AM
2548 #define EXT4_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
2549+#define EXT4_COW_FL 0x40000000 /* Copy on Write marker */
2380c486 2550 #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
d337f35e 2551
78865d5b 2552 #define EXT4_FL_USER_VISIBLE 0x004BDFFF /* User visible flags */
927ca606 2553@@ -674,7 +677,7 @@ struct ext4_inode {
ec22aa5c
AM
2554 __le16 l_i_uid_high; /* these 2 fields */
2555 __le16 l_i_gid_high; /* were reserved2[0] */
42bc425c
AM
2556 __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
2557- __le16 l_i_reserved;
ec22aa5c 2558+ __le16 l_i_tag; /* Context Tag */
ec22aa5c
AM
2559 } linux2;
2560 struct {
2561 __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
927ca606 2562@@ -831,6 +834,7 @@ do { \
ec22aa5c
AM
2563 #define i_gid_low i_gid
2564 #define i_uid_high osd2.linux2.l_i_uid_high
2565 #define i_gid_high osd2.linux2.l_i_gid_high
2566+#define i_raw_tag osd2.linux2.l_i_tag
42bc425c 2567 #define i_checksum_lo osd2.linux2.l_i_checksum_lo
d337f35e 2568
ec22aa5c 2569 #elif defined(__GNU__)
927ca606 2570@@ -1068,6 +1072,7 @@ struct ext4_inode_info {
ab30d09f
AM
2571 #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
2572 #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */
2573 #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */
2574+#define EXT4_MOUNT_TAGGED 0x40000 /* Enable Context Tags */
2575 #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */
2576 #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
2577 #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
927ca606
AM
2578@@ -2501,6 +2506,7 @@ extern int ext4_punch_hole(struct inode
2579 extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
2580 extern void ext4_set_inode_flags(struct inode *);
2581 extern void ext4_get_inode_flags(struct ext4_inode_info *);
d4263eb0 2582+extern int ext4_sync_flags(struct inode *, int, int);
927ca606
AM
2583 extern int ext4_alloc_da_blocks(struct inode *inode);
2584 extern void ext4_set_aops(struct inode *inode);
2585 extern int ext4_writepage_trans_blocks(struct inode *);
f19bd705
AM
2586diff -NurpP --minimal linux-4.4.111/fs/ext4/file.c linux-4.4.111-vs2.3.9.1/fs/ext4/file.c
2587--- linux-4.4.111/fs/ext4/file.c 2018-01-11 07:57:44.000000000 +0000
2588+++ linux-4.4.111-vs2.3.9.1/fs/ext4/file.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2589@@ -749,5 +749,6 @@ const struct inode_operations ext4_file_
a168f21d 2590 .get_acl = ext4_get_acl,
bb20add7 2591 .set_acl = ext4_set_acl,
ec22aa5c 2592 .fiemap = ext4_fiemap,
d337f35e
JR
2593+ .sync_flags = ext4_sync_flags,
2594 };
2595
f19bd705
AM
2596diff -NurpP --minimal linux-4.4.111/fs/ext4/ialloc.c linux-4.4.111-vs2.3.9.1/fs/ext4/ialloc.c
2597--- linux-4.4.111/fs/ext4/ialloc.c 2018-01-11 07:57:44.000000000 +0000
2598+++ linux-4.4.111-vs2.3.9.1/fs/ext4/ialloc.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2599@@ -21,6 +21,7 @@
e22b5178
AM
2600 #include <linux/random.h>
2601 #include <linux/bitops.h>
2602 #include <linux/blkdev.h>
2603+#include <linux/vs_tag.h>
2604 #include <asm/byteorder.h>
2605
2606 #include "ext4.h"
927ca606 2607@@ -799,6 +800,7 @@ struct inode *__ext4_new_inode(handle_t
76514441
AM
2608 inode->i_mode = mode;
2609 inode->i_uid = current_fsuid();
2610 inode->i_gid = dir->i_gid;
a4a22af8 2611+ i_tag_write(inode, dx_current_fstag(sb));
e22b5178 2612 } else
76514441 2613 inode_init_owner(inode, dir, mode);
927ca606 2614 err = dquot_initialize(inode);
f19bd705
AM
2615diff -NurpP --minimal linux-4.4.111/fs/ext4/inode.c linux-4.4.111-vs2.3.9.1/fs/ext4/inode.c
2616--- linux-4.4.111/fs/ext4/inode.c 2018-01-11 07:57:44.000000000 +0000
2617+++ linux-4.4.111-vs2.3.9.1/fs/ext4/inode.c 2018-01-09 16:36:31.000000000 +0000
927ca606
AM
2618@@ -37,6 +37,7 @@
2619 #include <linux/printk.h>
2620 #include <linux/slab.h>
52afa9bd 2621 #include <linux/bitops.h>
d337f35e 2622+#include <linux/vs_tag.h>
ec22aa5c 2623
2380c486 2624 #include "ext4_jbd2.h"
d337f35e 2625 #include "xattr.h"
927ca606 2626@@ -4128,12 +4129,15 @@ void ext4_set_inode_flags(struct inode *
d337f35e 2627 unsigned int flags = EXT4_I(inode)->i_flags;
52afa9bd 2628 unsigned int new_fl = 0;
978063ce 2629
d337f35e 2630+ if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2631+ new_fl |= S_IMMUTABLE;
2380c486 2632+ if (flags & EXT4_IXUNLINK_FL)
52afa9bd 2633+ new_fl |= S_IXUNLINK;
978063ce 2634+
d337f35e 2635 if (flags & EXT4_SYNC_FL)
52afa9bd 2636 new_fl |= S_SYNC;
d337f35e 2637 if (flags & EXT4_APPEND_FL)
52afa9bd 2638 new_fl |= S_APPEND;
d337f35e 2639- if (flags & EXT4_IMMUTABLE_FL)
52afa9bd 2640- new_fl |= S_IMMUTABLE;
d337f35e 2641 if (flags & EXT4_NOATIME_FL)
52afa9bd 2642 new_fl |= S_NOATIME;
d337f35e 2643 if (flags & EXT4_DIRSYNC_FL)
927ca606
AM
2644@@ -4141,31 +4145,52 @@ void ext4_set_inode_flags(struct inode *
2645 if (test_opt(inode->i_sb, DAX))
2646 new_fl |= S_DAX;
ca5d134c 2647 inode_set_flags(inode, new_fl,
927ca606
AM
2648- S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX);
2649+ S_IXUNLINK | S_IMMUTABLE | S_DAX |
ca5d134c 2650+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
2380c486 2651+
978063ce 2652+ new_fl = 0;
2380c486 2653+ if (flags & EXT4_BARRIER_FL)
978063ce 2654+ new_fl |= V_BARRIER;
2380c486 2655+ if (flags & EXT4_COW_FL)
978063ce
JR
2656+ new_fl |= V_COW;
2657+
2658+ set_mask_bits(&inode->i_vflags,
2659+ V_BARRIER | V_COW, new_fl);
d337f35e
JR
2660 }
2661
2380c486
JR
2662 /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
2663 void ext4_get_inode_flags(struct ext4_inode_info *ei)
2664 {
76514441
AM
2665- unsigned int vfs_fl;
2666+ unsigned int vfs_fl, vfs_vf;
2667 unsigned long old_fl, new_fl;
2380c486 2668
76514441
AM
2669 do {
2670 vfs_fl = ei->vfs_inode.i_flags;
2671+ vfs_vf = ei->vfs_inode.i_vflags;
2672 old_fl = ei->i_flags;
2673 new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
2674 EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
2675- EXT4_DIRSYNC_FL);
2676+ EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
2677+ EXT4_COW_FL);
2678+
2679+ if (vfs_fl & S_IMMUTABLE)
2680+ new_fl |= EXT4_IMMUTABLE_FL;
2681+ if (vfs_fl & S_IXUNLINK)
2682+ new_fl |= EXT4_IXUNLINK_FL;
2683+
2684 if (vfs_fl & S_SYNC)
2685 new_fl |= EXT4_SYNC_FL;
2686 if (vfs_fl & S_APPEND)
2687 new_fl |= EXT4_APPEND_FL;
2688- if (vfs_fl & S_IMMUTABLE)
2689- new_fl |= EXT4_IMMUTABLE_FL;
2690 if (vfs_fl & S_NOATIME)
2691 new_fl |= EXT4_NOATIME_FL;
2692 if (vfs_fl & S_DIRSYNC)
2693 new_fl |= EXT4_DIRSYNC_FL;
2694+
2695+ if (vfs_vf & V_BARRIER)
2696+ new_fl |= EXT4_BARRIER_FL;
2697+ if (vfs_vf & V_COW)
2698+ new_fl |= EXT4_COW_FL;
2699 } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
ec22aa5c
AM
2700 }
2701
927ca606 2702@@ -4269,8 +4294,10 @@ struct inode *ext4_iget(struct super_blo
42bc425c
AM
2703 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
2704 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
d337f35e 2705 }
42bc425c
AM
2706- i_uid_write(inode, i_uid);
2707- i_gid_write(inode, i_gid);
2708+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), i_uid, i_gid));
2709+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), i_uid, i_gid));
537831f9
AM
2710+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), i_uid, i_gid,
2711+ le16_to_cpu(raw_inode->i_raw_tag)));
f6c5ef8b 2712 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
2380c486 2713
d33d7b00 2714 ext4_clear_state_flags(ei); /* Only relevant on 32-bit archs */
927ca606 2715@@ -4583,8 +4610,10 @@ static int ext4_do_update_inode(handle_t
d337f35e 2716
2380c486 2717 ext4_get_inode_flags(ei);
d337f35e 2718 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
42bc425c
AM
2719- i_uid = i_uid_read(inode);
2720- i_gid = i_gid_read(inode);
a4a22af8
AM
2721+ i_uid = from_kuid(&init_user_ns,
2722+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag));
2723+ i_gid = from_kgid(&init_user_ns,
2724+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag));
ec22aa5c 2725 if (!(test_opt(inode->i_sb, NO_UID32))) {
42bc425c
AM
2726 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid));
2727 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid));
927ca606 2728@@ -4607,6 +4636,9 @@ static int ext4_do_update_inode(handle_t
d337f35e
JR
2729 raw_inode->i_uid_high = 0;
2730 raw_inode->i_gid_high = 0;
2731 }
2732+#ifdef CONFIG_TAGGING_INTERN
537831f9 2733+ raw_inode->i_raw_tag = cpu_to_le16(i_tag_read(inode));
d337f35e
JR
2734+#endif
2735 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2380c486
JR
2736
2737 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
927ca606
AM
2738@@ -4852,7 +4884,8 @@ int ext4_setattr(struct dentry *dentry,
2739 return error;
2740 }
42bc425c
AM
2741 if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
2742- (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
2743+ (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)) ||
537831f9 2744+ (ia_valid & ATTR_TAG && !tag_eq(attr->ia_tag, inode->i_tag))) {
d337f35e
JR
2745 handle_t *handle;
2746
2747 /* (user+group)*(old+new) structure, inode write (sb,
927ca606 2748@@ -4875,6 +4908,8 @@ int ext4_setattr(struct dentry *dentry,
d337f35e
JR
2749 inode->i_uid = attr->ia_uid;
2750 if (attr->ia_valid & ATTR_GID)
2751 inode->i_gid = attr->ia_gid;
2752+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2753+ inode->i_tag = attr->ia_tag;
2754 error = ext4_mark_inode_dirty(handle, inode);
2755 ext4_journal_stop(handle);
2756 }
f19bd705
AM
2757diff -NurpP --minimal linux-4.4.111/fs/ext4/ioctl.c linux-4.4.111-vs2.3.9.1/fs/ext4/ioctl.c
2758--- linux-4.4.111/fs/ext4/ioctl.c 2018-01-11 07:57:44.000000000 +0000
2759+++ linux-4.4.111-vs2.3.9.1/fs/ext4/ioctl.c 2018-01-09 16:36:31.000000000 +0000
09be7631 2760@@ -14,6 +14,7 @@
2380c486 2761 #include <linux/mount.h>
ec22aa5c 2762 #include <linux/file.h>
927ca606 2763 #include <linux/random.h>
d337f35e
JR
2764+#include <linux/vs_tag.h>
2765 #include <asm/uaccess.h>
2380c486
JR
2766 #include "ext4_jbd2.h"
2767 #include "ext4.h"
927ca606
AM
2768@@ -202,6 +203,33 @@ static int uuid_is_zero(__u8 u[16])
2769 return 1;
09be7631 2770 }
db55b927 2771
d4263eb0
JR
2772+int ext4_sync_flags(struct inode *inode, int flags, int vflags)
2773+{
2774+ handle_t *handle = NULL;
2775+ struct ext4_iloc iloc;
2776+ int err;
2777+
b00e13aa 2778+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
d4263eb0
JR
2779+ if (IS_ERR(handle))
2780+ return PTR_ERR(handle);
2781+
2782+ if (IS_SYNC(inode))
2783+ ext4_handle_sync(handle);
2784+ err = ext4_reserve_inode_write(handle, inode, &iloc);
2785+ if (err)
2786+ goto flags_err;
2787+
2788+ inode->i_flags = flags;
2789+ inode->i_vflags = vflags;
2790+ ext4_get_inode_flags(EXT4_I(inode));
2791+ inode->i_ctime = ext4_current_time(inode);
2792+
2793+ err = ext4_mark_iloc_dirty(handle, inode, &iloc);
2794+flags_err:
2795+ ext4_journal_stop(handle);
2796+ return err;
2797+}
2798+
2799 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2800 {
b00e13aa 2801 struct inode *inode = file_inode(filp);
927ca606 2802@@ -235,6 +263,11 @@ long ext4_ioctl(struct file *filp, unsig
ec22aa5c
AM
2803
2804 flags = ext4_mask_flags(inode->i_mode, flags);
2380c486
JR
2805
2806+ if (IS_BARRIER(inode)) {
2807+ vxwprintk_task(1, "messing with the barrier.");
2808+ return -EACCES;
2809+ }
2810+
2811 err = -EPERM;
ec22aa5c
AM
2812 mutex_lock(&inode->i_mutex);
2813 /* Is it quota file? Do not allow user to mess with it */
927ca606 2814@@ -252,7 +285,9 @@ long ext4_ioctl(struct file *filp, unsig
d337f35e
JR
2815 *
2816 * This test looks nicer. Thanks to Pauline Middelink
2817 */
2818- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
2819+ if ((oldflags & EXT4_IMMUTABLE_FL) ||
2820+ ((flags ^ oldflags) & (EXT4_APPEND_FL |
2380c486
JR
2821+ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) {
2822 if (!capable(CAP_LINUX_IMMUTABLE))
2823 goto flags_out;
2824 }
f19bd705
AM
2825diff -NurpP --minimal linux-4.4.111/fs/ext4/namei.c linux-4.4.111-vs2.3.9.1/fs/ext4/namei.c
2826--- linux-4.4.111/fs/ext4/namei.c 2018-01-11 07:57:44.000000000 +0000
2827+++ linux-4.4.111-vs2.3.9.1/fs/ext4/namei.c 2018-01-09 16:36:31.000000000 +0000
927ca606 2828@@ -33,6 +33,7 @@
2380c486 2829 #include <linux/quotaops.h>
d337f35e
JR
2830 #include <linux/buffer_head.h>
2831 #include <linux/bio.h>
d337f35e 2832+#include <linux/vs_tag.h>
2380c486
JR
2833 #include "ext4.h"
2834 #include "ext4_jbd2.h"
d337f35e 2835
927ca606 2836@@ -1444,6 +1445,7 @@ restart:
a168f21d
AM
2837 ll_rw_block(READ | REQ_META | REQ_PRIO,
2838 1, &bh);
2380c486 2839 }
d337f35e 2840+ dx_propagate_tag(nd, inode);
2380c486
JR
2841 }
2842 if ((bh = bh_use[ra_ptr++]) == NULL)
2843 goto next;
927ca606 2844@@ -3881,6 +3883,7 @@ const struct inode_operations ext4_dir_i
a168f21d 2845 .get_acl = ext4_get_acl,
bb20add7 2846 .set_acl = ext4_set_acl,
d4263eb0 2847 .fiemap = ext4_fiemap,
d337f35e
JR
2848+ .sync_flags = ext4_sync_flags,
2849 };
d4263eb0
JR
2850
2851 const struct inode_operations ext4_special_inode_operations = {
f19bd705
AM
2852diff -NurpP --minimal linux-4.4.111/fs/ext4/super.c linux-4.4.111-vs2.3.9.1/fs/ext4/super.c
2853--- linux-4.4.111/fs/ext4/super.c 2018-01-11 07:57:44.000000000 +0000
2854+++ linux-4.4.111-vs2.3.9.1/fs/ext4/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 2855@@ -1165,6 +1165,7 @@ enum {
78865d5b 2856 Opt_dioread_nolock, Opt_dioread_lock,
dd5f3080 2857 Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
927ca606
AM
2858 Opt_max_dir_size_kb, Opt_nojournal_checksum,
2859+ Opt_tag, Opt_notag, Opt_tagid
d337f35e
JR
2860 };
2861
ec22aa5c 2862 static const match_table_t tokens = {
927ca606 2863@@ -1250,6 +1251,9 @@ static const match_table_t tokens = {
1e8b8f9b
AM
2864 {Opt_removed, "reservation"}, /* mount option from ext2/3 */
2865 {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
2866 {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */
d337f35e
JR
2867+ {Opt_tag, "tag"},
2868+ {Opt_notag, "notag"},
2869+ {Opt_tagid, "tagid=%u"},
d337f35e 2870 {Opt_err, NULL},
d337f35e 2871 };
2380c486 2872
927ca606
AM
2873@@ -1492,6 +1496,20 @@ static int handle_mount_opt(struct super
2874 case Opt_nolazytime:
2875 sb->s_flags &= ~MS_LAZYTIME;
1e8b8f9b 2876 return 1;
d337f35e 2877+#ifndef CONFIG_TAGGING_NONE
1e8b8f9b
AM
2878+ case Opt_tag:
2879+ set_opt(sb, TAGGED);
2880+ return 1;
2881+ case Opt_notag:
2882+ clear_opt(sb, TAGGED);
2883+ return 1;
d337f35e
JR
2884+#endif
2885+#ifdef CONFIG_PROPAGATE
1e8b8f9b
AM
2886+ case Opt_tagid:
2887+ /* use args[0] */
2888+ set_opt(sb, TAGGED);
2889+ return 1;
d337f35e 2890+#endif
1e8b8f9b
AM
2891 }
2892
b00e13aa 2893 for (m = ext4_mount_opts; m->token != Opt_err; m++)
927ca606
AM
2894@@ -3379,6 +3397,9 @@ static int ext4_fill_super(struct super_
2895 sb->s_iflags |= SB_I_CGROUPWB;
f6c5ef8b 2896 }
d337f35e
JR
2897
2898+ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
2899+ sb->s_flags |= MS_TAGGED;
2900+
2901 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2902 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2903
927ca606 2904@@ -4727,6 +4748,14 @@ static int ext4_remount(struct super_blo
ec22aa5c 2905 if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
93de0823 2906 ext4_abort(sb, "Abort forced by user");
2380c486 2907
d337f35e
JR
2908+ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
2909+ !(sb->s_flags & MS_TAGGED)) {
2910+ printk("EXT4-fs: %s: tagging not permitted on remount.\n",
2911+ sb->s_id);
d4263eb0
JR
2912+ err = -EINVAL;
2913+ goto restore_opts;
d337f35e 2914+ }
2380c486 2915+
d337f35e 2916 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
78865d5b 2917 (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
d337f35e 2918
f19bd705
AM
2919diff -NurpP --minimal linux-4.4.111/fs/fcntl.c linux-4.4.111-vs2.3.9.1/fs/fcntl.c
2920--- linux-4.4.111/fs/fcntl.c 2018-01-11 07:57:44.000000000 +0000
2921+++ linux-4.4.111-vs2.3.9.1/fs/fcntl.c 2018-01-09 16:36:32.000000000 +0000
bb20add7 2922@@ -22,6 +22,7 @@
2380c486 2923 #include <linux/pid_namespace.h>
92598135 2924 #include <linux/user_namespace.h>
bb20add7 2925 #include <linux/shmem_fs.h>
d337f35e
JR
2926+#include <linux/vs_limit.h>
2927
2928 #include <asm/poll.h>
2929 #include <asm/siginfo.h>
bb20add7 2930@@ -385,6 +386,8 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, f
d337f35e 2931
537831f9 2932 if (!f.file)
2380c486
JR
2933 goto out;
2934+ if (!vx_files_avail(1))
2935+ goto out;
2936
537831f9 2937 if (unlikely(f.file->f_mode & FMODE_PATH)) {
42bc425c 2938 if (!check_fcntl_cmd(cmd))
f19bd705
AM
2939diff -NurpP --minimal linux-4.4.111/fs/file.c linux-4.4.111-vs2.3.9.1/fs/file.c
2940--- linux-4.4.111/fs/file.c 2016-07-05 04:15:07.000000000 +0000
2941+++ linux-4.4.111-vs2.3.9.1/fs/file.c 2018-01-09 16:36:32.000000000 +0000
537831f9 2942@@ -22,6 +22,7 @@
2380c486
JR
2943 #include <linux/spinlock.h>
2944 #include <linux/rcupdate.h>
2945 #include <linux/workqueue.h>
2946+#include <linux/vs_limit.h>
2947
09be7631
JR
2948 int sysctl_nr_open __read_mostly = 1024*1024;
2949 int sysctl_nr_open_min = BITS_PER_LONG;
927ca606 2950@@ -356,6 +357,8 @@ struct files_struct *dup_fd(struct files
2380c486
JR
2951 struct file *f = *old_fds++;
2952 if (f) {
2953 get_file(f);
2954+ /* TODO: sum it first for check and performance */
2955+ vx_openfd_inc(open_files - i);
2956 } else {
2957 /*
2958 * The fd may be claimed in the fd bitmap but not yet
927ca606 2959@@ -405,9 +408,11 @@ static struct fdtable *close_files(struc
537831f9 2960 filp_close(file, files);
bb20add7 2961 cond_resched_rcu_qs();
537831f9
AM
2962 }
2963+ vx_openfd_dec(i);
2964 }
2965 i++;
2966 set >>= 1;
2967+ cond_resched();
2968 }
2969 }
bb20add7 2970
927ca606 2971@@ -538,6 +543,7 @@ repeat:
2380c486 2972 else
1e8b8f9b 2973 __clear_close_on_exec(fd, fdt);
2380c486
JR
2974 error = fd;
2975+ vx_openfd_inc(fd);
2976 #if 1
2977 /* Sanity check */
bb20add7 2978 if (rcu_access_pointer(fdt->fd[fd]) != NULL) {
927ca606 2979@@ -568,6 +574,7 @@ static void __put_unused_fd(struct files
537831f9
AM
2980 __clear_open_fd(fd, fdt);
2981 if (fd < files->next_fd)
2982 files->next_fd = fd;
2983+ vx_openfd_dec(fd);
2984 }
2985
2986 void put_unused_fd(unsigned int fd)
927ca606 2987@@ -850,6 +857,8 @@ __releases(&files->file_lock)
537831f9
AM
2988
2989 if (tofree)
2990 filp_close(tofree, files);
2991+ else
2992+ vx_openfd_inc(fd); /* fd was unused */
2993
2994 return fd;
2995
f19bd705
AM
2996diff -NurpP --minimal linux-4.4.111/fs/file_table.c linux-4.4.111-vs2.3.9.1/fs/file_table.c
2997--- linux-4.4.111/fs/file_table.c 2015-10-29 09:21:35.000000000 +0000
2998+++ linux-4.4.111-vs2.3.9.1/fs/file_table.c 2018-01-09 17:25:51.000000000 +0000
92598135 2999@@ -26,6 +26,8 @@
92598135 3000 #include <linux/task_work.h>
2bf5ad28 3001 #include <linux/ima.h>
927ca606 3002 #include <linux/swap.h>
d337f35e
JR
3003+#include <linux/vs_limit.h>
3004+#include <linux/vs_context.h>
3005
a168f21d 3006 #include <linux/atomic.h>
d337f35e 3007
c2e5f7c8 3008@@ -137,6 +139,8 @@ struct file *get_empty_filp(void)
bb20add7 3009 mutex_init(&f->f_pos_lock);
d337f35e
JR
3010 eventpoll_init_file(f);
3011 /* f->f_version: 0 */
3012+ f->f_xid = vx_current_xid();
3013+ vx_files_inc(f);
3014 return f;
3015
3016 over:
bb20add7 3017@@ -219,6 +223,8 @@ static void __fput(struct file *file)
265de2f7
JR
3018 put_write_access(inode);
3019 __mnt_drop_write(mnt);
3020 }
d337f35e
JR
3021+ vx_files_dec(file);
3022+ file->f_xid = 0;
92598135
AM
3023 file->f_path.dentry = NULL;
3024 file->f_path.mnt = NULL;
b00e13aa 3025 file->f_inode = NULL;
bb20add7 3026@@ -305,6 +311,8 @@ void put_filp(struct file *file)
d337f35e 3027 {
2380c486 3028 if (atomic_long_dec_and_test(&file->f_count)) {
d337f35e
JR
3029 security_file_free(file);
3030+ vx_files_dec(file);
3031+ file->f_xid = 0;
d337f35e
JR
3032 file_free(file);
3033 }
c2e5f7c8 3034 }
f19bd705
AM
3035diff -NurpP --minimal linux-4.4.111/fs/fs_struct.c linux-4.4.111-vs2.3.9.1/fs/fs_struct.c
3036--- linux-4.4.111/fs/fs_struct.c 2015-04-12 22:12:50.000000000 +0000
3037+++ linux-4.4.111-vs2.3.9.1/fs/fs_struct.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c
AM
3038@@ -4,6 +4,7 @@
3039 #include <linux/path.h>
3040 #include <linux/slab.h>
3041 #include <linux/fs_struct.h>
3042+#include <linux/vserver/global.h>
d33d7b00 3043 #include "internal.h"
ec22aa5c 3044
92598135
AM
3045 /*
3046@@ -87,6 +88,7 @@ void free_fs_struct(struct fs_struct *fs
ec22aa5c 3047 {
92598135
AM
3048 path_put(&fs->root);
3049 path_put(&fs->pwd);
ec22aa5c
AM
3050+ atomic_dec(&vs_global_fs);
3051 kmem_cache_free(fs_cachep, fs);
3052 }
3053
537831f9 3054@@ -124,6 +126,7 @@ struct fs_struct *copy_fs_struct(struct
d33d7b00 3055 fs->pwd = old->pwd;
92598135 3056 path_get(&fs->pwd);
d33d7b00 3057 spin_unlock(&old->lock);
ec22aa5c
AM
3058+ atomic_inc(&vs_global_fs);
3059 }
3060 return fs;
3061 }
f19bd705
AM
3062diff -NurpP --minimal linux-4.4.111/fs/gfs2/file.c linux-4.4.111-vs2.3.9.1/fs/gfs2/file.c
3063--- linux-4.4.111/fs/gfs2/file.c 2018-01-11 07:57:44.000000000 +0000
3064+++ linux-4.4.111-vs2.3.9.1/fs/gfs2/file.c 2018-01-09 17:23:53.000000000 +0000
927ca606 3065@@ -137,6 +137,9 @@ static const u32 fsflags_to_gfs2[32] = {
e22b5178
AM
3066 [12] = GFS2_DIF_EXHASH,
3067 [14] = GFS2_DIF_INHERIT_JDATA,
92598135 3068 [17] = GFS2_DIF_TOPDIR,
e22b5178
AM
3069+ [27] = GFS2_DIF_IXUNLINK,
3070+ [26] = GFS2_DIF_BARRIER,
3071+ [29] = GFS2_DIF_COW,
3072 };
3073
3074 static const u32 gfs2_to_fsflags[32] = {
927ca606 3075@@ -147,6 +150,9 @@ static const u32 gfs2_to_fsflags[32] = {
e22b5178 3076 [gfs2fl_ExHash] = FS_INDEX_FL,
92598135 3077 [gfs2fl_TopLevel] = FS_TOPDIR_FL,
e22b5178
AM
3078 [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
3079+ [gfs2fl_IXUnlink] = FS_IXUNLINK_FL,
3080+ [gfs2fl_Barrier] = FS_BARRIER_FL,
3081+ [gfs2fl_Cow] = FS_COW_FL,
3082 };
3083
3084 static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
927ca606 3085@@ -177,12 +183,17 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3086 {
3087 struct gfs2_inode *ip = GFS2_I(inode);
3088 unsigned int flags = inode->i_flags;
3089+ unsigned int vflags = inode->i_vflags;
e22b5178 3090
a168f21d 3091- flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
927ca606
AM
3092+ flags &= ~(S_IMMUTABLE | S_IXUNLINK |
3093+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC | S_NOSEC);
3094+
a168f21d 3095 if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
927ca606 3096 flags |= S_NOSEC;
e22b5178
AM
3097 if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
3098 flags |= S_IMMUTABLE;
3099+ if (ip->i_diskflags & GFS2_DIF_IXUNLINK)
3100+ flags |= S_IXUNLINK;
e22b5178
AM
3101 if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
3102 flags |= S_APPEND;
3103 if (ip->i_diskflags & GFS2_DIF_NOATIME)
927ca606 3104@@ -190,6 +201,43 @@ void gfs2_set_inode_flags(struct inode *
e22b5178
AM
3105 if (ip->i_diskflags & GFS2_DIF_SYNC)
3106 flags |= S_SYNC;
3107 inode->i_flags = flags;
3108+
3109+ vflags &= ~(V_BARRIER | V_COW);
3110+
3111+ if (ip->i_diskflags & GFS2_DIF_BARRIER)
3112+ vflags |= V_BARRIER;
3113+ if (ip->i_diskflags & GFS2_DIF_COW)
3114+ vflags |= V_COW;
3115+ inode->i_vflags = vflags;
3116+}
3117+
3118+void gfs2_get_inode_flags(struct inode *inode)
3119+{
3120+ struct gfs2_inode *ip = GFS2_I(inode);
3121+ unsigned int flags = inode->i_flags;
3122+ unsigned int vflags = inode->i_vflags;
3123+
3124+ ip->i_diskflags &= ~(GFS2_DIF_APPENDONLY |
3125+ GFS2_DIF_NOATIME | GFS2_DIF_SYNC |
3126+ GFS2_DIF_IMMUTABLE | GFS2_DIF_IXUNLINK |
3127+ GFS2_DIF_BARRIER | GFS2_DIF_COW);
3128+
3129+ if (flags & S_IMMUTABLE)
3130+ ip->i_diskflags |= GFS2_DIF_IMMUTABLE;
3131+ if (flags & S_IXUNLINK)
3132+ ip->i_diskflags |= GFS2_DIF_IXUNLINK;
3133+
3134+ if (flags & S_APPEND)
3135+ ip->i_diskflags |= GFS2_DIF_APPENDONLY;
3136+ if (flags & S_NOATIME)
3137+ ip->i_diskflags |= GFS2_DIF_NOATIME;
3138+ if (flags & S_SYNC)
3139+ ip->i_diskflags |= GFS2_DIF_SYNC;
3140+
3141+ if (vflags & V_BARRIER)
3142+ ip->i_diskflags |= GFS2_DIF_BARRIER;
3143+ if (vflags & V_COW)
3144+ ip->i_diskflags |= GFS2_DIF_COW;
3145 }
3146
3147 /* Flags that can be set by user space */
927ca606 3148@@ -305,6 +353,37 @@ static int gfs2_set_flags(struct file *f
e22b5178
AM
3149 return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
3150 }
3151
3152+int gfs2_sync_flags(struct inode *inode, int flags, int vflags)
3153+{
3154+ struct gfs2_inode *ip = GFS2_I(inode);
3155+ struct gfs2_sbd *sdp = GFS2_SB(inode);
3156+ struct buffer_head *bh;
3157+ struct gfs2_holder gh;
3158+ int error;
3159+
3160+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
3161+ if (error)
3162+ return error;
3163+ error = gfs2_trans_begin(sdp, RES_DINODE, 0);
3164+ if (error)
3165+ goto out;
3166+ error = gfs2_meta_inode_buffer(ip, &bh);
3167+ if (error)
3168+ goto out_trans_end;
b00e13aa 3169+ gfs2_trans_add_meta(ip->i_gl, bh);
e22b5178
AM
3170+ inode->i_flags = flags;
3171+ inode->i_vflags = vflags;
3172+ gfs2_get_inode_flags(inode);
3173+ gfs2_dinode_out(ip, bh->b_data);
3174+ brelse(bh);
3175+ gfs2_set_aops(inode);
3176+out_trans_end:
3177+ gfs2_trans_end(sdp);
3178+out:
3179+ gfs2_glock_dq_uninit(&gh);
3180+ return error;
3181+}
3182+
3183 static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3184 {
3185 switch(cmd) {
f19bd705
AM
3186diff -NurpP --minimal linux-4.4.111/fs/gfs2/inode.h linux-4.4.111-vs2.3.9.1/fs/gfs2/inode.h
3187--- linux-4.4.111/fs/gfs2/inode.h 2015-04-12 22:12:50.000000000 +0000
3188+++ linux-4.4.111-vs2.3.9.1/fs/gfs2/inode.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 3189@@ -118,6 +118,7 @@ extern const struct file_operations gfs2
e22b5178
AM
3190 extern const struct file_operations gfs2_dir_fops_nolock;
3191
3192 extern void gfs2_set_inode_flags(struct inode *inode);
3193+extern int gfs2_sync_flags(struct inode *inode, int flags, int vflags);
3194
3195 #ifdef CONFIG_GFS2_FS_LOCKING_DLM
3196 extern const struct file_operations gfs2_file_fops;
f19bd705
AM
3197diff -NurpP --minimal linux-4.4.111/fs/hostfs/hostfs.h linux-4.4.111-vs2.3.9.1/fs/hostfs/hostfs.h
3198--- linux-4.4.111/fs/hostfs/hostfs.h 2015-07-06 20:41:42.000000000 +0000
3199+++ linux-4.4.111-vs2.3.9.1/fs/hostfs/hostfs.h 2018-01-09 16:36:32.000000000 +0000
537831f9
AM
3200@@ -42,6 +42,7 @@ struct hostfs_iattr {
3201 unsigned short ia_mode;
3202 uid_t ia_uid;
3203 gid_t ia_gid;
61333608 3204+ vtag_t ia_tag;
537831f9
AM
3205 loff_t ia_size;
3206 struct timespec ia_atime;
3207 struct timespec ia_mtime;
f19bd705
AM
3208diff -NurpP --minimal linux-4.4.111/fs/inode.c linux-4.4.111-vs2.3.9.1/fs/inode.c
3209--- linux-4.4.111/fs/inode.c 2018-01-11 07:57:45.000000000 +0000
3210+++ linux-4.4.111-vs2.3.9.1/fs/inode.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 3211@@ -18,6 +18,7 @@
763640ca 3212 #include <linux/buffer_head.h> /* for inode_has_buffers */
db55b927 3213 #include <linux/ratelimit.h>
c2e5f7c8 3214 #include <linux/list_lru.h>
76514441 3215+#include <linux/vs_tag.h>
927ca606 3216 #include <trace/events/writeback.h>
763640ca 3217 #include "internal.h"
76514441 3218
927ca606 3219@@ -133,6 +134,8 @@ int inode_init_always(struct super_block
ec22aa5c
AM
3220 struct address_space *const mapping = &inode->i_data;
3221
3222 inode->i_sb = sb;
3223+
3224+ /* essential because of inode slab reuse */
ec22aa5c
AM
3225 inode->i_blkbits = sb->s_blocksize_bits;
3226 inode->i_flags = 0;
3227 atomic_set(&inode->i_count, 1);
927ca606 3228@@ -142,6 +145,7 @@ int inode_init_always(struct super_block
537831f9
AM
3229 inode->i_opflags = 0;
3230 i_uid_write(inode, 0);
3231 i_gid_write(inode, 0);
3232+ i_tag_write(inode, 0);
3233 atomic_set(&inode->i_writecount, 0);
3234 inode->i_size = 0;
3235 inode->i_blocks = 0;
927ca606 3236@@ -152,6 +156,7 @@ int inode_init_always(struct super_block
ec22aa5c 3237 inode->i_cdev = NULL;
927ca606 3238 inode->i_link = NULL;
ec22aa5c
AM
3239 inode->i_rdev = 0;
3240+ inode->i_mdev = 0;
3241 inode->dirtied_when = 0;
3242
3243 if (security_inode_alloc(inode))
927ca606 3244@@ -469,6 +474,8 @@ void __insert_inode_hash(struct inode *i
d337f35e 3245 }
763640ca 3246 EXPORT_SYMBOL(__insert_inode_hash);
d337f35e
JR
3247
3248+EXPORT_SYMBOL_GPL(__iget);
3249+
3250 /**
a168f21d 3251 * __remove_inode_hash - remove an inode from the hash
ab30d09f 3252 * @inode: inode to unhash
927ca606 3253@@ -1911,9 +1918,11 @@ void init_special_inode(struct inode *in
2380c486
JR
3254 if (S_ISCHR(mode)) {
3255 inode->i_fop = &def_chr_fops;
3256 inode->i_rdev = rdev;
3257+ inode->i_mdev = rdev;
3258 } else if (S_ISBLK(mode)) {
3259 inode->i_fop = &def_blk_fops;
3260 inode->i_rdev = rdev;
3261+ inode->i_mdev = rdev;
3262 } else if (S_ISFIFO(mode))
09be7631 3263 inode->i_fop = &pipefifo_fops;
2380c486 3264 else if (S_ISSOCK(mode))
927ca606 3265@@ -1942,6 +1951,7 @@ void inode_init_owner(struct inode *inod
76514441
AM
3266 } else
3267 inode->i_gid = current_fsgid();
3268 inode->i_mode = mode;
8ce283e1 3269+ i_tag_write(inode, dx_current_fstag(inode->i_sb));
76514441
AM
3270 }
3271 EXPORT_SYMBOL(inode_init_owner);
763640ca 3272
f19bd705
AM
3273diff -NurpP --minimal linux-4.4.111/fs/ioctl.c linux-4.4.111-vs2.3.9.1/fs/ioctl.c
3274--- linux-4.4.111/fs/ioctl.c 2015-04-12 22:12:50.000000000 +0000
3275+++ linux-4.4.111-vs2.3.9.1/fs/ioctl.c 2018-01-09 16:36:32.000000000 +0000
ab30d09f 3276@@ -15,6 +15,9 @@
ec22aa5c
AM
3277 #include <linux/writeback.h>
3278 #include <linux/buffer_head.h>
3279 #include <linux/falloc.h>
d337f35e
JR
3280+#include <linux/proc_fs.h>
3281+#include <linux/vserver/inode.h>
3282+#include <linux/vs_tag.h>
3283
d337f35e
JR
3284 #include <asm/ioctls.h>
3285
f19bd705
AM
3286diff -NurpP --minimal linux-4.4.111/fs/jfs/file.c linux-4.4.111-vs2.3.9.1/fs/jfs/file.c
3287--- linux-4.4.111/fs/jfs/file.c 2016-07-05 04:12:33.000000000 +0000
3288+++ linux-4.4.111-vs2.3.9.1/fs/jfs/file.c 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
3289@@ -113,7 +113,8 @@ int jfs_setattr(struct dentry *dentry, s
3290 return rc;
3291 }
537831f9
AM
3292 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
3293- (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
3294+ (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) ||
3295+ (iattr->ia_valid & ATTR_TAG && !tag_eq(iattr->ia_tag, inode->i_tag))) {
78865d5b
AM
3296 rc = dquot_transfer(inode, iattr);
3297 if (rc)
3298 return rc;
927ca606 3299@@ -149,6 +150,7 @@ const struct inode_operations jfs_file_i
a168f21d 3300 .get_acl = jfs_get_acl,
bb20add7 3301 .set_acl = jfs_set_acl,
d337f35e
JR
3302 #endif
3303+ .sync_flags = jfs_sync_flags,
3304 };
3305
3306 const struct file_operations jfs_file_operations = {
f19bd705
AM
3307diff -NurpP --minimal linux-4.4.111/fs/jfs/ioctl.c linux-4.4.111-vs2.3.9.1/fs/jfs/ioctl.c
3308--- linux-4.4.111/fs/jfs/ioctl.c 2015-10-29 09:21:36.000000000 +0000
3309+++ linux-4.4.111-vs2.3.9.1/fs/jfs/ioctl.c 2018-01-09 16:36:32.000000000 +0000
537831f9 3310@@ -12,6 +12,7 @@
d337f35e 3311 #include <linux/time.h>
2380c486 3312 #include <linux/sched.h>
537831f9 3313 #include <linux/blkdev.h>
d337f35e
JR
3314+#include <linux/mount.h>
3315 #include <asm/current.h>
3316 #include <asm/uaccess.h>
3317
537831f9 3318@@ -56,6 +57,16 @@ static long jfs_map_ext2(unsigned long f
d4263eb0
JR
3319 }
3320
3321
3322+int jfs_sync_flags(struct inode *inode, int flags, int vflags)
3323+{
3324+ inode->i_flags = flags;
3325+ inode->i_vflags = vflags;
3326+ jfs_get_inode_flags(JFS_IP(inode));
3327+ inode->i_ctime = CURRENT_TIME_SEC;
3328+ mark_inode_dirty(inode);
3329+ return 0;
3330+}
3331+
3332 long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
3333 {
b00e13aa 3334 struct inode *inode = file_inode(filp);
537831f9 3335@@ -89,6 +100,11 @@ long jfs_ioctl(struct file *filp, unsign
2380c486
JR
3336 if (!S_ISDIR(inode->i_mode))
3337 flags &= ~JFS_DIRSYNC_FL;
d337f35e 3338
2380c486
JR
3339+ if (IS_BARRIER(inode)) {
3340+ vxwprintk_task(1, "messing with the barrier.");
3341+ return -EACCES;
3342+ }
3343+
3344 /* Is it quota file? Do not allow user to mess with it */
3345 if (IS_NOQUOTA(inode)) {
3346 err = -EPERM;
537831f9 3347@@ -106,8 +122,8 @@ long jfs_ioctl(struct file *filp, unsign
d337f35e
JR
3348 * the relevant capability.
3349 */
3350 if ((oldflags & JFS_IMMUTABLE_FL) ||
3351- ((flags ^ oldflags) &
3352- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
3353+ ((flags ^ oldflags) & (JFS_APPEND_FL |
2380c486
JR
3354+ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) {
3355 if (!capable(CAP_LINUX_IMMUTABLE)) {
3356 mutex_unlock(&inode->i_mutex);
3357 err = -EPERM;
537831f9 3358@@ -115,7 +131,7 @@ long jfs_ioctl(struct file *filp, unsign
d4263eb0
JR
3359 }
3360 }
3361
3362- flags = flags & JFS_FL_USER_MODIFIABLE;
3363+ flags &= JFS_FL_USER_MODIFIABLE;
3364 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
3365 jfs_inode->mode2 = flags;
3366
f19bd705
AM
3367diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_dinode.h linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_dinode.h
3368--- linux-4.4.111/fs/jfs/jfs_dinode.h 2015-04-12 22:12:50.000000000 +0000
3369+++ linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_dinode.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
3370@@ -161,9 +161,13 @@ struct dinode {
3371
d337f35e
JR
3372 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
3373 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
2380c486 3374+#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
d337f35e
JR
3375
3376-#define JFS_FL_USER_VISIBLE 0x03F80000
2380c486 3377-#define JFS_FL_USER_MODIFIABLE 0x03F80000
d337f35e 3378+#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
2380c486 3379+#define JFS_COW_FL 0x20000000 /* Copy on Write marker */
d337f35e 3380+
2380c486
JR
3381+#define JFS_FL_USER_VISIBLE 0x07F80000
3382+#define JFS_FL_USER_MODIFIABLE 0x07F80000
3383 #define JFS_FL_INHERIT 0x03C80000
d337f35e
JR
3384
3385 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
f19bd705
AM
3386diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_filsys.h linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_filsys.h
3387--- linux-4.4.111/fs/jfs/jfs_filsys.h 2015-04-12 22:12:50.000000000 +0000
3388+++ linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_filsys.h 2018-01-09 16:36:32.000000000 +0000
537831f9 3389@@ -266,6 +266,7 @@
ec22aa5c
AM
3390 #define JFS_NAME_MAX 255
3391 #define JFS_PATH_MAX BPSIZE
bd427b06 3392
ec22aa5c 3393+#define JFS_TAGGED 0x00800000 /* Context Tagging */
bd427b06 3394
ec22aa5c
AM
3395 /*
3396 * file system state (superblock state)
f19bd705
AM
3397diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_imap.c linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_imap.c
3398--- linux-4.4.111/fs/jfs/jfs_imap.c 2015-04-12 22:12:50.000000000 +0000
3399+++ linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_imap.c 2018-01-09 16:36:32.000000000 +0000
78865d5b 3400@@ -46,6 +46,7 @@
ec22aa5c
AM
3401 #include <linux/pagemap.h>
3402 #include <linux/quotaops.h>
78865d5b 3403 #include <linux/slab.h>
ec22aa5c 3404+#include <linux/vs_tag.h>
bd427b06 3405
ec22aa5c
AM
3406 #include "jfs_incore.h"
3407 #include "jfs_inode.h"
c2e5f7c8 3408@@ -3047,6 +3048,8 @@ static int copy_from_dinode(struct dinod
ec22aa5c
AM
3409 {
3410 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3411 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
a4a22af8
AM
3412+ kuid_t kuid;
3413+ kgid_t kgid;
bd427b06 3414
ec22aa5c
AM
3415 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3416 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
c2e5f7c8 3417@@ -3067,14 +3070,18 @@ static int copy_from_dinode(struct dinod
d337f35e 3418 }
f6c5ef8b 3419 set_nlink(ip, le32_to_cpu(dip->di_nlink));
bd427b06 3420
537831f9 3421- jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
a4a22af8
AM
3422+ kuid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid));
3423+ kgid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
3424+ ip->i_tag = INOTAG_KTAG(DX_TAG(ip), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 3425+
a4a22af8 3426+ jfs_ip->saved_uid = INOTAG_KUID(DX_TAG(ip), kuid, kgid);
537831f9 3427 if (!uid_valid(sbi->uid))
ec22aa5c
AM
3428 ip->i_uid = jfs_ip->saved_uid;
3429 else {
3430 ip->i_uid = sbi->uid;
bd427b06
AM
3431 }
3432
537831f9 3433- jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid));
a4a22af8 3434+ jfs_ip->saved_gid = INOTAG_KGID(DX_TAG(ip), kuid, kgid);
537831f9 3435 if (!gid_valid(sbi->gid))
d337f35e
JR
3436 ip->i_gid = jfs_ip->saved_gid;
3437 else {
c2e5f7c8 3438@@ -3139,16 +3146,14 @@ static void copy_to_dinode(struct dinode
d337f35e
JR
3439 dip->di_size = cpu_to_le64(ip->i_size);
3440 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3441 dip->di_nlink = cpu_to_le32(ip->i_nlink);
537831f9
AM
3442- if (!uid_valid(sbi->uid))
3443- dip->di_uid = cpu_to_le32(i_uid_read(ip));
d337f35e 3444- else
537831f9
AM
3445- dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns,
3446- jfs_ip->saved_uid));
3447- if (!gid_valid(sbi->gid))
3448- dip->di_gid = cpu_to_le32(i_gid_read(ip));
d337f35e 3449- else
537831f9
AM
3450- dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3451- jfs_ip->saved_gid));
3452+ dip->di_uid = cpu_to_le32(from_kuid(&init_user_ns,
a4a22af8 3453+ TAGINO_KUID(DX_TAG(ip),
537831f9
AM
3454+ !uid_valid(sbi->uid) ? ip->i_uid : jfs_ip->saved_uid,
3455+ ip->i_tag)));
a4a22af8
AM
3456+ dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns,
3457+ TAGINO_KGID(DX_TAG(ip),
537831f9
AM
3458+ !gid_valid(sbi->gid) ? ip->i_gid : jfs_ip->saved_gid,
3459+ ip->i_tag)));
2380c486 3460 jfs_get_inode_flags(jfs_ip);
d337f35e
JR
3461 /*
3462 * mode2 is only needed for storing the higher order bits.
f19bd705
AM
3463diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_inode.c linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_inode.c
3464--- linux-4.4.111/fs/jfs/jfs_inode.c 2016-07-05 04:12:33.000000000 +0000
3465+++ linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_inode.c 2018-01-09 16:36:32.000000000 +0000
e22b5178
AM
3466@@ -18,6 +18,7 @@
3467
3468 #include <linux/fs.h>
3469 #include <linux/quotaops.h>
3470+#include <linux/vs_tag.h>
3471 #include "jfs_incore.h"
3472 #include "jfs_inode.h"
3473 #include "jfs_filsys.h"
bb20add7 3474@@ -33,26 +34,45 @@ void jfs_set_inode_flags(struct inode *i
d337f35e
JR
3475
3476 if (flags & JFS_IMMUTABLE_FL)
bb20add7 3477 new_fl |= S_IMMUTABLE;
2380c486
JR
3478+ if (flags & JFS_IXUNLINK_FL)
3479+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
3480+
3481+ if (flags & JFS_SYNC_FL)
3482+ inode->i_flags |= S_SYNC;
3483 if (flags & JFS_APPEND_FL)
bb20add7 3484 new_fl |= S_APPEND;
d337f35e 3485 if (flags & JFS_NOATIME_FL)
bb20add7 3486 new_fl |= S_NOATIME;
d337f35e 3487 if (flags & JFS_DIRSYNC_FL)
bb20add7 3488 new_fl |= S_DIRSYNC;
d337f35e 3489- if (flags & JFS_SYNC_FL)
bb20add7
AM
3490- new_fl |= S_SYNC;
3491- inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
3492+ inode_set_flags(inode, new_fl, S_IMMUTABLE | S_IXUNLINK | S_APPEND | S_NOATIME |
3493 S_DIRSYNC | S_SYNC);
2380c486 3494+
bb20add7 3495+ new_fl = 0;
2380c486 3496+ if (flags & JFS_BARRIER_FL)
bb20add7 3497+ new_fl |= V_BARRIER;
2380c486 3498+ if (flags & JFS_COW_FL)
bb20add7
AM
3499+ new_fl |= V_COW;
3500+
3501+ set_mask_bits(&inode->i_vflags,
3502+ V_BARRIER | V_COW, new_fl);
2380c486
JR
3503 }
3504
3505 void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
3506 {
3507 unsigned int flags = jfs_ip->vfs_inode.i_flags;
3508+ unsigned int vflags = jfs_ip->vfs_inode.i_vflags;
3509+
3510+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL |
3511+ JFS_APPEND_FL | JFS_NOATIME_FL |
3512+ JFS_DIRSYNC_FL | JFS_SYNC_FL |
3513+ JFS_BARRIER_FL | JFS_COW_FL);
3514
3515- jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
3516- JFS_DIRSYNC_FL | JFS_SYNC_FL);
3517 if (flags & S_IMMUTABLE)
3518 jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
3519+ if (flags & S_IXUNLINK)
3520+ jfs_ip->mode2 |= JFS_IXUNLINK_FL;
3521+
3522 if (flags & S_APPEND)
3523 jfs_ip->mode2 |= JFS_APPEND_FL;
3524 if (flags & S_NOATIME)
bb20add7 3525@@ -61,6 +81,11 @@ void jfs_get_inode_flags(struct jfs_inod
2380c486
JR
3526 jfs_ip->mode2 |= JFS_DIRSYNC_FL;
3527 if (flags & S_SYNC)
3528 jfs_ip->mode2 |= JFS_SYNC_FL;
3529+
3530+ if (vflags & V_BARRIER)
3531+ jfs_ip->mode2 |= JFS_BARRIER_FL;
3532+ if (vflags & V_COW)
3533+ jfs_ip->mode2 |= JFS_COW_FL;
d337f35e
JR
3534 }
3535
3536 /*
f19bd705
AM
3537diff -NurpP --minimal linux-4.4.111/fs/jfs/jfs_inode.h linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_inode.h
3538--- linux-4.4.111/fs/jfs/jfs_inode.h 2015-04-12 22:12:50.000000000 +0000
3539+++ linux-4.4.111-vs2.3.9.1/fs/jfs/jfs_inode.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
3540@@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s
3541 extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
3542 int fh_len, int fh_type);
d337f35e 3543 extern void jfs_set_inode_flags(struct inode *);
d4263eb0 3544+extern int jfs_sync_flags(struct inode *, int, int);
d337f35e 3545 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
78865d5b 3546 extern int jfs_setattr(struct dentry *, struct iattr *);
d337f35e 3547
f19bd705
AM
3548diff -NurpP --minimal linux-4.4.111/fs/jfs/namei.c linux-4.4.111-vs2.3.9.1/fs/jfs/namei.c
3549--- linux-4.4.111/fs/jfs/namei.c 2016-07-05 04:15:08.000000000 +0000
3550+++ linux-4.4.111-vs2.3.9.1/fs/jfs/namei.c 2018-01-09 16:36:32.000000000 +0000
d33d7b00 3551@@ -22,6 +22,7 @@
d337f35e
JR
3552 #include <linux/ctype.h>
3553 #include <linux/quotaops.h>
2380c486 3554 #include <linux/exportfs.h>
d337f35e
JR
3555+#include <linux/vs_tag.h>
3556 #include "jfs_incore.h"
3557 #include "jfs_superblock.h"
3558 #include "jfs_inode.h"
927ca606 3559@@ -1480,6 +1481,7 @@ static struct dentry *jfs_lookup(struct
a168f21d 3560 jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
d337f35e
JR
3561 }
3562
3563+ dx_propagate_tag(nd, ip);
d33d7b00
AM
3564 return d_splice_alias(ip, dentry);
3565 }
d337f35e 3566
927ca606 3567@@ -1545,6 +1547,7 @@ const struct inode_operations jfs_dir_in
a168f21d 3568 .get_acl = jfs_get_acl,
bb20add7 3569 .set_acl = jfs_set_acl,
d337f35e
JR
3570 #endif
3571+ .sync_flags = jfs_sync_flags,
3572 };
3573
3574 const struct file_operations jfs_dir_operations = {
f19bd705
AM
3575diff -NurpP --minimal linux-4.4.111/fs/jfs/super.c linux-4.4.111-vs2.3.9.1/fs/jfs/super.c
3576--- linux-4.4.111/fs/jfs/super.c 2018-01-11 07:57:45.000000000 +0000
3577+++ linux-4.4.111-vs2.3.9.1/fs/jfs/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 3578@@ -206,7 +206,8 @@ enum {
d337f35e
JR
3579 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
3580 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
537831f9
AM
3581 Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
3582- Opt_discard, Opt_nodiscard, Opt_discard_minblk
3583+ Opt_discard, Opt_nodiscard, Opt_discard_minblk,
d337f35e
JR
3584+ Opt_tag, Opt_notag, Opt_tagid
3585 };
3586
ec22aa5c 3587 static const match_table_t tokens = {
927ca606 3588@@ -216,6 +217,10 @@ static const match_table_t tokens = {
d337f35e
JR
3589 {Opt_resize, "resize=%u"},
3590 {Opt_resize_nosize, "resize"},
3591 {Opt_errors, "errors=%s"},
3592+ {Opt_tag, "tag"},
3593+ {Opt_notag, "notag"},
3594+ {Opt_tagid, "tagid=%u"},
3595+ {Opt_tag, "tagxid"},
3596 {Opt_ignore, "noquota"},
3597 {Opt_ignore, "quota"},
3598 {Opt_usrquota, "usrquota"},
927ca606 3599@@ -405,7 +410,20 @@ static int parse_options(char *options,
bb20add7 3600 pr_err("JFS: discard option not supported on device\n");
d337f35e
JR
3601 break;
3602 }
537831f9 3603-
d337f35e
JR
3604+#ifndef CONFIG_TAGGING_NONE
3605+ case Opt_tag:
3606+ *flag |= JFS_TAGGED;
3607+ break;
3608+ case Opt_notag:
3609+ *flag &= JFS_TAGGED;
3610+ break;
3611+#endif
3612+#ifdef CONFIG_PROPAGATE
3613+ case Opt_tagid:
3614+ /* use args[0] */
3615+ *flag |= JFS_TAGGED;
3616+ break;
3617+#endif
3618 default:
bb20add7
AM
3619 printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
3620 p);
927ca606 3621@@ -437,6 +455,12 @@ static int jfs_remount(struct super_bloc
bb20add7 3622 if (!parse_options(data, sb, &newLVSize, &flag))
d337f35e 3623 return -EINVAL;
ab30d09f 3624
d337f35e
JR
3625+ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
3626+ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
3627+ sb->s_id);
3628+ return -EINVAL;
3629+ }
3630+
3631 if (newLVSize) {
3632 if (sb->s_flags & MS_RDONLY) {
bb20add7
AM
3633 pr_err("JFS: resize requires volume to be mounted read-write\n");
3634@@ -517,6 +541,9 @@ static int jfs_fill_super(struct super_b
d337f35e
JR
3635 #ifdef CONFIG_JFS_POSIX_ACL
3636 sb->s_flags |= MS_POSIXACL;
3637 #endif
3638+ /* map mount option tagxid */
3639+ if (sbi->flag & JFS_TAGGED)
3640+ sb->s_flags |= MS_TAGGED;
3641
3642 if (newLVSize) {
537831f9 3643 pr_err("resize option for remount only\n");
f19bd705
AM
3644diff -NurpP --minimal linux-4.4.111/fs/libfs.c linux-4.4.111-vs2.3.9.1/fs/libfs.c
3645--- linux-4.4.111/fs/libfs.c 2016-07-05 04:12:33.000000000 +0000
3646+++ linux-4.4.111-vs2.3.9.1/fs/libfs.c 2018-01-09 16:36:32.000000000 +0000
927ca606 3647@@ -141,13 +141,14 @@ static inline unsigned char dt_type(stru
d337f35e
JR
3648 * both impossible due to the lock on directory.
3649 */
3650
c2e5f7c8 3651-int dcache_readdir(struct file *file, struct dir_context *ctx)
2380c486 3652+static inline int do_dcache_readdir_filter(struct file *filp,
c2e5f7c8 3653+ struct dir_context *ctx, int (*filter)(struct dentry *dentry))
d337f35e 3654 {
c2e5f7c8
JR
3655- struct dentry *dentry = file->f_path.dentry;
3656- struct dentry *cursor = file->private_data;
3657+ struct dentry *dentry = filp->f_path.dentry;
3658+ struct dentry *cursor = filp->private_data;
bb20add7 3659 struct list_head *p, *q = &cursor->d_child;
c2e5f7c8
JR
3660
3661- if (!dir_emit_dots(file, ctx))
3662+ if (!dir_emit_dots(filp, ctx))
3663 return 0;
3664 spin_lock(&dentry->d_lock);
3665 if (ctx->pos == 2)
927ca606 3666@@ -155,6 +156,8 @@ int dcache_readdir(struct file *file, st
c2e5f7c8
JR
3667
3668 for (p = q->next; p != &dentry->d_subdirs; p = p->next) {
bb20add7 3669 struct dentry *next = list_entry(p, struct dentry, d_child);
c2e5f7c8
JR
3670+ if (filter && !filter(next))
3671+ continue;
3672 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
3673 if (!simple_positive(next)) {
3674 spin_unlock(&next->d_lock);
927ca606 3675@@ -177,8 +180,22 @@ int dcache_readdir(struct file *file, st
c2e5f7c8 3676 spin_unlock(&dentry->d_lock);
d337f35e
JR
3677 return 0;
3678 }
c2e5f7c8
JR
3679+
3680 EXPORT_SYMBOL(dcache_readdir);
d337f35e 3681
c2e5f7c8 3682+int dcache_readdir(struct file *filp, struct dir_context *ctx)
d337f35e 3683+{
c2e5f7c8 3684+ return do_dcache_readdir_filter(filp, ctx, NULL);
d337f35e
JR
3685+}
3686+
c2e5f7c8
JR
3687+EXPORT_SYMBOL(dcache_readdir_filter);
3688+
3689+int dcache_readdir_filter(struct file *filp, struct dir_context *ctx,
d337f35e
JR
3690+ int (*filter)(struct dentry *))
3691+{
c2e5f7c8 3692+ return do_dcache_readdir_filter(filp, ctx, filter);
d337f35e 3693+}
d337f35e
JR
3694+
3695 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
3696 {
3697 return -EISDIR;
f19bd705
AM
3698diff -NurpP --minimal linux-4.4.111/fs/locks.c linux-4.4.111-vs2.3.9.1/fs/locks.c
3699--- linux-4.4.111/fs/locks.c 2018-01-11 07:57:45.000000000 +0000
3700+++ linux-4.4.111-vs2.3.9.1/fs/locks.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8
JR
3701@@ -129,6 +129,8 @@
3702 #include <linux/hashtable.h>
3703 #include <linux/percpu.h>
3704 #include <linux/lglock.h>
d337f35e
JR
3705+#include <linux/vs_base.h>
3706+#include <linux/vs_limit.h>
3707
bb20add7
AM
3708 #define CREATE_TRACE_POINTS
3709 #include <trace/events/filelock.h>
927ca606 3710@@ -255,11 +257,15 @@ static void locks_init_lock_heads(struct
d337f35e 3711 /* Allocate an empty lock structure. */
ab30d09f 3712 struct file_lock *locks_alloc_lock(void)
d337f35e 3713 {
a168f21d 3714- struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a0a3e0cf 3715+ struct file_lock *fl;
a168f21d
AM
3716
3717- if (fl)
3718- locks_init_lock_heads(fl);
a168f21d 3719+ fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
927ca606 3720
a168f21d
AM
3721+ if (fl) {
3722+ locks_init_lock_heads(fl);
927ca606 3723+ vx_locks_inc(fl);
a168f21d
AM
3724+ fl->fl_xid = -1;
3725+ }
3726 return fl;
3727 }
3728 EXPORT_SYMBOL_GPL(locks_alloc_lock);
927ca606 3729@@ -311,6 +317,7 @@ void locks_init_lock(struct file_lock *f
a168f21d
AM
3730 {
3731 memset(fl, 0, sizeof(struct file_lock));
3732 locks_init_lock_heads(fl);
3733+ fl->fl_xid = -1;
3734 }
3735
3736 EXPORT_SYMBOL(locks_init_lock);
927ca606 3737@@ -328,6 +335,7 @@ void locks_copy_conflock(struct file_loc
bb20add7
AM
3738 new->fl_start = fl->fl_start;
3739 new->fl_end = fl->fl_end;
d337f35e
JR
3740 new->fl_lmops = fl->fl_lmops;
3741+ new->fl_xid = fl->fl_xid;
bb20add7 3742 new->fl_ops = NULL;
d337f35e 3743
bb20add7 3744 if (fl->fl_lmops) {
927ca606 3745@@ -389,7 +397,10 @@ flock_make_lock(struct file *filp, unsig
d337f35e
JR
3746 fl->fl_flags = FL_FLOCK;
3747 fl->fl_type = type;
3748 fl->fl_end = OFFSET_MAX;
927ca606 3749-
d337f35e
JR
3750+
3751+ vxd_assert(filp->f_xid == vx_current_xid(),
3752+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3753+ fl->fl_xid = filp->f_xid;
bb20add7
AM
3754 return fl;
3755 }
927ca606
AM
3756
3757@@ -511,6 +522,7 @@ static int lease_init(struct file *filp,
d337f35e 3758
bb20add7 3759 fl->fl_owner = filp;
d337f35e
JR
3760 fl->fl_pid = current->tgid;
3761+ fl->fl_xid = vx_current_xid();
3762
3763 fl->fl_file = filp;
3764 fl->fl_flags = FL_LEASE;
927ca606 3765@@ -530,6 +542,10 @@ static struct file_lock *lease_alloc(str
d337f35e 3766 if (fl == NULL)
2380c486 3767 return ERR_PTR(error);
d337f35e
JR
3768
3769+ fl->fl_xid = vx_current_xid();
3770+ if (filp)
3771+ vxd_assert(filp->f_xid == fl->fl_xid,
3772+ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
d337f35e
JR
3773 error = lease_init(filp, type, fl);
3774 if (error) {
3775 locks_free_lock(fl);
927ca606
AM
3776@@ -908,6 +924,7 @@ static int flock_lock_inode(struct inode
3777 goto out;
ab30d09f 3778 }
2380c486
JR
3779
3780+ new_fl->fl_xid = -1;
3781 find_conflict:
927ca606
AM
3782 list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
3783 if (!flock_locks_conflict(request, fl))
3784@@ -934,7 +951,8 @@ out:
d337f35e
JR
3785 return error;
3786 }
3787
2380c486
JR
3788-static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
3789+static int __posix_lock_file(struct inode *inode, struct file_lock *request,
61333608 3790+ struct file_lock *conflock, vxid_t xid)
d337f35e 3791 {
927ca606 3792 struct file_lock *fl, *tmp;
d337f35e 3793 struct file_lock *new_fl = NULL;
927ca606
AM
3794@@ -950,6 +968,9 @@ static int __posix_lock_file(struct inod
3795 if (!ctx)
3796 return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
d337f35e 3797
927ca606
AM
3798+ if (xid)
3799+ vxd_assert(xid == vx_current_xid(),
3800+ "xid(%d) == current(%d)", xid, vx_current_xid());
d337f35e
JR
3801 /*
3802 * We may need two file_lock structures for this operation,
3803 * so we get them in advance to avoid races.
927ca606 3804@@ -960,7 +981,11 @@ static int __posix_lock_file(struct inod
d337f35e
JR
3805 (request->fl_type != F_UNLCK ||
3806 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
3807 new_fl = locks_alloc_lock();
3808+ new_fl->fl_xid = xid;
927ca606 3809+ // vx_locks_inc(new_fl);
d337f35e
JR
3810 new_fl2 = locks_alloc_lock();
3811+ new_fl2->fl_xid = xid;
927ca606 3812+ // vx_locks_inc(new_fl2);
d337f35e
JR
3813 }
3814
927ca606
AM
3815 spin_lock(&ctx->flc_lock);
3816@@ -1162,7 +1187,8 @@ static int __posix_lock_file(struct inod
2380c486 3817 int posix_lock_file(struct file *filp, struct file_lock *fl,
d337f35e
JR
3818 struct file_lock *conflock)
3819 {
b00e13aa
AM
3820- return __posix_lock_file(file_inode(filp), fl, conflock);
3821+ return __posix_lock_file(file_inode(filp),
d337f35e
JR
3822+ fl, conflock, filp->f_xid);
3823 }
2380c486 3824 EXPORT_SYMBOL(posix_lock_file);
d337f35e 3825
927ca606
AM
3826@@ -1178,7 +1204,7 @@ static int posix_lock_inode_wait(struct
3827 int error;
3828 might_sleep ();
3829 for (;;) {
3830- error = __posix_lock_file(inode, fl, NULL);
3831+ error = __posix_lock_file(inode, fl, NULL, 0);
3832 if (error != FILE_LOCK_DEFERRED)
3833 break;
3834 error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
3835@@ -1257,10 +1283,13 @@ int locks_mandatory_area(int read_write,
3836 fl.fl_end = offset + count - 1;
3837
3838 for (;;) {
3839+ vxid_t f_xid = 0;
3840+
ca5d134c 3841 if (filp) {
bb20add7 3842 fl.fl_owner = filp;
ca5d134c
JR
3843 fl.fl_flags &= ~FL_SLEEP;
3844- error = __posix_lock_file(inode, &fl, NULL);
927ca606
AM
3845+ f_xid = filp->f_xid;
3846+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
ca5d134c
JR
3847 if (!error)
3848 break;
3849 }
927ca606 3850@@ -1268,7 +1297,7 @@ int locks_mandatory_area(int read_write,
ca5d134c
JR
3851 if (sleep)
3852 fl.fl_flags |= FL_SLEEP;
3853 fl.fl_owner = current->files;
2380c486 3854- error = __posix_lock_file(inode, &fl, NULL);
927ca606 3855+ error = __posix_lock_file(inode, &fl, NULL, f_xid);
2380c486 3856 if (error != FILE_LOCK_DEFERRED)
d337f35e 3857 break;
2380c486 3858 error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
927ca606 3859@@ -2165,6 +2194,11 @@ int fcntl_setlk(unsigned int fd, struct
d337f35e
JR
3860 if (file_lock == NULL)
3861 return -ENOLCK;
3862
3863+ vxd_assert(filp->f_xid == vx_current_xid(),
3864+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3865+ file_lock->fl_xid = filp->f_xid;
927ca606 3866+ // vx_locks_inc(file_lock);
d337f35e
JR
3867+
3868 /*
3869 * This might block, so we do it before checking the inode.
3870 */
927ca606 3871@@ -2307,6 +2341,11 @@ int fcntl_setlk64(unsigned int fd, struc
d337f35e
JR
3872 if (file_lock == NULL)
3873 return -ENOLCK;
3874
3875+ vxd_assert(filp->f_xid == vx_current_xid(),
3876+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
3877+ file_lock->fl_xid = filp->f_xid;
927ca606 3878+ // vx_locks_inc(file_lock);
d337f35e
JR
3879+
3880 /*
3881 * This might block, so we do it before checking the inode.
3882 */
927ca606 3883@@ -2620,8 +2659,11 @@ static int locks_show(struct seq_file *f
2380c486 3884
c2e5f7c8 3885 lock_get_status(f, fl, iter->li_pos, "");
2380c486
JR
3886
3887- list_for_each_entry(bfl, &fl->fl_block, fl_block)
3888+ list_for_each_entry(bfl, &fl->fl_block, fl_block) {
3889+ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT))
d337f35e 3890+ continue;
bb20add7 3891 lock_get_status(f, bfl, iter->li_pos, " ->");
2380c486 3892+ }
d337f35e 3893
2380c486 3894 return 0;
ab30d09f 3895 }
f19bd705
AM
3896diff -NurpP --minimal linux-4.4.111/fs/mount.h linux-4.4.111-vs2.3.9.1/fs/mount.h
3897--- linux-4.4.111/fs/mount.h 2018-01-11 07:57:45.000000000 +0000
3898+++ linux-4.4.111-vs2.3.9.1/fs/mount.h 2018-01-09 16:36:32.000000000 +0000
927ca606 3899@@ -68,6 +68,7 @@ struct mount {
bb20add7 3900 struct hlist_head mnt_pins;
927ca606
AM
3901 struct fs_pin mnt_umount;
3902 struct dentry *mnt_ex_mountpoint;
61333608 3903+ vtag_t mnt_tag; /* tagging used for vfsmount */
db55b927
AM
3904 };
3905
92598135 3906 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
f19bd705
AM
3907diff -NurpP --minimal linux-4.4.111/fs/namei.c linux-4.4.111-vs2.3.9.1/fs/namei.c
3908--- linux-4.4.111/fs/namei.c 2018-01-11 07:57:45.000000000 +0000
3909+++ linux-4.4.111-vs2.3.9.1/fs/namei.c 2018-01-10 12:02:48.000000000 +0000
bb20add7 3910@@ -34,10 +34,20 @@
2380c486 3911 #include <linux/device_cgroup.h>
ec22aa5c 3912 #include <linux/fs_struct.h>
a168f21d 3913 #include <linux/posix_acl.h>
d337f35e 3914+#include <linux/proc_fs.h>
09be7631 3915+#include <linux/magic.h>
d337f35e
JR
3916+#include <linux/vserver/inode.h>
3917+#include <linux/vs_base.h>
3918+#include <linux/vs_tag.h>
3919+#include <linux/vs_cowbl.h>
2380c486
JR
3920+#include <linux/vs_device.h>
3921+#include <linux/vs_context.h>
3922+#include <linux/pid_namespace.h>
bb20add7 3923 #include <linux/hash.h>
d337f35e
JR
3924 #include <asm/uaccess.h>
3925
2bf5ad28 3926 #include "internal.h"
09be7631
JR
3927+#include "proc/internal.h"
3928 #include "mount.h"
3929
3930 /* [Feb-1997 T. Schoebel-Theuer]
927ca606 3931@@ -283,6 +293,93 @@ static int check_acl(struct inode *inode
a168f21d
AM
3932 return -EAGAIN;
3933 }
d337f35e 3934
7e46296a 3935+static inline int dx_barrier(const struct inode *inode)
d337f35e 3936+{
2380c486
JR
3937+ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) {
3938+ vxwprintk_task(1, "did hit the barrier.");
d337f35e
JR
3939+ return 1;
3940+ }
3941+ return 0;
3942+}
3943+
7e46296a 3944+static int __dx_permission(const struct inode *inode, int mask)
d337f35e
JR
3945+{
3946+ if (dx_barrier(inode))
3947+ return -EACCES;
d337f35e 3948+
2380c486
JR
3949+ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) {
3950+ /* devpts is xid tagged */
3951+ if (S_ISDIR(inode->i_mode) ||
61333608 3952+ vx_check((vxid_t)i_tag_read(inode), VS_IDENT | VS_WATCH_P))
2380c486 3953+ return 0;
ba86f833 3954+
adc1caaa 3955+ /* just pretend we didn't find anything */
ba86f833 3956+ return -ENOENT;
2380c486
JR
3957+ }
3958+ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
3959+ struct proc_dir_entry *de = PDE(inode);
3960+
bb20add7
AM
3961+ if (de && !vx_hide_check(0, de->vx_flags)) {
3962+ vxdprintk(VXD_CBIT(misc, 9),
3963+ VS_Q("%*s") " hidden by _dx_permission",
3964+ de->namelen, de->name);
2380c486 3965+ goto out;
bb20add7 3966+ }
2380c486
JR
3967+
3968+ if ((mask & (MAY_WRITE | MAY_APPEND))) {
3969+ struct pid *pid;
3970+ struct task_struct *tsk;
3971+
3972+ if (vx_check(0, VS_ADMIN | VS_WATCH_P) ||
3973+ vx_flags(VXF_STATE_SETUP, 0))
3974+ return 0;
3975+
3976+ pid = PROC_I(inode)->pid;
3977+ if (!pid)
3978+ goto out;
3979+
c6ceaf95 3980+ rcu_read_lock();
2380c486
JR
3981+ tsk = pid_task(pid, PIDTYPE_PID);
3982+ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]",
3983+ tsk, (tsk ? vx_task_xid(tsk) : 0));
c6ceaf95
AM
3984+ if (tsk &&
3985+ vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) {
3986+ rcu_read_unlock();
2380c486 3987+ return 0;
c6ceaf95
AM
3988+ }
3989+ rcu_read_unlock();
2380c486
JR
3990+ }
3991+ else {
3992+ /* FIXME: Should we block some entries here? */
3993+ return 0;
3994+ }
3995+ }
3996+ else {
3997+ if (dx_notagcheck(inode->i_sb) ||
61333608 3998+ dx_check((vxid_t)i_tag_read(inode),
537831f9 3999+ DX_HOSTID | DX_ADMIN | DX_WATCH | DX_IDENT))
2380c486
JR
4000+ return 0;
4001+ }
4002+
4003+out:
d337f35e
JR
4004+ return -EACCES;
4005+}
4006+
7e46296a 4007+int dx_permission(const struct inode *inode, int mask)
2380c486
JR
4008+{
4009+ int ret = __dx_permission(inode, mask);
4010+ if (unlikely(ret)) {
ba86f833
AM
4011+#ifndef CONFIG_VSERVER_WARN_DEVPTS
4012+ if (inode->i_sb->s_magic != DEVPTS_SUPER_MAGIC)
4013+#endif
4014+ vxwprintk_task(1,
4015+ "denied [0x%x] access to inode %s:%p[#%d,%lu]",
8ce283e1
AM
4016+ mask, inode->i_sb->s_id, inode,
4017+ i_tag_read(inode), inode->i_ino);
2380c486
JR
4018+ }
4019+ return ret;
4020+}
4021+
7e46296a 4022 /*
f6c5ef8b 4023 * This does the basic permission checking
7e46296a 4024 */
927ca606 4025@@ -407,10 +504,14 @@ int __inode_permission(struct inode *ino
d337f35e
JR
4026 /*
4027 * Nobody gets write access to an immutable file.
4028 */
4029- if (IS_IMMUTABLE(inode))
4030+ if (IS_IMMUTABLE(inode) && !IS_COW(inode))
4031 return -EACCES;
4032 }
4033
2380c486
JR
4034+ retval = dx_permission(inode, mask);
4035+ if (retval)
d337f35e 4036+ return retval;
2380c486 4037+
a168f21d
AM
4038 retval = do_inode_permission(inode, mask);
4039 if (retval)
4040 return retval;
927ca606
AM
4041@@ -1583,6 +1684,9 @@ static int lookup_fast(struct nameidata
4042 */
4043 if (negative)
4044 return -ENOENT;
be261992
AM
4045+
4046+ /* FIXME: check dx permission */
4047+
4048 path->mnt = mnt;
4049 path->dentry = dentry;
927ca606
AM
4050 if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
4051@@ -1613,6 +1717,8 @@ unlazy:
4052 dput(dentry);
4053 return -ENOENT;
be261992 4054 }
be261992 4055+
927ca606 4056+ /* FIXME: check dx permission */
be261992
AM
4057 path->mnt = mnt;
4058 path->dentry = dentry;
927ca606
AM
4059 err = follow_managed(path, nd);
4060@@ -2571,7 +2677,7 @@ static int may_delete(struct inode *dir,
d337f35e 4061 return -EPERM;
c2e5f7c8
JR
4062
4063 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
4064- IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
4065+ IS_IXORUNLINK(inode) || IS_SWAPFILE(inode))
d337f35e
JR
4066 return -EPERM;
4067 if (isdir) {
bb20add7 4068 if (!d_is_dir(victim))
927ca606 4069@@ -2653,19 +2759,25 @@ int vfs_create(struct inode *dir, struct
92598135 4070 bool want_excl)
a168f21d
AM
4071 {
4072 int error = may_create(dir, dentry);
a168f21d
AM
4073- if (error)
4074+ if (error) {
4075+ vxdprintk(VXD_CBIT(misc, 3), "may_create failed with %d", error);
537831f9 4076 return error;
a168f21d
AM
4077+ }
4078
4079 if (!dir->i_op->create)
4080 return -EACCES; /* shouldn't it be ENOSYS? */
4081 mode &= S_IALLUGO;
4082 mode |= S_IFREG;
4083 error = security_inode_create(dir, dentry, mode);
4084- if (error)
4085+ if (error) {
4086+ vxdprintk(VXD_CBIT(misc, 3), "security_inode_create failed with %d", error);
537831f9 4087 return error;
a168f21d 4088+ }
92598135 4089 error = dir->i_op->create(dir, dentry, mode, want_excl);
a168f21d
AM
4090 if (!error)
4091 fsnotify_create(dir, dentry);
4092+ else
4093+ vxdprintk(VXD_CBIT(misc, 3), "i_op->create failed with %d", error);
4094 return error;
4095 }
bb20add7 4096 EXPORT_SYMBOL(vfs_create);
927ca606 4097@@ -2701,6 +2813,15 @@ static int may_open(struct path *path, i
ec22aa5c 4098 break;
2380c486 4099 }
d337f35e
JR
4100
4101+#ifdef CONFIG_VSERVER_COWBL
763640ca
JR
4102+ if (IS_COW(inode) &&
4103+ ((flag & O_ACCMODE) != O_RDONLY)) {
d337f35e
JR
4104+ if (IS_COW_LINK(inode))
4105+ return -EMLINK;
2380c486 4106+ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE);
d337f35e
JR
4107+ mark_inode_dirty(inode);
4108+ }
4109+#endif
ec22aa5c 4110 error = inode_permission(inode, acc_mode);
d337f35e
JR
4111 if (error)
4112 return error;
927ca606 4113@@ -3178,6 +3299,16 @@ finish_open:
7b17263b 4114 }
92598135 4115 finish_open_created:
7b17263b
AM
4116 error = may_open(&nd->path, acc_mode, open_flag);
4117+#ifdef CONFIG_VSERVER_COWBL
4118+ if (error == -EMLINK) {
4119+ struct dentry *dentry;
f19bd705 4120+ dentry = cow_break_link(nd->name->name);
7b17263b
AM
4121+ if (IS_ERR(dentry))
4122+ error = PTR_ERR(dentry);
4123+ else
4124+ dput(dentry);
4125+ }
4126+#endif
4127 if (error)
92598135 4128 goto out;
bb20add7 4129
927ca606 4130@@ -3302,6 +3433,9 @@ static struct file *path_openat(struct n
92598135 4131 int opened = 0;
7b17263b
AM
4132 int error;
4133
927ca606 4134+#ifdef CONFIG_VSERVER_COWBL
7b17263b 4135+restart:
927ca606 4136+#endif
92598135 4137 file = get_empty_filp();
b00e13aa
AM
4138 if (IS_ERR(file))
4139 return file;
f19bd705
AM
4140@@ -3328,6 +3462,12 @@ static struct file *path_openat(struct n
4141 }
4142 }
4143 terminate_walk(nd);
4144+#ifdef CONFIG_VSERVER_COWBL
4145+ if (error == -EMLINK) {
4146+ // path_cleanup(nd);
4147+ goto restart;
4148+ }
4149+#endif
4150 out2:
4151 if (!(opened & FILE_OPENED)) {
4152 BUG_ON(!error);
4153@@ -3448,6 +3588,11 @@ static struct dentry *filename_create(in
a168f21d
AM
4154 goto fail;
4155 }
927ca606
AM
4156 putname(name);
4157+ vxdprintk(VXD_CBIT(misc, 3), "filename_create path.dentry = %p (%.*s), dentry = %p (%.*s), d_inode = %p",
a168f21d
AM
4158+ path->dentry, path->dentry->d_name.len,
4159+ path->dentry->d_name.name, dentry,
4160+ dentry->d_name.len, dentry->d_name.name,
4161+ path->dentry->d_inode);
4162 return dentry;
92598135 4163 fail:
a168f21d 4164 dput(dentry);
f19bd705 4165@@ -3564,6 +3709,7 @@ retry:
927ca606
AM
4166 error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
4167 break;
4168 }
4169+
927ca606
AM
4170 out:
4171 done_path_create(&path, dentry);
4172 if (retry_estale(error, lookup_flags)) {
4173@@ -4010,7 +4156,7 @@ int vfs_link(struct dentry *old_dentry,
d337f35e
JR
4174 /*
4175 * A link to an append-only or immutable file cannot be created.
4176 */
4177- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4178+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4179 return -EPERM;
ec22aa5c 4180 if (!dir->i_op->link)
d337f35e 4181 return -EPERM;
927ca606 4182@@ -4519,6 +4665,295 @@ int generic_readlink(struct dentry *dent
d337f35e 4183 }
bb20add7 4184 EXPORT_SYMBOL(generic_readlink);
d337f35e
JR
4185
4186+
4187+#ifdef CONFIG_VSERVER_COWBL
4188+
2380c486
JR
4189+static inline
4190+long do_cow_splice(struct file *in, struct file *out, size_t len)
4191+{
4192+ loff_t ppos = 0;
09be7631 4193+ loff_t opos = 0;
2380c486 4194+
09be7631 4195+ return do_splice_direct(in, &ppos, out, &opos, len, 0);
2380c486
JR
4196+}
4197+
d337f35e
JR
4198+struct dentry *cow_break_link(const char *pathname)
4199+{
b00e13aa 4200+ int ret, mode, pathlen, redo = 0, drop = 1;
d337f35e 4201+ struct nameidata old_nd, dir_nd;
e915af4e 4202+ struct path dir_path, *old_path, *new_path;
a168f21d 4203+ struct dentry *dir, *old_dentry, *new_dentry = NULL;
d337f35e
JR
4204+ struct file *old_file;
4205+ struct file *new_file;
4206+ char *to, *path, pad='\251';
4207+ loff_t size;
927ca606
AM
4208+ struct filename *filename = getname_kernel(pathname);
4209+ struct filename *to_filename;
d337f35e 4210+
ba86f833
AM
4211+ vxdprintk(VXD_CBIT(misc, 1),
4212+ "cow_break_link(" VS_Q("%s") ")", pathname);
e915af4e 4213+
d337f35e 4214+ path = kmalloc(PATH_MAX, GFP_KERNEL);
2380c486 4215+ ret = -ENOMEM;
927ca606 4216+ if (!path || IS_ERR(filename))
2380c486 4217+ goto out;
d337f35e 4218+
e915af4e 4219+ /* old_nd.path will have refs to dentry and mnt */
f19bd705 4220+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, old_path, NULL);
a168f21d 4221+ vxdprintk(VXD_CBIT(misc, 2),
e915af4e 4222+ "do_path_lookup(old): %d", ret);
2380c486
JR
4223+ if (ret < 0)
4224+ goto out_free_path;
d337f35e 4225+
e915af4e
AM
4226+ /* dentry/mnt refs handed over to old_path */
4227+ old_path = &old_nd.path;
4228+ /* no explicit reference for old_dentry here */
4229+ old_dentry = old_path->dentry;
2380c486 4230+
e915af4e
AM
4231+ mode = old_dentry->d_inode->i_mode;
4232+ to = d_path(old_path, path, PATH_MAX-2);
d337f35e 4233+ pathlen = strlen(to);
ba86f833 4234+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
4235+ "old path " VS_Q("%s") " [%p:" VS_Q("%.*s") ":%d]", to,
4236+ old_dentry,
4237+ old_dentry->d_name.len, old_dentry->d_name.name,
4238+ old_dentry->d_name.len);
d337f35e 4239+
2380c486 4240+ to[pathlen + 1] = 0;
d337f35e 4241+retry:
a168f21d 4242+ new_dentry = NULL;
d337f35e 4243+ to[pathlen] = pad--;
a168f21d 4244+ ret = -ELOOP;
d337f35e
JR
4245+ if (pad <= '\240')
4246+ goto out_rel_old;
4247+
ba86f833 4248+ vxdprintk(VXD_CBIT(misc, 1), "temp copy " VS_Q("%s"), to);
e915af4e
AM
4249+
4250+ /* dir_nd.path will have refs to dentry and mnt */
927ca606
AM
4251+ to_filename = getname_kernel(to);
4252+ ret = filename_lookup(AT_FDCWD, to_filename,
f19bd705 4253+ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_path, NULL);
927ca606 4254+ putname(to_filename);
a168f21d 4255+ vxdprintk(VXD_CBIT(misc, 2), "do_path_lookup(new): %d", ret);
2380c486
JR
4256+ if (ret < 0)
4257+ goto retry;
4258+
e915af4e
AM
4259+ /* this puppy downs the dir inode mutex if successful.
4260+ dir_path will hold refs to dentry and mnt and
b00e13aa 4261+ we'll have write access to the mnt */
a168f21d
AM
4262+ new_dentry = kern_path_create(AT_FDCWD, to, &dir_path, 0);
4263+ if (!new_dentry || IS_ERR(new_dentry)) {
2380c486 4264+ path_put(&dir_nd.path);
a168f21d
AM
4265+ vxdprintk(VXD_CBIT(misc, 2),
4266+ "kern_path_create(new) failed with %ld",
4267+ PTR_ERR(new_dentry));
d337f35e
JR
4268+ goto retry;
4269+ }
2380c486 4270+ vxdprintk(VXD_CBIT(misc, 2),
a168f21d
AM
4271+ "kern_path_create(new): %p [" VS_Q("%.*s") ":%d]",
4272+ new_dentry,
4273+ new_dentry->d_name.len, new_dentry->d_name.name,
4274+ new_dentry->d_name.len);
4275+
e915af4e
AM
4276+ /* take a reference on new_dentry */
4277+ dget(new_dentry);
4278+
4279+ /* dentry/mnt refs handed over to new_path */
4280+ new_path = &dir_path;
4281+
4282+ /* dentry for old/new dir */
2380c486 4283+ dir = dir_nd.path.dentry;
d337f35e 4284+
e915af4e
AM
4285+ /* give up reference on dir */
4286+ dput(new_path->dentry);
4287+
4288+ /* new_dentry already has a reference */
4289+ new_path->dentry = new_dentry;
4290+
4291+ ret = vfs_create(dir->d_inode, new_dentry, mode, 1);
d337f35e
JR
4292+ vxdprintk(VXD_CBIT(misc, 2),
4293+ "vfs_create(new): %d", ret);
4294+ if (ret == -EEXIST) {
2380c486 4295+ path_put(&dir_nd.path);
b00e13aa 4296+ mutex_unlock(&dir->d_inode->i_mutex);
e915af4e
AM
4297+ mnt_drop_write(new_path->mnt);
4298+ path_put(new_path);
4299+ new_dentry = NULL;
d337f35e
JR
4300+ goto retry;
4301+ }
2380c486
JR
4302+ else if (ret < 0)
4303+ goto out_unlock_new;
4304+
927ca606 4305+ /* the old file went away */
2380c486 4306+ ret = -ENOENT;
a168f21d 4307+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4308+ goto out_unlock_new;
4309+
e915af4e
AM
4310+ /* doesn't change refs for old_path */
4311+ old_file = dentry_open(old_path, O_RDONLY, current_cred());
d337f35e
JR
4312+ vxdprintk(VXD_CBIT(misc, 2),
4313+ "dentry_open(old): %p", old_file);
a168f21d
AM
4314+ if (IS_ERR(old_file)) {
4315+ ret = PTR_ERR(old_file);
2380c486
JR
4316+ goto out_unlock_new;
4317+ }
d337f35e 4318+
e915af4e
AM
4319+ /* doesn't change refs for new_path */
4320+ new_file = dentry_open(new_path, O_WRONLY, current_cred());
d337f35e
JR
4321+ vxdprintk(VXD_CBIT(misc, 2),
4322+ "dentry_open(new): %p", new_file);
a168f21d
AM
4323+ if (IS_ERR(new_file)) {
4324+ ret = PTR_ERR(new_file);
d337f35e 4325+ goto out_fput_old;
a168f21d 4326+ }
d337f35e 4327+
b00e13aa
AM
4328+ /* unlock the inode mutex from kern_path_create() */
4329+ mutex_unlock(&dir->d_inode->i_mutex);
4330+
4331+ /* drop write access to mnt */
4332+ mnt_drop_write(new_path->mnt);
4333+
4334+ drop = 0;
4335+
927ca606 4336+ size = i_size_read(old_file->f_path.dentry->d_inode);
2380c486
JR
4337+ ret = do_cow_splice(old_file, new_file, size);
4338+ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret);
4339+ if (ret < 0) {
d337f35e 4340+ goto out_fput_both;
2380c486
JR
4341+ } else if (ret < size) {
4342+ ret = -ENOSPC;
4343+ goto out_fput_both;
4344+ } else {
a168f21d
AM
4345+ struct inode *old_inode = old_dentry->d_inode;
4346+ struct inode *new_inode = new_dentry->d_inode;
2380c486
JR
4347+ struct iattr attr = {
4348+ .ia_uid = old_inode->i_uid,
4349+ .ia_gid = old_inode->i_gid,
4350+ .ia_valid = ATTR_UID | ATTR_GID
4351+ };
4352+
93de0823
AM
4353+ setattr_copy(new_inode, &attr);
4354+ mark_inode_dirty(new_inode);
2380c486 4355+ }
d337f35e 4356+
e915af4e 4357+ /* lock rename mutex */
a168f21d 4358+ mutex_lock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
2380c486
JR
4359+
4360+ /* drop out late */
4361+ ret = -ENOENT;
a168f21d 4362+ if ((redo = d_unhashed(old_dentry)))
2380c486
JR
4363+ goto out_unlock;
4364+
4365+ vxdprintk(VXD_CBIT(misc, 2),
ba86f833 4366+ "vfs_rename: [" VS_Q("%*s") ":%d] -> [" VS_Q("%*s") ":%d]",
a168f21d
AM
4367+ new_dentry->d_name.len, new_dentry->d_name.name,
4368+ new_dentry->d_name.len,
4369+ old_dentry->d_name.len, old_dentry->d_name.name,
4370+ old_dentry->d_name.len);
4371+ ret = vfs_rename(dir_nd.path.dentry->d_inode, new_dentry,
eafa5b1d 4372+ old_dentry->d_parent->d_inode, old_dentry, NULL, 0);
d337f35e 4373+ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
2380c486
JR
4374+
4375+out_unlock:
a168f21d 4376+ mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex);
d337f35e
JR
4377+
4378+out_fput_both:
4379+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4380+ "fput(new_file=%p[#%ld])", new_file,
4a036bed 4381+ atomic_long_read(&new_file->f_count));
d337f35e
JR
4382+ fput(new_file);
4383+
4384+out_fput_old:
4385+ vxdprintk(VXD_CBIT(misc, 3),
2380c486 4386+ "fput(old_file=%p[#%ld])", old_file,
4a036bed 4387+ atomic_long_read(&old_file->f_count));
d337f35e
JR
4388+ fput(old_file);
4389+
2380c486 4390+out_unlock_new:
e915af4e
AM
4391+ /* drop references from dir_nd.path */
4392+ path_put(&dir_nd.path);
4393+
b00e13aa
AM
4394+ if (drop) {
4395+ /* unlock the inode mutex from kern_path_create() */
4396+ mutex_unlock(&dir->d_inode->i_mutex);
4397+
4398+ /* drop write access to mnt */
4399+ mnt_drop_write(new_path->mnt);
4400+ }
e915af4e 4401+
2380c486
JR
4402+ if (!ret)
4403+ goto out_redo;
4404+
4405+ /* error path cleanup */
c2e5f7c8 4406+ vfs_unlink(dir->d_inode, new_dentry, NULL);
2380c486
JR
4407+
4408+out_redo:
4409+ if (!redo)
4410+ goto out_rel_both;
e915af4e
AM
4411+
4412+ /* lookup dentry once again
4413+ old_nd.path will be freed as old_path in out_rel_old */
f19bd705 4414+ ret = filename_lookup(AT_FDCWD, filename, LOOKUP_FOLLOW, old_path, NULL);
2380c486
JR
4415+ if (ret)
4416+ goto out_rel_both;
d337f35e 4417+
e915af4e 4418+ /* drop reference on new_dentry */
a168f21d 4419+ dput(new_dentry);
e915af4e
AM
4420+ new_dentry = old_path->dentry;
4421+ dget(new_dentry);
2380c486 4422+ vxdprintk(VXD_CBIT(misc, 2),
763640ca 4423+ "do_path_lookup(redo): %p [" VS_Q("%.*s") ":%d]",
a168f21d
AM
4424+ new_dentry,
4425+ new_dentry->d_name.len, new_dentry->d_name.name,
4426+ new_dentry->d_name.len);
2380c486
JR
4427+
4428+out_rel_both:
e915af4e
AM
4429+ if (new_path)
4430+ path_put(new_path);
d337f35e 4431+out_rel_old:
e915af4e 4432+ path_put(old_path);
2380c486 4433+out_free_path:
d337f35e 4434+ kfree(path);
2380c486 4435+out:
a168f21d
AM
4436+ if (ret) {
4437+ dput(new_dentry);
4438+ new_dentry = ERR_PTR(ret);
4439+ }
927ca606
AM
4440+ if (!IS_ERR(filename))
4441+ putname(filename);
a168f21d 4442+ vxdprintk(VXD_CBIT(misc, 3),
e915af4e 4443+ "cow_break_link returning with %p", new_dentry);
a168f21d 4444+ return new_dentry;
d337f35e
JR
4445+}
4446+
4447+#endif
1e8b8f9b
AM
4448+
4449+int vx_info_mnt_namespace(struct mnt_namespace *ns, char *buffer)
4450+{
4451+ struct path path;
4452+ struct vfsmount *vmnt;
4453+ char *pstr, *root;
4454+ int length = 0;
4455+
4456+ pstr = kmalloc(PATH_MAX, GFP_KERNEL);
4457+ if (!pstr)
4458+ return 0;
4459+
4460+ vmnt = &ns->root->mnt;
4461+ path.mnt = vmnt;
4462+ path.dentry = vmnt->mnt_root;
4463+ root = d_path(&path, pstr, PATH_MAX - 2);
4464+ length = sprintf(buffer + length,
4465+ "Namespace:\t%p [#%u]\n"
4466+ "RootPath:\t%s\n",
4467+ ns, atomic_read(&ns->count),
4468+ root);
4469+ kfree(pstr);
4470+ return length;
4471+}
bb20add7 4472+
265de2f7 4473+EXPORT_SYMBOL(vx_info_mnt_namespace);
d337f35e
JR
4474+
4475 /* get the link contents into pagecache */
4476 static char *page_getlink(struct dentry * dentry, struct page **ppage)
4477 {
f19bd705
AM
4478diff -NurpP --minimal linux-4.4.111/fs/namespace.c linux-4.4.111-vs2.3.9.1/fs/namespace.c
4479--- linux-4.4.111/fs/namespace.c 2018-01-11 07:57:45.000000000 +0000
4480+++ linux-4.4.111-vs2.3.9.1/fs/namespace.c 2018-01-09 16:36:32.000000000 +0000
978063ce 4481@@ -24,6 +24,11 @@
09be7631 4482 #include <linux/magic.h>
52afa9bd 4483 #include <linux/bootmem.h>
bb20add7 4484 #include <linux/task_work.h>
d337f35e 4485+#include <linux/vs_base.h>
d337f35e
JR
4486+#include <linux/vs_context.h>
4487+#include <linux/vs_tag.h>
2380c486
JR
4488+#include <linux/vserver/space.h>
4489+#include <linux/vserver/global.h>
d337f35e 4490 #include "pnode.h"
db55b927
AM
4491 #include "internal.h"
4492
927ca606 4493@@ -971,6 +976,10 @@ vfs_kern_mount(struct file_system_type *
be261992
AM
4494 if (!type)
4495 return ERR_PTR(-ENODEV);
4496
4497+ if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
4498+ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
4499+ return ERR_PTR(-EPERM);
4500+
4501 mnt = alloc_vfsmnt(name);
4502 if (!mnt)
4503 return ERR_PTR(-ENOMEM);
927ca606 4504@@ -1046,6 +1055,7 @@ static struct mount *clone_mnt(struct mo
92598135
AM
4505 mnt->mnt.mnt_root = dget(root);
4506 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
4507 mnt->mnt_parent = mnt;
c2e5f7c8
JR
4508+ mnt->mnt_tag = old->mnt_tag;
4509 lock_mount_hash();
92598135 4510 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
c2e5f7c8 4511 unlock_mount_hash();
927ca606 4512@@ -1620,7 +1630,8 @@ out_unlock:
c2e5f7c8
JR
4513 */
4514 static inline bool may_mount(void)
4515 {
4516- return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
4517+ return vx_ns_capable(current->nsproxy->mnt_ns->user_ns,
4518+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT);
4519 }
4520
4521 /*
927ca606 4522@@ -2121,6 +2132,7 @@ static int do_change_type(struct path *p
763640ca
JR
4523 if (err)
4524 goto out_unlock;
4525 }
4526+ // mnt->mnt_flags = mnt_flags;
4527
c2e5f7c8 4528 lock_mount_hash();
763640ca 4529 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
927ca606 4530@@ -2149,12 +2161,14 @@ static bool has_locked_children(struct m
ec22aa5c 4531 * do loopback mount.
d337f35e 4532 */
537831f9 4533 static int do_loopback(struct path *path, const char *old_name,
2380c486 4534- int recurse)
61333608 4535+ vtag_t tag, unsigned long flags, int mnt_flags)
d337f35e 4536 {
ec22aa5c 4537 struct path old_path;
09be7631
JR
4538 struct mount *mnt = NULL, *old, *parent;
4539 struct mountpoint *mp;
d337f35e 4540+ int recurse = flags & MS_REC;
b00e13aa 4541 int err;
2380c486 4542+
d337f35e 4543 if (!old_name || !*old_name)
b00e13aa
AM
4544 return -EINVAL;
4545 err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
927ca606 4546@@ -2234,7 +2248,7 @@ static int change_mount_flags(struct vfs
ec22aa5c 4547 * on it - tough luck.
d337f35e 4548 */
ec22aa5c 4549 static int do_remount(struct path *path, int flags, int mnt_flags,
d337f35e 4550- void *data)
61333608 4551+ void *data, vxid_t xid)
d337f35e
JR
4552 {
4553 int err;
ec22aa5c 4554 struct super_block *sb = path->mnt->mnt_sb;
927ca606 4555@@ -2742,6 +2756,7 @@ long do_mount(const char *dev_name, cons
ec22aa5c 4556 struct path path;
d337f35e
JR
4557 int retval = 0;
4558 int mnt_flags = 0;
61333608 4559+ vtag_t tag = 0;
d337f35e
JR
4560
4561 /* Discard magic */
4562 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
927ca606 4563@@ -2767,6 +2782,12 @@ long do_mount(const char *dev_name, cons
ec22aa5c
AM
4564 if (!(flags & MS_NOATIME))
4565 mnt_flags |= MNT_RELATIME;
d337f35e 4566
2380c486
JR
4567+ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) {
4568+ /* FIXME: bind and re-mounts get the tag flag? */
d337f35e
JR
4569+ if (flags & (MS_BIND|MS_REMOUNT))
4570+ flags |= MS_TAGID;
4571+ }
d337f35e
JR
4572+
4573 /* Separate the per-mountpoint flags */
d337f35e
JR
4574 if (flags & MS_NOSUID)
4575 mnt_flags |= MNT_NOSUID;
927ca606 4576@@ -2791,15 +2812,17 @@ long do_mount(const char *dev_name, cons
bb20add7
AM
4577 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
4578 }
d337f35e 4579
b00e13aa 4580+ if (!vx_capable(CAP_SYS_ADMIN, VXC_DEV_MOUNT))
d337f35e 4581+ mnt_flags |= MNT_NODEV;
c146dd73 4582 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
ec22aa5c
AM
4583 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
4584 MS_STRICTATIME);
d337f35e
JR
4585
4586 if (flags & MS_REMOUNT)
ec22aa5c 4587 retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
d337f35e
JR
4588- data_page);
4589+ data_page, tag);
4590 else if (flags & MS_BIND)
ec22aa5c
AM
4591- retval = do_loopback(&path, dev_name, flags & MS_REC);
4592+ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags);
d337f35e 4593 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
ec22aa5c 4594 retval = do_change_type(&path, flags);
d337f35e 4595 else if (flags & MS_MOVE)
927ca606 4596@@ -2919,6 +2942,7 @@ struct mnt_namespace *copy_mnt_ns(unsign
c2e5f7c8 4597 p = next_mnt(p, old);
d337f35e 4598 }
09be7631 4599 namespace_unlock();
2380c486
JR
4600+ atomic_inc(&vs_global_mnt_ns);
4601
4602 if (rootmnt)
4603 mntput(rootmnt);
927ca606 4604@@ -3094,9 +3118,10 @@ SYSCALL_DEFINE2(pivot_root, const char _
db55b927
AM
4605 new_mnt = real_mount(new.mnt);
4606 root_mnt = real_mount(root.mnt);
09be7631
JR
4607 old_mnt = real_mount(old.mnt);
4608- if (IS_MNT_SHARED(old_mnt) ||
4609+ if ((IS_MNT_SHARED(old_mnt) ||
db55b927
AM
4610 IS_MNT_SHARED(new_mnt->mnt_parent) ||
4611- IS_MNT_SHARED(root_mnt->mnt_parent))
4612+ IS_MNT_SHARED(root_mnt->mnt_parent)) &&
50e68740 4613+ !vx_flags(VXF_STATE_SETUP, 0))
763640ca 4614 goto out4;
db55b927 4615 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
763640ca 4616 goto out4;
927ca606 4617@@ -3234,6 +3259,7 @@ void put_mnt_ns(struct mnt_namespace *ns
c2e5f7c8
JR
4618 if (!atomic_dec_and_test(&ns->count))
4619 return;
4620 drop_collected_mounts(&ns->root->mnt);
2380c486 4621+ atomic_dec(&vs_global_mnt_ns);
b00e13aa 4622 free_mnt_ns(ns);
2380c486 4623 }
db55b927 4624
f19bd705
AM
4625diff -NurpP --minimal linux-4.4.111/fs/nfs/client.c linux-4.4.111-vs2.3.9.1/fs/nfs/client.c
4626--- linux-4.4.111/fs/nfs/client.c 2016-07-05 04:15:08.000000000 +0000
4627+++ linux-4.4.111-vs2.3.9.1/fs/nfs/client.c 2018-01-09 16:36:32.000000000 +0000
927ca606 4628@@ -583,6 +583,9 @@ int nfs_init_server_rpcclient(struct nfs
2380c486
JR
4629 if (server->flags & NFS_MOUNT_SOFT)
4630 server->client->cl_softrtry = 1;
d337f35e
JR
4631
4632+ server->client->cl_tag = 0;
4633+ if (server->flags & NFS_MOUNT_TAGGED)
4634+ server->client->cl_tag = 1;
4635 return 0;
4636 }
92598135 4637 EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
927ca606 4638@@ -760,6 +763,10 @@ static void nfs_server_set_fsinfo(struct
d337f35e
JR
4639 server->acdirmin = server->acdirmax = 0;
4640 }
4641
4642+ /* FIXME: needs fsinfo
4643+ if (server->flags & NFS_MOUNT_TAGGED)
4644+ sb->s_flags |= MS_TAGGED; */
4645+
4646 server->maxfilesize = fsinfo->maxfilesize;
4647
ab30d09f 4648 server->time_delta = fsinfo->time_delta;
f19bd705
AM
4649diff -NurpP --minimal linux-4.4.111/fs/nfs/dir.c linux-4.4.111-vs2.3.9.1/fs/nfs/dir.c
4650--- linux-4.4.111/fs/nfs/dir.c 2018-01-11 07:57:45.000000000 +0000
4651+++ linux-4.4.111-vs2.3.9.1/fs/nfs/dir.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 4652@@ -37,6 +37,7 @@
2380c486 4653 #include <linux/sched.h>
ab30d09f 4654 #include <linux/kmemleak.h>
d33d7b00 4655 #include <linux/xattr.h>
d337f35e
JR
4656+#include <linux/vs_tag.h>
4657
d337f35e 4658 #include "delegation.h"
ab30d09f 4659 #include "iostat.h"
927ca606 4660@@ -1396,6 +1397,7 @@ struct dentry *nfs_lookup(struct inode *
42bc425c
AM
4661 /* Success: notify readdir to use READDIRPLUS */
4662 nfs_advise_use_readdirplus(dir);
d337f35e
JR
4663
4664+ dx_propagate_tag(nd, inode);
4665 no_entry:
927ca606 4666 res = d_splice_alias(inode, dentry);
d337f35e 4667 if (res != NULL) {
f19bd705
AM
4668diff -NurpP --minimal linux-4.4.111/fs/nfs/inode.c linux-4.4.111-vs2.3.9.1/fs/nfs/inode.c
4669--- linux-4.4.111/fs/nfs/inode.c 2018-01-11 07:57:45.000000000 +0000
4670+++ linux-4.4.111-vs2.3.9.1/fs/nfs/inode.c 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8
JR
4671@@ -38,6 +38,7 @@
4672 #include <linux/slab.h>
d33d7b00 4673 #include <linux/compat.h>
db55b927 4674 #include <linux/freezer.h>
d337f35e
JR
4675+#include <linux/vs_tag.h>
4676
d337f35e 4677 #include <asm/uaccess.h>
1e8b8f9b 4678
927ca606 4679@@ -376,6 +377,8 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4680 if (inode->i_state & I_NEW) {
4681 struct nfs_inode *nfsi = NFS_I(inode);
4682 unsigned long now = jiffies;
a4a22af8
AM
4683+ kuid_t kuid;
4684+ kgid_t kgid;
ec22aa5c
AM
4685
4686 /* We set i_ino for the few things that still rely on it,
4687 * such as stat(2) */
927ca606 4688@@ -419,8 +422,8 @@ nfs_fhget(struct super_block *sb, struct
f6c5ef8b 4689 inode->i_version = 0;
ec22aa5c 4690 inode->i_size = 0;
f6c5ef8b 4691 clear_nlink(inode);
b00e13aa
AM
4692- inode->i_uid = make_kuid(&init_user_ns, -2);
4693- inode->i_gid = make_kgid(&init_user_ns, -2);
a4a22af8
AM
4694+ kuid = make_kuid(&init_user_ns, -2);
4695+ kgid = make_kgid(&init_user_ns, -2);
ec22aa5c
AM
4696 inode->i_blocks = 0;
4697 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
42bc425c 4698 nfsi->write_io = 0;
927ca606 4699@@ -455,11 +458,11 @@ nfs_fhget(struct super_block *sb, struct
7e46296a 4700 else if (nfs_server_capable(inode, NFS_CAP_NLINK))
bb20add7 4701 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4702 if (fattr->valid & NFS_ATTR_FATTR_OWNER)
4703- inode->i_uid = fattr->uid;
a4a22af8 4704+ kuid = fattr->uid;
7e46296a 4705 else if (nfs_server_capable(inode, NFS_CAP_OWNER))
bb20add7 4706 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
ec22aa5c
AM
4707 if (fattr->valid & NFS_ATTR_FATTR_GROUP)
4708- inode->i_gid = fattr->gid;
a4a22af8 4709+ kgid = fattr->gid;
7e46296a 4710 else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
bb20add7 4711 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR);
42bc425c 4712 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
927ca606 4713@@ -470,6 +473,10 @@ nfs_fhget(struct super_block *sb, struct
ec22aa5c
AM
4714 */
4715 inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
4716 }
a4a22af8
AM
4717+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4718+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4719+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, GLOBAL_ROOT_TAG);
ec22aa5c 4720+ /* maybe fattr->xid someday */
c2e5f7c8
JR
4721
4722 nfs_setsecurity(inode, fattr, label);
4723
927ca606 4724@@ -611,6 +618,8 @@ void nfs_setattr_update_inode(struct ino
d337f35e
JR
4725 inode->i_uid = attr->ia_uid;
4726 if ((attr->ia_valid & ATTR_GID) != 0)
4727 inode->i_gid = attr->ia_gid;
4728+ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4729+ inode->i_tag = attr->ia_tag;
bb20add7
AM
4730 nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS
4731 | NFS_INO_INVALID_ACL);
927ca606
AM
4732 }
4733@@ -1235,7 +1244,9 @@ static int nfs_check_inode_attributes(st
d337f35e
JR
4734 struct nfs_inode *nfsi = NFS_I(inode);
4735 loff_t cur_size, new_isize;
2380c486 4736 unsigned long invalid = 0;
a4a22af8 4737-
b00e13aa
AM
4738+ kuid_t kuid;
4739+ kgid_t kgid;
4740+ ktag_t ktag;
d337f35e 4741
42bc425c 4742 if (nfs_have_delegated_attributes(inode))
a4a22af8 4743 return 0;
927ca606
AM
4744@@ -1262,13 +1273,18 @@ static int nfs_check_inode_attributes(st
4745 if (nfsi->nrequests != 0)
4746 invalid &= ~NFS_INO_REVAL_PAGECACHE;
d337f35e 4747
a4a22af8
AM
4748+ kuid = INOTAG_KUID(DX_TAG(inode), fattr->uid, fattr->gid);
4749+ kgid = INOTAG_KGID(DX_TAG(inode), fattr->uid, fattr->gid);
4750+ ktag = INOTAG_KTAG(DX_TAG(inode), fattr->uid, fattr->gid, GLOBAL_ROOT_TAG);
d337f35e
JR
4751+
4752 /* Have any file permissions changed? */
ec22aa5c 4753 if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
9474138d 4754 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4755- if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
4756+ if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, kuid))
ec22aa5c 4757 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
b00e13aa
AM
4758- if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
4759+ if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, kgid))
ec22aa5c
AM
4760 invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
4761+ /* maybe check for tag too? */
d337f35e
JR
4762
4763 /* Has the link count changed? */
ec22aa5c 4764 if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
927ca606 4765@@ -1642,6 +1658,9 @@ static int nfs_update_inode(struct inode
2380c486 4766 unsigned long now = jiffies;
7e46296a 4767 unsigned long save_cache_validity;
927ca606 4768 bool cache_revalidated = true;
a4a22af8
AM
4769+ kuid_t kuid;
4770+ kgid_t kgid;
4771+ ktag_t ktag;
d337f35e 4772
bb20add7 4773 dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
2380c486 4774 __func__, inode->i_sb->s_id, inode->i_ino,
927ca606
AM
4775@@ -1752,6 +1771,9 @@ static int nfs_update_inode(struct inode
4776 cache_revalidated = false;
4777 }
d337f35e 4778
a4a22af8
AM
4779+ kuid = TAGINO_KUID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4780+ kgid = TAGINO_KGID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4781+ ktag = TAGINO_KTAG(DX_TAG(inode), inode->i_tag);
ec22aa5c
AM
4782
4783 if (fattr->valid & NFS_ATTR_FATTR_ATIME)
4784 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
927ca606
AM
4785@@ -1806,6 +1828,10 @@ static int nfs_update_inode(struct inode
4786 cache_revalidated = false;
4787 }
ec22aa5c 4788
a4a22af8
AM
4789+ inode->i_uid = INOTAG_KUID(DX_TAG(inode), kuid, kgid);
4790+ inode->i_gid = INOTAG_KGID(DX_TAG(inode), kuid, kgid);
4791+ inode->i_tag = INOTAG_KTAG(DX_TAG(inode), kuid, kgid, ktag);
ec22aa5c
AM
4792+
4793 if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
4794 if (inode->i_nlink != fattr->nlink) {
4795 invalid |= NFS_INO_INVALID_ATTR;
f19bd705
AM
4796diff -NurpP --minimal linux-4.4.111/fs/nfs/nfs3xdr.c linux-4.4.111-vs2.3.9.1/fs/nfs/nfs3xdr.c
4797--- linux-4.4.111/fs/nfs/nfs3xdr.c 2016-07-05 04:12:33.000000000 +0000
4798+++ linux-4.4.111-vs2.3.9.1/fs/nfs/nfs3xdr.c 2018-01-09 17:17:07.000000000 +0000
78865d5b 4799@@ -20,6 +20,7 @@
d337f35e
JR
4800 #include <linux/nfs3.h>
4801 #include <linux/nfs_fs.h>
4802 #include <linux/nfsacl.h>
4803+#include <linux/vs_tag.h>
4804 #include "internal.h"
4805
4806 #define NFSDBG_FACILITY NFSDBG_XDR
b00e13aa 4807@@ -558,7 +559,8 @@ static __be32 *xdr_decode_nfstime3(__be3
d33d7b00
AM
4808 * set_mtime mtime;
4809 * };
4810 */
4811-static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
4812+static void encode_sattr3(struct xdr_stream *xdr,
4813+ const struct iattr *attr, int tag)
d337f35e 4814 {
d33d7b00
AM
4815 u32 nbytes;
4816 __be32 *p;
b00e13aa 4817@@ -590,15 +592,19 @@ static void encode_sattr3(struct xdr_str
d33d7b00 4818 } else
d337f35e 4819 *p++ = xdr_zero;
d33d7b00 4820
d337f35e
JR
4821- if (attr->ia_valid & ATTR_UID) {
4822+ if (attr->ia_valid & ATTR_UID ||
4823+ (tag && (attr->ia_valid & ATTR_TAG))) {
4824 *p++ = xdr_one;
b00e13aa 4825- *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
a4a22af8
AM
4826+ *p++ = cpu_to_be32(from_kuid(&init_user_ns,
4827+ TAGINO_KUID(tag, attr->ia_uid, attr->ia_tag)));
d33d7b00 4828 } else
d337f35e 4829 *p++ = xdr_zero;
d33d7b00 4830
d337f35e
JR
4831- if (attr->ia_valid & ATTR_GID) {
4832+ if (attr->ia_valid & ATTR_GID ||
4833+ (tag && (attr->ia_valid & ATTR_TAG))) {
4834 *p++ = xdr_one;
b00e13aa 4835- *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
a4a22af8
AM
4836+ *p++ = cpu_to_be32(from_kgid(&init_user_ns,
4837+ TAGINO_KGID(tag, attr->ia_gid, attr->ia_tag)));
d33d7b00 4838 } else
d337f35e 4839 *p++ = xdr_zero;
d33d7b00 4840
b00e13aa 4841@@ -887,7 +893,7 @@ static void nfs3_xdr_enc_setattr3args(st
d33d7b00 4842 const struct nfs3_sattrargs *args)
d337f35e 4843 {
d33d7b00
AM
4844 encode_nfs_fh3(xdr, args->fh);
4845- encode_sattr3(xdr, args->sattr);
4846+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
4847 encode_sattrguard3(xdr, args);
4848 }
d337f35e 4849
b00e13aa 4850@@ -1037,13 +1043,13 @@ static void nfs3_xdr_enc_write3args(stru
d33d7b00
AM
4851 * };
4852 */
4853 static void encode_createhow3(struct xdr_stream *xdr,
4854- const struct nfs3_createargs *args)
4855+ const struct nfs3_createargs *args, int tag)
d337f35e 4856 {
d33d7b00
AM
4857 encode_uint32(xdr, args->createmode);
4858 switch (args->createmode) {
4859 case NFS3_CREATE_UNCHECKED:
4860 case NFS3_CREATE_GUARDED:
4861- encode_sattr3(xdr, args->sattr);
4862+ encode_sattr3(xdr, args->sattr, tag);
4863 break;
4864 case NFS3_CREATE_EXCLUSIVE:
4865 encode_createverf3(xdr, args->verifier);
b00e13aa 4866@@ -1058,7 +1064,7 @@ static void nfs3_xdr_enc_create3args(str
d33d7b00
AM
4867 const struct nfs3_createargs *args)
4868 {
4869 encode_diropargs3(xdr, args->fh, args->name, args->len);
4870- encode_createhow3(xdr, args);
4871+ encode_createhow3(xdr, args, req->rq_task->tk_client->cl_tag);
4872 }
4873
4874 /*
b00e13aa 4875@@ -1074,7 +1080,7 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4876 const struct nfs3_mkdirargs *args)
4877 {
4878 encode_diropargs3(xdr, args->fh, args->name, args->len);
4879- encode_sattr3(xdr, args->sattr);
4880+ encode_sattr3(xdr, args->sattr, req->rq_task->tk_client->cl_tag);
d337f35e 4881 }
d33d7b00
AM
4882
4883 /*
b00e13aa 4884@@ -1091,9 +1097,9 @@ static void nfs3_xdr_enc_mkdir3args(stru
d33d7b00
AM
4885 * };
4886 */
4887 static void encode_symlinkdata3(struct xdr_stream *xdr,
4888- const struct nfs3_symlinkargs *args)
4889+ const struct nfs3_symlinkargs *args, int tag)
4890 {
4891- encode_sattr3(xdr, args->sattr);
4892+ encode_sattr3(xdr, args->sattr, tag);
4893 encode_nfspath3(xdr, args->pages, args->pathlen);
4894 }
4895
b00e13aa 4896@@ -1102,7 +1108,7 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4897 const struct nfs3_symlinkargs *args)
4898 {
4899 encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
4900- encode_symlinkdata3(xdr, args);
4901+ encode_symlinkdata3(xdr, args, req->rq_task->tk_client->cl_tag);
927ca606 4902 xdr->buf->flags |= XDRBUF_WRITE;
d33d7b00
AM
4903 }
4904
927ca606 4905@@ -1131,24 +1137,24 @@ static void nfs3_xdr_enc_symlink3args(st
d33d7b00
AM
4906 * };
4907 */
4908 static void encode_devicedata3(struct xdr_stream *xdr,
4909- const struct nfs3_mknodargs *args)
4910+ const struct nfs3_mknodargs *args, int tag)
4911 {
4912- encode_sattr3(xdr, args->sattr);
4913+ encode_sattr3(xdr, args->sattr, tag);
4914 encode_specdata3(xdr, args->rdev);
4915 }
4916
4917 static void encode_mknoddata3(struct xdr_stream *xdr,
4918- const struct nfs3_mknodargs *args)
4919+ const struct nfs3_mknodargs *args, int tag)
4920 {
4921 encode_ftype3(xdr, args->type);
4922 switch (args->type) {
4923 case NF3CHR:
4924 case NF3BLK:
4925- encode_devicedata3(xdr, args);
4926+ encode_devicedata3(xdr, args, tag);
4927 break;
4928 case NF3SOCK:
4929 case NF3FIFO:
4930- encode_sattr3(xdr, args->sattr);
4931+ encode_sattr3(xdr, args->sattr, tag);
4932 break;
4933 case NF3REG:
4934 case NF3DIR:
927ca606 4935@@ -1163,7 +1169,7 @@ static void nfs3_xdr_enc_mknod3args(stru
d33d7b00 4936 const struct nfs3_mknodargs *args)
d337f35e 4937 {
d33d7b00
AM
4938 encode_diropargs3(xdr, args->fh, args->name, args->len);
4939- encode_mknoddata3(xdr, args);
4940+ encode_mknoddata3(xdr, args, req->rq_task->tk_client->cl_tag);
4941 }
4942
4943 /*
f19bd705
AM
4944diff -NurpP --minimal linux-4.4.111/fs/nfs/super.c linux-4.4.111-vs2.3.9.1/fs/nfs/super.c
4945--- linux-4.4.111/fs/nfs/super.c 2018-01-11 07:57:45.000000000 +0000
4946+++ linux-4.4.111-vs2.3.9.1/fs/nfs/super.c 2018-01-09 16:36:32.000000000 +0000
927ca606 4947@@ -54,6 +54,7 @@
b00e13aa 4948 #include <linux/parser.h>
1e8b8f9b
AM
4949 #include <linux/nsproxy.h>
4950 #include <linux/rcupdate.h>
d337f35e
JR
4951+#include <linux/vs_tag.h>
4952
d337f35e 4953 #include <asm/uaccess.h>
1e8b8f9b 4954
927ca606 4955@@ -102,6 +103,7 @@ enum {
1e8b8f9b 4956 Opt_mountport,
ab30d09f 4957 Opt_mountvers,
ab30d09f
AM
4958 Opt_minorversion,
4959+ Opt_tagid,
4960
4961 /* Mount options that take string arguments */
1e8b8f9b 4962 Opt_nfsvers,
927ca606 4963@@ -114,6 +116,9 @@ enum {
537831f9
AM
4964 /* Special mount options */
4965 Opt_userspace, Opt_deprecated, Opt_sloppy,
4966
4967+ /* Linux-VServer tagging options */
4968+ Opt_tag, Opt_notag,
4969+
4970 Opt_err
4971 };
4972
927ca606 4973@@ -183,6 +188,10 @@ static const match_table_t nfs_mount_opt
537831f9
AM
4974 { Opt_fscache_uniq, "fsc=%s" },
4975 { Opt_local_lock, "local_lock=%s" },
ab30d09f
AM
4976
4977+ { Opt_tag, "tag" },
4978+ { Opt_notag, "notag" },
4979+ { Opt_tagid, "tagid=%u" },
4980+
537831f9
AM
4981 /* The following needs to be listed after all other options */
4982 { Opt_nfsvers, "v%s" },
ab30d09f 4983
927ca606 4984@@ -642,6 +651,7 @@ static void nfs_show_mount_options(struc
2380c486 4985 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
ec22aa5c
AM
4986 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
4987 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
d337f35e
JR
4988+ { NFS_MOUNT_TAGGED, ",tag", "" },
4989 { 0, NULL, NULL }
4990 };
4991 const struct proc_nfs_info *nfs_infop;
927ca606 4992@@ -1324,6 +1334,14 @@ static int nfs_parse_mount_options(char
537831f9 4993 case Opt_nomigration:
927ca606 4994 mnt->options &= ~NFS_OPTION_MIGRATION;
ab30d09f
AM
4995 break;
4996+#ifndef CONFIG_TAGGING_NONE
4997+ case Opt_tag:
4998+ mnt->flags |= NFS_MOUNT_TAGGED;
4999+ break;
5000+ case Opt_notag:
5001+ mnt->flags &= ~NFS_MOUNT_TAGGED;
5002+ break;
5003+#endif
5004
5005 /*
5006 * options that take numeric values
927ca606 5007@@ -1410,6 +1428,12 @@ static int nfs_parse_mount_options(char
ab30d09f
AM
5008 goto out_invalid_value;
5009 mnt->minorversion = option;
5010 break;
5011+#ifdef CONFIG_PROPAGATE
5012+ case Opt_tagid:
5013+ /* use args[0] */
5014+ nfs_data.flags |= NFS_MOUNT_TAGGED;
5015+ break;
5016+#endif
5017
5018 /*
5019 * options that take text values
f19bd705
AM
5020diff -NurpP --minimal linux-4.4.111/fs/nfsd/auth.c linux-4.4.111-vs2.3.9.1/fs/nfsd/auth.c
5021--- linux-4.4.111/fs/nfsd/auth.c 2018-01-11 07:57:45.000000000 +0000
5022+++ linux-4.4.111-vs2.3.9.1/fs/nfsd/auth.c 2018-01-11 08:03:00.000000000 +0000
bb20add7
AM
5023@@ -1,6 +1,7 @@
5024 /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
2bf5ad28
AM
5025
5026 #include <linux/sched.h>
d337f35e 5027+#include <linux/vs_tag.h>
2bf5ad28 5028 #include "nfsd.h"
2380c486 5029 #include "auth.h"
d337f35e 5030
bb20add7 5031@@ -35,6 +36,9 @@ int nfsd_setuser(struct svc_rqst *rqstp,
d337f35e 5032
ec22aa5c
AM
5033 new->fsuid = rqstp->rq_cred.cr_uid;
5034 new->fsgid = rqstp->rq_cred.cr_gid;
5035+ /* FIXME: this desperately needs a tag :)
61333608 5036+ new->xid = (vxid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
ec22aa5c 5037+ */
d337f35e 5038
ec22aa5c
AM
5039 rqgi = rqstp->rq_cred.cr_group_info;
5040
f19bd705
AM
5041diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfs3xdr.c linux-4.4.111-vs2.3.9.1/fs/nfsd/nfs3xdr.c
5042--- linux-4.4.111/fs/nfsd/nfs3xdr.c 2018-01-11 07:57:45.000000000 +0000
5043+++ linux-4.4.111-vs2.3.9.1/fs/nfsd/nfs3xdr.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 5044@@ -8,6 +8,7 @@
2bf5ad28
AM
5045
5046 #include <linux/namei.h>
b00e13aa 5047 #include <linux/sunrpc/svc_xprt.h>
d337f35e 5048+#include <linux/vs_tag.h>
2bf5ad28 5049 #include "xdr3.h"
2380c486 5050 #include "auth.h"
b00e13aa
AM
5051 #include "netns.h"
5052@@ -98,6 +99,8 @@ static __be32 *
d337f35e
JR
5053 decode_sattr3(__be32 *p, struct iattr *iap)
5054 {
5055 u32 tmp;
a4a22af8
AM
5056+ kuid_t kuid = GLOBAL_ROOT_UID;
5057+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5058
5059 iap->ia_valid = 0;
5060
b00e13aa
AM
5061@@ -106,15 +109,18 @@ decode_sattr3(__be32 *p, struct iattr *i
5062 iap->ia_mode = ntohl(*p++);
d337f35e
JR
5063 }
5064 if (*p++) {
b00e13aa 5065- iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
a4a22af8 5066+ kuid = make_kuid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5067 if (uid_valid(iap->ia_uid))
5068 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5069 }
5070 if (*p++) {
b00e13aa 5071- iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
a4a22af8 5072+ kgid = make_kgid(&init_user_ns, ntohl(*p++));
b00e13aa
AM
5073 if (gid_valid(iap->ia_gid))
5074 iap->ia_valid |= ATTR_GID;
d337f35e 5075 }
a4a22af8
AM
5076+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5077+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5078+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5079 if (*p++) {
5080 u64 newsize;
5081
bb20add7 5082@@ -167,8 +173,12 @@ encode_fattr3(struct svc_rqst *rqstp, __
d337f35e 5083 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
bb20add7 5084 *p++ = htonl((u32) (stat->mode & S_IALLUGO));
d337f35e 5085 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5086- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5087- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5088+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5089+ TAGINO_KUID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5090+ stat->uid, stat->tag)));
b00e13aa 5091+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5092+ TAGINO_KGID(0 /* FIXME: DX_TAG(dentry->d_inode) */,
2380c486 5093+ stat->gid, stat->tag)));
d337f35e
JR
5094 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
5095 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
5096 } else {
f19bd705
AM
5097diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfs4xdr.c linux-4.4.111-vs2.3.9.1/fs/nfsd/nfs4xdr.c
5098--- linux-4.4.111/fs/nfsd/nfs4xdr.c 2018-01-11 07:57:45.000000000 +0000
5099+++ linux-4.4.111-vs2.3.9.1/fs/nfsd/nfs4xdr.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5100@@ -40,6 +40,7 @@
d33d7b00 5101 #include <linux/utsname.h>
a168f21d 5102 #include <linux/pagemap.h>
2380c486 5103 #include <linux/sunrpc/svcauth_gss.h>
d337f35e
JR
5104+#include <linux/vs_tag.h>
5105
d33d7b00
AM
5106 #include "idmap.h"
5107 #include "acl.h"
927ca606 5108@@ -2637,12 +2638,16 @@ out_acl:
bb20add7 5109 *p++ = cpu_to_be32(stat.nlink);
d337f35e
JR
5110 }
5111 if (bmval1 & FATTR4_WORD1_OWNER) {
bb20add7
AM
5112- status = nfsd4_encode_user(xdr, rqstp, stat.uid);
5113+ status = nfsd4_encode_user(xdr, rqstp,
a4a22af8 5114+ TAGINO_KUID(DX_TAG(dentry->d_inode),
bb20add7 5115+ stat.uid, stat.tag));
d337f35e
JR
5116 if (status)
5117 goto out;
5118 }
5119 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
bb20add7
AM
5120- status = nfsd4_encode_group(xdr, rqstp, stat.gid);
5121+ status = nfsd4_encode_group(xdr, rqstp,
a4a22af8 5122+ TAGINO_KGID(DX_TAG(dentry->d_inode),
bb20add7 5123+ stat.gid, stat.tag));
d337f35e 5124 if (status)
f15949f2
JR
5125 goto out;
5126 }
f19bd705
AM
5127diff -NurpP --minimal linux-4.4.111/fs/nfsd/nfsxdr.c linux-4.4.111-vs2.3.9.1/fs/nfsd/nfsxdr.c
5128--- linux-4.4.111/fs/nfsd/nfsxdr.c 2018-01-11 07:57:45.000000000 +0000
5129+++ linux-4.4.111-vs2.3.9.1/fs/nfsd/nfsxdr.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa
AM
5130@@ -7,6 +7,7 @@
5131 #include "vfs.h"
2bf5ad28 5132 #include "xdr.h"
2380c486 5133 #include "auth.h"
2bf5ad28 5134+#include <linux/vs_tag.h>
d337f35e
JR
5135
5136 #define NFSDDBG_FACILITY NFSDDBG_XDR
2bf5ad28 5137
b00e13aa 5138@@ -89,6 +90,8 @@ static __be32 *
d337f35e
JR
5139 decode_sattr(__be32 *p, struct iattr *iap)
5140 {
5141 u32 tmp, tmp1;
a4a22af8
AM
5142+ kuid_t kuid = GLOBAL_ROOT_UID;
5143+ kgid_t kgid = GLOBAL_ROOT_GID;
d337f35e
JR
5144
5145 iap->ia_valid = 0;
5146
b00e13aa
AM
5147@@ -101,15 +104,18 @@ decode_sattr(__be32 *p, struct iattr *ia
5148 iap->ia_mode = tmp;
d337f35e
JR
5149 }
5150 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5151- iap->ia_uid = make_kuid(&init_user_ns, tmp);
a4a22af8 5152+ kuid = make_kuid(&init_user_ns, tmp);
b00e13aa
AM
5153 if (uid_valid(iap->ia_uid))
5154 iap->ia_valid |= ATTR_UID;
d337f35e
JR
5155 }
5156 if ((tmp = ntohl(*p++)) != (u32)-1) {
b00e13aa 5157- iap->ia_gid = make_kgid(&init_user_ns, tmp);
a4a22af8 5158+ kgid = make_kgid(&init_user_ns, tmp);
b00e13aa
AM
5159 if (gid_valid(iap->ia_gid))
5160 iap->ia_valid |= ATTR_GID;
d337f35e 5161 }
a4a22af8
AM
5162+ iap->ia_uid = INOTAG_KUID(DX_TAG_NFSD, kuid, kgid);
5163+ iap->ia_gid = INOTAG_KGID(DX_TAG_NFSD, kuid, kgid);
5164+ iap->ia_tag = INOTAG_KTAG(DX_TAG_NFSD, kuid, kgid, GLOBAL_ROOT_TAG);
d337f35e
JR
5165 if ((tmp = ntohl(*p++)) != (u32)-1) {
5166 iap->ia_valid |= ATTR_SIZE;
5167 iap->ia_size = tmp;
b00e13aa 5168@@ -154,8 +160,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
d337f35e
JR
5169 *p++ = htonl(nfs_ftypes[type >> 12]);
5170 *p++ = htonl((u32) stat->mode);
5171 *p++ = htonl((u32) stat->nlink);
b00e13aa
AM
5172- *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
5173- *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
5174+ *p++ = htonl((u32) from_kuid(&init_user_ns,
a4a22af8 5175+ TAGINO_KUID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
b00e13aa 5176+ *p++ = htonl((u32) from_kgid(&init_user_ns,
a4a22af8 5177+ TAGINO_KGID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
d337f35e
JR
5178
5179 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
5180 *p++ = htonl(NFS_MAXPATHLEN);
f19bd705
AM
5181diff -NurpP --minimal linux-4.4.111/fs/ocfs2/dlmglue.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/dlmglue.c
5182--- linux-4.4.111/fs/ocfs2/dlmglue.c 2018-01-11 07:57:46.000000000 +0000
5183+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/dlmglue.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5184@@ -2128,6 +2128,7 @@ static void __ocfs2_stuff_meta_lvb(struc
d337f35e 5185 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
b00e13aa
AM
5186 lvb->lvb_iuid = cpu_to_be32(i_uid_read(inode));
5187 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
a4a22af8 5188+ lvb->lvb_itag = cpu_to_be16(i_tag_read(inode));
d337f35e
JR
5189 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
5190 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
5191 lvb->lvb_iatime_packed =
927ca606 5192@@ -2178,6 +2179,7 @@ static void ocfs2_refresh_inode_from_lvb
d337f35e 5193
b00e13aa
AM
5194 i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
5195 i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
5196+ i_tag_write(inode, be16_to_cpu(lvb->lvb_itag));
d337f35e 5197 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
f6c5ef8b 5198 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
d337f35e 5199 ocfs2_unpack_timespec(&inode->i_atime,
f19bd705
AM
5200diff -NurpP --minimal linux-4.4.111/fs/ocfs2/dlmglue.h linux-4.4.111-vs2.3.9.1/fs/ocfs2/dlmglue.h
5201--- linux-4.4.111/fs/ocfs2/dlmglue.h 2018-01-11 07:57:46.000000000 +0000
5202+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/dlmglue.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
5203@@ -46,7 +46,8 @@ struct ocfs2_meta_lvb {
5204 __be16 lvb_inlink;
5205 __be32 lvb_iattr;
5206 __be32 lvb_igeneration;
5207- __be32 lvb_reserved2;
d337f35e 5208+ __be16 lvb_itag;
2380c486
JR
5209+ __be16 lvb_reserved2;
5210 };
5211
ec22aa5c 5212 #define OCFS2_QINFO_LVB_VERSION 1
f19bd705
AM
5213diff -NurpP --minimal linux-4.4.111/fs/ocfs2/file.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/file.c
5214--- linux-4.4.111/fs/ocfs2/file.c 2018-01-11 07:57:46.000000000 +0000
5215+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/file.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5216@@ -1151,7 +1151,7 @@ int ocfs2_setattr(struct dentry *dentry,
763640ca 5217 attr->ia_valid &= ~ATTR_SIZE;
d337f35e
JR
5218
5219 #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
5220- | ATTR_GID | ATTR_UID | ATTR_MODE)
5221+ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
763640ca 5222 if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
d337f35e 5223 return 0;
763640ca 5224
f19bd705
AM
5225diff -NurpP --minimal linux-4.4.111/fs/ocfs2/inode.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/inode.c
5226--- linux-4.4.111/fs/ocfs2/inode.c 2016-07-05 04:12:34.000000000 +0000
5227+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/inode.c 2018-01-09 16:36:32.000000000 +0000
78865d5b 5228@@ -28,6 +28,7 @@
d337f35e
JR
5229 #include <linux/highmem.h>
5230 #include <linux/pagemap.h>
ec22aa5c 5231 #include <linux/quotaops.h>
d337f35e
JR
5232+#include <linux/vs_tag.h>
5233
5234 #include <asm/byteorder.h>
5235
537831f9 5236@@ -78,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5237 {
5238 unsigned int flags = OCFS2_I(inode)->ip_attr;
5239
5240- inode->i_flags &= ~(S_IMMUTABLE |
5241+ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK |
5242 S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
d337f35e
JR
5243
5244 if (flags & OCFS2_IMMUTABLE_FL)
5245 inode->i_flags |= S_IMMUTABLE;
2380c486
JR
5246+ if (flags & OCFS2_IXUNLINK_FL)
5247+ inode->i_flags |= S_IXUNLINK;
d337f35e
JR
5248
5249 if (flags & OCFS2_SYNC_FL)
5250 inode->i_flags |= S_SYNC;
537831f9 5251@@ -92,25 +95,44 @@ void ocfs2_set_inode_flags(struct inode
2380c486
JR
5252 inode->i_flags |= S_NOATIME;
5253 if (flags & OCFS2_DIRSYNC_FL)
d337f35e 5254 inode->i_flags |= S_DIRSYNC;
2380c486
JR
5255+
5256+ inode->i_vflags &= ~(V_BARRIER | V_COW);
5257+
5258+ if (flags & OCFS2_BARRIER_FL)
5259+ inode->i_vflags |= V_BARRIER;
5260+ if (flags & OCFS2_COW_FL)
5261+ inode->i_vflags |= V_COW;
d337f35e
JR
5262 }
5263
2380c486
JR
5264 /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
5265 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
5266 {
5267 unsigned int flags = oi->vfs_inode.i_flags;
5268+ unsigned int vflags = oi->vfs_inode.i_vflags;
5269+
5270+ oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL |
5271+ OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL |
5272+ OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL |
5273+ OCFS2_BARRIER_FL | OCFS2_COW_FL);
5274+
5275+ if (flags & S_IMMUTABLE)
5276+ oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5277+ if (flags & S_IXUNLINK)
5278+ oi->ip_attr |= OCFS2_IXUNLINK_FL;
5279
5280- oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
5281- OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
5282 if (flags & S_SYNC)
5283 oi->ip_attr |= OCFS2_SYNC_FL;
5284 if (flags & S_APPEND)
5285 oi->ip_attr |= OCFS2_APPEND_FL;
5286- if (flags & S_IMMUTABLE)
5287- oi->ip_attr |= OCFS2_IMMUTABLE_FL;
5288 if (flags & S_NOATIME)
5289 oi->ip_attr |= OCFS2_NOATIME_FL;
5290 if (flags & S_DIRSYNC)
5291 oi->ip_attr |= OCFS2_DIRSYNC_FL;
5292+
5293+ if (vflags & V_BARRIER)
5294+ oi->ip_attr |= OCFS2_BARRIER_FL;
5295+ if (vflags & V_COW)
5296+ oi->ip_attr |= OCFS2_COW_FL;
2380c486
JR
5297 }
5298
ec22aa5c 5299 struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
bb20add7 5300@@ -268,6 +290,8 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5301 struct super_block *sb;
5302 struct ocfs2_super *osb;
ec22aa5c 5303 int use_plocks = 1;
d337f35e
JR
5304+ uid_t uid;
5305+ gid_t gid;
5306
763640ca
JR
5307 sb = inode->i_sb;
5308 osb = OCFS2_SB(sb);
bb20add7 5309@@ -296,8 +320,12 @@ void ocfs2_populate_inode(struct inode *
d337f35e
JR
5310 inode->i_generation = le32_to_cpu(fe->i_generation);
5311 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
5312 inode->i_mode = le16_to_cpu(fe->i_mode);
b00e13aa
AM
5313- i_uid_write(inode, le32_to_cpu(fe->i_uid));
5314- i_gid_write(inode, le32_to_cpu(fe->i_gid));
d337f35e
JR
5315+ uid = le32_to_cpu(fe->i_uid);
5316+ gid = le32_to_cpu(fe->i_gid);
b00e13aa
AM
5317+ i_uid_write(inode, INOTAG_UID(DX_TAG(inode), uid, gid));
5318+ i_gid_write(inode, INOTAG_GID(DX_TAG(inode), uid, gid));
5319+ i_tag_write(inode, INOTAG_TAG(DX_TAG(inode), uid, gid,
5320+ /* le16_to_cpu(raw_inode->i_raw_tag) */ 0));
d337f35e
JR
5321
5322 /* Fast symlinks will have i_size but no allocated clusters. */
42bc425c 5323 if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
f19bd705
AM
5324diff -NurpP --minimal linux-4.4.111/fs/ocfs2/inode.h linux-4.4.111-vs2.3.9.1/fs/ocfs2/inode.h
5325--- linux-4.4.111/fs/ocfs2/inode.h 2016-07-05 04:15:08.000000000 +0000
5326+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/inode.h 2018-01-09 16:36:32.000000000 +0000
927ca606 5327@@ -161,6 +161,7 @@ struct buffer_head *ocfs2_bread(struct i
d337f35e
JR
5328
5329 void ocfs2_set_inode_flags(struct inode *inode);
2380c486 5330 void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi);
d4263eb0 5331+int ocfs2_sync_flags(struct inode *inode, int, int);
d337f35e 5332
2380c486
JR
5333 static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
5334 {
f19bd705
AM
5335diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ioctl.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/ioctl.c
5336--- linux-4.4.111/fs/ocfs2/ioctl.c 2015-10-29 09:21:37.000000000 +0000
5337+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/ioctl.c 2018-01-09 16:36:32.000000000 +0000
1e8b8f9b 5338@@ -76,7 +76,41 @@ static int ocfs2_get_inode_attr(struct i
d337f35e
JR
5339 return status;
5340 }
5341
5342-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
d4263eb0
JR
5343+int ocfs2_sync_flags(struct inode *inode, int flags, int vflags)
5344+{
5345+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
5346+ struct buffer_head *bh = NULL;
5347+ handle_t *handle = NULL;
5348+ int status;
5349+
5350+ status = ocfs2_inode_lock(inode, &bh, 1);
5351+ if (status < 0) {
5352+ mlog_errno(status);
5353+ return status;
5354+ }
5355+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5356+ if (IS_ERR(handle)) {
5357+ status = PTR_ERR(handle);
5358+ mlog_errno(status);
5359+ goto bail_unlock;
5360+ }
5361+
5362+ inode->i_flags = flags;
5363+ inode->i_vflags = vflags;
5364+ ocfs2_get_inode_flags(OCFS2_I(inode));
5365+
5366+ status = ocfs2_mark_inode_dirty(handle, inode, bh);
5367+ if (status < 0)
5368+ mlog_errno(status);
5369+
5370+ ocfs2_commit_trans(osb, handle);
5371+bail_unlock:
5372+ ocfs2_inode_unlock(inode, 1);
5373+ brelse(bh);
5374+ return status;
5375+}
5376+
d337f35e
JR
5377+int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
5378 unsigned mask)
5379 {
5380 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
09be7631
JR
5381@@ -116,6 +150,11 @@ static int ocfs2_set_inode_attr(struct i
5382 goto bail_unlock;
5383 }
2380c486
JR
5384
5385+ if (IS_BARRIER(inode)) {
5386+ vxwprintk_task(1, "messing with the barrier.");
5387+ goto bail_unlock;
5388+ }
5389+
5390 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
5391 if (IS_ERR(handle)) {
5392 status = PTR_ERR(handle);
bb20add7 5393@@ -841,6 +880,7 @@ bail:
d4263eb0
JR
5394 return status;
5395 }
d337f35e 5396
d337f35e 5397+
d4263eb0
JR
5398 long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
5399 {
b00e13aa 5400 struct inode *inode = file_inode(filp);
f19bd705
AM
5401diff -NurpP --minimal linux-4.4.111/fs/ocfs2/namei.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/namei.c
5402--- linux-4.4.111/fs/ocfs2/namei.c 2018-01-11 07:57:46.000000000 +0000
5403+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/namei.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c 5404@@ -41,6 +41,7 @@
d337f35e
JR
5405 #include <linux/slab.h>
5406 #include <linux/highmem.h>
ec22aa5c 5407 #include <linux/quotaops.h>
d337f35e
JR
5408+#include <linux/vs_tag.h>
5409
d337f35e 5410 #include <cluster/masklog.h>
763640ca 5411
927ca606 5412@@ -516,6 +517,7 @@ static int __ocfs2_mknod_locked(struct i
93de0823 5413 struct ocfs2_extent_list *fel;
ec22aa5c 5414 u16 feat;
265de2f7 5415 struct ocfs2_inode_info *oi = OCFS2_I(inode);
a4a22af8 5416+ ktag_t ktag;
d337f35e 5417
7e46296a
AM
5418 *new_fe_bh = NULL;
5419
927ca606 5420@@ -553,8 +555,13 @@ static int __ocfs2_mknod_locked(struct i
76514441 5421 fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
d337f35e 5422 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
2380c486 5423 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
b00e13aa
AM
5424- fe->i_uid = cpu_to_le32(i_uid_read(inode));
5425- fe->i_gid = cpu_to_le32(i_gid_read(inode));
d337f35e 5426+
a4a22af8
AM
5427+ ktag = make_ktag(&init_user_ns, dx_current_fstag(osb->sb));
5428+ fe->i_uid = cpu_to_le32(from_kuid(&init_user_ns,
5429+ TAGINO_KUID(DX_TAG(inode), inode->i_uid, ktag)));
5430+ fe->i_gid = cpu_to_le32(from_kgid(&init_user_ns,
5431+ TAGINO_KGID(DX_TAG(inode), inode->i_gid, ktag)));
5432+ inode->i_tag = ktag; /* is this correct? */
ec22aa5c
AM
5433 fe->i_mode = cpu_to_le16(inode->i_mode);
5434 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
d337f35e 5435 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
f19bd705
AM
5436diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ocfs2.h linux-4.4.111-vs2.3.9.1/fs/ocfs2/ocfs2.h
5437--- linux-4.4.111/fs/ocfs2/ocfs2.h 2018-01-11 07:57:46.000000000 +0000
5438+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/ocfs2.h 2018-01-09 17:21:54.000000000 +0000
927ca606
AM
5439@@ -289,6 +289,7 @@ enum ocfs2_mount_options
5440 OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
5441 OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
5442 OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
5443+ OCFS2_MOUNT_TAGGED = 1 << 18, /* use tagging */
d33d7b00
AM
5444 };
5445
bb20add7 5446 #define OCFS2_OSB_SOFT_RO 0x0001
f19bd705
AM
5447diff -NurpP --minimal linux-4.4.111/fs/ocfs2/ocfs2_fs.h linux-4.4.111-vs2.3.9.1/fs/ocfs2/ocfs2_fs.h
5448--- linux-4.4.111/fs/ocfs2/ocfs2_fs.h 2016-07-05 04:12:34.000000000 +0000
5449+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/ocfs2_fs.h 2018-01-09 16:36:32.000000000 +0000
927ca606 5450@@ -275,6 +275,11 @@
93de0823
AM
5451 #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
5452 #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
2380c486 5453
93de0823
AM
5454+#define OCFS2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */
5455+
5456+#define OCFS2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
5457+#define OCFS2_COW_FL FS_COW_FL /* Copy on Write marker */
5458+
5459 #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
5460 #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */
5461
f19bd705
AM
5462diff -NurpP --minimal linux-4.4.111/fs/ocfs2/super.c linux-4.4.111-vs2.3.9.1/fs/ocfs2/super.c
5463--- linux-4.4.111/fs/ocfs2/super.c 2016-07-05 04:12:34.000000000 +0000
5464+++ linux-4.4.111-vs2.3.9.1/fs/ocfs2/super.c 2018-01-09 17:22:51.000000000 +0000
927ca606 5465@@ -193,6 +193,7 @@ enum {
76514441 5466 Opt_dir_resv_level,
927ca606
AM
5467 Opt_journal_async_commit,
5468 Opt_err_cont,
d337f35e
JR
5469+ Opt_tag, Opt_notag, Opt_tagid,
5470 Opt_err,
5471 };
5472
927ca606 5473@@ -226,6 +227,9 @@ static const match_table_t tokens = {
76514441 5474 {Opt_dir_resv_level, "dir_resv_level=%u"},
927ca606
AM
5475 {Opt_journal_async_commit, "journal_async_commit"},
5476 {Opt_err_cont, "errors=continue"},
d337f35e 5477+ {Opt_tag, "tag"},
d337f35e
JR
5478+ {Opt_notag, "notag"},
5479+ {Opt_tagid, "tagid=%u"},
5480 {Opt_err, NULL}
5481 };
5482
927ca606 5483@@ -677,6 +681,13 @@ static int ocfs2_remount(struct super_bl
d337f35e
JR
5484 goto out;
5485 }
5486
d4263eb0
JR
5487+ if ((osb->s_mount_opt & OCFS2_MOUNT_TAGGED) !=
5488+ (parsed_options.mount_opt & OCFS2_MOUNT_TAGGED)) {
d337f35e
JR
5489+ ret = -EINVAL;
5490+ mlog(ML_ERROR, "Cannot change tagging on remount\n");
5491+ goto out;
5492+ }
5493+
ab30d09f
AM
5494 /* We're going to/from readonly mode. */
5495 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
5496 /* Disable quota accounting before remounting RO */
927ca606 5497@@ -1166,6 +1177,9 @@ static int ocfs2_fill_super(struct super
d337f35e
JR
5498
5499 ocfs2_complete_mount_recovery(osb);
5500
5501+ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
5502+ sb->s_flags |= MS_TAGGED;
5503+
2380c486
JR
5504 if (ocfs2_mount_local(osb))
5505 snprintf(nodestr, sizeof(nodestr), "local");
5506 else
927ca606
AM
5507@@ -1486,6 +1500,20 @@ static int ocfs2_parse_options(struct su
5508 case Opt_journal_async_commit:
5509 mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
d337f35e
JR
5510 break;
5511+#ifndef CONFIG_TAGGING_NONE
5512+ case Opt_tag:
2380c486 5513+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5514+ break;
5515+ case Opt_notag:
2380c486 5516+ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED;
d337f35e
JR
5517+ break;
5518+#endif
5519+#ifdef CONFIG_PROPAGATE
5520+ case Opt_tagid:
5521+ /* use args[0] */
2380c486 5522+ mopt->mount_opt |= OCFS2_MOUNT_TAGGED;
d337f35e
JR
5523+ break;
5524+#endif
5525 default:
5526 mlog(ML_ERROR,
5527 "Unrecognized mount option \"%s\" "
f19bd705
AM
5528diff -NurpP --minimal linux-4.4.111/fs/open.c linux-4.4.111-vs2.3.9.1/fs/open.c
5529--- linux-4.4.111/fs/open.c 2018-01-11 07:57:46.000000000 +0000
5530+++ linux-4.4.111-vs2.3.9.1/fs/open.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 5531@@ -31,6 +31,11 @@
2bf5ad28 5532 #include <linux/ima.h>
93de0823 5533 #include <linux/dnotify.h>
b00e13aa 5534 #include <linux/compat.h>
d337f35e
JR
5535+#include <linux/vs_base.h>
5536+#include <linux/vs_limit.h>
d337f35e
JR
5537+#include <linux/vs_tag.h>
5538+#include <linux/vs_cowbl.h>
78865d5b 5539+#include <linux/vserver/dlimit.h>
d337f35e 5540
2bf5ad28
AM
5541 #include "internal.h"
5542
927ca606 5543@@ -70,6 +75,11 @@ long vfs_truncate(struct path *path, lof
b00e13aa
AM
5544 struct inode *inode;
5545 long error;
5546
76514441 5547+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5548+ error = cow_check_and_break(path);
d337f35e 5549+ if (error)
b00e13aa 5550+ goto out;
76514441 5551+#endif
b00e13aa 5552 inode = path->dentry->d_inode;
d337f35e 5553
a168f21d 5554 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
927ca606 5555@@ -548,6 +558,13 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons
b00e13aa
AM
5556 unsigned int lookup_flags = LOOKUP_FOLLOW;
5557 retry:
5558 error = user_path_at(dfd, filename, lookup_flags, &path);
a168f21d 5559+#ifdef CONFIG_VSERVER_COWBL
b00e13aa 5560+ if (!error) {
a168f21d 5561+ error = cow_check_and_break(&path);
b00e13aa
AM
5562+ if (error)
5563+ path_put(&path);
5564+ }
a168f21d 5565+#endif
b00e13aa 5566 if (!error) {
a168f21d
AM
5567 error = chmod_common(&path, mode);
5568 path_put(&path);
927ca606 5569@@ -582,13 +599,15 @@ retry_deleg:
42bc425c
AM
5570 if (!uid_valid(uid))
5571 return -EINVAL;
d337f35e 5572 newattrs.ia_valid |= ATTR_UID;
42bc425c 5573- newattrs.ia_uid = uid;
8ce283e1
AM
5574+ newattrs.ia_uid = make_kuid(&init_user_ns,
5575+ dx_map_uid(user));
d337f35e
JR
5576 }
5577 if (group != (gid_t) -1) {
42bc425c
AM
5578 if (!gid_valid(gid))
5579 return -EINVAL;
d337f35e 5580 newattrs.ia_valid |= ATTR_GID;
42bc425c 5581- newattrs.ia_gid = gid;
8ce283e1
AM
5582+ newattrs.ia_gid = make_kgid(&init_user_ns,
5583+ dx_map_gid(group));
d337f35e
JR
5584 }
5585 if (!S_ISDIR(inode->i_mode))
2380c486 5586 newattrs.ia_valid |=
927ca606 5587@@ -626,6 +645,10 @@ retry:
2380c486 5588 error = mnt_want_write(path.mnt);
d337f35e 5589 if (error)
2380c486 5590 goto out_release;
d337f35e 5591+#ifdef CONFIG_VSERVER_COWBL
2380c486 5592+ error = cow_check_and_break(&path);
d337f35e 5593+ if (!error)
d337f35e 5594+#endif
2bf5ad28 5595 error = chown_common(&path, user, group);
2380c486
JR
5596 mnt_drop_write(path.mnt);
5597 out_release:
f19bd705
AM
5598diff -NurpP --minimal linux-4.4.111/fs/proc/array.c linux-4.4.111-vs2.3.9.1/fs/proc/array.c
5599--- linux-4.4.111/fs/proc/array.c 2018-01-11 07:57:46.000000000 +0000
5600+++ linux-4.4.111-vs2.3.9.1/fs/proc/array.c 2018-01-09 17:30:44.000000000 +0000
927ca606 5601@@ -83,6 +83,8 @@
2380c486 5602 #include <linux/tracehook.h>
927ca606 5603 #include <linux/string_helpers.h>
42bc425c 5604 #include <linux/user_namespace.h>
d337f35e
JR
5605+#include <linux/vs_context.h>
5606+#include <linux/vs_network.h>
5607
d337f35e 5608 #include <asm/pgtable.h>
2380c486 5609 #include <asm/processor.h>
927ca606 5610@@ -154,6 +156,9 @@ static inline void task_state(struct seq
2380c486
JR
5611 ppid = pid_alive(p) ?
5612 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
927ca606 5613
2380c486
JR
5614+ if (unlikely(vx_current_initpid(p->pid)))
5615+ ppid = 0;
5616+
927ca606
AM
5617 tracer = ptrace_parent(p);
5618 if (tracer)
5619 tpid = task_pid_nr_ns(tracer, ns);
5620@@ -292,8 +297,8 @@ static inline void task_sig(struct seq_f
bb20add7 5621 render_sigset_t(m, "SigCgt:\t", &caught);
2380c486
JR
5622 }
5623
bb20add7 5624-static void render_cap_t(struct seq_file *m, const char *header,
2380c486 5625- kernel_cap_t *a)
bb20add7 5626+void render_cap_t(struct seq_file *m, const char *header,
2380c486 5627+ struct vx_info *vxi, kernel_cap_t *a)
d337f35e 5628 {
2380c486
JR
5629 unsigned __capi;
5630
927ca606
AM
5631@@ -320,11 +325,12 @@ static inline void task_cap(struct seq_f
5632 cap_ambient = cred->cap_ambient;
bb20add7 5633 rcu_read_unlock();
2380c486 5634
ec22aa5c
AM
5635- render_cap_t(m, "CapInh:\t", &cap_inheritable);
5636- render_cap_t(m, "CapPrm:\t", &cap_permitted);
5637- render_cap_t(m, "CapEff:\t", &cap_effective);
5638- render_cap_t(m, "CapBnd:\t", &cap_bset);
927ca606 5639- render_cap_t(m, "CapAmb:\t", &cap_ambient);
ec22aa5c
AM
5640+ /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */
5641+ render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable);
5642+ render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted);
5643+ render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective);
5644+ render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset);
927ca606 5645+ render_cap_t(m, "CapAmb:\t", p->vx_info, &cap_ambient);
d337f35e
JR
5646 }
5647
b00e13aa 5648 static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
927ca606
AM
5649@@ -351,6 +357,43 @@ static void task_cpus_allowed(struct seq
5650 cpumask_pr_args(&task->cpus_allowed));
2380c486
JR
5651 }
5652
5653+int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
5654+ struct pid *pid, struct task_struct *task)
5655+{
5656+ seq_printf(m, "Proxy:\t%p(%c)\n"
5657+ "Count:\t%u\n"
5658+ "uts:\t%p(%c)\n"
5659+ "ipc:\t%p(%c)\n"
5660+ "mnt:\t%p(%c)\n"
5661+ "pid:\t%p(%c)\n"
5662+ "net:\t%p(%c)\n",
5663+ task->nsproxy,
5664+ (task->nsproxy == init_task.nsproxy ? 'I' : '-'),
5665+ atomic_read(&task->nsproxy->count),
5666+ task->nsproxy->uts_ns,
5667+ (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'),
5668+ task->nsproxy->ipc_ns,
5669+ (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'),
5670+ task->nsproxy->mnt_ns,
5671+ (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'),
c2e5f7c8
JR
5672+ task->nsproxy->pid_ns_for_children,
5673+ (task->nsproxy->pid_ns_for_children ==
5674+ init_task.nsproxy->pid_ns_for_children ? 'I' : '-'),
2380c486
JR
5675+ task->nsproxy->net_ns,
5676+ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-'));
5677+ return 0;
5678+}
d337f35e 5679+
2380c486
JR
5680+void task_vs_id(struct seq_file *m, struct task_struct *task)
5681+{
d337f35e 5682+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
2380c486
JR
5683+ return;
5684+
bb20add7
AM
5685+ seq_printf(m, "VxID:\t%d\n", vx_task_xid(task));
5686+ seq_printf(m, "NxID:\t%d\n", nx_task_nid(task));
2380c486
JR
5687+}
5688+
5689+
5690 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
5691 struct pid *pid, struct task_struct *task)
5692 {
927ca606 5693@@ -368,6 +411,7 @@ int proc_pid_status(struct seq_file *m,
b00e13aa 5694 task_seccomp(m, task);
2bf5ad28 5695 task_cpus_allowed(m, task);
2380c486
JR
5696 cpuset_task_status_allowed(m, task);
5697+ task_vs_id(m, task);
152aeb71
JR
5698 task_context_switch_counts(m, task);
5699 return 0;
5700 }
927ca606 5701@@ -471,6 +515,17 @@ static int do_task_stat(struct seq_file
d337f35e 5702 /* convert nsec -> ticks */
bb20add7 5703 start_time = nsec_to_clock_t(task->real_start_time);
d337f35e
JR
5704
5705+ /* fixup start time for virt uptime */
5706+ if (vx_flags(VXF_VIRT_UPTIME, 0)) {
5707+ unsigned long long bias =
5708+ current->vx_info->cvirt.bias_clock;
5709+
5710+ if (start_time > bias)
5711+ start_time -= bias;
5712+ else
5713+ start_time = 0;
5714+ }
5715+
1e8b8f9b
AM
5716 seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
5717 seq_put_decimal_ll(m, ' ', ppid);
5718 seq_put_decimal_ll(m, ' ', pgid);
f19bd705
AM
5719diff -NurpP --minimal linux-4.4.111/fs/proc/base.c linux-4.4.111-vs2.3.9.1/fs/proc/base.c
5720--- linux-4.4.111/fs/proc/base.c 2018-01-11 07:57:46.000000000 +0000
5721+++ linux-4.4.111-vs2.3.9.1/fs/proc/base.c 2018-01-09 16:36:32.000000000 +0000
09be7631 5722@@ -87,6 +87,8 @@
78865d5b 5723 #include <linux/slab.h>
db55b927 5724 #include <linux/flex_array.h>
09be7631 5725 #include <linux/posix-timers.h>
d337f35e
JR
5726+#include <linux/vs_context.h>
5727+#include <linux/vs_network.h>
763640ca
JR
5728 #ifdef CONFIG_HARDWALL
5729 #include <asm/hardwall.h>
5730 #endif
927ca606 5731@@ -1097,11 +1099,15 @@ static ssize_t oom_adj_write(struct file
537831f9 5732 oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
7e46296a 5733
537831f9
AM
5734 if (oom_adj < task->signal->oom_score_adj &&
5735- !capable(CAP_SYS_RESOURCE)) {
5736+ !vx_capable(CAP_SYS_RESOURCE, VXC_OOM_ADJUST)) {
ab30d09f
AM
5737 err = -EACCES;
5738 goto err_sighand;
4a036bed 5739 }
7e46296a 5740
4a036bed 5741+ /* prevent guest processes from circumventing the oom killer */
537831f9
AM
5742+ if (vx_current_xid() && (oom_adj == OOM_DISABLE))
5743+ oom_adj = OOM_ADJUST_MIN;
7e46296a 5744+
f6c5ef8b 5745 /*
537831f9
AM
5746 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
5747 * /proc/pid/oom_score_adj instead.
927ca606 5748@@ -1666,6 +1672,8 @@ struct inode *proc_pid_make_inode(struct
ec22aa5c
AM
5749 inode->i_gid = cred->egid;
5750 rcu_read_unlock();
d337f35e
JR
5751 }
5752+ /* procfs is xid tagged */
61333608 5753+ i_tag_write(inode, (vtag_t)vx_task_xid(task));
d337f35e
JR
5754 security_task_to_inode(task, inode);
5755
5756 out:
927ca606 5757@@ -1711,6 +1719,8 @@ int pid_getattr(struct vfsmount *mnt, st
d33d7b00
AM
5758
5759 /* dentry stuff */
5760
bb20add7 5761+// static unsigned name_to_int(struct dentry *dentry);
d33d7b00
AM
5762+
5763 /*
5764 * Exceptional case: normally we are not allowed to unhash a busy
5765 * directory. In this case, however, we can do it - no aliasing problems
927ca606 5766@@ -1739,6 +1749,19 @@ int pid_revalidate(struct dentry *dentry
d33d7b00
AM
5767 task = get_proc_task(inode);
5768
5769 if (task) {
bb20add7
AM
5770+ unsigned pid = name_to_int(&dentry->d_name);
5771+
5772+ if (pid != ~0U && pid != vx_map_pid(task->pid) &&
5773+ pid != __task_pid_nr_ns(task, PIDTYPE_PID,
5774+ task_active_pid_ns(task))) {
5775+ vxdprintk(VXD_CBIT(misc, 10),
5776+ VS_Q("%*s") " dropped by pid_revalidate(%d!=%d)",
5777+ dentry->d_name.len, dentry->d_name.name,
5778+ pid, vx_map_pid(task->pid));
d33d7b00 5779+ put_task_struct(task);
bb20add7
AM
5780+ d_drop(dentry);
5781+ return 0;
d33d7b00
AM
5782+ }
5783 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
5784 task_dumpable(task)) {
5785 rcu_read_lock();
927ca606 5786@@ -2283,6 +2306,13 @@ static struct dentry *proc_pident_lookup
d337f35e
JR
5787 if (!task)
5788 goto out_no_task;
5789
2380c486 5790+ /* TODO: maybe we can come up with a generic approach? */
d337f35e
JR
5791+ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
5792+ (dentry->d_name.len == 5) &&
5793+ (!memcmp(dentry->d_name.name, "vinfo", 5) ||
5794+ !memcmp(dentry->d_name.name, "ninfo", 5)))
5795+ goto out;
5796+
5797 /*
5798 * Yes, it does not scale. And it should not. Don't add
5799 * new entries into /proc/<tgid>/ without very good reasons.
927ca606 5800@@ -2725,6 +2755,11 @@ static int proc_pid_personality(struct s
2380c486
JR
5801 static const struct file_operations proc_task_operations;
5802 static const struct inode_operations proc_task_inode_operations;
d337f35e 5803
bb20add7
AM
5804+extern int proc_pid_vx_info(struct seq_file *,
5805+ struct pid_namespace *, struct pid *, struct task_struct *);
5806+extern int proc_pid_nx_info(struct seq_file *,
5807+ struct pid_namespace *, struct pid *, struct task_struct *);
d337f35e 5808+
2380c486 5809 static const struct pid_entry tgid_base_stuff[] = {
ec22aa5c
AM
5810 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
5811 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
927ca606 5812@@ -2789,6 +2824,8 @@ static const struct pid_entry tgid_base_
2380c486 5813 #ifdef CONFIG_CGROUPS
bb20add7 5814 ONE("cgroup", S_IRUGO, proc_cgroup_show),
d337f35e 5815 #endif
bb20add7
AM
5816+ ONE("vinfo", S_IRUGO, proc_pid_vx_info),
5817+ ONE("ninfo", S_IRUGO, proc_pid_nx_info),
5818 ONE("oom_score", S_IRUGO, proc_oom_score),
537831f9 5819 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations),
93de0823 5820 REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
927ca606 5821@@ -3003,7 +3040,7 @@ retry:
2380c486
JR
5822 iter.task = NULL;
5823 pid = find_ge_pid(iter.tgid, ns);
5824 if (pid) {
5825- iter.tgid = pid_nr_ns(pid, ns);
5826+ iter.tgid = pid_unmapped_nr_ns(pid, ns);
5827 iter.task = pid_task(pid, PIDTYPE_PID);
5828 /* What we to know is if the pid we have find is the
5829 * pid of a thread_group_leader. Testing for task
927ca606 5830@@ -3063,8 +3100,10 @@ int proc_pid_readdir(struct file *file,
c2e5f7c8
JR
5831 if (!has_pid_permissions(ns, iter.task, 2))
5832 continue;
db55b927 5833
c2e5f7c8
JR
5834- len = snprintf(name, sizeof(name), "%d", iter.tgid);
5835+ len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid));
5836 ctx->pos = iter.tgid + TGID_OFFSET;
2380c486 5837+ if (!vx_proc_task_visible(iter.task))
d337f35e 5838+ continue;
c2e5f7c8
JR
5839 if (!proc_fill_cache(file, ctx, name, len,
5840 proc_pid_instantiate, iter.task, NULL)) {
2380c486 5841 put_task_struct(iter.task);
927ca606 5842@@ -3161,6 +3200,7 @@ static const struct pid_entry tid_base_s
09be7631 5843 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
bb20add7 5844 REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations),
09be7631
JR
5845 #endif
5846+ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy),
5847 };
5848
c2e5f7c8 5849 static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
927ca606 5850@@ -3227,6 +3267,8 @@ static struct dentry *proc_task_lookup(s
bb20add7 5851 tid = name_to_int(&dentry->d_name);
d337f35e
JR
5852 if (tid == ~0U)
5853 goto out;
5854+ if (vx_current_initpid(tid))
5855+ goto out;
5856
2380c486 5857 ns = dentry->d_sb->s_fs_info;
d337f35e 5858 rcu_read_lock();
f19bd705
AM
5859diff -NurpP --minimal linux-4.4.111/fs/proc/generic.c linux-4.4.111-vs2.3.9.1/fs/proc/generic.c
5860--- linux-4.4.111/fs/proc/generic.c 2018-01-11 07:57:46.000000000 +0000
5861+++ linux-4.4.111-vs2.3.9.1/fs/proc/generic.c 2018-01-09 17:29:24.000000000 +0000
927ca606 5862@@ -22,6 +22,7 @@
d337f35e
JR
5863 #include <linux/bitops.h>
5864 #include <linux/spinlock.h>
2380c486 5865 #include <linux/completion.h>
d337f35e
JR
5866+#include <linux/vserver/inode.h>
5867 #include <asm/uaccess.h>
5868
5869 #include "internal.h"
927ca606
AM
5870@@ -66,8 +67,16 @@ static struct proc_dir_entry *pde_subdir
5871 node = node->rb_left;
5872 else if (result > 0)
5873 node = node->rb_right;
5874- else
5875+ else {
5876+ if (!vx_hide_check(0, de->vx_flags)) {
5877+ vxdprintk(VXD_CBIT(misc, 9),
5878+ VS_Q("%*s")
5879+ " hidden in pde_subdir_find()",
5880+ de->namelen, de->name);
5881+ return 0;
5882+ }
5883 return de;
bb20add7 5884+ }
927ca606
AM
5885 }
5886 return NULL;
5887 }
5888@@ -241,6 +250,8 @@ struct dentry *proc_lookup_de(struct pro
5889 return ERR_PTR(-ENOMEM);
5890 d_set_d_op(dentry, &simple_dentry_operations);
5891 d_add(dentry, inode);
ba86f833 5892+ /* generic proc entries belong to the host */
537831f9 5893+ i_tag_write(inode, 0);
927ca606 5894 return NULL;
2380c486 5895 }
927ca606
AM
5896 read_unlock(&proc_subdir_lock);
5897@@ -287,6 +298,12 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5898 do {
5899 struct proc_dir_entry *next;
5900 pde_get(de);
bb20add7
AM
5901+ if (!vx_hide_check(0, de->vx_flags)) {
5902+ vxdprintk(VXD_CBIT(misc, 9),
5903+ VS_Q("%*s") " hidden in proc_readdir_de()",
5904+ de->namelen, de->name);
c2e5f7c8 5905+ goto skip;
bb20add7 5906+ }
927ca606 5907 read_unlock(&proc_subdir_lock);
c2e5f7c8
JR
5908 if (!dir_emit(ctx, de->name, de->namelen,
5909 de->low_ino, de->mode >> 12)) {
927ca606 5910@@ -294,6 +311,7 @@ int proc_readdir_de(struct proc_dir_entr
c2e5f7c8
JR
5911 return 0;
5912 }
927ca606 5913 read_lock(&proc_subdir_lock);
c2e5f7c8
JR
5914+ skip:
5915 ctx->pos++;
927ca606 5916 next = pde_subdir_next(de);
c2e5f7c8 5917 pde_put(de);
927ca606 5918@@ -387,6 +405,7 @@ static struct proc_dir_entry *__proc_cre
537831f9 5919 ent->mode = mode;
d337f35e 5920 ent->nlink = nlink;
927ca606 5921 ent->subdir = RB_ROOT;
d337f35e 5922+ ent->vx_flags = IATTR_PROC_DEFAULT;
537831f9 5923 atomic_set(&ent->count, 1);
2380c486 5924 spin_lock_init(&ent->pde_unload_lock);
2380c486 5925 INIT_LIST_HEAD(&ent->pde_openers);
927ca606 5926@@ -411,7 +430,8 @@ struct proc_dir_entry *proc_symlink(cons
d337f35e
JR
5927 kfree(ent->data);
5928 kfree(ent);
5929 ent = NULL;
5930- }
5931+ } else
5932+ ent->vx_flags = IATTR_PROC_SYMLINK;
5933 } else {
5934 kfree(ent);
5935 ent = NULL;
f19bd705
AM
5936diff -NurpP --minimal linux-4.4.111/fs/proc/inode.c linux-4.4.111-vs2.3.9.1/fs/proc/inode.c
5937--- linux-4.4.111/fs/proc/inode.c 2015-10-29 09:21:39.000000000 +0000
5938+++ linux-4.4.111-vs2.3.9.1/fs/proc/inode.c 2018-01-09 16:36:32.000000000 +0000
927ca606 5939@@ -431,6 +431,8 @@ struct inode *proc_get_inode(struct supe
d337f35e
JR
5940 inode->i_uid = de->uid;
5941 inode->i_gid = de->gid;
5942 }
5943+ if (de->vx_flags)
5944+ PROC_I(inode)->vx_flags = de->vx_flags;
5945 if (de->size)
5946 inode->i_size = de->size;
5947 if (de->nlink)
f19bd705
AM
5948diff -NurpP --minimal linux-4.4.111/fs/proc/internal.h linux-4.4.111-vs2.3.9.1/fs/proc/internal.h
5949--- linux-4.4.111/fs/proc/internal.h 2015-10-29 09:21:39.000000000 +0000
5950+++ linux-4.4.111-vs2.3.9.1/fs/proc/internal.h 2018-01-09 16:36:32.000000000 +0000
09be7631
JR
5951@@ -14,6 +14,7 @@
5952 #include <linux/spinlock.h>
5953 #include <linux/atomic.h>
b00e13aa 5954 #include <linux/binfmts.h>
d337f35e
JR
5955+#include <linux/vs_pid.h>
5956
09be7631
JR
5957 struct ctl_table_header;
5958 struct mempolicy;
927ca606 5959@@ -34,6 +35,7 @@ struct proc_dir_entry {
09be7631
JR
5960 nlink_t nlink;
5961 kuid_t uid;
5962 kgid_t gid;
5963+ int vx_flags;
5964 loff_t size;
5965 const struct inode_operations *proc_iops;
5966 const struct file_operations *proc_fops;
927ca606 5967@@ -51,15 +53,22 @@ struct proc_dir_entry {
09be7631
JR
5968 char name[];
5969 };
5970
5971+struct vx_info;
5972+struct nx_info;
2380c486 5973+
09be7631
JR
5974 union proc_op {
5975 int (*proc_get_link)(struct dentry *, struct path *);
09be7631
JR
5976 int (*proc_show)(struct seq_file *m,
5977 struct pid_namespace *ns, struct pid *pid,
5978 struct task_struct *task);
5979+ int (*proc_vs_read)(char *page);
5980+ int (*proc_vxi_read)(struct vx_info *vxi, char *page);
5981+ int (*proc_nxi_read)(struct nx_info *nxi, char *page);
5982 };
2380c486 5983
09be7631
JR
5984 struct proc_inode {
5985 struct pid *pid;
5986+ int vx_flags;
5987 int fd;
5988 union proc_op op;
5989 struct proc_dir_entry *pde;
927ca606 5990@@ -92,11 +101,16 @@ static inline struct pid *proc_pid(struc
d337f35e
JR
5991 return PROC_I(inode)->pid;
5992 }
5993
5994-static inline struct task_struct *get_proc_task(struct inode *inode)
5995+static inline struct task_struct *get_proc_task_real(struct inode *inode)
5996 {
5997 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
5998 }
5999
6000+static inline struct task_struct *get_proc_task(struct inode *inode)
6001+{
6002+ return vx_get_proc_task(inode, proc_pid(inode));
6003+}
6004+
09be7631 6005 static inline int task_dumpable(struct task_struct *task)
d337f35e 6006 {
09be7631 6007 int dumpable = 0;
927ca606 6008@@ -155,6 +169,8 @@ extern int proc_pid_status(struct seq_fi
09be7631
JR
6009 struct pid *, struct task_struct *);
6010 extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
6011 struct pid *, struct task_struct *);
6012+extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
6013+ struct pid *pid, struct task_struct *task);
6014
6015 /*
6016 * base.c
f19bd705
AM
6017diff -NurpP --minimal linux-4.4.111/fs/proc/loadavg.c linux-4.4.111-vs2.3.9.1/fs/proc/loadavg.c
6018--- linux-4.4.111/fs/proc/loadavg.c 2015-04-12 22:12:50.000000000 +0000
6019+++ linux-4.4.111-vs2.3.9.1/fs/proc/loadavg.c 2018-01-09 16:36:32.000000000 +0000
ec22aa5c 6020@@ -12,15 +12,27 @@
1bc743c0 6021
ec22aa5c 6022 static int loadavg_proc_show(struct seq_file *m, void *v)
1bc743c0
JR
6023 {
6024+ unsigned long running;
6025+ unsigned int threads;
ec22aa5c 6026 unsigned long avnrun[3];
1bc743c0 6027
ec22aa5c 6028 get_avenrun(avnrun, FIXED_1/200, 0);
bd427b06 6029
ec22aa5c 6030+ if (vx_flags(VXF_VIRT_LOAD, 0)) {
eab5a9a6 6031+ struct vx_info *vxi = current_vx_info();
ec22aa5c
AM
6032+
6033+ running = atomic_read(&vxi->cvirt.nr_running);
6034+ threads = atomic_read(&vxi->cvirt.nr_threads);
6035+ } else {
6036+ running = nr_running();
6037+ threads = nr_threads;
6038+ }
6039+
6040 seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
6041 LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
6042 LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
6043 LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
1bc743c0
JR
6044- nr_running(), nr_threads,
6045+ running, threads,
6046 task_active_pid_ns(current)->last_pid);
ec22aa5c 6047 return 0;
1bc743c0 6048 }
f19bd705
AM
6049diff -NurpP --minimal linux-4.4.111/fs/proc/meminfo.c linux-4.4.111-vs2.3.9.1/fs/proc/meminfo.c
6050--- linux-4.4.111/fs/proc/meminfo.c 2016-07-05 04:15:09.000000000 +0000
6051+++ linux-4.4.111-vs2.3.9.1/fs/proc/meminfo.c 2018-01-09 16:36:32.000000000 +0000
927ca606 6052@@ -43,7 +43,8 @@ static int meminfo_proc_show(struct seq_
c2e5f7c8
JR
6053 si_swapinfo(&i);
6054 committed = percpu_counter_read_positive(&vm_committed_as);
e3afe727
AM
6055
6056- cached = global_page_state(NR_FILE_PAGES) -
6057+ cached = vx_flags(VXF_VIRT_MEM, 0) ?
6058+ vx_vsi_cached(&i) : global_page_state(NR_FILE_PAGES) -
b00e13aa 6059 total_swapcache_pages() - i.bufferram;
e3afe727 6060 if (cached < 0)
d337f35e 6061 cached = 0;
f19bd705
AM
6062diff -NurpP --minimal linux-4.4.111/fs/proc/root.c linux-4.4.111-vs2.3.9.1/fs/proc/root.c
6063--- linux-4.4.111/fs/proc/root.c 2018-01-11 07:57:46.000000000 +0000
6064+++ linux-4.4.111-vs2.3.9.1/fs/proc/root.c 2018-01-09 16:36:32.000000000 +0000
b00e13aa 6065@@ -20,9 +20,14 @@
2380c486
JR
6066 #include <linux/mount.h>
6067 #include <linux/pid_namespace.h>
db55b927 6068 #include <linux/parser.h>
2380c486 6069+#include <linux/vserver/inode.h>
d337f35e 6070
2380c486 6071 #include "internal.h"
d337f35e 6072
d337f35e
JR
6073+struct proc_dir_entry *proc_virtual;
6074+
6075+extern void proc_vx_init(void);
2380c486
JR
6076+
6077 static int proc_test_super(struct super_block *sb, void *data)
6078 {
6079 return sb->s_fs_info == data;
927ca606
AM
6080@@ -113,7 +118,8 @@ static struct dentry *proc_mount(struct
6081 options = data;
c2e5f7c8
JR
6082
6083 /* Does the mounter have privilege over the pid namespace? */
6084- if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
6085+ if (!vx_ns_capable(ns->user_ns,
6086+ CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
6087 return ERR_PTR(-EPERM);
6088 }
6089
927ca606 6090@@ -196,6 +202,7 @@ void __init proc_root_init(void)
bb20add7 6091 proc_tty_init();
2380c486
JR
6092 proc_mkdir("bus", NULL);
6093 proc_sys_init();
d337f35e
JR
6094+ proc_vx_init();
6095 }
6096
6097 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
927ca606 6098@@ -257,6 +264,7 @@ struct proc_dir_entry proc_root = {
2380c486
JR
6099 .proc_iops = &proc_root_inode_operations,
6100 .proc_fops = &proc_root_operations,
6101 .parent = &proc_root,
6102+ .vx_flags = IATTR_ADMIN | IATTR_WATCH,
927ca606 6103 .subdir = RB_ROOT,
a168f21d 6104 .name = "/proc",
2380c486 6105 };
f19bd705
AM
6106diff -NurpP --minimal linux-4.4.111/fs/proc/self.c linux-4.4.111-vs2.3.9.1/fs/proc/self.c
6107--- linux-4.4.111/fs/proc/self.c 2015-10-29 09:21:39.000000000 +0000
6108+++ linux-4.4.111-vs2.3.9.1/fs/proc/self.c 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6109@@ -1,6 +1,7 @@
6110 #include <linux/sched.h>
09be7631
JR
6111 #include <linux/slab.h>
6112 #include <linux/pid_namespace.h>
b00e13aa 6113+#include <linux/vserver/inode.h>
09be7631 6114 #include "internal.h"
b00e13aa
AM
6115
6116 /*
927ca606 6117@@ -52,6 +53,8 @@ int proc_setup_self(struct super_block *
09be7631
JR
6118 self = d_alloc_name(s->s_root, "self");
6119 if (self) {
6120 struct inode *inode = new_inode_pseudo(s);
6121+
6122+ // self->vx_flags = IATTR_PROC_SYMLINK;
6123 if (inode) {
6124 inode->i_ino = self_inum;
6125 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
f19bd705
AM
6126diff -NurpP --minimal linux-4.4.111/fs/proc/stat.c linux-4.4.111-vs2.3.9.1/fs/proc/stat.c
6127--- linux-4.4.111/fs/proc/stat.c 2015-04-12 22:12:50.000000000 +0000
6128+++ linux-4.4.111-vs2.3.9.1/fs/proc/stat.c 2018-01-09 16:36:32.000000000 +0000
537831f9 6129@@ -9,8 +9,10 @@
1e8b8f9b
AM
6130 #include <linux/slab.h>
6131 #include <linux/time.h>
6132 #include <linux/irqnr.h>
6133+#include <linux/vserver/cvirt.h>
265de2f7 6134 #include <linux/cputime.h>
1e8b8f9b 6135 #include <linux/tick.h>
537831f9
AM
6136+#include <linux/cpuset.h>
6137
6138 #ifndef arch_irq_stat_cpu
6139 #define arch_irq_stat_cpu(cpu) 0
6140@@ -87,14 +89,26 @@ static int show_stat(struct seq_file *p,
6141 u64 sum_softirq = 0;
6142 unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
6143 struct timespec boottime;
6144+ cpumask_var_t cpus_allowed;
6145+ bool virt_cpu = vx_flags(VXF_VIRT_CPU, 0);
6146
6147 user = nice = system = idle = iowait =
1e8b8f9b
AM
6148 irq = softirq = steal = 0;
6149 guest = guest_nice = 0;
6150 getboottime(&boottime);
6151+
6152+ if (vx_flags(VXF_VIRT_UPTIME, 0))
6153+ vx_vsi_boottime(&boottime);
537831f9
AM
6154+
6155+ if (virt_cpu)
6156+ cpuset_cpus_allowed(current, cpus_allowed);
1e8b8f9b
AM
6157+
6158 jif = boottime.tv_sec;
6159
6160 for_each_possible_cpu(i) {
537831f9
AM
6161+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6162+ continue;
6163+
6164 user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
6165 nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
6166 system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
6167@@ -131,6 +145,9 @@ static int show_stat(struct seq_file *p,
6168 seq_putc(p, '\n');
6169
6170 for_each_online_cpu(i) {
6171+ if (virt_cpu && !cpumask_test_cpu(i, cpus_allowed))
6172+ continue;
6173+
6174 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
6175 user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
6176 nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
f19bd705
AM
6177diff -NurpP --minimal linux-4.4.111/fs/proc/uptime.c linux-4.4.111-vs2.3.9.1/fs/proc/uptime.c
6178--- linux-4.4.111/fs/proc/uptime.c 2015-04-12 22:12:50.000000000 +0000
6179+++ linux-4.4.111-vs2.3.9.1/fs/proc/uptime.c 2018-01-09 16:36:32.000000000 +0000
f6c5ef8b 6180@@ -5,6 +5,7 @@
ec22aa5c
AM
6181 #include <linux/seq_file.h>
6182 #include <linux/time.h>
f6c5ef8b 6183 #include <linux/kernel_stat.h>
ec22aa5c 6184+#include <linux/vserver/cvirt.h>
265de2f7 6185 #include <linux/cputime.h>
ec22aa5c
AM
6186
6187 static int uptime_proc_show(struct seq_file *m, void *v)
c2e5f7c8 6188@@ -24,6 +25,10 @@ static int uptime_proc_show(struct seq_f
f6c5ef8b
AM
6189 nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
6190 idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
6191 idle.tv_nsec = rem;
ec22aa5c
AM
6192+
6193+ if (vx_flags(VXF_VIRT_UPTIME, 0))
6194+ vx_vsi_uptime(&uptime, &idle);
6195+
6196 seq_printf(m, "%lu.%02lu %lu.%02lu\n",
6197 (unsigned long) uptime.tv_sec,
6198 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
f19bd705
AM
6199diff -NurpP --minimal linux-4.4.111/fs/proc_namespace.c linux-4.4.111-vs2.3.9.1/fs/proc_namespace.c
6200--- linux-4.4.111/fs/proc_namespace.c 2018-01-11 07:57:46.000000000 +0000
6201+++ linux-4.4.111-vs2.3.9.1/fs/proc_namespace.c 2018-01-09 16:36:32.000000000 +0000
927ca606 6202@@ -46,6 +46,8 @@ static int show_sb_opts(struct seq_file
db55b927
AM
6203 { MS_DIRSYNC, ",dirsync" },
6204 { MS_MANDLOCK, ",mand" },
927ca606 6205 { MS_LAZYTIME, ",lazytime" },
db55b927
AM
6206+ { MS_TAGGED, ",tag" },
6207+ { MS_NOTAGCHECK, ",notagcheck" },
6208 { 0, NULL }
6209 };
6210 const struct proc_fs_info *fs_infop;
927ca606 6211@@ -82,6 +84,38 @@ static inline void mangle(struct seq_fil
db55b927
AM
6212 seq_escape(m, s, " \t\n\\");
6213 }
6214
61b0c03f
JR
6215+#ifdef CONFIG_VSERVER_EXTRA_MNT_CHECK
6216+
db55b927
AM
6217+static int mnt_is_reachable(struct vfsmount *vfsmnt)
6218+{
6219+ struct path root;
6220+ struct dentry *point;
6221+ struct mount *mnt = real_mount(vfsmnt);
6222+ struct mount *root_mnt;
6223+ int ret;
6224+
6225+ if (mnt == mnt->mnt_ns->root)
6226+ return 1;
6227+
98d9a5b1 6228+ rcu_read_lock();
db55b927
AM
6229+ root = current->fs->root;
6230+ root_mnt = real_mount(root.mnt);
6231+ point = root.dentry;
6232+
6233+ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
6234+ point = mnt->mnt_mountpoint;
6235+ mnt = mnt->mnt_parent;
6236+ }
98d9a5b1 6237+ rcu_read_unlock();
db55b927
AM
6238+
6239+ ret = (mnt == root_mnt) && is_subdir(point, root.dentry);
db55b927
AM
6240+ return ret;
6241+}
61b0c03f
JR
6242+
6243+#else
6244+#define mnt_is_reachable(v) (1)
6245+#endif
db55b927
AM
6246+
6247 static void show_type(struct seq_file *m, struct super_block *sb)
6248 {
6249 mangle(m, sb->s_type->name);
927ca606 6250@@ -99,6 +133,17 @@ static int show_vfsmnt(struct seq_file *
db55b927
AM
6251 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
6252 struct super_block *sb = mnt_path.dentry->d_sb;
6253
6254+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6255+ return SEQ_SKIP;
6256+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6257+ return SEQ_SKIP;
6258+
6259+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6260+ mnt == current->fs->root.mnt) {
6261+ seq_puts(m, "/dev/root / ");
6262+ goto type;
6263+ }
6264+
6265 if (sb->s_op->show_devname) {
6266 err = sb->s_op->show_devname(m, mnt_path.dentry);
6267 if (err)
927ca606
AM
6268@@ -112,6 +157,7 @@ static int show_vfsmnt(struct seq_file *
6269 if (err)
6270 goto out;
db55b927
AM
6271 seq_putc(m, ' ');
6272+type:
6273 show_type(m, sb);
6274 seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw");
6275 err = show_sb_opts(m, sb);
927ca606
AM
6276@@ -133,6 +179,11 @@ static int show_mountinfo(struct seq_fil
6277 struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
db55b927
AM
6278 int err = 0;
6279
6280+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6281+ return SEQ_SKIP;
6282+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6283+ return SEQ_SKIP;
6284+
6285 seq_printf(m, "%i %i %u:%u ", r->mnt_id, r->mnt_parent->mnt_id,
6286 MAJOR(sb->s_dev), MINOR(sb->s_dev));
6287 if (sb->s_op->show_path)
927ca606 6288@@ -193,6 +244,17 @@ static int show_vfsstat(struct seq_file
db55b927
AM
6289 struct super_block *sb = mnt_path.dentry->d_sb;
6290 int err = 0;
6291
6292+ if (vx_flags(VXF_HIDE_MOUNT, 0))
6293+ return SEQ_SKIP;
6294+ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
6295+ return SEQ_SKIP;
6296+
6297+ if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
6298+ mnt == current->fs->root.mnt) {
6299+ seq_puts(m, "device /dev/root mounted on / ");
6300+ goto type;
6301+ }
6302+
6303 /* device */
6304 if (sb->s_op->show_devname) {
6305 seq_puts(m, "device ");
927ca606
AM
6306@@ -214,7 +276,7 @@ static int show_vfsstat(struct seq_file
6307 if (err)
6308 goto out;
db55b927
AM
6309 seq_putc(m, ' ');
6310-
6311+type:
6312 /* file system type */
6313 seq_puts(m, "with fstype ");
6314 show_type(m, sb);
f19bd705
AM
6315diff -NurpP --minimal linux-4.4.111/fs/quota/dquot.c linux-4.4.111-vs2.3.9.1/fs/quota/dquot.c
6316--- linux-4.4.111/fs/quota/dquot.c 2018-01-11 07:57:46.000000000 +0000
6317+++ linux-4.4.111-vs2.3.9.1/fs/quota/dquot.c 2018-01-09 16:36:32.000000000 +0000
927ca606 6318@@ -1643,6 +1643,9 @@ int __dquot_alloc_space(struct inode *in
76514441 6319 int reserve = flags & DQUOT_SPACE_RESERVE;
927ca606 6320 struct dquot **dquots;
76514441
AM
6321
6322+ if ((ret = dl_alloc_space(inode, number)))
6323+ return ret;
6324+
bb20add7
AM
6325 if (!dquot_active(inode)) {
6326 inode_incr_space(inode, number, reserve);
6327 goto out;
927ca606 6328@@ -1695,6 +1698,9 @@ int dquot_alloc_inode(struct inode *inod
1e8b8f9b 6329 struct dquot_warn warn[MAXQUOTAS];
927ca606 6330 struct dquot * const *dquots;
76514441
AM
6331
6332+ if ((ret = dl_alloc_inode(inode)))
6333+ return ret;
6334+
93de0823 6335 if (!dquot_active(inode))
bb20add7
AM
6336 return 0;
6337 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
927ca606
AM
6338@@ -1797,6 +1803,8 @@ void __dquot_free_space(struct inode *in
6339 struct dquot **dquots;
bb20add7 6340 int reserve = flags & DQUOT_SPACE_RESERVE, index;
76514441
AM
6341
6342+ dl_free_space(inode, number);
6343+
93de0823 6344 if (!dquot_active(inode)) {
bb20add7
AM
6345 inode_decr_space(inode, number, reserve);
6346 return;
927ca606
AM
6347@@ -1841,6 +1849,8 @@ void dquot_free_inode(struct inode *inod
6348 struct dquot * const *dquots;
bb20add7 6349 int index;
76514441
AM
6350
6351+ dl_free_inode(inode);
6352+
93de0823 6353 if (!dquot_active(inode))
bb20add7
AM
6354 return;
6355
f19bd705
AM
6356diff -NurpP --minimal linux-4.4.111/fs/quota/quota.c linux-4.4.111-vs2.3.9.1/fs/quota/quota.c
6357--- linux-4.4.111/fs/quota/quota.c 2016-07-05 04:12:34.000000000 +0000
6358+++ linux-4.4.111-vs2.3.9.1/fs/quota/quota.c 2018-01-09 16:36:32.000000000 +0000
78865d5b
AM
6359@@ -8,6 +8,7 @@
6360 #include <linux/fs.h>
6361 #include <linux/namei.h>
6362 #include <linux/slab.h>
d337f35e 6363+#include <linux/vs_context.h>
78865d5b 6364 #include <asm/current.h>
92598135 6365 #include <linux/uaccess.h>
78865d5b 6366 #include <linux/kernel.h>
c2e5f7c8 6367@@ -38,7 +39,7 @@ static int check_quotactl_permission(str
78865d5b
AM
6368 break;
6369 /*FALLTHROUGH*/
6370 default:
d337f35e
JR
6371- if (!capable(CAP_SYS_ADMIN))
6372+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
6373 return -EPERM;
6374 }
6375
927ca606 6376@@ -702,6 +703,46 @@ static int do_quotactl(struct super_bloc
b00e13aa
AM
6377
6378 #ifdef CONFIG_BLOCK
d337f35e 6379
d337f35e
JR
6380+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6381+
6382+#include <linux/vroot.h>
2380c486
JR
6383+#include <linux/major.h>
6384+#include <linux/module.h>
d337f35e 6385+#include <linux/kallsyms.h>
2380c486 6386+#include <linux/vserver/debug.h>
d337f35e
JR
6387+
6388+static vroot_grb_func *vroot_get_real_bdev = NULL;
6389+
763640ca 6390+static DEFINE_SPINLOCK(vroot_grb_lock);
d337f35e
JR
6391+
6392+int register_vroot_grb(vroot_grb_func *func) {
6393+ int ret = -EBUSY;
6394+
6395+ spin_lock(&vroot_grb_lock);
6396+ if (!vroot_get_real_bdev) {
6397+ vroot_get_real_bdev = func;
6398+ ret = 0;
6399+ }
6400+ spin_unlock(&vroot_grb_lock);
6401+ return ret;
6402+}
6403+EXPORT_SYMBOL(register_vroot_grb);
6404+
6405+int unregister_vroot_grb(vroot_grb_func *func) {
6406+ int ret = -EINVAL;
6407+
6408+ spin_lock(&vroot_grb_lock);
6409+ if (vroot_get_real_bdev) {
6410+ vroot_get_real_bdev = NULL;
6411+ ret = 0;
6412+ }
6413+ spin_unlock(&vroot_grb_lock);
6414+ return ret;
6415+}
6416+EXPORT_SYMBOL(unregister_vroot_grb);
6417+
6418+#endif
6419+
db55b927
AM
6420 /* Return 1 if 'cmd' will block on frozen filesystem */
6421 static int quotactl_cmd_write(int cmd)
6422 {
927ca606 6423@@ -737,6 +778,22 @@ static struct super_block *quotactl_bloc
2380c486
JR
6424 putname(tmp);
6425 if (IS_ERR(bdev))
6426 return ERR_CAST(bdev);
6427+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
6428+ if (bdev && bdev->bd_inode &&
537831f9 6429+ imajor(bdev->bd_inode) == VROOT_MAJOR) {
2380c486
JR
6430+ struct block_device *bdnew = (void *)-EINVAL;
6431+
6432+ if (vroot_get_real_bdev)
6433+ bdnew = vroot_get_real_bdev(bdev);
6434+ else
6435+ vxdprintk(VXD_CBIT(misc, 0),
6436+ "vroot_get_real_bdev not set");
6437+ bdput(bdev);
6438+ if (IS_ERR(bdnew))
6439+ return ERR_PTR(PTR_ERR(bdnew));
6440+ bdev = bdnew;
6441+ }
6442+#endif
db55b927
AM
6443 if (quotactl_cmd_write(cmd))
6444 sb = get_super_thawed(bdev);
6445 else
f19bd705
AM
6446diff -NurpP --minimal linux-4.4.111/fs/stat.c linux-4.4.111-vs2.3.9.1/fs/stat.c
6447--- linux-4.4.111/fs/stat.c 2018-01-11 07:57:46.000000000 +0000
6448+++ linux-4.4.111-vs2.3.9.1/fs/stat.c 2018-01-09 16:36:32.000000000 +0000
2380c486 6449@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod
d337f35e
JR
6450 stat->nlink = inode->i_nlink;
6451 stat->uid = inode->i_uid;
6452 stat->gid = inode->i_gid;
6453+ stat->tag = inode->i_tag;
6454 stat->rdev = inode->i_rdev;
a168f21d 6455 stat->size = i_size_read(inode);
d337f35e 6456 stat->atime = inode->i_atime;
f19bd705
AM
6457diff -NurpP --minimal linux-4.4.111/fs/statfs.c linux-4.4.111-vs2.3.9.1/fs/statfs.c
6458--- linux-4.4.111/fs/statfs.c 2015-04-12 22:12:50.000000000 +0000
6459+++ linux-4.4.111-vs2.3.9.1/fs/statfs.c 2018-01-09 16:36:32.000000000 +0000
93de0823 6460@@ -7,6 +7,8 @@
76514441
AM
6461 #include <linux/statfs.h>
6462 #include <linux/security.h>
6463 #include <linux/uaccess.h>
6464+#include <linux/vs_base.h>
6465+#include <linux/vs_dlimit.h>
db55b927 6466 #include "internal.h"
76514441 6467
93de0823 6468 static int flags_by_mnt(int mnt_flags)
db55b927 6469@@ -60,6 +62,8 @@ static int statfs_by_dentry(struct dentr
93de0823
AM
6470 retval = dentry->d_sb->s_op->statfs(dentry, buf);
6471 if (retval == 0 && buf->f_frsize == 0)
6472 buf->f_frsize = buf->f_bsize;
6473+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
6474+ vx_vsi_statfs(dentry->d_sb, buf);
76514441
AM
6475 return retval;
6476 }
93de0823 6477
f19bd705
AM
6478diff -NurpP --minimal linux-4.4.111/fs/super.c linux-4.4.111-vs2.3.9.1/fs/super.c
6479--- linux-4.4.111/fs/super.c 2018-01-11 07:57:46.000000000 +0000
6480+++ linux-4.4.111-vs2.3.9.1/fs/super.c 2018-01-09 16:36:32.000000000 +0000
bb20add7 6481@@ -33,6 +33,8 @@
be261992 6482 #include <linux/cleancache.h>
1e8b8f9b 6483 #include <linux/fsnotify.h>
92598135 6484 #include <linux/lockdep.h>
1e8b8f9b 6485+#include <linux/magic.h>
be261992
AM
6486+#include <linux/vs_context.h>
6487 #include "internal.h"
6488
6489
927ca606
AM
6490@@ -1131,6 +1133,13 @@ mount_fs(struct file_system_type *type,
6491 WARN_ON(!sb->s_bdi);
be261992
AM
6492 sb->s_flags |= MS_BORN;
6493
6494+ error = -EPERM;
6495+ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) &&
6496+ !sb->s_bdev &&
6497+ (sb->s_magic != PROC_SUPER_MAGIC) &&
6498+ (sb->s_magic != DEVPTS_SUPER_MAGIC))
6499+ goto out_sb;
6500+
6501 error = security_sb_kern_mount(sb, flags, secdata);
6502 if (error)
6503 goto out_sb;
f19bd705
AM
6504diff -NurpP --minimal linux-4.4.111/fs/utimes.c linux-4.4.111-vs2.3.9.1/fs/utimes.c
6505--- linux-4.4.111/fs/utimes.c 2018-01-11 07:57:46.000000000 +0000
6506+++ linux-4.4.111-vs2.3.9.1/fs/utimes.c 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
6507@@ -8,6 +8,8 @@
6508 #include <linux/stat.h>
d337f35e 6509 #include <linux/utime.h>
2380c486 6510 #include <linux/syscalls.h>
d337f35e
JR
6511+#include <linux/mount.h>
6512+#include <linux/vs_cowbl.h>
6513 #include <asm/uaccess.h>
6514 #include <asm/unistd.h>
6515
c2e5f7c8 6516@@ -52,13 +54,19 @@ static int utimes_common(struct path *pa
76514441
AM
6517 {
6518 int error;
6519 struct iattr newattrs;
6520- struct inode *inode = path->dentry->d_inode;
c2e5f7c8 6521 struct inode *delegated_inode = NULL;
76514441 6522+ struct inode *inode;
b00e13aa
AM
6523+
6524+ error = cow_check_and_break(path);
6525+ if (error)
6526+ goto out;
76514441
AM
6527
6528 error = mnt_want_write(path->mnt);
6529 if (error)
6530 goto out;
6531
76514441
AM
6532+ inode = path->dentry->d_inode;
6533+
6534 if (times && times[0].tv_nsec == UTIME_NOW &&
6535 times[1].tv_nsec == UTIME_NOW)
6536 times = NULL;
f19bd705
AM
6537diff -NurpP --minimal linux-4.4.111/fs/xattr.c linux-4.4.111-vs2.3.9.1/fs/xattr.c
6538--- linux-4.4.111/fs/xattr.c 2018-01-11 07:57:46.000000000 +0000
6539+++ linux-4.4.111-vs2.3.9.1/fs/xattr.c 2018-01-09 16:36:32.000000000 +0000
537831f9 6540@@ -21,6 +21,7 @@
d337f35e 6541 #include <linux/audit.h>
1e8b8f9b 6542 #include <linux/vmalloc.h>
537831f9 6543 #include <linux/posix_acl_xattr.h>
d337f35e 6544+#include <linux/mount.h>
d337f35e 6545
1e8b8f9b 6546 #include <asm/uaccess.h>
d337f35e 6547
537831f9 6548@@ -52,7 +53,7 @@ xattr_permission(struct inode *inode, co
763640ca 6549 * The trusted.* namespace can only be accessed by privileged users.
e03b8c3c 6550 */
763640ca
JR
6551 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
6552- if (!capable(CAP_SYS_ADMIN))
a168f21d
AM
6553+ if (!vx_capable(CAP_SYS_ADMIN, VXC_FS_TRUSTED))
6554 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
6555 return 0;
6556 }
f19bd705
AM
6557diff -NurpP --minimal linux-4.4.111/include/linux/capability.h linux-4.4.111-vs2.3.9.1/include/linux/capability.h
6558--- linux-4.4.111/include/linux/capability.h 2018-01-11 07:57:47.000000000 +0000
6559+++ linux-4.4.111-vs2.3.9.1/include/linux/capability.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6560@@ -77,7 +77,8 @@ extern const kernel_cap_t __cap_init_eff
bb20add7
AM
6561 #else /* HAND-CODED capability initializers */
6562
6563 #define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1)
6564-#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
6565+#define CAP_LAST_U32_VALID_MASK ((CAP_TO_MASK(CAP_LAST_CAP + 1) -1) \
6566+ | CAP_TO_MASK(CAP_CONTEXT))
6567
6568 # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
6569 # define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
f19bd705
AM
6570diff -NurpP --minimal linux-4.4.111/include/linux/cred.h linux-4.4.111-vs2.3.9.1/include/linux/cred.h
6571--- linux-4.4.111/include/linux/cred.h 2018-01-11 07:57:47.000000000 +0000
6572+++ linux-4.4.111-vs2.3.9.1/include/linux/cred.h 2018-01-11 08:03:00.000000000 +0000
6573@@ -161,6 +161,7 @@ extern void exit_creds(struct task_struc
1163e6ab
AM
6574 extern int copy_creds(struct task_struct *, unsigned long);
6575 extern const struct cred *get_task_cred(struct task_struct *);
6576 extern struct cred *cred_alloc_blank(void);
6577+extern struct cred *__prepare_creds(const struct cred *);
6578 extern struct cred *prepare_creds(void);
6579 extern struct cred *prepare_exec_creds(void);
6580 extern int commit_creds(struct cred *);
f19bd705 6581@@ -221,6 +222,31 @@ static inline bool cap_ambient_invariant
927ca606 6582 cred->cap_inheritable));
3bac966d 6583 }
3bac966d
AM
6584
6585+static inline void set_cred_subscribers(struct cred *cred, int n)
6586+{
6587+#ifdef CONFIG_DEBUG_CREDENTIALS
6588+ atomic_set(&cred->subscribers, n);
6589+#endif
6590+}
6591+
6592+static inline int read_cred_subscribers(const struct cred *cred)
6593+{
6594+#ifdef CONFIG_DEBUG_CREDENTIALS
6595+ return atomic_read(&cred->subscribers);
6596+#else
6597+ return 0;
6598+#endif
6599+}
6600+
6601+static inline void alter_cred_subscribers(const struct cred *_cred, int n)
6602+{
6603+#ifdef CONFIG_DEBUG_CREDENTIALS
6604+ struct cred *cred = (struct cred *) _cred;
6605+
6606+ atomic_add(n, &cred->subscribers);
6607+#endif
6608+}
6609+
6610 /**
6611 * get_new_cred - Get a reference on a new set of credentials
6612 * @cred: The new credentials to reference
f19bd705
AM
6613diff -NurpP --minimal linux-4.4.111/include/linux/dcache.h linux-4.4.111-vs2.3.9.1/include/linux/dcache.h
6614--- linux-4.4.111/include/linux/dcache.h 2018-01-11 07:57:47.000000000 +0000
6615+++ linux-4.4.111-vs2.3.9.1/include/linux/dcache.h 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6616@@ -10,6 +10,7 @@
6617 #include <linux/cache.h>
6618 #include <linux/rcupdate.h>
6619 #include <linux/lockref.h>
6620+// #include <linux/vs_limit.h>
6621
6622 struct path;
6623 struct vfsmount;
6624@@ -351,8 +352,10 @@ extern char *dentry_path(struct dentry *
6625 */
6626 static inline struct dentry *dget_dlock(struct dentry *dentry)
6627 {
6628- if (dentry)
6629+ if (dentry) {
6630 dentry->d_lockref.count++;
6631+ // vx_dentry_inc(dentry);
6632+ }
6633 return dentry;
6634 }
6635
f19bd705
AM
6636diff -NurpP --minimal linux-4.4.111/include/linux/devpts_fs.h linux-4.4.111-vs2.3.9.1/include/linux/devpts_fs.h
6637--- linux-4.4.111/include/linux/devpts_fs.h 2018-01-11 07:57:47.000000000 +0000
6638+++ linux-4.4.111-vs2.3.9.1/include/linux/devpts_fs.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6639@@ -35,5 +35,4 @@ void devpts_pty_kill(struct inode *inode
2380c486
JR
6640
6641 #endif
d337f35e 6642
2380c486 6643-
d337f35e 6644 #endif /* _LINUX_DEVPTS_FS_H */
f19bd705
AM
6645diff -NurpP --minimal linux-4.4.111/include/linux/fs.h linux-4.4.111-vs2.3.9.1/include/linux/fs.h
6646--- linux-4.4.111/include/linux/fs.h 2018-01-11 07:57:47.000000000 +0000
6647+++ linux-4.4.111-vs2.3.9.1/include/linux/fs.h 2018-01-09 16:43:56.000000000 +0000
927ca606 6648@@ -227,6 +227,7 @@ typedef void (dax_iodone_t)(struct buffe
2380c486
JR
6649 #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
6650 #define ATTR_TIMES_SET (1 << 16)
927ca606
AM
6651 #define ATTR_TOUCH (1 << 17)
6652+#define ATTR_TAG (1 << 18)
d337f35e
JR
6653
6654 /*
bb20add7 6655 * Whiteout is represented by a char device. The following constants define the
927ca606 6656@@ -249,6 +250,7 @@ struct iattr {
d337f35e 6657 umode_t ia_mode;
42bc425c
AM
6658 kuid_t ia_uid;
6659 kgid_t ia_gid;
537831f9 6660+ ktag_t ia_tag;
d337f35e
JR
6661 loff_t ia_size;
6662 struct timespec ia_atime;
6663 struct timespec ia_mtime;
927ca606 6664@@ -587,7 +589,9 @@ struct inode {
a168f21d 6665 unsigned short i_opflags;
42bc425c
AM
6666 kuid_t i_uid;
6667 kgid_t i_gid;
2380c486 6668- unsigned int i_flags;
537831f9 6669+ ktag_t i_tag;
2380c486
JR
6670+ unsigned short i_flags;
6671+ unsigned short i_vflags;
a168f21d
AM
6672
6673 #ifdef CONFIG_FS_POSIX_ACL
6674 struct posix_acl *i_acl;
927ca606 6675@@ -616,6 +620,7 @@ struct inode {
f6c5ef8b
AM
6676 unsigned int __i_nlink;
6677 };
d33d7b00
AM
6678 dev_t i_rdev;
6679+ dev_t i_mdev;
42bc425c 6680 loff_t i_size;
a168f21d
AM
6681 struct timespec i_atime;
6682 struct timespec i_mtime;
927ca606 6683@@ -814,6 +819,11 @@ static inline gid_t i_gid_read(const str
537831f9
AM
6684 return from_kgid(&init_user_ns, inode->i_gid);
6685 }
6686
61333608 6687+static inline vtag_t i_tag_read(const struct inode *inode)
537831f9
AM
6688+{
6689+ return from_ktag(&init_user_ns, inode->i_tag);
6690+}
6691+
6692 static inline void i_uid_write(struct inode *inode, uid_t uid)
6693 {
6694 inode->i_uid = make_kuid(&init_user_ns, uid);
927ca606 6695@@ -824,14 +834,19 @@ static inline void i_gid_write(struct in
537831f9
AM
6696 inode->i_gid = make_kgid(&init_user_ns, gid);
6697 }
2380c486 6698
61333608 6699+static inline void i_tag_write(struct inode *inode, vtag_t tag)
537831f9
AM
6700+{
6701+ inode->i_tag = make_ktag(&init_user_ns, tag);
6702+}
6703+
2380c486
JR
6704 static inline unsigned iminor(const struct inode *inode)
6705 {
6706- return MINOR(inode->i_rdev);
6707+ return MINOR(inode->i_mdev);
6708 }
6709
6710 static inline unsigned imajor(const struct inode *inode)
6711 {
6712- return MAJOR(inode->i_rdev);
6713+ return MAJOR(inode->i_mdev);
6714 }
6715
6716 extern struct block_device *I_BDEV(struct inode *inode);
927ca606 6717@@ -888,6 +903,7 @@ struct file {
d337f35e
JR
6718 loff_t f_pos;
6719 struct fown_struct f_owner;
ec22aa5c 6720 const struct cred *f_cred;
61333608 6721+ vxid_t f_xid;
d337f35e
JR
6722 struct file_ra_state f_ra;
6723
2380c486 6724 u64 f_version;
927ca606 6725@@ -1022,6 +1038,7 @@ struct file_lock {
2380c486 6726 struct file *fl_file;
d337f35e
JR
6727 loff_t fl_start;
6728 loff_t fl_end;
61333608 6729+ vxid_t fl_xid;
d337f35e
JR
6730
6731 struct fasync_struct * fl_fasync; /* for lease break notifications */
f6c5ef8b 6732 /* for lease breaks: */
927ca606 6733@@ -1698,6 +1715,7 @@ struct inode_operations {
d4263eb0
JR
6734 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
6735 ssize_t (*listxattr) (struct dentry *, char *, size_t);
6736 int (*removexattr) (struct dentry *, const char *);
6737+ int (*sync_flags) (struct inode *, int, int);
d33d7b00
AM
6738 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
6739 u64 len);
42bc425c 6740 int (*update_time)(struct inode *, struct timespec *, int);
927ca606 6741@@ -1712,6 +1730,7 @@ ssize_t rw_copy_check_uvector(int type,
537831f9
AM
6742 unsigned long nr_segs, unsigned long fast_segs,
6743 struct iovec *fast_pointer,
6744 struct iovec **ret_pointer);
d337f35e
JR
6745+ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
6746
927ca606
AM
6747 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
6748 extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
6749@@ -1777,6 +1796,14 @@ struct super_operations {
6750 #else
6751 #define S_DAX 0 /* Make all the DAX code disappear */
6752 #endif
6753+#define S_IXUNLINK 16384 /* Immutable Invert on unlink */
537831f9
AM
6754+
6755+/* Linux-VServer related Inode flags */
6756+
6757+#define V_VALID 1
6758+#define V_XATTR 2
6759+#define V_BARRIER 4 /* Barrier for chroot() */
6760+#define V_COW 8 /* Copy on Write */
6761
6762 /*
6763 * Note that nosuid etc flags are inode-specific: setting some file-system
927ca606 6764@@ -1801,10 +1828,13 @@ struct super_operations {
537831f9
AM
6765 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
6766 #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
6767 #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
6768+#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
6769
6770 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
6771 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
6772 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
6773+#define IS_IXUNLINK(inode) ((inode)->i_flags & S_IXUNLINK)
6774+#define IS_IXORUNLINK(inode) ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
6775 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
6776
6777 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
927ca606 6778@@ -1819,6 +1849,16 @@ struct super_operations {
bb20add7
AM
6779 #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
6780 (inode)->i_rdev == WHITEOUT_DEV)
537831f9
AM
6781
6782+#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER))
6783+
6784+#ifdef CONFIG_VSERVER_COWBL
6785+# define IS_COW(inode) (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode))
6786+# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
6787+#else
6788+# define IS_COW(inode) (0)
6789+# define IS_COW_LINK(inode) (0)
6790+#endif
6791+
6792 /*
6793 * Inode state bits. Protected by inode->i_lock
6794 *
927ca606 6795@@ -2075,6 +2115,9 @@ extern struct kobject *fs_kobj;
bb20add7 6796 extern int locks_mandatory_locked(struct file *);
537831f9
AM
6797 extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
6798
6799+#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
6800+#define ATTR_FLAG_IXUNLINK 1024 /* Immutable invert on unlink */
6801+
6802 /*
6803 * Candidates for mandatory locking have the setgid bit set
6804 * but no group execute bit - an otherwise meaningless combination.
927ca606 6805@@ -2830,6 +2873,7 @@ extern int dcache_dir_open(struct inode
d337f35e
JR
6806 extern int dcache_dir_close(struct inode *, struct file *);
6807 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
c2e5f7c8
JR
6808 extern int dcache_readdir(struct file *, struct dir_context *);
6809+extern int dcache_readdir_filter(struct file *, struct dir_context *, int (*)(struct dentry *));
76514441 6810 extern int simple_setattr(struct dentry *, struct iattr *);
d337f35e
JR
6811 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
6812 extern int simple_statfs(struct dentry *, struct kstatfs *);
f19bd705
AM
6813diff -NurpP --minimal linux-4.4.111/include/linux/init_task.h linux-4.4.111-vs2.3.9.1/include/linux/init_task.h
6814--- linux-4.4.111/include/linux/init_task.h 2016-07-05 04:15:10.000000000 +0000
6815+++ linux-4.4.111-vs2.3.9.1/include/linux/init_task.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6816@@ -260,6 +260,10 @@ extern struct task_group root_task_group
b00e13aa 6817 INIT_VTIME(tsk) \
927ca606
AM
6818 INIT_NUMA_BALANCING(tsk) \
6819 INIT_KASAN(tsk) \
d337f35e
JR
6820+ .xid = 0, \
6821+ .vx_info = NULL, \
6822+ .nid = 0, \
6823+ .nx_info = NULL, \
6824 }
6825
6826
f19bd705
AM
6827diff -NurpP --minimal linux-4.4.111/include/linux/ipc.h linux-4.4.111-vs2.3.9.1/include/linux/ipc.h
6828--- linux-4.4.111/include/linux/ipc.h 2015-04-12 22:12:50.000000000 +0000
6829+++ linux-4.4.111-vs2.3.9.1/include/linux/ipc.h 2018-01-09 16:36:32.000000000 +0000
537831f9 6830@@ -16,6 +16,7 @@ struct kern_ipc_perm
d337f35e 6831 key_t key;
537831f9
AM
6832 kuid_t uid;
6833 kgid_t gid;
61333608 6834+ vxid_t xid;
537831f9
AM
6835 kuid_t cuid;
6836 kgid_t cgid;
db55b927 6837 umode_t mode;
f19bd705
AM
6838diff -NurpP --minimal linux-4.4.111/include/linux/memcontrol.h linux-4.4.111-vs2.3.9.1/include/linux/memcontrol.h
6839--- linux-4.4.111/include/linux/memcontrol.h 2018-01-11 07:57:48.000000000 +0000
6840+++ linux-4.4.111-vs2.3.9.1/include/linux/memcontrol.h 2018-01-09 16:36:32.000000000 +0000
927ca606
AM
6841@@ -113,6 +113,7 @@ struct cg_proto {
6842 struct mem_cgroup *memcg;
6843 };
6844
6845+
6846 #ifdef CONFIG_MEMCG
6847 struct mem_cgroup_stat_cpu {
6848 long count[MEM_CGROUP_STAT_NSTATS];
6849@@ -338,6 +339,11 @@ static inline bool mem_cgroup_is_descend
6850 return cgroup_is_descendant(memcg->css.cgroup, root->css.cgroup);
6851 }
6852
6853+extern u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg);
6854+extern u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg);
6855+extern u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg);
6856+extern u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg);
6857+
6858 static inline bool mm_match_cgroup(struct mm_struct *mm,
6859 struct mem_cgroup *memcg)
e3afe727 6860 {
f19bd705
AM
6861diff -NurpP --minimal linux-4.4.111/include/linux/mount.h linux-4.4.111-vs2.3.9.1/include/linux/mount.h
6862--- linux-4.4.111/include/linux/mount.h 2018-01-11 07:57:48.000000000 +0000
6863+++ linux-4.4.111-vs2.3.9.1/include/linux/mount.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6864@@ -63,6 +63,9 @@ struct mnt_namespace;
bb20add7 6865 #define MNT_MARKED 0x4000000
927ca606 6866 #define MNT_UMOUNT 0x8000000
d337f35e 6867
2380c486
JR
6868+#define MNT_TAGID 0x10000
6869+#define MNT_NOTAG 0x20000
6870+
d337f35e 6871 struct vfsmount {
db55b927
AM
6872 struct dentry *mnt_root; /* root of the mounted tree */
6873 struct super_block *mnt_sb; /* pointer to superblock */
f19bd705
AM
6874diff -NurpP --minimal linux-4.4.111/include/linux/net.h linux-4.4.111-vs2.3.9.1/include/linux/net.h
6875--- linux-4.4.111/include/linux/net.h 2018-01-11 07:57:48.000000000 +0000
6876+++ linux-4.4.111-vs2.3.9.1/include/linux/net.h 2018-01-09 16:42:30.000000000 +0000
927ca606
AM
6877@@ -43,6 +43,7 @@ struct net;
6878 #define SOCK_NOSPACE 2
d337f35e
JR
6879 #define SOCK_PASSCRED 3
6880 #define SOCK_PASSSEC 4
927ca606 6881+#define SOCK_USER_SOCKET 5
d337f35e
JR
6882
6883 #ifndef ARCH_HAS_SOCKET_TYPES
6884 /**
f19bd705
AM
6885diff -NurpP --minimal linux-4.4.111/include/linux/netdevice.h linux-4.4.111-vs2.3.9.1/include/linux/netdevice.h
6886--- linux-4.4.111/include/linux/netdevice.h 2018-01-11 07:57:48.000000000 +0000
6887+++ linux-4.4.111-vs2.3.9.1/include/linux/netdevice.h 2018-01-09 16:36:32.000000000 +0000
927ca606 6888@@ -2296,6 +2296,7 @@ static inline int dev_recursion_level(vo
c2e5f7c8
JR
6889
6890 struct net_device *dev_get_by_index(struct net *net, int ifindex);
6891 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
6892+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex);
6893 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
6894 int netdev_get_name(struct net *net, char *name, int ifindex);
6895 int dev_restart(struct net_device *dev);
f19bd705
AM
6896diff -NurpP --minimal linux-4.4.111/include/linux/nsproxy.h linux-4.4.111-vs2.3.9.1/include/linux/nsproxy.h
6897--- linux-4.4.111/include/linux/nsproxy.h 2015-04-12 22:12:50.000000000 +0000
6898+++ linux-4.4.111-vs2.3.9.1/include/linux/nsproxy.h 2018-01-09 16:36:32.000000000 +0000
2380c486 6899@@ -3,6 +3,7 @@
d337f35e 6900
2380c486
JR
6901 #include <linux/spinlock.h>
6902 #include <linux/sched.h>
6903+#include <linux/vserver/debug.h>
6904
6905 struct mnt_namespace;
6906 struct uts_namespace;
bb20add7
AM
6907@@ -63,6 +64,7 @@ extern struct nsproxy init_nsproxy;
6908 */
2380c486
JR
6909
6910 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
6911+struct nsproxy *copy_nsproxy(struct nsproxy *orig);
6912 void exit_task_namespaces(struct task_struct *tsk);
6913 void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
6914 void free_nsproxy(struct nsproxy *ns);
bb20add7 6915@@ -70,16 +72,26 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 6916 struct cred *, struct fs_struct *);
a168f21d 6917 int __init nsproxy_cache_init(void);
2380c486
JR
6918
6919-static inline void put_nsproxy(struct nsproxy *ns)
6920+#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__)
d337f35e 6921+
2380c486
JR
6922+static inline void __get_nsproxy(struct nsproxy *ns,
6923+ const char *_file, int _line)
6924 {
6925- if (atomic_dec_and_test(&ns->count)) {
6926- free_nsproxy(ns);
6927- }
6928+ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])",
6929+ ns, atomic_read(&ns->count), _file, _line);
d337f35e 6930+ atomic_inc(&ns->count);
2380c486
JR
6931 }
6932
6933-static inline void get_nsproxy(struct nsproxy *ns)
6934+#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__)
d337f35e 6935+
2380c486
JR
6936+static inline void __put_nsproxy(struct nsproxy *ns,
6937+ const char *_file, int _line)
6938 {
6939- atomic_inc(&ns->count);
6940+ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])",
6941+ ns, atomic_read(&ns->count), _file, _line);
6942+ if (atomic_dec_and_test(&ns->count)) {
6943+ free_nsproxy(ns);
6944+ }
6945 }
d337f35e 6946
763640ca 6947 #endif
f19bd705
AM
6948diff -NurpP --minimal linux-4.4.111/include/linux/pid.h linux-4.4.111-vs2.3.9.1/include/linux/pid.h
6949--- linux-4.4.111/include/linux/pid.h 2018-01-11 07:57:48.000000000 +0000
6950+++ linux-4.4.111-vs2.3.9.1/include/linux/pid.h 2018-01-09 16:45:21.000000000 +0000
927ca606 6951@@ -10,7 +10,8 @@ enum pid_type
d337f35e 6952 PIDTYPE_SID,
927ca606
AM
6953 PIDTYPE_MAX,
6954 /* only valid to __task_pid_nr_ns() */
6955- __PIDTYPE_TGID
6956+ __PIDTYPE_TGID,
6957+ __PIDTYPE_REALPID
d337f35e
JR
6958 };
6959
6960 /*
927ca606 6961@@ -172,6 +173,7 @@ static inline pid_t pid_nr(struct pid *p
2380c486
JR
6962 }
6963
6964 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
6965+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns);
6966 pid_t pid_vnr(struct pid *pid);
6967
6968 #define do_each_pid_task(pid, type, task) \
f19bd705
AM
6969diff -NurpP --minimal linux-4.4.111/include/linux/quotaops.h linux-4.4.111-vs2.3.9.1/include/linux/quotaops.h
6970--- linux-4.4.111/include/linux/quotaops.h 2016-07-05 04:12:37.000000000 +0000
6971+++ linux-4.4.111-vs2.3.9.1/include/linux/quotaops.h 2018-01-09 16:36:32.000000000 +0000
e22b5178
AM
6972@@ -8,6 +8,7 @@
6973 #define _LINUX_QUOTAOPS_
6974
6975 #include <linux/fs.h>
6976+#include <linux/vs_dlimit.h>
6977
76514441
AM
6978 #define DQUOT_SPACE_WARN 0x1
6979 #define DQUOT_SPACE_RESERVE 0x2
927ca606 6980@@ -211,11 +212,12 @@ static inline void dquot_drop(struct ino
76514441 6981
927ca606 6982 static inline int dquot_alloc_inode(struct inode *inode)
76514441
AM
6983 {
6984- return 0;
6985+ return dl_alloc_inode(inode);
6986 }
6987
927ca606 6988 static inline void dquot_free_inode(struct inode *inode)
e22b5178 6989 {
76514441
AM
6990+ dl_free_inode(inode);
6991 }
6992
6993 static inline int dquot_transfer(struct inode *inode, struct iattr *iattr)
927ca606 6994@@ -226,6 +228,10 @@ static inline int dquot_transfer(struct
76514441
AM
6995 static inline int __dquot_alloc_space(struct inode *inode, qsize_t number,
6996 int flags)
6997 {
6998+ int ret = 0;
6999+
7000+ if ((ret = dl_alloc_space(inode, number)))
7001+ return ret;
7002 if (!(flags & DQUOT_SPACE_RESERVE))
7003 inode_add_bytes(inode, number);
7004 return 0;
927ca606 7005@@ -236,6 +242,7 @@ static inline void __dquot_free_space(st
76514441
AM
7006 {
7007 if (!(flags & DQUOT_SPACE_RESERVE))
7008 inode_sub_bytes(inode, number);
7009+ dl_free_space(inode, number);
7010 }
7011
7012 static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
f19bd705
AM
7013diff -NurpP --minimal linux-4.4.111/include/linux/sched.h linux-4.4.111-vs2.3.9.1/include/linux/sched.h
7014--- linux-4.4.111/include/linux/sched.h 2018-01-11 07:57:48.000000000 +0000
7015+++ linux-4.4.111-vs2.3.9.1/include/linux/sched.h 2018-01-09 16:36:32.000000000 +0000
927ca606 7016@@ -1600,6 +1600,14 @@ struct task_struct {
2380c486 7017 #endif
42bc425c 7018 struct seccomp seccomp;
2380c486
JR
7019
7020+/* vserver context data */
7021+ struct vx_info *vx_info;
7022+ struct nx_info *nx_info;
d337f35e 7023+
61333608
AM
7024+ vxid_t xid;
7025+ vnid_t nid;
7026+ vtag_t tag;
2380c486
JR
7027+
7028 /* Thread group tracking */
7029 u32 parent_exec_id;
7030 u32 self_exec_id;
927ca606 7031@@ -1927,6 +1935,11 @@ struct pid_namespace;
ec22aa5c
AM
7032 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
7033 struct pid_namespace *ns);
d337f35e 7034
2380c486
JR
7035+#include <linux/vserver/base.h>
7036+#include <linux/vserver/context.h>
7037+#include <linux/vserver/debug.h>
7038+#include <linux/vserver/pid.h>
7039+
7040 static inline pid_t task_pid_nr(struct task_struct *tsk)
7041 {
7042 return tsk->pid;
927ca606 7043@@ -1940,7 +1953,8 @@ static inline pid_t task_pid_nr_ns(struc
d337f35e 7044
2380c486
JR
7045 static inline pid_t task_pid_vnr(struct task_struct *tsk)
7046 {
ec22aa5c
AM
7047- return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7048+ // return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL);
7049+ return vx_map_pid(__task_pid_nr_ns(tsk, PIDTYPE_PID, NULL));
2380c486 7050 }
d337f35e 7051
d337f35e 7052
f19bd705
AM
7053diff -NurpP --minimal linux-4.4.111/include/linux/shmem_fs.h linux-4.4.111-vs2.3.9.1/include/linux/shmem_fs.h
7054--- linux-4.4.111/include/linux/shmem_fs.h 2018-01-11 07:57:48.000000000 +0000
7055+++ linux-4.4.111-vs2.3.9.1/include/linux/shmem_fs.h 2018-01-09 16:36:32.000000000 +0000
bb20add7 7056@@ -10,6 +10,9 @@
2380c486 7057
a168f21d 7058 /* inode in-kernel data */
2380c486
JR
7059
7060+#define TMPFS_SUPER_MAGIC 0x01021994
7061+
7062+
7063 struct shmem_inode_info {
7064 spinlock_t lock;
bb20add7 7065 unsigned int seals; /* shmem seals */
f19bd705
AM
7066diff -NurpP --minimal linux-4.4.111/include/linux/stat.h linux-4.4.111-vs2.3.9.1/include/linux/stat.h
7067--- linux-4.4.111/include/linux/stat.h 2015-04-12 22:12:50.000000000 +0000
7068+++ linux-4.4.111-vs2.3.9.1/include/linux/stat.h 2018-01-09 16:36:32.000000000 +0000
537831f9 7069@@ -25,6 +25,7 @@ struct kstat {
2380c486 7070 unsigned int nlink;
42bc425c
AM
7071 kuid_t uid;
7072 kgid_t gid;
8ce283e1 7073+ ktag_t tag;
2380c486
JR
7074 dev_t rdev;
7075 loff_t size;
7076 struct timespec atime;
f19bd705
AM
7077diff -NurpP --minimal linux-4.4.111/include/linux/sunrpc/auth.h linux-4.4.111-vs2.3.9.1/include/linux/sunrpc/auth.h
7078--- linux-4.4.111/include/linux/sunrpc/auth.h 2016-07-05 04:12:37.000000000 +0000
7079+++ linux-4.4.111-vs2.3.9.1/include/linux/sunrpc/auth.h 2018-01-09 16:36:32.000000000 +0000
927ca606 7080@@ -40,6 +40,7 @@ enum {
2380c486 7081 struct auth_cred {
b00e13aa
AM
7082 kuid_t uid;
7083 kgid_t gid;
7084+ ktag_t tag;
2380c486 7085 struct group_info *group_info;
db55b927 7086 const char *principal;
c2e5f7c8 7087 unsigned long ac_flags;
f19bd705
AM
7088diff -NurpP --minimal linux-4.4.111/include/linux/sunrpc/clnt.h linux-4.4.111-vs2.3.9.1/include/linux/sunrpc/clnt.h
7089--- linux-4.4.111/include/linux/sunrpc/clnt.h 2018-01-11 07:57:48.000000000 +0000
7090+++ linux-4.4.111-vs2.3.9.1/include/linux/sunrpc/clnt.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 7091@@ -51,7 +51,8 @@ struct rpc_clnt {
2380c486 7092 cl_discrtry : 1,/* disconnect before retry */
c2e5f7c8 7093 cl_noretranstimeo: 1,/* No retransmit timeouts */
2380c486
JR
7094 cl_autobind : 1,/* use getport() */
7095- cl_chatty : 1;/* be verbose */
7096+ cl_chatty : 1,/* be verbose */
7097+ cl_tag : 1;/* context tagging */
d337f35e 7098
2380c486
JR
7099 struct rpc_rtt * cl_rtt; /* RTO estimator data */
7100 const struct rpc_timeout *cl_timeout; /* Timeout strategy */
f19bd705
AM
7101diff -NurpP --minimal linux-4.4.111/include/linux/types.h linux-4.4.111-vs2.3.9.1/include/linux/types.h
7102--- linux-4.4.111/include/linux/types.h 2016-07-05 04:15:11.000000000 +0000
7103+++ linux-4.4.111-vs2.3.9.1/include/linux/types.h 2018-01-09 16:36:32.000000000 +0000
537831f9 7104@@ -32,6 +32,9 @@ typedef __kernel_uid32_t uid_t;
2380c486
JR
7105 typedef __kernel_gid32_t gid_t;
7106 typedef __kernel_uid16_t uid16_t;
7107 typedef __kernel_gid16_t gid16_t;
61333608
AM
7108+typedef unsigned int vxid_t;
7109+typedef unsigned int vnid_t;
7110+typedef unsigned int vtag_t;
2380c486
JR
7111
7112 typedef unsigned long uintptr_t;
7113
f19bd705
AM
7114diff -NurpP --minimal linux-4.4.111/include/linux/uidgid.h linux-4.4.111-vs2.3.9.1/include/linux/uidgid.h
7115--- linux-4.4.111/include/linux/uidgid.h 2015-07-06 20:41:43.000000000 +0000
7116+++ linux-4.4.111-vs2.3.9.1/include/linux/uidgid.h 2018-01-09 16:36:32.000000000 +0000
bb20add7 7117@@ -21,13 +21,17 @@ typedef struct {
537831f9
AM
7118 uid_t val;
7119 } kuid_t;
7120
7121-
7122 typedef struct {
7123 gid_t val;
7124 } kgid_t;
7125
7126+typedef struct {
61333608 7127+ vtag_t val;
537831f9
AM
7128+} ktag_t;
7129+
7130 #define KUIDT_INIT(value) (kuid_t){ value }
7131 #define KGIDT_INIT(value) (kgid_t){ value }
7132+#define KTAGT_INIT(value) (ktag_t){ value }
7133
927ca606 7134 #ifdef CONFIG_MULTIUSER
537831f9 7135 static inline uid_t __kuid_val(kuid_t uid)
927ca606 7136@@ -51,11 +55,18 @@ static inline gid_t __kgid_val(kgid_t gi
537831f9 7137 }
927ca606 7138 #endif
537831f9 7139
61333608 7140+static inline vtag_t __ktag_val(ktag_t tag)
537831f9
AM
7141+{
7142+ return tag.val;
7143+}
7144+
537831f9
AM
7145 #define GLOBAL_ROOT_UID KUIDT_INIT(0)
7146 #define GLOBAL_ROOT_GID KGIDT_INIT(0)
7147+#define GLOBAL_ROOT_TAG KTAGT_INIT(0)
7148
7149 #define INVALID_UID KUIDT_INIT(-1)
7150 #define INVALID_GID KGIDT_INIT(-1)
7151+#define INVALID_TAG KTAGT_INIT(-1)
7152
7153 static inline bool uid_eq(kuid_t left, kuid_t right)
7154 {
927ca606 7155@@ -67,6 +78,11 @@ static inline bool gid_eq(kgid_t left, k
537831f9
AM
7156 return __kgid_val(left) == __kgid_val(right);
7157 }
7158
7159+static inline bool tag_eq(ktag_t left, ktag_t right)
7160+{
7161+ return __ktag_val(left) == __ktag_val(right);
7162+}
7163+
7164 static inline bool uid_gt(kuid_t left, kuid_t right)
7165 {
7166 return __kuid_val(left) > __kuid_val(right);
927ca606
AM
7167@@ -117,13 +133,21 @@ static inline bool gid_valid(kgid_t gid)
7168 return __kgid_val(gid) != (gid_t) -1;
537831f9
AM
7169 }
7170
7171+static inline bool tag_valid(ktag_t tag)
7172+{
7173+ return !tag_eq(tag, INVALID_TAG);
7174+}
7175+
7176 #ifdef CONFIG_USER_NS
7177
7178 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
7179 extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
c90fe048 7180+extern ktag_t make_ktag(struct user_namespace *from, gid_t gid);
537831f9
AM
7181
7182 extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
7183 extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
61333608 7184+extern vtag_t from_ktag(struct user_namespace *to, ktag_t tag);
537831f9
AM
7185+
7186 extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
7187 extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
7188
927ca606 7189@@ -149,6 +173,11 @@ static inline kgid_t make_kgid(struct us
537831f9
AM
7190 return KGIDT_INIT(gid);
7191 }
7192
61333608 7193+static inline ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
537831f9
AM
7194+{
7195+ return KTAGT_INIT(tag);
7196+}
7197+
7198 static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
7199 {
7200 return __kuid_val(kuid);
927ca606 7201@@ -159,6 +188,11 @@ static inline gid_t from_kgid(struct use
537831f9
AM
7202 return __kgid_val(kgid);
7203 }
7204
61333608 7205+static inline vtag_t from_ktag(struct user_namespace *to, ktag_t ktag)
537831f9
AM
7206+{
7207+ return __ktag_val(ktag);
7208+}
7209+
7210 static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
7211 {
7212 uid_t uid = from_kuid(to, kuid);
f19bd705
AM
7213diff -NurpP --minimal linux-4.4.111/include/linux/vroot.h linux-4.4.111-vs2.3.9.1/include/linux/vroot.h
7214--- linux-4.4.111/include/linux/vroot.h 1970-01-01 00:00:00.000000000 +0000
7215+++ linux-4.4.111-vs2.3.9.1/include/linux/vroot.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7216@@ -0,0 +1,51 @@
7217+
7218+/*
7219+ * include/linux/vroot.h
7220+ *
927ca606
AM
7221+ * written by Herbert P?tzl, 9/11/2002
7222+ * ported to 2.6 by Herbert P?tzl, 30/12/2004
2380c486 7223+ *
927ca606 7224+ * Copyright (C) 2002-2007 by Herbert P?tzl.
2380c486
JR
7225+ * Redistribution of this file is permitted under the
7226+ * GNU General Public License.
7227+ */
7228+
7229+#ifndef _LINUX_VROOT_H
7230+#define _LINUX_VROOT_H
7231+
7232+
7233+#ifdef __KERNEL__
7234+
7235+/* Possible states of device */
7236+enum {
7237+ Vr_unbound,
7238+ Vr_bound,
7239+};
7240+
7241+struct vroot_device {
7242+ int vr_number;
7243+ int vr_refcnt;
7244+
7245+ struct semaphore vr_ctl_mutex;
7246+ struct block_device *vr_device;
7247+ int vr_state;
7248+};
7249+
7250+
7251+typedef struct block_device *(vroot_grb_func)(struct block_device *);
7252+
7253+extern int register_vroot_grb(vroot_grb_func *);
7254+extern int unregister_vroot_grb(vroot_grb_func *);
7255+
7256+#endif /* __KERNEL__ */
7257+
7258+#define MAX_VROOT_DEFAULT 8
7259+
7260+/*
7261+ * IOCTL commands --- we will commandeer 0x56 ('V')
7262+ */
7263+
7264+#define VROOT_SET_DEV 0x5600
7265+#define VROOT_CLR_DEV 0x5601
7266+
7267+#endif /* _LINUX_VROOT_H */
f19bd705
AM
7268diff -NurpP --minimal linux-4.4.111/include/linux/vs_base.h linux-4.4.111-vs2.3.9.1/include/linux/vs_base.h
7269--- linux-4.4.111/include/linux/vs_base.h 1970-01-01 00:00:00.000000000 +0000
7270+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_base.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7271@@ -0,0 +1,10 @@
7272+#ifndef _VS_BASE_H
7273+#define _VS_BASE_H
7274+
7275+#include "vserver/base.h"
7276+#include "vserver/check.h"
7277+#include "vserver/debug.h"
7278+
7279+#else
7280+#warning duplicate inclusion
7281+#endif
f19bd705
AM
7282diff -NurpP --minimal linux-4.4.111/include/linux/vs_context.h linux-4.4.111-vs2.3.9.1/include/linux/vs_context.h
7283--- linux-4.4.111/include/linux/vs_context.h 1970-01-01 00:00:00.000000000 +0000
7284+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_context.h 2018-01-09 16:36:32.000000000 +0000
4a036bed 7285@@ -0,0 +1,242 @@
2380c486
JR
7286+#ifndef _VS_CONTEXT_H
7287+#define _VS_CONTEXT_H
7288+
7289+#include "vserver/base.h"
7290+#include "vserver/check.h"
7291+#include "vserver/context.h"
7292+#include "vserver/history.h"
7293+#include "vserver/debug.h"
7294+
7295+#include <linux/sched.h>
7296+
7297+
7298+#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__)
7299+
7300+static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
7301+ const char *_file, int _line, void *_here)
7302+{
7303+ if (!vxi)
7304+ return NULL;
7305+
7306+ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
7307+ vxi, vxi ? vxi->vx_id : 0,
7308+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7309+ _file, _line);
7310+ __vxh_get_vx_info(vxi, _here);
7311+
7312+ atomic_inc(&vxi->vx_usecnt);
7313+ return vxi;
7314+}
7315+
7316+
7317+extern void free_vx_info(struct vx_info *);
7318+
7319+#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__)
7320+
7321+static inline void __put_vx_info(struct vx_info *vxi,
7322+ const char *_file, int _line, void *_here)
7323+{
7324+ if (!vxi)
7325+ return;
7326+
7327+ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
7328+ vxi, vxi ? vxi->vx_id : 0,
7329+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7330+ _file, _line);
7331+ __vxh_put_vx_info(vxi, _here);
7332+
7333+ if (atomic_dec_and_test(&vxi->vx_usecnt))
7334+ free_vx_info(vxi);
7335+}
7336+
7337+
7338+#define init_vx_info(p, i) \
7339+ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7340+
7341+static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7342+ const char *_file, int _line, void *_here)
7343+{
7344+ if (vxi) {
7345+ vxlprintk(VXD_CBIT(xid, 3),
7346+ "init_vx_info(%p[#%d.%d])",
7347+ vxi, vxi ? vxi->vx_id : 0,
7348+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7349+ _file, _line);
7350+ __vxh_init_vx_info(vxi, vxp, _here);
7351+
7352+ atomic_inc(&vxi->vx_usecnt);
7353+ }
7354+ *vxp = vxi;
7355+}
7356+
7357+
7358+#define set_vx_info(p, i) \
7359+ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__)
7360+
7361+static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
7362+ const char *_file, int _line, void *_here)
7363+{
7364+ struct vx_info *vxo;
7365+
7366+ if (!vxi)
7367+ return;
7368+
7369+ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
7370+ vxi, vxi ? vxi->vx_id : 0,
7371+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7372+ _file, _line);
7373+ __vxh_set_vx_info(vxi, vxp, _here);
7374+
7375+ atomic_inc(&vxi->vx_usecnt);
7376+ vxo = xchg(vxp, vxi);
7377+ BUG_ON(vxo);
7378+}
7379+
7380+
7381+#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__)
7382+
7383+static inline void __clr_vx_info(struct vx_info **vxp,
7384+ const char *_file, int _line, void *_here)
7385+{
7386+ struct vx_info *vxo;
7387+
7388+ vxo = xchg(vxp, NULL);
7389+ if (!vxo)
7390+ return;
7391+
7392+ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
7393+ vxo, vxo ? vxo->vx_id : 0,
7394+ vxo ? atomic_read(&vxo->vx_usecnt) : 0,
7395+ _file, _line);
7396+ __vxh_clr_vx_info(vxo, vxp, _here);
7397+
7398+ if (atomic_dec_and_test(&vxo->vx_usecnt))
7399+ free_vx_info(vxo);
7400+}
7401+
7402+
7403+#define claim_vx_info(v, p) \
7404+ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7405+
7406+static inline void __claim_vx_info(struct vx_info *vxi,
7407+ struct task_struct *task,
7408+ const char *_file, int _line, void *_here)
7409+{
7410+ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
7411+ vxi, vxi ? vxi->vx_id : 0,
7412+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7413+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7414+ task, _file, _line);
7415+ __vxh_claim_vx_info(vxi, task, _here);
7416+
7417+ atomic_inc(&vxi->vx_tasks);
7418+}
7419+
7420+
7421+extern void unhash_vx_info(struct vx_info *);
7422+
7423+#define release_vx_info(v, p) \
7424+ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__)
7425+
7426+static inline void __release_vx_info(struct vx_info *vxi,
7427+ struct task_struct *task,
7428+ const char *_file, int _line, void *_here)
7429+{
7430+ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
7431+ vxi, vxi ? vxi->vx_id : 0,
7432+ vxi ? atomic_read(&vxi->vx_usecnt) : 0,
7433+ vxi ? atomic_read(&vxi->vx_tasks) : 0,
7434+ task, _file, _line);
7435+ __vxh_release_vx_info(vxi, task, _here);
7436+
7437+ might_sleep();
7438+
7439+ if (atomic_dec_and_test(&vxi->vx_tasks))
7440+ unhash_vx_info(vxi);
7441+}
7442+
7443+
7444+#define task_get_vx_info(p) \
7445+ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__)
7446+
7447+static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
7448+ const char *_file, int _line, void *_here)
7449+{
7450+ struct vx_info *vxi;
7451+
7452+ task_lock(p);
7453+ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
7454+ p, _file, _line);
7455+ vxi = __get_vx_info(p->vx_info, _file, _line, _here);
7456+ task_unlock(p);
7457+ return vxi;
7458+}
7459+
7460+
7461+static inline void __wakeup_vx_info(struct vx_info *vxi)
7462+{
7463+ if (waitqueue_active(&vxi->vx_wait))
7464+ wake_up_interruptible(&vxi->vx_wait);
7465+}
7466+
7467+
7468+#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__)
7469+
7470+static inline void __enter_vx_info(struct vx_info *vxi,
7471+ struct vx_info_save *vxis, const char *_file, int _line)
7472+{
7473+ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
7474+ vxi, vxi ? vxi->vx_id : 0, vxis, current,
7475+ current->xid, current->vx_info, _file, _line);
7476+ vxis->vxi = xchg(&current->vx_info, vxi);
7477+ vxis->xid = current->xid;
7478+ current->xid = vxi ? vxi->vx_id : 0;
7479+}
7480+
7481+#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__)
7482+
7483+static inline void __leave_vx_info(struct vx_info_save *vxis,
7484+ const char *_file, int _line)
7485+{
7486+ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
7487+ vxis, vxis->xid, vxis->vxi, current,
7488+ current->xid, current->vx_info, _file, _line);
7489+ (void)xchg(&current->vx_info, vxis->vxi);
7490+ current->xid = vxis->xid;
7491+}
7492+
7493+
7494+static inline void __enter_vx_admin(struct vx_info_save *vxis)
7495+{
7496+ vxis->vxi = xchg(&current->vx_info, NULL);
61333608 7497+ vxis->xid = xchg(&current->xid, (vxid_t)0);
2380c486
JR
7498+}
7499+
7500+static inline void __leave_vx_admin(struct vx_info_save *vxis)
7501+{
7502+ (void)xchg(&current->xid, vxis->xid);
7503+ (void)xchg(&current->vx_info, vxis->vxi);
7504+}
7505+
4a036bed
AM
7506+#define task_is_init(p) \
7507+ __task_is_init(p, __FILE__, __LINE__, __HERE__)
7508+
7509+static inline int __task_is_init(struct task_struct *p,
7510+ const char *_file, int _line, void *_here)
7511+{
7512+ int is_init = is_global_init(p);
7513+
7514+ task_lock(p);
7515+ if (p->vx_info)
7516+ is_init = p->vx_info->vx_initpid == p->pid;
7517+ task_unlock(p);
7518+ return is_init;
7519+}
7520+
2380c486
JR
7521+extern void exit_vx_info(struct task_struct *, int);
7522+extern void exit_vx_info_early(struct task_struct *, int);
7523+
7524+
7525+#else
7526+#warning duplicate inclusion
7527+#endif
f19bd705
AM
7528diff -NurpP --minimal linux-4.4.111/include/linux/vs_cowbl.h linux-4.4.111-vs2.3.9.1/include/linux/vs_cowbl.h
7529--- linux-4.4.111/include/linux/vs_cowbl.h 1970-01-01 00:00:00.000000000 +0000
7530+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_cowbl.h 2018-01-09 16:36:32.000000000 +0000
78865d5b 7531@@ -0,0 +1,48 @@
2380c486
JR
7532+#ifndef _VS_COWBL_H
7533+#define _VS_COWBL_H
7534+
7535+#include <linux/fs.h>
7536+#include <linux/dcache.h>
7537+#include <linux/namei.h>
78865d5b 7538+#include <linux/slab.h>
2380c486
JR
7539+
7540+extern struct dentry *cow_break_link(const char *pathname);
7541+
7542+static inline int cow_check_and_break(struct path *path)
7543+{
7544+ struct inode *inode = path->dentry->d_inode;
7545+ int error = 0;
7546+
7547+ /* do we need this check? */
7548+ if (IS_RDONLY(inode))
7549+ return -EROFS;
7550+
7551+ if (IS_COW(inode)) {
7552+ if (IS_COW_LINK(inode)) {
7553+ struct dentry *new_dentry, *old_dentry = path->dentry;
7554+ char *pp, *buf;
7555+
7556+ buf = kmalloc(PATH_MAX, GFP_KERNEL);
7557+ if (!buf) {
7558+ return -ENOMEM;
7559+ }
7560+ pp = d_path(path, buf, PATH_MAX);
7561+ new_dentry = cow_break_link(pp);
7562+ kfree(buf);
7563+ if (!IS_ERR(new_dentry)) {
7564+ path->dentry = new_dentry;
7565+ dput(old_dentry);
7566+ } else
7567+ error = PTR_ERR(new_dentry);
7568+ } else {
7569+ inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE);
7570+ inode->i_ctime = CURRENT_TIME;
7571+ mark_inode_dirty(inode);
7572+ }
7573+ }
7574+ return error;
7575+}
7576+
7577+#else
7578+#warning duplicate inclusion
7579+#endif
f19bd705
AM
7580diff -NurpP --minimal linux-4.4.111/include/linux/vs_cvirt.h linux-4.4.111-vs2.3.9.1/include/linux/vs_cvirt.h
7581--- linux-4.4.111/include/linux/vs_cvirt.h 1970-01-01 00:00:00.000000000 +0000
7582+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_cvirt.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7583@@ -0,0 +1,50 @@
7584+#ifndef _VS_CVIRT_H
7585+#define _VS_CVIRT_H
7586+
7587+#include "vserver/cvirt.h"
7588+#include "vserver/context.h"
7589+#include "vserver/base.h"
7590+#include "vserver/check.h"
7591+#include "vserver/debug.h"
7592+
7593+
7594+static inline void vx_activate_task(struct task_struct *p)
7595+{
7596+ struct vx_info *vxi;
7597+
7598+ if ((vxi = p->vx_info)) {
7599+ vx_update_load(vxi);
7600+ atomic_inc(&vxi->cvirt.nr_running);
7601+ }
7602+}
7603+
7604+static inline void vx_deactivate_task(struct task_struct *p)
7605+{
7606+ struct vx_info *vxi;
7607+
7608+ if ((vxi = p->vx_info)) {
7609+ vx_update_load(vxi);
7610+ atomic_dec(&vxi->cvirt.nr_running);
7611+ }
7612+}
7613+
7614+static inline void vx_uninterruptible_inc(struct task_struct *p)
7615+{
7616+ struct vx_info *vxi;
7617+
7618+ if ((vxi = p->vx_info))
7619+ atomic_inc(&vxi->cvirt.nr_uninterruptible);
7620+}
7621+
7622+static inline void vx_uninterruptible_dec(struct task_struct *p)
7623+{
7624+ struct vx_info *vxi;
7625+
7626+ if ((vxi = p->vx_info))
7627+ atomic_dec(&vxi->cvirt.nr_uninterruptible);
7628+}
7629+
7630+
7631+#else
7632+#warning duplicate inclusion
7633+#endif
f19bd705
AM
7634diff -NurpP --minimal linux-4.4.111/include/linux/vs_device.h linux-4.4.111-vs2.3.9.1/include/linux/vs_device.h
7635--- linux-4.4.111/include/linux/vs_device.h 1970-01-01 00:00:00.000000000 +0000
7636+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_device.h 2018-01-09 16:36:32.000000000 +0000
2380c486
JR
7637@@ -0,0 +1,45 @@
7638+#ifndef _VS_DEVICE_H
7639+#define _VS_DEVICE_H
7640+
7641+#include "vserver/base.h"
7642+#include "vserver/device.h"
7643+#include "vserver/debug.h"
7644+
7645+
7646+#ifdef CONFIG_VSERVER_DEVICE
7647+
7648+int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t);
7649+
7650+#define vs_device_perm(v, d, m, p) \
7651+ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p))
7652+
7653+#else
7654+
7655+static inline
7656+int vs_map_device(struct vx_info *vxi,
7657+ dev_t device, dev_t *target, umode_t mode)
7658+{
7659+ if (target)
7660+ *target = device;
7661+ return ~0;
7662+}
7663+
7664+#define vs_device_perm(v, d, m, p) ((p) == (p))
7665+
7666+#endif
7667+
7668+
7669+#define vs_map_chrdev(d, t, p) \
7670+ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p))
7671+#define vs_map_blkdev(d, t, p) \
7672+ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p))
7673+
7674+#define vs_chrdev_perm(d, p) \
7675+ vs_device_perm(current_vx_info(), d, S_IFCHR, p)
7676+#define vs_blkdev_perm(d, p) \
7677+ vs_device_perm(current_vx_info(), d, S_IFBLK, p)
7678+
7679+
7680+#else
7681+#warning duplicate inclusion
7682+#endif
f19bd705
AM
7683diff -NurpP --minimal linux-4.4.111/include/linux/vs_dlimit.h linux-4.4.111-vs2.3.9.1/include/linux/vs_dlimit.h
7684--- linux-4.4.111/include/linux/vs_dlimit.h 1970-01-01 00:00:00.000000000 +0000
7685+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_dlimit.h 2018-01-09 16:36:32.000000000 +0000
2c8c5bc5 7686@@ -0,0 +1,215 @@
2380c486
JR
7687+#ifndef _VS_DLIMIT_H
7688+#define _VS_DLIMIT_H
7689+
7690+#include <linux/fs.h>
7691+
7692+#include "vserver/dlimit.h"
7693+#include "vserver/base.h"
7694+#include "vserver/debug.h"
7695+
7696+
7697+#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__)
7698+
7699+static inline struct dl_info *__get_dl_info(struct dl_info *dli,
7700+ const char *_file, int _line)
7701+{
7702+ if (!dli)
7703+ return NULL;
7704+ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
7705+ dli, dli ? dli->dl_tag : 0,
7706+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7707+ _file, _line);
7708+ atomic_inc(&dli->dl_usecnt);
7709+ return dli;
7710+}
7711+
7712+
7713+#define free_dl_info(i) \
7714+ call_rcu(&(i)->dl_rcu, rcu_free_dl_info)
7715+
7716+#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__)
7717+
7718+static inline void __put_dl_info(struct dl_info *dli,
7719+ const char *_file, int _line)
7720+{
7721+ if (!dli)
7722+ return;
7723+ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
7724+ dli, dli ? dli->dl_tag : 0,
7725+ dli ? atomic_read(&dli->dl_usecnt) : 0,
7726+ _file, _line);
7727+ if (atomic_dec_and_test(&dli->dl_usecnt))
7728+ free_dl_info(dli);
7729+}
7730+
7731+
7732+#define __dlimit_char(d) ((d) ? '*' : ' ')
7733+
7734+static inline int __dl_alloc_space(struct super_block *sb,
61333608 7735+ vtag_t tag, dlsize_t nr, const char *file, int line)
2380c486
JR
7736+{
7737+ struct dl_info *dli = NULL;
7738+ int ret = 0;
7739+
7740+ if (nr == 0)
7741+ goto out;
7742+ dli = locate_dl_info(sb, tag);
7743+ if (!dli)
7744+ goto out;
7745+
7746+ spin_lock(&dli->dl_lock);
7747+ ret = (dli->dl_space_used + nr > dli->dl_space_total);
7748+ if (!ret)
7749+ dli->dl_space_used += nr;
7750+ spin_unlock(&dli->dl_lock);
7751+ put_dl_info(dli);
7752+out:
7753+ vxlprintk(VXD_CBIT(dlim, 1),
7754+ "ALLOC (%p,#%d)%c %lld bytes (%d)",
7755+ sb, tag, __dlimit_char(dli), (long long)nr,
7756+ ret, file, line);
76514441 7757+ return ret ? -ENOSPC : 0;
2380c486
JR
7758+}
7759+
7760+static inline void __dl_free_space(struct super_block *sb,
61333608 7761+ vtag_t tag, dlsize_t nr, const char *_file, int _line)
2380c486
JR
7762+{
7763+ struct dl_info *dli = NULL;
7764+
7765+ if (nr == 0)
7766+ goto out;
7767+ dli = locate_dl_info(sb, tag);
7768+ if (!dli)
7769+ goto out;
7770+
7771+ spin_lock(&dli->dl_lock);
7772+ if (dli->dl_space_used > nr)
7773+ dli->dl_space_used -= nr;
7774+ else
7775+ dli->dl_space_used = 0;
7776+ spin_unlock(&dli->dl_lock);
7777+ put_dl_info(dli);
7778+out:
7779+ vxlprintk(VXD_CBIT(dlim, 1),
7780+ "FREE (%p,#%d)%c %lld bytes",
7781+ sb, tag, __dlimit_char(dli), (long long)nr,
7782+ _file, _line);
7783+}
7784+
7785+static inline int __dl_alloc_inode(struct super_block *sb,
61333608 7786+ vtag_t tag, const char *_file, int _line)
2380c486
JR
7787+{
7788+ struct dl_info *dli;
7789+ int ret = 0;
d337f35e 7790+
2380c486
JR
7791+ dli = locate_dl_info(sb, tag);
7792+ if (!dli)
7793+ goto out;
d337f35e 7794+
2380c486 7795+ spin_lock(&dli->dl_lock);
2c8c5bc5
AM
7796+ dli->dl_inodes_used++;
7797+ ret = (dli->dl_inodes_used > dli->dl_inodes_total);
2380c486
JR
7798+ spin_unlock(&dli->dl_lock);
7799+ put_dl_info(dli);
7800+out:
7801+ vxlprintk(VXD_CBIT(dlim, 0),
7802+ "ALLOC (%p,#%d)%c inode (%d)",
7803+ sb, tag, __dlimit_char(dli), ret, _file, _line);
76514441 7804+ return ret ? -ENOSPC : 0;
2380c486 7805+}
d337f35e 7806+
2380c486 7807+static inline void __dl_free_inode(struct super_block *sb,
61333608 7808+ vtag_t tag, const char *_file, int _line)
d337f35e 7809+{
2380c486
JR
7810+ struct dl_info *dli;
7811+
7812+ dli = locate_dl_info(sb, tag);
7813+ if (!dli)
7814+ goto out;
7815+
7816+ spin_lock(&dli->dl_lock);
7817+ if (dli->dl_inodes_used > 1)
7818+ dli->dl_inodes_used--;
7819+ else
7820+ dli->dl_inodes_used = 0;
7821+ spin_unlock(&dli->dl_lock);
7822+ put_dl_info(dli);
7823+out:
7824+ vxlprintk(VXD_CBIT(dlim, 0),
7825+ "FREE (%p,#%d)%c inode",
7826+ sb, tag, __dlimit_char(dli), _file, _line);
d337f35e
JR
7827+}
7828+
61333608 7829+static inline void __dl_adjust_block(struct super_block *sb, vtag_t tag,
2380c486
JR
7830+ unsigned long long *free_blocks, unsigned long long *root_blocks,
7831+ const char *_file, int _line)
d337f35e 7832+{
2380c486
JR
7833+ struct dl_info *dli;
7834+ uint64_t broot, bfree;
7835+
7836+ dli = locate_dl_info(sb, tag);
7837+ if (!dli)
7838+ return;
7839+
7840+ spin_lock(&dli->dl_lock);
7841+ broot = (dli->dl_space_total -
7842+ (dli->dl_space_total >> 10) * dli->dl_nrlmult)
7843+ >> sb->s_blocksize_bits;
7844+ bfree = (dli->dl_space_total - dli->dl_space_used)
7845+ >> sb->s_blocksize_bits;
7846+ spin_unlock(&dli->dl_lock);
7847+
7848+ vxlprintk(VXD_CBIT(dlim, 2),
7849+ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
7850+ (long long)bfree, (long long)broot,
7851+ *free_blocks, *root_blocks, dli->dl_nrlmult,
7852+ _file, _line);
7853+ if (free_blocks) {
7854+ if (*free_blocks > bfree)
7855+ *free_blocks = bfree;
7856+ }
7857+ if (root_blocks) {
7858+ if (*root_blocks > broot)
7859+ *root_blocks = broot;
7860+ }
7861+ put_dl_info(dli);
d337f35e
JR
7862+}
7863+
e22b5178 7864+#define dl_prealloc_space(in, bytes) \
537831f9 7865+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7866+ __FILE__, __LINE__ )
d337f35e 7867+
e22b5178 7868+#define dl_alloc_space(in, bytes) \
537831f9 7869+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7870+ __FILE__, __LINE__ )
d337f35e 7871+
e22b5178 7872+#define dl_reserve_space(in, bytes) \
537831f9 7873+ __dl_alloc_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7874+ __FILE__, __LINE__ )
d337f35e 7875+
e22b5178
AM
7876+#define dl_claim_space(in, bytes) (0)
7877+
7878+#define dl_release_space(in, bytes) \
537831f9 7879+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
2380c486 7880+ __FILE__, __LINE__ )
d337f35e 7881+
e22b5178 7882+#define dl_free_space(in, bytes) \
537831f9 7883+ __dl_free_space((in)->i_sb, i_tag_read(in), (dlsize_t)(bytes), \
e22b5178
AM
7884+ __FILE__, __LINE__ )
7885+
7886+
d337f35e 7887+
e22b5178 7888+#define dl_alloc_inode(in) \
537831f9 7889+ __dl_alloc_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7890+
e22b5178 7891+#define dl_free_inode(in) \
537831f9 7892+ __dl_free_inode((in)->i_sb, i_tag_read(in), __FILE__, __LINE__ )
d337f35e 7893+
d337f35e 7894+
e22b5178 7895+#define dl_adjust_block(sb, tag, fb, rb) \
2380c486 7896+ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
d337f35e 7897+
d337f35e 7898+
2380c486
JR
7899+#else
7900+#warning duplicate inclusion
7901+#endif
f19bd705
AM
7902diff -NurpP --minimal linux-4.4.111/include/linux/vs_inet.h linux-4.4.111-vs2.3.9.1/include/linux/vs_inet.h
7903--- linux-4.4.111/include/linux/vs_inet.h 1970-01-01 00:00:00.000000000 +0000
7904+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_inet.h 2018-01-09 16:36:32.000000000 +0000
5cb1760b 7905@@ -0,0 +1,364 @@
d33d7b00
AM
7906+#ifndef _VS_INET_H
7907+#define _VS_INET_H
d337f35e 7908+
d33d7b00
AM
7909+#include "vserver/base.h"
7910+#include "vserver/network.h"
7911+#include "vserver/debug.h"
d337f35e 7912+
d33d7b00 7913+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
d337f35e 7914+
d33d7b00
AM
7915+#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \
7916+ NIPQUAD((a)->mask), (a)->type
7917+#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]"
d337f35e 7918+
d33d7b00
AM
7919+#define NIPQUAD(addr) \
7920+ ((unsigned char *)&addr)[0], \
7921+ ((unsigned char *)&addr)[1], \
7922+ ((unsigned char *)&addr)[2], \
7923+ ((unsigned char *)&addr)[3]
d337f35e 7924+
d33d7b00 7925+#define NIPQUAD_FMT "%u.%u.%u.%u"
d337f35e 7926+
d337f35e 7927+
d33d7b00
AM
7928+static inline
7929+int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask)
7930+{
7931+ __be32 ip = nxa->ip[0].s_addr;
7932+ __be32 mask = nxa->mask.s_addr;
7933+ __be32 bcast = ip | ~mask;
7934+ int ret = 0;
d337f35e 7935+
d33d7b00
AM
7936+ switch (nxa->type & tmask) {
7937+ case NXA_TYPE_MASK:
7938+ ret = (ip == (addr & mask));
7939+ break;
7940+ case NXA_TYPE_ADDR:
7941+ ret = 3;
7942+ if (addr == ip)
7943+ break;
7944+ /* fall through to broadcast */
7945+ case NXA_MOD_BCAST:
7946+ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast));
7947+ break;
7948+ case NXA_TYPE_RANGE:
7949+ ret = ((nxa->ip[0].s_addr <= addr) &&
7950+ (nxa->ip[1].s_addr > addr));
7951+ break;
7952+ case NXA_TYPE_ANY:
7953+ ret = 2;
7954+ break;
7955+ }
d337f35e 7956+
d33d7b00
AM
7957+ vxdprintk(VXD_CBIT(net, 0),
7958+ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d",
7959+ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret);
7960+ return ret;
7961+}
d337f35e 7962+
d33d7b00
AM
7963+static inline
7964+int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask)
7965+{
7966+ struct nx_addr_v4 *nxa;
7a9e40b8 7967+ unsigned long irqflags;
d33d7b00 7968+ int ret = 1;
d337f35e 7969+
d33d7b00
AM
7970+ if (!nxi)
7971+ goto out;
d337f35e 7972+
d33d7b00
AM
7973+ ret = 2;
7974+ /* allow 127.0.0.1 when remapping lback */
7975+ if ((tmask & NXA_LOOPBACK) &&
7976+ (addr == IPI_LOOPBACK) &&
7977+ nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
7978+ goto out;
7979+ ret = 3;
7980+ /* check for lback address */
7981+ if ((tmask & NXA_MOD_LBACK) &&
7982+ (nxi->v4_lback.s_addr == addr))
7983+ goto out;
7984+ ret = 4;
7985+ /* check for broadcast address */
7986+ if ((tmask & NXA_MOD_BCAST) &&
7987+ (nxi->v4_bcast.s_addr == addr))
7988+ goto out;
7989+ ret = 5;
4bf69007 7990+
d33d7b00 7991+ /* check for v4 addresses */
7a9e40b8 7992+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
7993+ for (nxa = &nxi->v4; nxa; nxa = nxa->next)
7994+ if (v4_addr_match(nxa, addr, tmask))
4bf69007 7995+ goto out_unlock;
d33d7b00 7996+ ret = 0;
4bf69007 7997+out_unlock:
7a9e40b8 7998+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
7999+out:
8000+ vxdprintk(VXD_CBIT(net, 0),
8001+ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
8002+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
8003+ return ret;
8004+}
d337f35e 8005+
d33d7b00
AM
8006+static inline
8007+int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask)
8008+{
8009+ /* FIXME: needs full range checks */
8010+ return v4_addr_match(nxa, addr->ip[0].s_addr, mask);
8011+}
d337f35e 8012+
d33d7b00
AM
8013+static inline
8014+int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
8015+{
8016+ struct nx_addr_v4 *ptr;
7a9e40b8 8017+ unsigned long irqflags;
4bf69007 8018+ int ret = 1;
d337f35e 8019+
7a9e40b8 8020+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8021+ for (ptr = &nxi->v4; ptr; ptr = ptr->next)
8022+ if (v4_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8023+ goto out_unlock;
8024+ ret = 0;
8025+out_unlock:
7a9e40b8 8026+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8027+ return ret;
d33d7b00 8028+}
d337f35e 8029+
d33d7b00 8030+#include <net/inet_sock.h>
d337f35e 8031+
d33d7b00
AM
8032+/*
8033+ * Check if a given address matches for a socket
8034+ *
8035+ * nxi: the socket's nx_info if any
8036+ * addr: to be verified address
8037+ */
8038+static inline
8039+int v4_sock_addr_match (
8040+ struct nx_info *nxi,
8041+ struct inet_sock *inet,
8042+ __be32 addr)
8043+{
8044+ __be32 saddr = inet->inet_rcv_saddr;
8045+ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST;
d337f35e 8046+
d33d7b00
AM
8047+ if (addr && (saddr == addr || bcast == addr))
8048+ return 1;
8049+ if (!saddr)
8050+ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND);
8051+ return 0;
8052+}
d337f35e 8053+
d337f35e 8054+
d33d7b00 8055+/* inet related checks and helpers */
d337f35e
JR
8056+
8057+
d33d7b00
AM
8058+struct in_ifaddr;
8059+struct net_device;
8060+struct sock;
d337f35e 8061+
d33d7b00 8062+#ifdef CONFIG_INET
d337f35e 8063+
d33d7b00
AM
8064+#include <linux/netdevice.h>
8065+#include <linux/inetdevice.h>
8066+#include <net/inet_sock.h>
8067+#include <net/inet_timewait_sock.h>
d337f35e 8068+
d337f35e 8069+
d33d7b00
AM
8070+int dev_in_nx_info(struct net_device *, struct nx_info *);
8071+int v4_dev_in_nx_info(struct net_device *, struct nx_info *);
8072+int nx_v4_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e 8073+
d337f35e 8074+
d33d7b00
AM
8075+/*
8076+ * check if address is covered by socket
8077+ *
8078+ * sk: the socket to check against
8079+ * addr: the address in question (must be != 0)
8080+ */
d337f35e 8081+
d33d7b00
AM
8082+static inline
8083+int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa)
8084+{
8085+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8086+ __be32 saddr = sk->sk_rcv_saddr;
d337f35e 8087+
d33d7b00
AM
8088+ vxdprintk(VXD_CBIT(net, 5),
8089+ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx",
8090+ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket,
8091+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8092+
d33d7b00
AM
8093+ if (saddr) { /* direct address match */
8094+ return v4_addr_match(nxa, saddr, -1);
8095+ } else if (nxi) { /* match against nx_info */
8096+ return v4_nx_addr_in_nx_info(nxi, nxa, -1);
8097+ } else { /* unrestricted any socket */
8098+ return 1;
8099+ }
8100+}
d337f35e
JR
8101+
8102+
d337f35e 8103+
d33d7b00
AM
8104+static inline
8105+int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
8106+{
8107+ vxdprintk(VXD_CBIT(net, 1),
8108+ "nx_dev_visible(%p[#%u],%p " VS_Q("%s") ") %d",
8109+ nxi, nxi ? nxi->nx_id : 0, dev, dev->name,
8110+ nxi ? dev_in_nx_info(dev, nxi) : 0);
d337f35e 8111+
d33d7b00
AM
8112+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8113+ return 1;
8114+ if (dev_in_nx_info(dev, nxi))
8115+ return 1;
8116+ return 0;
8117+}
d337f35e
JR
8118+
8119+
d33d7b00
AM
8120+static inline
8121+int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
8122+{
8123+ if (!nxi)
8124+ return 1;
8125+ if (!ifa)
8126+ return 0;
8127+ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW);
8128+}
d337f35e 8129+
d33d7b00
AM
8130+static inline
8131+int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
8132+{
8133+ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d",
8134+ nxi, nxi ? nxi->nx_id : 0, ifa,
8135+ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8136+
d33d7b00
AM
8137+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8138+ return 1;
8139+ if (v4_ifa_in_nx_info(ifa, nxi))
8140+ return 1;
8141+ return 0;
8142+}
d337f35e 8143+
d337f35e 8144+
d33d7b00
AM
8145+struct nx_v4_sock_addr {
8146+ __be32 saddr; /* Address used for validation */
8147+ __be32 baddr; /* Address used for socket bind */
8148+};
d337f35e 8149+
d33d7b00
AM
8150+static inline
8151+int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr,
8152+ struct nx_v4_sock_addr *nsa)
8153+{
8154+ struct sock *sk = &inet->sk;
8155+ struct nx_info *nxi = sk->sk_nx_info;
8156+ __be32 saddr = addr->sin_addr.s_addr;
8157+ __be32 baddr = saddr;
d337f35e 8158+
d33d7b00
AM
8159+ vxdprintk(VXD_CBIT(net, 3),
8160+ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT,
8161+ sk, sk->sk_nx_info, sk->sk_socket,
8162+ (sk->sk_socket ? sk->sk_socket->flags : 0),
8163+ NIPQUAD(saddr));
d337f35e 8164+
d33d7b00
AM
8165+ if (nxi) {
8166+ if (saddr == INADDR_ANY) {
8167+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0))
8168+ baddr = nxi->v4.ip[0].s_addr;
8169+ } else if (saddr == IPI_LOOPBACK) {
8170+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8171+ baddr = nxi->v4_lback.s_addr;
9795bf04
AM
8172+ } else if (!ipv4_is_multicast(saddr) ||
8173+ !nx_info_ncaps(nxi, NXC_MULTICAST)) {
8174+ /* normal address bind */
d33d7b00
AM
8175+ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND))
8176+ return -EADDRNOTAVAIL;
8177+ }
8178+ }
d337f35e 8179+
d33d7b00
AM
8180+ vxdprintk(VXD_CBIT(net, 3),
8181+ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT,
8182+ sk, NIPQUAD(saddr), NIPQUAD(baddr));
d337f35e 8183+
d33d7b00
AM
8184+ nsa->saddr = saddr;
8185+ nsa->baddr = baddr;
8186+ return 0;
8187+}
d337f35e 8188+
d33d7b00
AM
8189+static inline
8190+void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa)
8191+{
8192+ inet->inet_saddr = nsa->baddr;
8193+ inet->inet_rcv_saddr = nsa->baddr;
8194+}
d337f35e 8195+
d337f35e 8196+
d33d7b00
AM
8197+/*
8198+ * helper to simplify inet_lookup_listener
8199+ *
8200+ * nxi: the socket's nx_info if any
8201+ * addr: to be verified address
8202+ * saddr: socket address
8203+ */
8204+static inline int v4_inet_addr_match (
8205+ struct nx_info *nxi,
8206+ __be32 addr,
8207+ __be32 saddr)
8208+{
8209+ if (addr && (saddr == addr))
8210+ return 1;
8211+ if (!saddr)
8212+ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1;
8213+ return 0;
8214+}
d337f35e 8215+
d33d7b00
AM
8216+static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr)
8217+{
8218+ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) &&
8219+ (addr == nxi->v4_lback.s_addr))
8220+ return IPI_LOOPBACK;
8221+ return addr;
8222+}
d337f35e 8223+
d33d7b00
AM
8224+static inline
8225+int nx_info_has_v4(struct nx_info *nxi)
8226+{
8227+ if (!nxi)
8228+ return 1;
8229+ if (NX_IPV4(nxi))
8230+ return 1;
8231+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0))
8232+ return 1;
8233+ return 0;
8234+}
d337f35e 8235+
d33d7b00 8236+#else /* CONFIG_INET */
d337f35e 8237+
d33d7b00
AM
8238+static inline
8239+int nx_dev_visible(struct nx_info *n, struct net_device *d)
8240+{
8241+ return 1;
8242+}
d337f35e 8243+
d33d7b00
AM
8244+static inline
8245+int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
8246+{
8247+ return 1;
8248+}
d337f35e 8249+
d33d7b00
AM
8250+static inline
8251+int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8252+{
8253+ return 1;
8254+}
d337f35e 8255+
d33d7b00
AM
8256+static inline
8257+int nx_info_has_v4(struct nx_info *nxi)
8258+{
8259+ return 0;
8260+}
d337f35e 8261+
d33d7b00 8262+#endif /* CONFIG_INET */
d337f35e 8263+
d33d7b00
AM
8264+#define current_nx_info_has_v4() \
8265+ nx_info_has_v4(current_nx_info())
d337f35e 8266+
d33d7b00
AM
8267+#else
8268+// #warning duplicate inclusion
3bac966d 8269+#endif
f19bd705
AM
8270diff -NurpP --minimal linux-4.4.111/include/linux/vs_inet6.h linux-4.4.111-vs2.3.9.1/include/linux/vs_inet6.h
8271--- linux-4.4.111/include/linux/vs_inet6.h 1970-01-01 00:00:00.000000000 +0000
8272+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_inet6.h 2018-01-09 16:36:32.000000000 +0000
5cb1760b 8273@@ -0,0 +1,257 @@
d33d7b00
AM
8274+#ifndef _VS_INET6_H
8275+#define _VS_INET6_H
4a036bed 8276+
d33d7b00
AM
8277+#include "vserver/base.h"
8278+#include "vserver/network.h"
8279+#include "vserver/debug.h"
d337f35e 8280+
d33d7b00 8281+#include <net/ipv6.h>
d337f35e 8282+
d33d7b00
AM
8283+#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type
8284+#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]"
7e46296a 8285+
7e46296a 8286+
d33d7b00 8287+#ifdef CONFIG_IPV6
7e46296a 8288+
d33d7b00
AM
8289+static inline
8290+int v6_addr_match(struct nx_addr_v6 *nxa,
8291+ const struct in6_addr *addr, uint16_t mask)
8292+{
8293+ int ret = 0;
7e46296a 8294+
d33d7b00
AM
8295+ switch (nxa->type & mask) {
8296+ case NXA_TYPE_MASK:
8297+ ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr);
8298+ break;
8299+ case NXA_TYPE_ADDR:
8300+ ret = ipv6_addr_equal(&nxa->ip, addr);
8301+ break;
8302+ case NXA_TYPE_ANY:
8303+ ret = 1;
8304+ break;
8305+ }
8306+ vxdprintk(VXD_CBIT(net, 0),
8307+ "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d",
8308+ nxa, NXAV6(nxa), addr, mask, ret);
8309+ return ret;
8310+}
7e46296a 8311+
d33d7b00
AM
8312+static inline
8313+int v6_addr_in_nx_info(struct nx_info *nxi,
8314+ const struct in6_addr *addr, uint16_t mask)
8315+{
8316+ struct nx_addr_v6 *nxa;
7a9e40b8 8317+ unsigned long irqflags;
d33d7b00 8318+ int ret = 1;
d337f35e 8319+
d33d7b00
AM
8320+ if (!nxi)
8321+ goto out;
4bf69007 8322+
7a9e40b8 8323+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8324+ for (nxa = &nxi->v6; nxa; nxa = nxa->next)
8325+ if (v6_addr_match(nxa, addr, mask))
4bf69007 8326+ goto out_unlock;
d33d7b00 8327+ ret = 0;
4bf69007 8328+out_unlock:
7a9e40b8 8329+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
d33d7b00
AM
8330+out:
8331+ vxdprintk(VXD_CBIT(net, 0),
8332+ "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
8333+ nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
8334+ return ret;
8335+}
d337f35e 8336+
d33d7b00
AM
8337+static inline
8338+int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask)
8339+{
8340+ /* FIXME: needs full range checks */
8341+ return v6_addr_match(nxa, &addr->ip, mask);
8342+}
d337f35e 8343+
d33d7b00
AM
8344+static inline
8345+int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
8346+{
8347+ struct nx_addr_v6 *ptr;
7a9e40b8 8348+ unsigned long irqflags;
4bf69007 8349+ int ret = 1;
d337f35e 8350+
7a9e40b8 8351+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
d33d7b00
AM
8352+ for (ptr = &nxi->v6; ptr; ptr = ptr->next)
8353+ if (v6_nx_addr_match(ptr, nxa, mask))
4bf69007
AM
8354+ goto out_unlock;
8355+ ret = 0;
8356+out_unlock:
7a9e40b8 8357+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007 8358+ return ret;
d33d7b00 8359+}
d337f35e 8360+
d337f35e 8361+
d33d7b00
AM
8362+/*
8363+ * Check if a given address matches for a socket
8364+ *
8365+ * nxi: the socket's nx_info if any
8366+ * addr: to be verified address
8367+ */
8368+static inline
8369+int v6_sock_addr_match (
8370+ struct nx_info *nxi,
8371+ struct inet_sock *inet,
8372+ struct in6_addr *addr)
8373+{
8374+ struct sock *sk = &inet->sk;
c2e5f7c8 8375+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8376+
d33d7b00
AM
8377+ if (!ipv6_addr_any(addr) &&
8378+ ipv6_addr_equal(saddr, addr))
8379+ return 1;
8380+ if (ipv6_addr_any(saddr))
8381+ return v6_addr_in_nx_info(nxi, addr, -1);
8382+ return 0;
8383+}
d337f35e 8384+
d33d7b00
AM
8385+/*
8386+ * check if address is covered by socket
8387+ *
8388+ * sk: the socket to check against
8389+ * addr: the address in question (must be != 0)
8390+ */
d337f35e 8391+
d33d7b00
AM
8392+static inline
8393+int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa)
8394+{
8395+ struct nx_info *nxi = sk->sk_nx_info;
c2e5f7c8 8396+ const struct in6_addr *saddr = inet6_rcv_saddr(sk);
d337f35e 8397+
d33d7b00
AM
8398+ vxdprintk(VXD_CBIT(net, 5),
8399+ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx",
8400+ sk, NXAV6(nxa), nxi, saddr, sk->sk_socket,
8401+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 8402+
d33d7b00
AM
8403+ if (!ipv6_addr_any(saddr)) { /* direct address match */
8404+ return v6_addr_match(nxa, saddr, -1);
8405+ } else if (nxi) { /* match against nx_info */
8406+ return v6_nx_addr_in_nx_info(nxi, nxa, -1);
8407+ } else { /* unrestricted any socket */
8408+ return 1;
8409+ }
8410+}
d337f35e 8411+
d337f35e 8412+
d33d7b00 8413+/* inet related checks and helpers */
d337f35e 8414+
d337f35e 8415+
d33d7b00
AM
8416+struct in_ifaddr;
8417+struct net_device;
8418+struct sock;
d337f35e
JR
8419+
8420+
d33d7b00
AM
8421+#include <linux/netdevice.h>
8422+#include <linux/inetdevice.h>
8423+#include <net/inet_timewait_sock.h>
d337f35e 8424+
d337f35e 8425+
d33d7b00
AM
8426+int dev_in_nx_info(struct net_device *, struct nx_info *);
8427+int v6_dev_in_nx_info(struct net_device *, struct nx_info *);
8428+int nx_v6_addr_conflict(struct nx_info *, struct nx_info *);
d337f35e
JR
8429+
8430+
3bac966d 8431+
d33d7b00
AM
8432+static inline
8433+int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi)
adc1caaa 8434+{
d33d7b00
AM
8435+ if (!nxi)
8436+ return 1;
8437+ if (!ifa)
8438+ return 0;
8439+ return v6_addr_in_nx_info(nxi, &ifa->addr, -1);
8440+}
d337f35e 8441+
d33d7b00
AM
8442+static inline
8443+int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa)
8444+{
8445+ vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d",
8446+ nxi, nxi ? nxi->nx_id : 0, ifa,
8447+ nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0);
d337f35e 8448+
d33d7b00
AM
8449+ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
8450+ return 1;
8451+ if (v6_ifa_in_nx_info(ifa, nxi))
8452+ return 1;
8453+ return 0;
adc1caaa 8454+}
d337f35e 8455+
d337f35e 8456+
d33d7b00
AM
8457+struct nx_v6_sock_addr {
8458+ struct in6_addr saddr; /* Address used for validation */
8459+ struct in6_addr baddr; /* Address used for socket bind */
8460+};
8461+
8462+static inline
8463+int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr,
8464+ struct nx_v6_sock_addr *nsa)
8465+{
8466+ // struct sock *sk = &inet->sk;
8467+ // struct nx_info *nxi = sk->sk_nx_info;
8468+ struct in6_addr saddr = addr->sin6_addr;
8469+ struct in6_addr baddr = saddr;
3bac966d 8470+
d33d7b00
AM
8471+ nsa->saddr = saddr;
8472+ nsa->baddr = baddr;
8473+ return 0;
8474+}
3bac966d 8475+
d33d7b00
AM
8476+static inline
8477+void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa)
8478+{
8479+ // struct sock *sk = &inet->sk;
8480+ // struct in6_addr *saddr = inet6_rcv_saddr(sk);
3bac966d 8481+
d33d7b00
AM
8482+ // *saddr = nsa->baddr;
8483+ // inet->inet_saddr = nsa->baddr;
8484+}
3bac966d 8485+
d33d7b00
AM
8486+static inline
8487+int nx_info_has_v6(struct nx_info *nxi)
8488+{
8489+ if (!nxi)
8490+ return 1;
8491+ if (NX_IPV6(nxi))
8492+ return 1;
8493+ return 0;
8494+}
3bac966d 8495+
d33d7b00 8496+#else /* CONFIG_IPV6 */
d337f35e 8497+
2380c486 8498+static inline
d33d7b00 8499+int nx_v6_dev_visible(struct nx_info *n, struct net_device *d)
2380c486 8500+{
d33d7b00 8501+ return 1;
d337f35e
JR
8502+}
8503+
3bac966d 8504+
adc1caaa 8505+static inline
d33d7b00 8506+int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s)
adc1caaa 8507+{
d33d7b00 8508+ return 1;
adc1caaa 8509+}
2380c486 8510+
d33d7b00
AM
8511+static inline
8512+int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
8513+{
8514+ return 1;
8515+}
8516+
8517+static inline
8518+int nx_info_has_v6(struct nx_info *nxi)
8519+{
8520+ return 0;
8521+}
2380c486 8522+
d33d7b00 8523+#endif /* CONFIG_IPV6 */
d337f35e 8524+
d33d7b00
AM
8525+#define current_nx_info_has_v6() \
8526+ nx_info_has_v6(current_nx_info())
3bac966d 8527+
d337f35e 8528+#else
d33d7b00 8529+#warning duplicate inclusion
d337f35e 8530+#endif
f19bd705
AM
8531diff -NurpP --minimal linux-4.4.111/include/linux/vs_limit.h linux-4.4.111-vs2.3.9.1/include/linux/vs_limit.h
8532--- linux-4.4.111/include/linux/vs_limit.h 1970-01-01 00:00:00.000000000 +0000
8533+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_limit.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8534@@ -0,0 +1,140 @@
8535+#ifndef _VS_LIMIT_H
8536+#define _VS_LIMIT_H
d337f35e 8537+
d33d7b00
AM
8538+#include "vserver/limit.h"
8539+#include "vserver/base.h"
8540+#include "vserver/context.h"
8541+#include "vserver/debug.h"
8542+#include "vserver/context.h"
8543+#include "vserver/limit_int.h"
d337f35e
JR
8544+
8545+
d33d7b00
AM
8546+#define vx_acc_cres(v, d, p, r) \
8547+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
d337f35e 8548+
d33d7b00
AM
8549+#define vx_acc_cres_cond(x, d, p, r) \
8550+ __vx_acc_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8551+ r, d, p, __FILE__, __LINE__)
d337f35e
JR
8552+
8553+
d33d7b00
AM
8554+#define vx_add_cres(v, a, p, r) \
8555+ __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
8556+#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r)
d337f35e 8557+
d33d7b00
AM
8558+#define vx_add_cres_cond(x, a, p, r) \
8559+ __vx_add_cres(((x) == vx_current_xid()) ? current_vx_info() : 0, \
8560+ r, a, p, __FILE__, __LINE__)
8561+#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r)
d337f35e 8562+
d337f35e 8563+
d33d7b00 8564+/* process and file limits */
d337f35e 8565+
d33d7b00
AM
8566+#define vx_nproc_inc(p) \
8567+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
d337f35e 8568+
d33d7b00
AM
8569+#define vx_nproc_dec(p) \
8570+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
d337f35e 8571+
d33d7b00
AM
8572+#define vx_files_inc(f) \
8573+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
d337f35e 8574+
d33d7b00
AM
8575+#define vx_files_dec(f) \
8576+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
d337f35e 8577+
d33d7b00
AM
8578+#define vx_locks_inc(l) \
8579+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
d337f35e 8580+
d33d7b00
AM
8581+#define vx_locks_dec(l) \
8582+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
d337f35e 8583+
d33d7b00
AM
8584+#define vx_openfd_inc(f) \
8585+ vx_acc_cres(current_vx_info(), 1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8586+
d33d7b00
AM
8587+#define vx_openfd_dec(f) \
8588+ vx_acc_cres(current_vx_info(),-1, (void *)(long)(f), VLIMIT_OPENFD)
d337f35e 8589+
d337f35e 8590+
d33d7b00
AM
8591+#define vx_cres_avail(v, n, r) \
8592+ __vx_cres_avail(v, r, n, __FILE__, __LINE__)
d337f35e 8593+
d337f35e 8594+
d33d7b00
AM
8595+#define vx_nproc_avail(n) \
8596+ vx_cres_avail(current_vx_info(), n, RLIMIT_NPROC)
d337f35e 8597+
d33d7b00
AM
8598+#define vx_files_avail(n) \
8599+ vx_cres_avail(current_vx_info(), n, RLIMIT_NOFILE)
d337f35e 8600+
d33d7b00
AM
8601+#define vx_locks_avail(n) \
8602+ vx_cres_avail(current_vx_info(), n, RLIMIT_LOCKS)
d337f35e 8603+
d33d7b00
AM
8604+#define vx_openfd_avail(n) \
8605+ vx_cres_avail(current_vx_info(), n, VLIMIT_OPENFD)
d337f35e 8606+
d337f35e 8607+
d33d7b00 8608+/* dentry limits */
d337f35e 8609+
d33d7b00 8610+#define vx_dentry_inc(d) do { \
c2e5f7c8 8611+ if (d_count(d) == 1) \
d33d7b00
AM
8612+ vx_acc_cres(current_vx_info(), 1, d, VLIMIT_DENTRY); \
8613+ } while (0)
d337f35e 8614+
d33d7b00 8615+#define vx_dentry_dec(d) do { \
c2e5f7c8 8616+ if (d_count(d) == 0) \
d33d7b00
AM
8617+ vx_acc_cres(current_vx_info(),-1, d, VLIMIT_DENTRY); \
8618+ } while (0)
d337f35e 8619+
d33d7b00
AM
8620+#define vx_dentry_avail(n) \
8621+ vx_cres_avail(current_vx_info(), n, VLIMIT_DENTRY)
d337f35e 8622+
d337f35e 8623+
d33d7b00 8624+/* socket limits */
d337f35e 8625+
d33d7b00
AM
8626+#define vx_sock_inc(s) \
8627+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
d337f35e 8628+
d33d7b00
AM
8629+#define vx_sock_dec(s) \
8630+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
d337f35e 8631+
d33d7b00
AM
8632+#define vx_sock_avail(n) \
8633+ vx_cres_avail(current_vx_info(), n, VLIMIT_NSOCK)
d337f35e 8634+
d337f35e 8635+
d33d7b00 8636+/* ipc resource limits */
d337f35e 8637+
d33d7b00
AM
8638+#define vx_ipcmsg_add(v, u, a) \
8639+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8640+
d33d7b00
AM
8641+#define vx_ipcmsg_sub(v, u, a) \
8642+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
d337f35e 8643+
d33d7b00
AM
8644+#define vx_ipcmsg_avail(v, a) \
8645+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
d337f35e 8646+
d337f35e 8647+
d33d7b00
AM
8648+#define vx_ipcshm_add(v, k, a) \
8649+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8650+
d33d7b00
AM
8651+#define vx_ipcshm_sub(v, k, a) \
8652+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
d337f35e 8653+
d33d7b00
AM
8654+#define vx_ipcshm_avail(v, a) \
8655+ vx_cres_avail(v, a, VLIMIT_SHMEM)
d337f35e
JR
8656+
8657+
d33d7b00
AM
8658+#define vx_semary_inc(a) \
8659+ vx_acc_cres(current_vx_info(), 1, a, VLIMIT_SEMARY)
d337f35e 8660+
d33d7b00
AM
8661+#define vx_semary_dec(a) \
8662+ vx_acc_cres(current_vx_info(), -1, a, VLIMIT_SEMARY)
d337f35e 8663+
d337f35e 8664+
d33d7b00
AM
8665+#define vx_nsems_add(a,n) \
8666+ vx_add_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e 8667+
d33d7b00
AM
8668+#define vx_nsems_sub(a,n) \
8669+ vx_sub_cres(current_vx_info(), n, a, VLIMIT_NSEMS)
d337f35e
JR
8670+
8671+
d33d7b00
AM
8672+#else
8673+#warning duplicate inclusion
8674+#endif
f19bd705
AM
8675diff -NurpP --minimal linux-4.4.111/include/linux/vs_network.h linux-4.4.111-vs2.3.9.1/include/linux/vs_network.h
8676--- linux-4.4.111/include/linux/vs_network.h 1970-01-01 00:00:00.000000000 +0000
8677+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_network.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8678@@ -0,0 +1,169 @@
8679+#ifndef _NX_VS_NETWORK_H
8680+#define _NX_VS_NETWORK_H
7e46296a 8681+
d33d7b00
AM
8682+#include "vserver/context.h"
8683+#include "vserver/network.h"
8684+#include "vserver/base.h"
8685+#include "vserver/check.h"
8686+#include "vserver/debug.h"
2380c486 8687+
d33d7b00 8688+#include <linux/sched.h>
2380c486 8689+
2380c486 8690+
d33d7b00 8691+#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__)
2380c486 8692+
d33d7b00
AM
8693+static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
8694+ const char *_file, int _line)
8695+{
8696+ if (!nxi)
8697+ return NULL;
d337f35e 8698+
d33d7b00
AM
8699+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
8700+ nxi, nxi ? nxi->nx_id : 0,
8701+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8702+ _file, _line);
d337f35e 8703+
d33d7b00
AM
8704+ atomic_inc(&nxi->nx_usecnt);
8705+ return nxi;
8706+}
d337f35e
JR
8707+
8708+
d33d7b00 8709+extern void free_nx_info(struct nx_info *);
d337f35e 8710+
d33d7b00 8711+#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__)
d337f35e 8712+
d33d7b00
AM
8713+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
8714+{
8715+ if (!nxi)
8716+ return;
d337f35e 8717+
d33d7b00
AM
8718+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
8719+ nxi, nxi ? nxi->nx_id : 0,
8720+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8721+ _file, _line);
d337f35e 8722+
d33d7b00
AM
8723+ if (atomic_dec_and_test(&nxi->nx_usecnt))
8724+ free_nx_info(nxi);
8725+}
d337f35e 8726+
d337f35e 8727+
d33d7b00 8728+#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8729+
d33d7b00
AM
8730+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8731+ const char *_file, int _line)
8732+{
8733+ if (nxi) {
8734+ vxlprintk(VXD_CBIT(nid, 3),
8735+ "init_nx_info(%p[#%d.%d])",
8736+ nxi, nxi ? nxi->nx_id : 0,
8737+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8738+ _file, _line);
d337f35e 8739+
d33d7b00
AM
8740+ atomic_inc(&nxi->nx_usecnt);
8741+ }
8742+ *nxp = nxi;
8743+}
d337f35e 8744+
d337f35e 8745+
d33d7b00 8746+#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__)
d337f35e 8747+
d33d7b00
AM
8748+static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
8749+ const char *_file, int _line)
8750+{
8751+ struct nx_info *nxo;
d337f35e 8752+
d33d7b00
AM
8753+ if (!nxi)
8754+ return;
d337f35e 8755+
d33d7b00
AM
8756+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
8757+ nxi, nxi ? nxi->nx_id : 0,
8758+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8759+ _file, _line);
d337f35e 8760+
d33d7b00
AM
8761+ atomic_inc(&nxi->nx_usecnt);
8762+ nxo = xchg(nxp, nxi);
8763+ BUG_ON(nxo);
8764+}
d337f35e 8765+
d33d7b00 8766+#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__)
d337f35e 8767+
d33d7b00
AM
8768+static inline void __clr_nx_info(struct nx_info **nxp,
8769+ const char *_file, int _line)
8770+{
8771+ struct nx_info *nxo;
d337f35e 8772+
d33d7b00
AM
8773+ nxo = xchg(nxp, NULL);
8774+ if (!nxo)
8775+ return;
d337f35e 8776+
d33d7b00
AM
8777+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
8778+ nxo, nxo ? nxo->nx_id : 0,
8779+ nxo ? atomic_read(&nxo->nx_usecnt) : 0,
8780+ _file, _line);
d337f35e 8781+
d33d7b00
AM
8782+ if (atomic_dec_and_test(&nxo->nx_usecnt))
8783+ free_nx_info(nxo);
8784+}
d337f35e
JR
8785+
8786+
d33d7b00 8787+#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8788+
d33d7b00
AM
8789+static inline void __claim_nx_info(struct nx_info *nxi,
8790+ struct task_struct *task, const char *_file, int _line)
8791+{
8792+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
8793+ nxi, nxi ? nxi->nx_id : 0,
8794+ nxi?atomic_read(&nxi->nx_usecnt):0,
8795+ nxi?atomic_read(&nxi->nx_tasks):0,
8796+ task, _file, _line);
d337f35e 8797+
d33d7b00
AM
8798+ atomic_inc(&nxi->nx_tasks);
8799+}
d337f35e 8800+
d337f35e 8801+
d33d7b00 8802+extern void unhash_nx_info(struct nx_info *);
d337f35e 8803+
d33d7b00 8804+#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__)
d337f35e 8805+
d33d7b00
AM
8806+static inline void __release_nx_info(struct nx_info *nxi,
8807+ struct task_struct *task, const char *_file, int _line)
8808+{
8809+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
8810+ nxi, nxi ? nxi->nx_id : 0,
8811+ nxi ? atomic_read(&nxi->nx_usecnt) : 0,
8812+ nxi ? atomic_read(&nxi->nx_tasks) : 0,
8813+ task, _file, _line);
ab30d09f 8814+
d33d7b00 8815+ might_sleep();
d337f35e 8816+
d33d7b00
AM
8817+ if (atomic_dec_and_test(&nxi->nx_tasks))
8818+ unhash_nx_info(nxi);
8819+}
d337f35e
JR
8820+
8821+
d33d7b00 8822+#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__)
d337f35e 8823+
d33d7b00
AM
8824+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
8825+ const char *_file, int _line)
8826+{
8827+ struct nx_info *nxi;
d337f35e 8828+
d33d7b00
AM
8829+ task_lock(p);
8830+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
8831+ p, _file, _line);
8832+ nxi = __get_nx_info(p->nx_info, _file, _line);
8833+ task_unlock(p);
8834+ return nxi;
8835+}
d337f35e 8836+
d337f35e 8837+
d33d7b00
AM
8838+static inline void exit_nx_info(struct task_struct *p)
8839+{
8840+ if (p->nx_info)
8841+ release_nx_info(p->nx_info, p);
8842+}
adc1caaa 8843+
d337f35e 8844+
2380c486 8845+#else
d33d7b00 8846+#warning duplicate inclusion
2380c486 8847+#endif
f19bd705
AM
8848diff -NurpP --minimal linux-4.4.111/include/linux/vs_pid.h linux-4.4.111-vs2.3.9.1/include/linux/vs_pid.h
8849--- linux-4.4.111/include/linux/vs_pid.h 1970-01-01 00:00:00.000000000 +0000
8850+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_pid.h 2018-01-09 16:36:32.000000000 +0000
b3b0d4fd 8851@@ -0,0 +1,50 @@
d33d7b00
AM
8852+#ifndef _VS_PID_H
8853+#define _VS_PID_H
d337f35e 8854+
d33d7b00
AM
8855+#include "vserver/base.h"
8856+#include "vserver/check.h"
8857+#include "vserver/context.h"
8858+#include "vserver/debug.h"
8859+#include "vserver/pid.h"
8860+#include <linux/pid_namespace.h>
d337f35e 8861+
d337f35e 8862+
d33d7b00 8863+#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT)
d337f35e 8864+
d33d7b00
AM
8865+static inline
8866+int vx_proc_task_visible(struct task_struct *task)
8867+{
8868+ if ((task->pid == 1) &&
8869+ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
8870+ /* show a blend through init */
8871+ goto visible;
8872+ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT))
8873+ goto visible;
8874+ return 0;
8875+visible:
8876+ return 1;
8877+}
d337f35e 8878+
d33d7b00 8879+#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns)
d337f35e 8880+
d337f35e 8881+
d33d7b00
AM
8882+static inline
8883+struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
8884+{
8885+ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
d337f35e 8886+
d33d7b00
AM
8887+ if (task && !vx_proc_task_visible(task)) {
8888+ vxdprintk(VXD_CBIT(misc, 6),
8889+ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
8890+ task, task->xid, task->pid,
8891+ current, current->xid, current->pid);
8892+ put_task_struct(task);
8893+ task = NULL;
8894+ }
8895+ return task;
8896+}
d337f35e 8897+
d337f35e 8898+
d33d7b00
AM
8899+#else
8900+#warning duplicate inclusion
8901+#endif
f19bd705
AM
8902diff -NurpP --minimal linux-4.4.111/include/linux/vs_sched.h linux-4.4.111-vs2.3.9.1/include/linux/vs_sched.h
8903--- linux-4.4.111/include/linux/vs_sched.h 1970-01-01 00:00:00.000000000 +0000
8904+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_sched.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8905@@ -0,0 +1,40 @@
8906+#ifndef _VS_SCHED_H
8907+#define _VS_SCHED_H
d337f35e 8908+
d33d7b00
AM
8909+#include "vserver/base.h"
8910+#include "vserver/context.h"
8911+#include "vserver/sched.h"
d337f35e
JR
8912+
8913+
d33d7b00
AM
8914+#define MAX_PRIO_BIAS 20
8915+#define MIN_PRIO_BIAS -20
d337f35e 8916+
d33d7b00
AM
8917+static inline
8918+int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
8919+{
8920+ struct vx_info *vxi = p->vx_info;
d337f35e 8921+
d33d7b00
AM
8922+ if (vxi)
8923+ prio += vx_cpu(vxi, sched_pc).prio_bias;
8924+ return prio;
8925+}
d337f35e 8926+
d33d7b00
AM
8927+static inline void vx_account_user(struct vx_info *vxi,
8928+ cputime_t cputime, int nice)
8929+{
8930+ if (!vxi)
8931+ return;
8932+ vx_cpu(vxi, sched_pc).user_ticks += cputime;
8933+}
d337f35e 8934+
d33d7b00
AM
8935+static inline void vx_account_system(struct vx_info *vxi,
8936+ cputime_t cputime, int idle)
8937+{
8938+ if (!vxi)
8939+ return;
8940+ vx_cpu(vxi, sched_pc).sys_ticks += cputime;
8941+}
d337f35e 8942+
d33d7b00
AM
8943+#else
8944+#warning duplicate inclusion
8945+#endif
f19bd705
AM
8946diff -NurpP --minimal linux-4.4.111/include/linux/vs_socket.h linux-4.4.111-vs2.3.9.1/include/linux/vs_socket.h
8947--- linux-4.4.111/include/linux/vs_socket.h 1970-01-01 00:00:00.000000000 +0000
8948+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_socket.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
8949@@ -0,0 +1,67 @@
8950+#ifndef _VS_SOCKET_H
8951+#define _VS_SOCKET_H
d337f35e 8952+
d33d7b00
AM
8953+#include "vserver/debug.h"
8954+#include "vserver/base.h"
8955+#include "vserver/cacct.h"
8956+#include "vserver/context.h"
8957+#include "vserver/tag.h"
d337f35e 8958+
d337f35e 8959+
d33d7b00 8960+/* socket accounting */
d337f35e 8961+
d33d7b00 8962+#include <linux/socket.h>
d337f35e 8963+
d33d7b00
AM
8964+static inline int vx_sock_type(int family)
8965+{
8966+ switch (family) {
8967+ case PF_UNSPEC:
8968+ return VXA_SOCK_UNSPEC;
8969+ case PF_UNIX:
8970+ return VXA_SOCK_UNIX;
8971+ case PF_INET:
8972+ return VXA_SOCK_INET;
8973+ case PF_INET6:
8974+ return VXA_SOCK_INET6;
8975+ case PF_PACKET:
8976+ return VXA_SOCK_PACKET;
8977+ default:
8978+ return VXA_SOCK_OTHER;
8979+ }
8980+}
d337f35e 8981+
d33d7b00
AM
8982+#define vx_acc_sock(v, f, p, s) \
8983+ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__)
d337f35e 8984+
d33d7b00
AM
8985+static inline void __vx_acc_sock(struct vx_info *vxi,
8986+ int family, int pos, int size, char *file, int line)
8987+{
8988+ if (vxi) {
8989+ int type = vx_sock_type(family);
d337f35e 8990+
d33d7b00
AM
8991+ atomic_long_inc(&vxi->cacct.sock[type][pos].count);
8992+ atomic_long_add(size, &vxi->cacct.sock[type][pos].total);
8993+ }
8994+}
d337f35e 8995+
d33d7b00
AM
8996+#define vx_sock_recv(sk, s) \
8997+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s)
8998+#define vx_sock_send(sk, s) \
8999+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s)
9000+#define vx_sock_fail(sk, s) \
9001+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s)
d337f35e 9002+
d337f35e 9003+
d33d7b00
AM
9004+#define sock_vx_init(s) do { \
9005+ (s)->sk_xid = 0; \
9006+ (s)->sk_vx_info = NULL; \
9007+ } while (0)
d337f35e 9008+
d33d7b00
AM
9009+#define sock_nx_init(s) do { \
9010+ (s)->sk_nid = 0; \
9011+ (s)->sk_nx_info = NULL; \
9012+ } while (0)
d337f35e 9013+
d33d7b00
AM
9014+#else
9015+#warning duplicate inclusion
9016+#endif
f19bd705
AM
9017diff -NurpP --minimal linux-4.4.111/include/linux/vs_tag.h linux-4.4.111-vs2.3.9.1/include/linux/vs_tag.h
9018--- linux-4.4.111/include/linux/vs_tag.h 1970-01-01 00:00:00.000000000 +0000
9019+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_tag.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
9020@@ -0,0 +1,47 @@
9021+#ifndef _VS_TAG_H
9022+#define _VS_TAG_H
d337f35e 9023+
d33d7b00 9024+#include <linux/vserver/tag.h>
d337f35e 9025+
d33d7b00 9026+/* check conditions */
d337f35e 9027+
d33d7b00
AM
9028+#define DX_ADMIN 0x0001
9029+#define DX_WATCH 0x0002
9030+#define DX_HOSTID 0x0008
d337f35e 9031+
d33d7b00 9032+#define DX_IDENT 0x0010
d337f35e 9033+
d33d7b00 9034+#define DX_ARG_MASK 0x0010
d337f35e 9035+
d337f35e 9036+
d33d7b00 9037+#define dx_task_tag(t) ((t)->tag)
d337f35e 9038+
d33d7b00 9039+#define dx_current_tag() dx_task_tag(current)
d337f35e 9040+
d33d7b00 9041+#define dx_check(c, m) __dx_check(dx_current_tag(), c, m)
d337f35e 9042+
d33d7b00 9043+#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1)
d337f35e
JR
9044+
9045+
d33d7b00
AM
9046+/*
9047+ * check current context for ADMIN/WATCH and
9048+ * optionally against supplied argument
9049+ */
61333608 9050+static inline int __dx_check(vtag_t cid, vtag_t id, unsigned int mode)
d33d7b00
AM
9051+{
9052+ if (mode & DX_ARG_MASK) {
9053+ if ((mode & DX_IDENT) && (id == cid))
9054+ return 1;
9055+ }
9056+ return (((mode & DX_ADMIN) && (cid == 0)) ||
9057+ ((mode & DX_WATCH) && (cid == 1)) ||
9058+ ((mode & DX_HOSTID) && (id == 0)));
9059+}
d337f35e 9060+
d33d7b00
AM
9061+struct inode;
9062+int dx_permission(const struct inode *inode, int mask);
d337f35e 9063+
d337f35e 9064+
d33d7b00
AM
9065+#else
9066+#warning duplicate inclusion
9067+#endif
f19bd705
AM
9068diff -NurpP --minimal linux-4.4.111/include/linux/vs_time.h linux-4.4.111-vs2.3.9.1/include/linux/vs_time.h
9069--- linux-4.4.111/include/linux/vs_time.h 1970-01-01 00:00:00.000000000 +0000
9070+++ linux-4.4.111-vs2.3.9.1/include/linux/vs_time.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00
AM
9071@@ -0,0 +1,19 @@
9072+#ifndef _VS_TIME_H
9073+#define _VS_TIME_H
d337f35e 9074+
d337f35e 9075+
d33d7b00 9076+/* time faking stuff */
d337f35e 9077+
d33d7b00 9078+#ifdef CONFIG_VSERVER_VTIME
d337f35e 9079+
d33d7b00 9080+extern void vx_adjust_timespec(struct timespec *ts);
763640ca 9081+extern int vx_settimeofday(const struct timespec *ts);
d337f35e 9082+
d33d7b00
AM
9083+#else
9084+#define vx_adjust_timespec(t) do { } while (0)
9085+#define vx_settimeofday(t) do_settimeofday(t)
9086+#endif
d337f35e 9087+
d33d7b00
AM
9088+#else
9089+#warning duplicate inclusion
9090+#endif
f19bd705
AM
9091diff -NurpP --minimal linux-4.4.111/include/linux/vserver/base.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/base.h
9092--- linux-4.4.111/include/linux/vserver/base.h 1970-01-01 00:00:00.000000000 +0000
9093+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/base.h 2018-01-09 16:36:32.000000000 +0000
c2e5f7c8 9094@@ -0,0 +1,184 @@
4bf69007
AM
9095+#ifndef _VSERVER_BASE_H
9096+#define _VSERVER_BASE_H
d337f35e 9097+
d337f35e 9098+
d33d7b00 9099+/* context state changes */
d337f35e 9100+
d33d7b00
AM
9101+enum {
9102+ VSC_STARTUP = 1,
9103+ VSC_SHUTDOWN,
d337f35e 9104+
d33d7b00
AM
9105+ VSC_NETUP,
9106+ VSC_NETDOWN,
3bac966d 9107+};
d337f35e 9108+
d337f35e
JR
9109+
9110+
d33d7b00 9111+#define vx_task_xid(t) ((t)->xid)
d337f35e 9112+
d33d7b00 9113+#define vx_current_xid() vx_task_xid(current)
d337f35e 9114+
d33d7b00 9115+#define current_vx_info() (current->vx_info)
d337f35e 9116+
ba86f833 9117+
d33d7b00 9118+#define nx_task_nid(t) ((t)->nid)
ba86f833 9119+
d33d7b00 9120+#define nx_current_nid() nx_task_nid(current)
d337f35e 9121+
d33d7b00 9122+#define current_nx_info() (current->nx_info)
d337f35e 9123+
d337f35e 9124+
d33d7b00 9125+/* generic flag merging */
d337f35e 9126+
d33d7b00 9127+#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f))
d337f35e 9128+
d33d7b00 9129+#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m)))
d337f35e 9130+
d33d7b00 9131+#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m)))
d337f35e 9132+
d33d7b00 9133+#define vs_check_bit(v, n) ((v) & (1LL << (n)))
d337f35e 9134+
d337f35e 9135+
d33d7b00 9136+/* context flags */
d337f35e 9137+
d33d7b00 9138+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
d337f35e 9139+
d33d7b00 9140+#define vx_current_flags() __vx_flags(current_vx_info())
d337f35e 9141+
d33d7b00
AM
9142+#define vx_info_flags(v, m, f) \
9143+ vs_check_flags(__vx_flags(v), m, f)
d337f35e 9144+
d33d7b00
AM
9145+#define task_vx_flags(t, m, f) \
9146+ ((t) && vx_info_flags((t)->vx_info, m, f))
d337f35e 9147+
d33d7b00 9148+#define vx_flags(m, f) vx_info_flags(current_vx_info(), m, f)
d337f35e
JR
9149+
9150+
d33d7b00 9151+/* context caps */
d337f35e 9152+
d33d7b00 9153+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
d337f35e 9154+
d33d7b00 9155+#define vx_current_ccaps() __vx_ccaps(current_vx_info())
d337f35e 9156+
d33d7b00 9157+#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c))
d337f35e 9158+
d33d7b00 9159+#define vx_ccaps(c) vx_info_ccaps(current_vx_info(), (c))
d337f35e 9160+
d337f35e
JR
9161+
9162+
d33d7b00 9163+/* network flags */
2380c486 9164+
d33d7b00 9165+#define __nx_flags(n) ((n) ? (n)->nx_flags : 0)
d337f35e 9166+
d33d7b00 9167+#define nx_current_flags() __nx_flags(current_nx_info())
d337f35e 9168+
d33d7b00
AM
9169+#define nx_info_flags(n, m, f) \
9170+ vs_check_flags(__nx_flags(n), m, f)
d337f35e 9171+
d33d7b00
AM
9172+#define task_nx_flags(t, m, f) \
9173+ ((t) && nx_info_flags((t)->nx_info, m, f))
d337f35e 9174+
d33d7b00 9175+#define nx_flags(m, f) nx_info_flags(current_nx_info(), m, f)
d337f35e 9176+
d337f35e 9177+
d33d7b00 9178+/* network caps */
d337f35e 9179+
d33d7b00 9180+#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0)
d337f35e 9181+
d33d7b00 9182+#define nx_current_ncaps() __nx_ncaps(current_nx_info())
d337f35e 9183+
d33d7b00 9184+#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c))
d337f35e 9185+
d33d7b00 9186+#define nx_ncaps(c) nx_info_ncaps(current_nx_info(), c)
d337f35e 9187+
d337f35e 9188+
d33d7b00 9189+/* context mask capabilities */
d337f35e 9190+
d33d7b00 9191+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
d337f35e 9192+
d33d7b00 9193+#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c))
d337f35e 9194+
d33d7b00 9195+#define vx_mcaps(c) vx_info_mcaps(current_vx_info(), c)
d337f35e
JR
9196+
9197+
d33d7b00 9198+/* context bcap mask */
d337f35e 9199+
d33d7b00 9200+#define __vx_bcaps(v) ((v)->vx_bcaps)
d337f35e 9201+
d33d7b00 9202+#define vx_current_bcaps() __vx_bcaps(current_vx_info())
d337f35e 9203+
d337f35e 9204+
d33d7b00 9205+/* mask given bcaps */
adc1caaa 9206+
d33d7b00 9207+#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c)
2380c486 9208+
d33d7b00 9209+#define vx_mbcaps(c) vx_info_mbcaps(current_vx_info(), c)
d337f35e
JR
9210+
9211+
d33d7b00 9212+/* masked cap_bset */
2380c486 9213+
d33d7b00 9214+#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset)
2380c486 9215+
d33d7b00 9216+#define vx_current_cap_bset() vx_info_cap_bset(current_vx_info())
d337f35e 9217+
d33d7b00
AM
9218+#if 0
9219+#define vx_info_mbcap(v, b) \
9220+ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
9221+ vx_info_bcaps(v, b) : (b))
d337f35e 9222+
d33d7b00
AM
9223+#define task_vx_mbcap(t, b) \
9224+ vx_info_mbcap((t)->vx_info, (t)->b)
9225+
9226+#define vx_mbcap(b) task_vx_mbcap(current, b)
3bac966d 9227+#endif
d337f35e 9228+
d33d7b00 9229+#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f)
d337f35e 9230+
d33d7b00
AM
9231+#define vx_capable(b, c) (capable(b) || \
9232+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
d337f35e 9233+
763640ca
JR
9234+#define vx_ns_capable(n, b, c) (ns_capable(n, b) || \
9235+ (cap_raised(current_cap(), b) && vx_ccaps(c)))
9236+
d33d7b00
AM
9237+#define nx_capable(b, c) (capable(b) || \
9238+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
d337f35e 9239+
c2e5f7c8
JR
9240+#define nx_ns_capable(n, b, c) (ns_capable(n, b) || \
9241+ (cap_raised(current_cap(), b) && nx_ncaps(c)))
9242+
d33d7b00
AM
9243+#define vx_task_initpid(t, n) \
9244+ ((t)->vx_info && \
9245+ ((t)->vx_info->vx_initpid == (n)))
d337f35e 9246+
d33d7b00 9247+#define vx_current_initpid(n) vx_task_initpid(current, n)
d337f35e 9248+
d337f35e 9249+
d33d7b00 9250+/* context unshare mask */
d337f35e 9251+
d33d7b00 9252+#define __vx_umask(v) ((v)->vx_umask)
7e46296a 9253+
d33d7b00 9254+#define vx_current_umask() __vx_umask(current_vx_info())
7e46296a 9255+
d33d7b00
AM
9256+#define vx_can_unshare(b, f) (capable(b) || \
9257+ (cap_raised(current_cap(), b) && \
9258+ !((f) & ~vx_current_umask())))
7e46296a 9259+
b00e13aa
AM
9260+#define vx_ns_can_unshare(n, b, f) (ns_capable(n, b) || \
9261+ (cap_raised(current_cap(), b) && \
9262+ !((f) & ~vx_current_umask())))
7e46296a 9263+
265d6dcc
JR
9264+#define __vx_wmask(v) ((v)->vx_wmask)
9265+
9266+#define vx_current_wmask() __vx_wmask(current_vx_info())
9267+
9268+
d33d7b00 9269+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
7e46296a 9270+
d33d7b00 9271+#define vx_info_state(v, m) (__vx_state(v) & (m))
d337f35e 9272+
d337f35e 9273+
d33d7b00 9274+#define __nx_state(n) ((n) ? ((n)->nx_state) : 0)
d337f35e 9275+
d33d7b00 9276+#define nx_info_state(n, m) (__nx_state(n) & (m))
d337f35e 9277+
d33d7b00 9278+#endif
f19bd705
AM
9279diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct.h
9280--- linux-4.4.111/include/linux/vserver/cacct.h 1970-01-01 00:00:00.000000000 +0000
9281+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9282@@ -0,0 +1,15 @@
4bf69007
AM
9283+#ifndef _VSERVER_CACCT_H
9284+#define _VSERVER_CACCT_H
d337f35e 9285+
d337f35e 9286+
d33d7b00
AM
9287+enum sock_acc_field {
9288+ VXA_SOCK_UNSPEC = 0,
9289+ VXA_SOCK_UNIX,
9290+ VXA_SOCK_INET,
9291+ VXA_SOCK_INET6,
9292+ VXA_SOCK_PACKET,
9293+ VXA_SOCK_OTHER,
9294+ VXA_SOCK_SIZE /* array size */
9295+};
d337f35e 9296+
4bf69007 9297+#endif /* _VSERVER_CACCT_H */
f19bd705
AM
9298diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_cmd.h
9299--- linux-4.4.111/include/linux/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
9300+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9301@@ -0,0 +1,10 @@
9302+#ifndef _VSERVER_CACCT_CMD_H
9303+#define _VSERVER_CACCT_CMD_H
d337f35e 9304+
d337f35e 9305+
3bac966d 9306+#include <linux/compiler.h>
4bf69007 9307+#include <uapi/vserver/cacct_cmd.h>
d337f35e 9308+
d33d7b00 9309+extern int vc_sock_stat(struct vx_info *, void __user *);
d337f35e 9310+
4bf69007 9311+#endif /* _VSERVER_CACCT_CMD_H */
f19bd705
AM
9312diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_def.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_def.h
9313--- linux-4.4.111/include/linux/vserver/cacct_def.h 1970-01-01 00:00:00.000000000 +0000
9314+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9315@@ -0,0 +1,43 @@
4bf69007
AM
9316+#ifndef _VSERVER_CACCT_DEF_H
9317+#define _VSERVER_CACCT_DEF_H
d337f35e 9318+
d33d7b00
AM
9319+#include <asm/atomic.h>
9320+#include <linux/vserver/cacct.h>
d337f35e
JR
9321+
9322+
d33d7b00
AM
9323+struct _vx_sock_acc {
9324+ atomic_long_t count;
9325+ atomic_long_t total;
9326+};
d337f35e 9327+
d33d7b00 9328+/* context sub struct */
d337f35e 9329+
d33d7b00
AM
9330+struct _vx_cacct {
9331+ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
9332+ atomic_t slab[8];
9333+ atomic_t page[6][8];
9334+};
d337f35e 9335+
d33d7b00 9336+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9337+
d33d7b00
AM
9338+static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
9339+{
9340+ int i, j;
d337f35e 9341+
d33d7b00
AM
9342+ printk("\t_vx_cacct:");
9343+ for (i = 0; i < 6; i++) {
9344+ struct _vx_sock_acc *ptr = cacct->sock[i];
d337f35e 9345+
d33d7b00
AM
9346+ printk("\t [%d] =", i);
9347+ for (j = 0; j < 3; j++) {
9348+ printk(" [%d] = %8lu, %8lu", j,
9349+ atomic_long_read(&ptr[j].count),
9350+ atomic_long_read(&ptr[j].total));
9351+ }
9352+ printk("\n");
9353+ }
9354+}
2380c486 9355+
d33d7b00 9356+#endif
d337f35e 9357+
4bf69007 9358+#endif /* _VSERVER_CACCT_DEF_H */
f19bd705
AM
9359diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cacct_int.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_int.h
9360--- linux-4.4.111/include/linux/vserver/cacct_int.h 1970-01-01 00:00:00.000000000 +0000
9361+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cacct_int.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9362@@ -0,0 +1,17 @@
9363+#ifndef _VSERVER_CACCT_INT_H
9364+#define _VSERVER_CACCT_INT_H
d337f35e 9365+
d33d7b00
AM
9366+static inline
9367+unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
9368+{
9369+ return atomic_long_read(&cacct->sock[type][pos].count);
9370+}
d337f35e 9371+
d337f35e 9372+
d33d7b00
AM
9373+static inline
9374+unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
9375+{
9376+ return atomic_long_read(&cacct->sock[type][pos].total);
9377+}
d337f35e 9378+
4bf69007 9379+#endif /* _VSERVER_CACCT_INT_H */
f19bd705
AM
9380diff -NurpP --minimal linux-4.4.111/include/linux/vserver/check.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/check.h
9381--- linux-4.4.111/include/linux/vserver/check.h 1970-01-01 00:00:00.000000000 +0000
9382+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/check.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9383@@ -0,0 +1,89 @@
4bf69007
AM
9384+#ifndef _VSERVER_CHECK_H
9385+#define _VSERVER_CHECK_H
d337f35e 9386+
d337f35e 9387+
d33d7b00 9388+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
d337f35e 9389+
d33d7b00
AM
9390+#ifdef CONFIG_VSERVER_DYNAMIC_IDS
9391+#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */
9392+#else
9393+#define MIN_D_CONTEXT 65536
9394+#endif
d337f35e 9395+
d33d7b00 9396+/* check conditions */
d337f35e 9397+
d33d7b00
AM
9398+#define VS_ADMIN 0x0001
9399+#define VS_WATCH 0x0002
9400+#define VS_HIDE 0x0004
9401+#define VS_HOSTID 0x0008
d337f35e 9402+
d33d7b00
AM
9403+#define VS_IDENT 0x0010
9404+#define VS_EQUIV 0x0020
9405+#define VS_PARENT 0x0040
9406+#define VS_CHILD 0x0080
d337f35e 9407+
d33d7b00 9408+#define VS_ARG_MASK 0x00F0
d337f35e 9409+
d33d7b00
AM
9410+#define VS_DYNAMIC 0x0100
9411+#define VS_STATIC 0x0200
d337f35e 9412+
d33d7b00 9413+#define VS_ATR_MASK 0x0F00
d337f35e 9414+
d33d7b00
AM
9415+#ifdef CONFIG_VSERVER_PRIVACY
9416+#define VS_ADMIN_P (0)
9417+#define VS_WATCH_P (0)
9418+#else
9419+#define VS_ADMIN_P VS_ADMIN
9420+#define VS_WATCH_P VS_WATCH
9421+#endif
d337f35e 9422+
d33d7b00
AM
9423+#define VS_HARDIRQ 0x1000
9424+#define VS_SOFTIRQ 0x2000
9425+#define VS_IRQ 0x4000
d337f35e 9426+
d33d7b00 9427+#define VS_IRQ_MASK 0xF000
d337f35e 9428+
d33d7b00 9429+#include <linux/hardirq.h>
d337f35e 9430+
d33d7b00
AM
9431+/*
9432+ * check current context for ADMIN/WATCH and
9433+ * optionally against supplied argument
9434+ */
9435+static inline int __vs_check(int cid, int id, unsigned int mode)
9436+{
9437+ if (mode & VS_ARG_MASK) {
9438+ if ((mode & VS_IDENT) && (id == cid))
9439+ return 1;
9440+ }
9441+ if (mode & VS_ATR_MASK) {
9442+ if ((mode & VS_DYNAMIC) &&
9443+ (id >= MIN_D_CONTEXT) &&
9444+ (id <= MAX_S_CONTEXT))
9445+ return 1;
9446+ if ((mode & VS_STATIC) &&
9447+ (id > 1) && (id < MIN_D_CONTEXT))
9448+ return 1;
9449+ }
9450+ if (mode & VS_IRQ_MASK) {
9451+ if ((mode & VS_IRQ) && unlikely(in_interrupt()))
9452+ return 1;
9453+ if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
9454+ return 1;
9455+ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
9456+ return 1;
9457+ }
9458+ return (((mode & VS_ADMIN) && (cid == 0)) ||
9459+ ((mode & VS_WATCH) && (cid == 1)) ||
9460+ ((mode & VS_HOSTID) && (id == 0)));
9461+}
d337f35e 9462+
d33d7b00 9463+#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ)
d337f35e 9464+
d33d7b00 9465+#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1)
2380c486 9466+
d337f35e 9467+
d33d7b00 9468+#define nx_check(c, m) __vs_check(nx_current_nid(), c, m)
d337f35e 9469+
d33d7b00 9470+#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1)
d337f35e 9471+
d33d7b00 9472+#endif
f19bd705
AM
9473diff -NurpP --minimal linux-4.4.111/include/linux/vserver/context.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/context.h
9474--- linux-4.4.111/include/linux/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
9475+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/context.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9476@@ -0,0 +1,110 @@
9477+#ifndef _VSERVER_CONTEXT_H
9478+#define _VSERVER_CONTEXT_H
d337f35e
JR
9479+
9480+
d33d7b00
AM
9481+#include <linux/list.h>
9482+#include <linux/spinlock.h>
9483+#include <linux/rcupdate.h>
4bf69007 9484+#include <uapi/vserver/context.h>
d337f35e 9485+
d33d7b00
AM
9486+#include "limit_def.h"
9487+#include "sched_def.h"
9488+#include "cvirt_def.h"
9489+#include "cacct_def.h"
9490+#include "device_def.h"
d337f35e 9491+
d33d7b00 9492+#define VX_SPACES 2
d337f35e 9493+
d33d7b00
AM
9494+struct _vx_info_pc {
9495+ struct _vx_sched_pc sched_pc;
9496+ struct _vx_cvirt_pc cvirt_pc;
9497+};
d337f35e 9498+
d33d7b00
AM
9499+struct _vx_space {
9500+ unsigned long vx_nsmask; /* assignment mask */
9501+ struct nsproxy *vx_nsproxy; /* private namespaces */
9502+ struct fs_struct *vx_fs; /* private namespace fs */
9503+ const struct cred *vx_cred; /* task credentials */
9504+};
d337f35e 9505+
d33d7b00
AM
9506+struct vx_info {
9507+ struct hlist_node vx_hlist; /* linked list of contexts */
61333608 9508+ vxid_t vx_id; /* context id */
d33d7b00
AM
9509+ atomic_t vx_usecnt; /* usage count */
9510+ atomic_t vx_tasks; /* tasks count */
9511+ struct vx_info *vx_parent; /* parent context */
9512+ int vx_state; /* context state */
d337f35e 9513+
d33d7b00 9514+ struct _vx_space space[VX_SPACES]; /* namespace store */
d337f35e 9515+
d33d7b00
AM
9516+ uint64_t vx_flags; /* context flags */
9517+ uint64_t vx_ccaps; /* context caps (vserver) */
763640ca 9518+ uint64_t vx_umask; /* unshare mask (guest) */
265d6dcc 9519+ uint64_t vx_wmask; /* warn mask (guest) */
d33d7b00 9520+ kernel_cap_t vx_bcaps; /* bounding caps (system) */
d337f35e 9521+
d33d7b00
AM
9522+ struct task_struct *vx_reaper; /* guest reaper process */
9523+ pid_t vx_initpid; /* PID of guest init */
9524+ int64_t vx_badness_bias; /* OOM points bias */
d337f35e 9525+
d33d7b00
AM
9526+ struct _vx_limit limit; /* vserver limits */
9527+ struct _vx_sched sched; /* vserver scheduler */
9528+ struct _vx_cvirt cvirt; /* virtual/bias stuff */
9529+ struct _vx_cacct cacct; /* context accounting */
d337f35e 9530+
d33d7b00 9531+ struct _vx_device dmap; /* default device map targets */
d337f35e 9532+
d33d7b00
AM
9533+#ifndef CONFIG_SMP
9534+ struct _vx_info_pc info_pc; /* per cpu data */
9535+#else
9536+ struct _vx_info_pc *ptr_pc; /* per cpu array */
9537+#endif
d337f35e 9538+
d33d7b00
AM
9539+ wait_queue_head_t vx_wait; /* context exit waitqueue */
9540+ int reboot_cmd; /* last sys_reboot() cmd */
9541+ int exit_code; /* last process exit code */
d337f35e 9542+
d33d7b00
AM
9543+ char vx_name[65]; /* vserver name */
9544+};
d337f35e 9545+
d33d7b00
AM
9546+#ifndef CONFIG_SMP
9547+#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
9548+#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
9549+#else
9550+#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
9551+#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
9552+#endif
d337f35e 9553+
d33d7b00 9554+#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
d337f35e 9555+
d337f35e 9556+
d33d7b00
AM
9557+struct vx_info_save {
9558+ struct vx_info *vxi;
61333608 9559+ vxid_t xid;
d33d7b00 9560+};
d337f35e
JR
9561+
9562+
d33d7b00 9563+/* status flags */
d337f35e 9564+
d33d7b00
AM
9565+#define VXS_HASHED 0x0001
9566+#define VXS_PAUSED 0x0010
9567+#define VXS_SHUTDOWN 0x0100
9568+#define VXS_HELPER 0x1000
9569+#define VXS_RELEASED 0x8000
d337f35e 9570+
d337f35e 9571+
d33d7b00
AM
9572+extern void claim_vx_info(struct vx_info *, struct task_struct *);
9573+extern void release_vx_info(struct vx_info *, struct task_struct *);
adc1caaa 9574+
d33d7b00
AM
9575+extern struct vx_info *lookup_vx_info(int);
9576+extern struct vx_info *lookup_or_create_vx_info(int);
d337f35e 9577+
d33d7b00 9578+extern int get_xid_list(int, unsigned int *, int);
61333608 9579+extern int xid_is_hashed(vxid_t);
d337f35e 9580+
d33d7b00 9581+extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
d337f35e 9582+
d33d7b00 9583+extern long vs_state_change(struct vx_info *, unsigned int);
d337f35e 9584+
d337f35e 9585+
4bf69007 9586+#endif /* _VSERVER_CONTEXT_H */
f19bd705
AM
9587diff -NurpP --minimal linux-4.4.111/include/linux/vserver/context_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/context_cmd.h
9588--- linux-4.4.111/include/linux/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
9589+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/context_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9590@@ -0,0 +1,33 @@
9591+#ifndef _VSERVER_CONTEXT_CMD_H
9592+#define _VSERVER_CONTEXT_CMD_H
d337f35e 9593+
4bf69007 9594+#include <uapi/vserver/context_cmd.h>
d337f35e 9595+
d33d7b00 9596+extern int vc_task_xid(uint32_t);
d337f35e 9597+
d33d7b00 9598+extern int vc_vx_info(struct vx_info *, void __user *);
d337f35e 9599+
d33d7b00 9600+extern int vc_ctx_stat(struct vx_info *, void __user *);
d337f35e 9601+
4bf69007
AM
9602+extern int vc_ctx_create(uint32_t, void __user *);
9603+extern int vc_ctx_migrate(struct vx_info *, void __user *);
d337f35e 9604+
4bf69007
AM
9605+extern int vc_get_cflags(struct vx_info *, void __user *);
9606+extern int vc_set_cflags(struct vx_info *, void __user *);
d337f35e 9607+
4bf69007
AM
9608+extern int vc_get_ccaps(struct vx_info *, void __user *);
9609+extern int vc_set_ccaps(struct vx_info *, void __user *);
d337f35e 9610+
4bf69007
AM
9611+extern int vc_get_bcaps(struct vx_info *, void __user *);
9612+extern int vc_set_bcaps(struct vx_info *, void __user *);
d337f35e 9613+
4bf69007
AM
9614+extern int vc_get_umask(struct vx_info *, void __user *);
9615+extern int vc_set_umask(struct vx_info *, void __user *);
d33d7b00 9616+
4bf69007
AM
9617+extern int vc_get_wmask(struct vx_info *, void __user *);
9618+extern int vc_set_wmask(struct vx_info *, void __user *);
d33d7b00 9619+
4bf69007
AM
9620+extern int vc_get_badness(struct vx_info *, void __user *);
9621+extern int vc_set_badness(struct vx_info *, void __user *);
d337f35e 9622+
4bf69007 9623+#endif /* _VSERVER_CONTEXT_CMD_H */
f19bd705
AM
9624diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt.h
9625--- linux-4.4.111/include/linux/vserver/cvirt.h 1970-01-01 00:00:00.000000000 +0000
9626+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9627@@ -0,0 +1,18 @@
9628+#ifndef _VSERVER_CVIRT_H
9629+#define _VSERVER_CVIRT_H
d337f35e 9630+
4bf69007 9631+struct timespec;
d337f35e 9632+
4bf69007 9633+void vx_vsi_boottime(struct timespec *);
d337f35e 9634+
4bf69007 9635+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e 9636+
d337f35e 9637+
4bf69007 9638+struct vx_info;
d337f35e 9639+
4bf69007 9640+void vx_update_load(struct vx_info *);
d337f35e 9641+
d337f35e 9642+
4bf69007 9643+int vx_do_syslog(int, char __user *, int);
d337f35e 9644+
4bf69007 9645+#endif /* _VSERVER_CVIRT_H */
f19bd705
AM
9646diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt_cmd.h
9647--- linux-4.4.111/include/linux/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
9648+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9649@@ -0,0 +1,13 @@
9650+#ifndef _VSERVER_CVIRT_CMD_H
9651+#define _VSERVER_CVIRT_CMD_H
d337f35e 9652+
d337f35e 9653+
4bf69007
AM
9654+#include <linux/compiler.h>
9655+#include <uapi/vserver/cvirt_cmd.h>
d337f35e 9656+
4bf69007
AM
9657+extern int vc_set_vhi_name(struct vx_info *, void __user *);
9658+extern int vc_get_vhi_name(struct vx_info *, void __user *);
d337f35e 9659+
4bf69007 9660+extern int vc_virt_stat(struct vx_info *, void __user *);
d337f35e 9661+
4bf69007 9662+#endif /* _VSERVER_CVIRT_CMD_H */
f19bd705
AM
9663diff -NurpP --minimal linux-4.4.111/include/linux/vserver/cvirt_def.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt_def.h
9664--- linux-4.4.111/include/linux/vserver/cvirt_def.h 1970-01-01 00:00:00.000000000 +0000
9665+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/cvirt_def.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9666@@ -0,0 +1,80 @@
9667+#ifndef _VSERVER_CVIRT_DEF_H
9668+#define _VSERVER_CVIRT_DEF_H
d337f35e 9669+
d33d7b00
AM
9670+#include <linux/jiffies.h>
9671+#include <linux/spinlock.h>
9672+#include <linux/wait.h>
9673+#include <linux/time.h>
9674+#include <asm/atomic.h>
d337f35e 9675+
d337f35e 9676+
d33d7b00
AM
9677+struct _vx_usage_stat {
9678+ uint64_t user;
9679+ uint64_t nice;
9680+ uint64_t system;
9681+ uint64_t softirq;
9682+ uint64_t irq;
9683+ uint64_t idle;
9684+ uint64_t iowait;
9685+};
d337f35e 9686+
d33d7b00
AM
9687+struct _vx_syslog {
9688+ wait_queue_head_t log_wait;
9689+ spinlock_t logbuf_lock; /* lock for the log buffer */
d337f35e 9690+
d33d7b00
AM
9691+ unsigned long log_start; /* next char to be read by syslog() */
9692+ unsigned long con_start; /* next char to be sent to consoles */
9693+ unsigned long log_end; /* most-recently-written-char + 1 */
9694+ unsigned long logged_chars; /* #chars since last read+clear operation */
d337f35e 9695+
d33d7b00
AM
9696+ char log_buf[1024];
9697+};
d337f35e 9698+
d337f35e 9699+
d33d7b00 9700+/* context sub struct */
d337f35e 9701+
d33d7b00
AM
9702+struct _vx_cvirt {
9703+ atomic_t nr_threads; /* number of current threads */
9704+ atomic_t nr_running; /* number of running threads */
9705+ atomic_t nr_uninterruptible; /* number of uninterruptible threads */
d337f35e 9706+
d33d7b00
AM
9707+ atomic_t nr_onhold; /* processes on hold */
9708+ uint32_t onhold_last; /* jiffies when put on hold */
d337f35e 9709+
d33d7b00
AM
9710+ struct timespec bias_ts; /* time offset to the host */
9711+ struct timespec bias_idle;
9712+ struct timespec bias_uptime; /* context creation point */
9713+ uint64_t bias_clock; /* offset in clock_t */
3bac966d 9714+
d33d7b00
AM
9715+ spinlock_t load_lock; /* lock for the load averages */
9716+ atomic_t load_updates; /* nr of load updates done so far */
9717+ uint32_t load_last; /* last time load was calculated */
9718+ uint32_t load[3]; /* load averages 1,5,15 */
d337f35e 9719+
d33d7b00 9720+ atomic_t total_forks; /* number of forks so far */
d337f35e 9721+
d33d7b00
AM
9722+ struct _vx_syslog syslog;
9723+};
d337f35e 9724+
d33d7b00
AM
9725+struct _vx_cvirt_pc {
9726+ struct _vx_usage_stat cpustat;
9727+};
3bac966d 9728+
d337f35e 9729+
d33d7b00 9730+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9731+
d33d7b00 9732+static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
3bac966d 9733+{
d33d7b00
AM
9734+ printk("\t_vx_cvirt:\n");
9735+ printk("\t threads: %4d, %4d, %4d, %4d\n",
9736+ atomic_read(&cvirt->nr_threads),
9737+ atomic_read(&cvirt->nr_running),
9738+ atomic_read(&cvirt->nr_uninterruptible),
9739+ atomic_read(&cvirt->nr_onhold));
9740+ /* add rest here */
9741+ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
3bac966d 9742+}
d337f35e 9743+
d33d7b00 9744+#endif
d337f35e 9745+
4bf69007 9746+#endif /* _VSERVER_CVIRT_DEF_H */
f19bd705
AM
9747diff -NurpP --minimal linux-4.4.111/include/linux/vserver/debug.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/debug.h
9748--- linux-4.4.111/include/linux/vserver/debug.h 1970-01-01 00:00:00.000000000 +0000
9749+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/debug.h 2018-01-09 16:36:32.000000000 +0000
a4a22af8 9750@@ -0,0 +1,146 @@
4bf69007
AM
9751+#ifndef _VSERVER_DEBUG_H
9752+#define _VSERVER_DEBUG_H
d337f35e 9753+
d337f35e 9754+
dd5f3080 9755+#define VXD_CBIT(n, m) (vs_debug_ ## n & (1 << (m)))
9756+#define VXD_CMIN(n, m) (vs_debug_ ## n > (m))
9757+#define VXD_MASK(n, m) (vs_debug_ ## n & (m))
d337f35e 9758+
d33d7b00
AM
9759+#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
9760+ imajor((d)->bd_inode), iminor((d)->bd_inode)
9761+#define VXF_DEV "%p[%lu,%d:%d]"
d337f35e 9762+
d33d7b00
AM
9763+#if defined(CONFIG_QUOTES_UTF8)
9764+#define VS_Q_LQM "\xc2\xbb"
9765+#define VS_Q_RQM "\xc2\xab"
9766+#elif defined(CONFIG_QUOTES_ASCII)
9767+#define VS_Q_LQM "\x27"
9768+#define VS_Q_RQM "\x27"
9769+#else
9770+#define VS_Q_LQM "\xbb"
9771+#define VS_Q_RQM "\xab"
9772+#endif
d337f35e 9773+
d33d7b00 9774+#define VS_Q(f) VS_Q_LQM f VS_Q_RQM
d337f35e
JR
9775+
9776+
d33d7b00
AM
9777+#define vxd_path(p) \
9778+ ({ static char _buffer[PATH_MAX]; \
9779+ d_path(p, _buffer, sizeof(_buffer)); })
d337f35e 9780+
d33d7b00
AM
9781+#define vxd_cond_path(n) \
9782+ ((n) ? vxd_path(&(n)->path) : "<null>" )
d337f35e 9783+
d337f35e 9784+
d33d7b00 9785+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 9786+
dd5f3080 9787+extern unsigned int vs_debug_switch;
9788+extern unsigned int vs_debug_xid;
9789+extern unsigned int vs_debug_nid;
9790+extern unsigned int vs_debug_tag;
9791+extern unsigned int vs_debug_net;
9792+extern unsigned int vs_debug_limit;
9793+extern unsigned int vs_debug_cres;
9794+extern unsigned int vs_debug_dlim;
9795+extern unsigned int vs_debug_quota;
9796+extern unsigned int vs_debug_cvirt;
9797+extern unsigned int vs_debug_space;
9798+extern unsigned int vs_debug_perm;
9799+extern unsigned int vs_debug_misc;
d337f35e 9800+
d337f35e 9801+
d33d7b00
AM
9802+#define VX_LOGLEVEL "vxD: "
9803+#define VX_PROC_FMT "%p: "
9804+#define VX_PROCESS current
d337f35e 9805+
d33d7b00
AM
9806+#define vxdprintk(c, f, x...) \
9807+ do { \
9808+ if (c) \
9809+ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \
9810+ VX_PROCESS , ##x); \
9811+ } while (0)
d337f35e 9812+
d33d7b00
AM
9813+#define vxlprintk(c, f, x...) \
9814+ do { \
9815+ if (c) \
9816+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \
9817+ } while (0)
d337f35e 9818+
d33d7b00
AM
9819+#define vxfprintk(c, f, x...) \
9820+ do { \
9821+ if (c) \
9822+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
9823+ } while (0)
d337f35e 9824+
d337f35e 9825+
d33d7b00 9826+struct vx_info;
d337f35e 9827+
d33d7b00
AM
9828+void dump_vx_info(struct vx_info *, int);
9829+void dump_vx_info_inactive(int);
d337f35e 9830+
d33d7b00 9831+#else /* CONFIG_VSERVER_DEBUG */
d337f35e 9832+
dd5f3080 9833+#define vs_debug_switch 0
9834+#define vs_debug_xid 0
9835+#define vs_debug_nid 0
9836+#define vs_debug_tag 0
9837+#define vs_debug_net 0
9838+#define vs_debug_limit 0
9839+#define vs_debug_cres 0
9840+#define vs_debug_dlim 0
9841+#define vs_debug_quota 0
9842+#define vs_debug_cvirt 0
9843+#define vs_debug_space 0
9844+#define vs_debug_perm 0
9845+#define vs_debug_misc 0
d337f35e 9846+
d33d7b00
AM
9847+#define vxdprintk(x...) do { } while (0)
9848+#define vxlprintk(x...) do { } while (0)
9849+#define vxfprintk(x...) do { } while (0)
2380c486 9850+
d33d7b00 9851+#endif /* CONFIG_VSERVER_DEBUG */
2380c486 9852+
d337f35e 9853+
d33d7b00 9854+#ifdef CONFIG_VSERVER_WARN
d337f35e 9855+
d33d7b00
AM
9856+#define VX_WARNLEVEL KERN_WARNING "vxW: "
9857+#define VX_WARN_TASK "[" VS_Q("%s") ",%u:#%u|%u|%u] "
9858+#define VX_WARN_XID "[xid #%u] "
9859+#define VX_WARN_NID "[nid #%u] "
9860+#define VX_WARN_TAG "[tag #%u] "
d337f35e 9861+
d33d7b00
AM
9862+#define vxwprintk(c, f, x...) \
9863+ do { \
9864+ if (c) \
9865+ printk(VX_WARNLEVEL f "\n", ##x); \
9866+ } while (0)
d337f35e 9867+
d33d7b00 9868+#else /* CONFIG_VSERVER_WARN */
d337f35e 9869+
d33d7b00 9870+#define vxwprintk(x...) do { } while (0)
d337f35e 9871+
d33d7b00 9872+#endif /* CONFIG_VSERVER_WARN */
d337f35e 9873+
d33d7b00
AM
9874+#define vxwprintk_task(c, f, x...) \
9875+ vxwprintk(c, VX_WARN_TASK f, \
9876+ current->comm, current->pid, \
a4a22af8
AM
9877+ current->xid, current->nid, \
9878+ current->tag, ##x)
d33d7b00
AM
9879+#define vxwprintk_xid(c, f, x...) \
9880+ vxwprintk(c, VX_WARN_XID f, current->xid, x)
9881+#define vxwprintk_nid(c, f, x...) \
9882+ vxwprintk(c, VX_WARN_NID f, current->nid, x)
9883+#define vxwprintk_tag(c, f, x...) \
9884+ vxwprintk(c, VX_WARN_TAG f, current->tag, x)
d337f35e 9885+
d33d7b00
AM
9886+#ifdef CONFIG_VSERVER_DEBUG
9887+#define vxd_assert_lock(l) assert_spin_locked(l)
9888+#define vxd_assert(c, f, x...) vxlprintk(!(c), \
9889+ "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
9890+#else
9891+#define vxd_assert_lock(l) do { } while (0)
9892+#define vxd_assert(c, f, x...) do { } while (0)
9893+#endif
d337f35e 9894+
d337f35e 9895+
4bf69007 9896+#endif /* _VSERVER_DEBUG_H */
f19bd705
AM
9897diff -NurpP --minimal linux-4.4.111/include/linux/vserver/debug_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/debug_cmd.h
9898--- linux-4.4.111/include/linux/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
9899+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/debug_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9900@@ -0,0 +1,37 @@
9901+#ifndef _VSERVER_DEBUG_CMD_H
9902+#define _VSERVER_DEBUG_CMD_H
d337f35e 9903+
4bf69007 9904+#include <uapi/vserver/debug_cmd.h>
d337f35e
JR
9905+
9906+
d33d7b00 9907+#ifdef CONFIG_COMPAT
d337f35e 9908+
d33d7b00 9909+#include <asm/compat.h>
d337f35e 9910+
d33d7b00
AM
9911+struct vcmd_read_history_v0_x32 {
9912+ uint32_t index;
9913+ uint32_t count;
9914+ compat_uptr_t data_ptr;
3bac966d 9915+};
d337f35e 9916+
d33d7b00
AM
9917+struct vcmd_read_monitor_v0_x32 {
9918+ uint32_t index;
9919+ uint32_t count;
9920+ compat_uptr_t data_ptr;
3bac966d 9921+};
d337f35e 9922+
d33d7b00 9923+#endif /* CONFIG_COMPAT */
d337f35e 9924+
d33d7b00 9925+extern int vc_dump_history(uint32_t);
d337f35e 9926+
d33d7b00
AM
9927+extern int vc_read_history(uint32_t, void __user *);
9928+extern int vc_read_monitor(uint32_t, void __user *);
d337f35e 9929+
d33d7b00 9930+#ifdef CONFIG_COMPAT
d337f35e 9931+
d33d7b00
AM
9932+extern int vc_read_history_x32(uint32_t, void __user *);
9933+extern int vc_read_monitor_x32(uint32_t, void __user *);
d337f35e 9934+
d33d7b00 9935+#endif /* CONFIG_COMPAT */
d337f35e 9936+
4bf69007 9937+#endif /* _VSERVER_DEBUG_CMD_H */
f19bd705
AM
9938diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/device.h
9939--- linux-4.4.111/include/linux/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
9940+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/device.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9941@@ -0,0 +1,9 @@
9942+#ifndef _VSERVER_DEVICE_H
9943+#define _VSERVER_DEVICE_H
d337f35e 9944+
d337f35e 9945+
4bf69007 9946+#include <uapi/vserver/device.h>
d337f35e 9947+
4bf69007 9948+#else /* _VSERVER_DEVICE_H */
d33d7b00 9949+#warning duplicate inclusion
4bf69007 9950+#endif /* _VSERVER_DEVICE_H */
f19bd705
AM
9951diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/device_cmd.h
9952--- linux-4.4.111/include/linux/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
9953+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/device_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
9954@@ -0,0 +1,31 @@
9955+#ifndef _VSERVER_DEVICE_CMD_H
9956+#define _VSERVER_DEVICE_CMD_H
d337f35e 9957+
4bf69007 9958+#include <uapi/vserver/device_cmd.h>
d337f35e 9959+
d337f35e 9960+
d33d7b00 9961+#ifdef CONFIG_COMPAT
d337f35e 9962+
d33d7b00 9963+#include <asm/compat.h>
3bac966d 9964+
d33d7b00
AM
9965+struct vcmd_set_mapping_v0_x32 {
9966+ compat_uptr_t device_ptr;
9967+ compat_uptr_t target_ptr;
9968+ uint32_t flags;
d337f35e
JR
9969+};
9970+
d33d7b00 9971+#endif /* CONFIG_COMPAT */
d337f35e 9972+
d33d7b00 9973+#include <linux/compiler.h>
d337f35e 9974+
d33d7b00
AM
9975+extern int vc_set_mapping(struct vx_info *, void __user *);
9976+extern int vc_unset_mapping(struct vx_info *, void __user *);
d337f35e 9977+
d33d7b00 9978+#ifdef CONFIG_COMPAT
d337f35e 9979+
d33d7b00
AM
9980+extern int vc_set_mapping_x32(struct vx_info *, void __user *);
9981+extern int vc_unset_mapping_x32(struct vx_info *, void __user *);
d337f35e 9982+
d33d7b00 9983+#endif /* CONFIG_COMPAT */
d337f35e 9984+
4bf69007 9985+#endif /* _VSERVER_DEVICE_CMD_H */
f19bd705
AM
9986diff -NurpP --minimal linux-4.4.111/include/linux/vserver/device_def.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/device_def.h
9987--- linux-4.4.111/include/linux/vserver/device_def.h 1970-01-01 00:00:00.000000000 +0000
9988+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/device_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 9989@@ -0,0 +1,17 @@
4bf69007
AM
9990+#ifndef _VSERVER_DEVICE_DEF_H
9991+#define _VSERVER_DEVICE_DEF_H
d337f35e 9992+
d33d7b00 9993+#include <linux/types.h>
d337f35e 9994+
d33d7b00
AM
9995+struct vx_dmap_target {
9996+ dev_t target;
9997+ uint32_t flags;
9998+};
d337f35e 9999+
d33d7b00
AM
10000+struct _vx_device {
10001+#ifdef CONFIG_VSERVER_DEVICE
10002+ struct vx_dmap_target targets[2];
10003+#endif
10004+};
d337f35e 10005+
4bf69007 10006+#endif /* _VSERVER_DEVICE_DEF_H */
f19bd705
AM
10007diff -NurpP --minimal linux-4.4.111/include/linux/vserver/dlimit.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/dlimit.h
10008--- linux-4.4.111/include/linux/vserver/dlimit.h 1970-01-01 00:00:00.000000000 +0000
10009+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/dlimit.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10010@@ -0,0 +1,54 @@
4bf69007
AM
10011+#ifndef _VSERVER_DLIMIT_H
10012+#define _VSERVER_DLIMIT_H
d337f35e 10013+
d33d7b00 10014+#include "switch.h"
3bac966d 10015+
d337f35e 10016+
3bac966d 10017+#ifdef __KERNEL__
d337f35e 10018+
d33d7b00 10019+/* keep in sync with CDLIM_INFINITY */
d337f35e 10020+
d33d7b00 10021+#define DLIM_INFINITY (~0ULL)
d337f35e 10022+
d33d7b00
AM
10023+#include <linux/spinlock.h>
10024+#include <linux/rcupdate.h>
d337f35e 10025+
d33d7b00 10026+struct super_block;
d337f35e 10027+
d33d7b00
AM
10028+struct dl_info {
10029+ struct hlist_node dl_hlist; /* linked list of contexts */
10030+ struct rcu_head dl_rcu; /* the rcu head */
61333608 10031+ vtag_t dl_tag; /* context tag */
d33d7b00
AM
10032+ atomic_t dl_usecnt; /* usage count */
10033+ atomic_t dl_refcnt; /* reference count */
d337f35e 10034+
d33d7b00 10035+ struct super_block *dl_sb; /* associated superblock */
d337f35e 10036+
d33d7b00 10037+ spinlock_t dl_lock; /* protect the values */
d337f35e 10038+
d33d7b00
AM
10039+ unsigned long long dl_space_used; /* used space in bytes */
10040+ unsigned long long dl_space_total; /* maximum space in bytes */
10041+ unsigned long dl_inodes_used; /* used inodes */
10042+ unsigned long dl_inodes_total; /* maximum inodes */
d337f35e 10043+
d33d7b00
AM
10044+ unsigned int dl_nrlmult; /* non root limit mult */
10045+};
d337f35e 10046+
d33d7b00 10047+struct rcu_head;
d337f35e 10048+
d33d7b00
AM
10049+extern void rcu_free_dl_info(struct rcu_head *);
10050+extern void unhash_dl_info(struct dl_info *);
d337f35e 10051+
61333608 10052+extern struct dl_info *locate_dl_info(struct super_block *, vtag_t);
d337f35e 10053+
d337f35e 10054+
d33d7b00 10055+struct kstatfs;
d337f35e 10056+
d33d7b00 10057+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
d337f35e 10058+
d33d7b00 10059+typedef uint64_t dlsize_t;
d337f35e 10060+
d33d7b00 10061+#endif /* __KERNEL__ */
4bf69007 10062+#else /* _VSERVER_DLIMIT_H */
d33d7b00 10063+#warning duplicate inclusion
4bf69007 10064+#endif /* _VSERVER_DLIMIT_H */
f19bd705
AM
10065diff -NurpP --minimal linux-4.4.111/include/linux/vserver/dlimit_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/dlimit_cmd.h
10066--- linux-4.4.111/include/linux/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10067+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/dlimit_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10068@@ -0,0 +1,46 @@
10069+#ifndef _VSERVER_DLIMIT_CMD_H
10070+#define _VSERVER_DLIMIT_CMD_H
d337f35e 10071+
4bf69007 10072+#include <uapi/vserver/dlimit_cmd.h>
d337f35e 10073+
d337f35e 10074+
4bf69007 10075+#ifdef CONFIG_COMPAT
d337f35e 10076+
4bf69007 10077+#include <asm/compat.h>
2380c486 10078+
4bf69007
AM
10079+struct vcmd_ctx_dlimit_base_v0_x32 {
10080+ compat_uptr_t name_ptr;
d33d7b00
AM
10081+ uint32_t flags;
10082+};
adc1caaa 10083+
4bf69007
AM
10084+struct vcmd_ctx_dlimit_v0_x32 {
10085+ compat_uptr_t name_ptr;
d33d7b00
AM
10086+ uint32_t space_used; /* used space in kbytes */
10087+ uint32_t space_total; /* maximum space in kbytes */
10088+ uint32_t inodes_used; /* used inodes */
10089+ uint32_t inodes_total; /* maximum inodes */
10090+ uint32_t reserved; /* reserved for root in % */
10091+ uint32_t flags;
10092+};
d337f35e 10093+
4bf69007 10094+#endif /* CONFIG_COMPAT */
d337f35e 10095+
4bf69007 10096+#include <linux/compiler.h>
d337f35e 10097+
4bf69007
AM
10098+extern int vc_add_dlimit(uint32_t, void __user *);
10099+extern int vc_rem_dlimit(uint32_t, void __user *);
d337f35e 10100+
4bf69007
AM
10101+extern int vc_set_dlimit(uint32_t, void __user *);
10102+extern int vc_get_dlimit(uint32_t, void __user *);
d337f35e 10103+
4bf69007 10104+#ifdef CONFIG_COMPAT
d337f35e 10105+
4bf69007
AM
10106+extern int vc_add_dlimit_x32(uint32_t, void __user *);
10107+extern int vc_rem_dlimit_x32(uint32_t, void __user *);
2380c486 10108+
d33d7b00
AM
10109+extern int vc_set_dlimit_x32(uint32_t, void __user *);
10110+extern int vc_get_dlimit_x32(uint32_t, void __user *);
d337f35e 10111+
d33d7b00 10112+#endif /* CONFIG_COMPAT */
d337f35e 10113+
4bf69007 10114+#endif /* _VSERVER_DLIMIT_CMD_H */
f19bd705
AM
10115diff -NurpP --minimal linux-4.4.111/include/linux/vserver/global.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/global.h
10116--- linux-4.4.111/include/linux/vserver/global.h 1970-01-01 00:00:00.000000000 +0000
10117+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/global.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10118@@ -0,0 +1,19 @@
4bf69007
AM
10119+#ifndef _VSERVER_GLOBAL_H
10120+#define _VSERVER_GLOBAL_H
d337f35e 10121+
d337f35e 10122+
d33d7b00
AM
10123+extern atomic_t vx_global_ctotal;
10124+extern atomic_t vx_global_cactive;
d337f35e 10125+
d33d7b00
AM
10126+extern atomic_t nx_global_ctotal;
10127+extern atomic_t nx_global_cactive;
d337f35e 10128+
d33d7b00
AM
10129+extern atomic_t vs_global_nsproxy;
10130+extern atomic_t vs_global_fs;
10131+extern atomic_t vs_global_mnt_ns;
10132+extern atomic_t vs_global_uts_ns;
10133+extern atomic_t vs_global_user_ns;
10134+extern atomic_t vs_global_pid_ns;
d337f35e
JR
10135+
10136+
4bf69007 10137+#endif /* _VSERVER_GLOBAL_H */
f19bd705
AM
10138diff -NurpP --minimal linux-4.4.111/include/linux/vserver/history.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/history.h
10139--- linux-4.4.111/include/linux/vserver/history.h 1970-01-01 00:00:00.000000000 +0000
10140+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/history.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10141@@ -0,0 +1,197 @@
4bf69007
AM
10142+#ifndef _VSERVER_HISTORY_H
10143+#define _VSERVER_HISTORY_H
d337f35e 10144+
d337f35e 10145+
d33d7b00
AM
10146+enum {
10147+ VXH_UNUSED = 0,
10148+ VXH_THROW_OOPS = 1,
d337f35e 10149+
d33d7b00
AM
10150+ VXH_GET_VX_INFO,
10151+ VXH_PUT_VX_INFO,
10152+ VXH_INIT_VX_INFO,
10153+ VXH_SET_VX_INFO,
10154+ VXH_CLR_VX_INFO,
10155+ VXH_CLAIM_VX_INFO,
10156+ VXH_RELEASE_VX_INFO,
10157+ VXH_ALLOC_VX_INFO,
10158+ VXH_DEALLOC_VX_INFO,
10159+ VXH_HASH_VX_INFO,
10160+ VXH_UNHASH_VX_INFO,
10161+ VXH_LOC_VX_INFO,
10162+ VXH_LOOKUP_VX_INFO,
10163+ VXH_CREATE_VX_INFO,
10164+};
d337f35e 10165+
d33d7b00
AM
10166+struct _vxhe_vxi {
10167+ struct vx_info *ptr;
10168+ unsigned xid;
10169+ unsigned usecnt;
10170+ unsigned tasks;
10171+};
d337f35e 10172+
d33d7b00
AM
10173+struct _vxhe_set_clr {
10174+ void *data;
10175+};
d337f35e 10176+
d33d7b00
AM
10177+struct _vxhe_loc_lookup {
10178+ unsigned arg;
10179+};
d337f35e 10180+
d33d7b00
AM
10181+struct _vx_hist_entry {
10182+ void *loc;
10183+ unsigned short seq;
10184+ unsigned short type;
10185+ struct _vxhe_vxi vxi;
10186+ union {
10187+ struct _vxhe_set_clr sc;
10188+ struct _vxhe_loc_lookup ll;
10189+ };
3bac966d 10190+};
d337f35e 10191+
d33d7b00 10192+#ifdef CONFIG_VSERVER_HISTORY
d337f35e 10193+
d33d7b00 10194+extern unsigned volatile int vxh_active;
d337f35e 10195+
d33d7b00 10196+struct _vx_hist_entry *vxh_advance(void *loc);
d337f35e 10197+
d337f35e 10198+
d33d7b00
AM
10199+static inline
10200+void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
10201+{
10202+ entry->vxi.ptr = vxi;
10203+ if (vxi) {
10204+ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
10205+ entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
10206+ entry->vxi.xid = vxi->vx_id;
10207+ }
10208+}
d337f35e 10209+
d337f35e 10210+
d33d7b00 10211+#define __HERE__ current_text_addr()
d337f35e 10212+
d33d7b00
AM
10213+#define __VXH_BODY(__type, __data, __here) \
10214+ struct _vx_hist_entry *entry; \
10215+ \
10216+ preempt_disable(); \
10217+ entry = vxh_advance(__here); \
10218+ __data; \
10219+ entry->type = __type; \
10220+ preempt_enable();
d337f35e 10221+
d337f35e 10222+
d33d7b00 10223+ /* pass vxi only */
d337f35e 10224+
d33d7b00
AM
10225+#define __VXH_SMPL \
10226+ __vxh_copy_vxi(entry, vxi)
d337f35e 10227+
d33d7b00
AM
10228+static inline
10229+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
10230+{
10231+ __VXH_BODY(__type, __VXH_SMPL, __here)
10232+}
d337f35e 10233+
d33d7b00 10234+ /* pass vxi and data (void *) */
d337f35e 10235+
d33d7b00
AM
10236+#define __VXH_DATA \
10237+ __vxh_copy_vxi(entry, vxi); \
10238+ entry->sc.data = data
d337f35e 10239+
d33d7b00
AM
10240+static inline
10241+void __vxh_data(struct vx_info *vxi, void *data,
10242+ int __type, void *__here)
3bac966d 10243+{
d33d7b00 10244+ __VXH_BODY(__type, __VXH_DATA, __here)
3bac966d 10245+}
d337f35e 10246+
d33d7b00 10247+ /* pass vxi and arg (long) */
d337f35e 10248+
d33d7b00
AM
10249+#define __VXH_LONG \
10250+ __vxh_copy_vxi(entry, vxi); \
10251+ entry->ll.arg = arg
d337f35e 10252+
d33d7b00
AM
10253+static inline
10254+void __vxh_long(struct vx_info *vxi, long arg,
10255+ int __type, void *__here)
10256+{
10257+ __VXH_BODY(__type, __VXH_LONG, __here)
10258+}
d337f35e 10259+
d337f35e 10260+
d33d7b00
AM
10261+static inline
10262+void __vxh_throw_oops(void *__here)
10263+{
10264+ __VXH_BODY(VXH_THROW_OOPS, {}, __here);
10265+ /* prevent further acquisition */
10266+ vxh_active = 0;
10267+}
d337f35e 10268+
d337f35e 10269+
d33d7b00 10270+#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
d337f35e 10271+
d33d7b00
AM
10272+#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
10273+#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
d337f35e 10274+
d33d7b00
AM
10275+#define __vxh_init_vx_info(v, d, h) \
10276+ __vxh_data(v, d, VXH_INIT_VX_INFO, h);
10277+#define __vxh_set_vx_info(v, d, h) \
10278+ __vxh_data(v, d, VXH_SET_VX_INFO, h);
10279+#define __vxh_clr_vx_info(v, d, h) \
10280+ __vxh_data(v, d, VXH_CLR_VX_INFO, h);
d337f35e 10281+
d33d7b00
AM
10282+#define __vxh_claim_vx_info(v, d, h) \
10283+ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h);
10284+#define __vxh_release_vx_info(v, d, h) \
10285+ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h);
d337f35e 10286+
d33d7b00
AM
10287+#define vxh_alloc_vx_info(v) \
10288+ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
10289+#define vxh_dealloc_vx_info(v) \
10290+ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
d337f35e 10291+
d33d7b00
AM
10292+#define vxh_hash_vx_info(v) \
10293+ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
10294+#define vxh_unhash_vx_info(v) \
10295+ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
d337f35e 10296+
d33d7b00
AM
10297+#define vxh_loc_vx_info(v, l) \
10298+ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__);
10299+#define vxh_lookup_vx_info(v, l) \
10300+ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__);
10301+#define vxh_create_vx_info(v, l) \
10302+ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__);
d337f35e 10303+
d33d7b00 10304+extern void vxh_dump_history(void);
d337f35e 10305+
d337f35e 10306+
d33d7b00 10307+#else /* CONFIG_VSERVER_HISTORY */
2380c486 10308+
d33d7b00 10309+#define __HERE__ 0
d337f35e 10310+
d33d7b00 10311+#define vxh_throw_oops() do { } while (0)
d337f35e 10312+
d33d7b00
AM
10313+#define __vxh_get_vx_info(v, h) do { } while (0)
10314+#define __vxh_put_vx_info(v, h) do { } while (0)
d337f35e 10315+
d33d7b00
AM
10316+#define __vxh_init_vx_info(v, d, h) do { } while (0)
10317+#define __vxh_set_vx_info(v, d, h) do { } while (0)
10318+#define __vxh_clr_vx_info(v, d, h) do { } while (0)
d337f35e 10319+
d33d7b00
AM
10320+#define __vxh_claim_vx_info(v, d, h) do { } while (0)
10321+#define __vxh_release_vx_info(v, d, h) do { } while (0)
3bac966d 10322+
d33d7b00
AM
10323+#define vxh_alloc_vx_info(v) do { } while (0)
10324+#define vxh_dealloc_vx_info(v) do { } while (0)
d337f35e 10325+
d33d7b00
AM
10326+#define vxh_hash_vx_info(v) do { } while (0)
10327+#define vxh_unhash_vx_info(v) do { } while (0)
d337f35e 10328+
d33d7b00
AM
10329+#define vxh_loc_vx_info(v, l) do { } while (0)
10330+#define vxh_lookup_vx_info(v, l) do { } while (0)
10331+#define vxh_create_vx_info(v, l) do { } while (0)
d337f35e 10332+
d33d7b00 10333+#define vxh_dump_history() do { } while (0)
d337f35e 10334+
d337f35e 10335+
d33d7b00 10336+#endif /* CONFIG_VSERVER_HISTORY */
d337f35e 10337+
4bf69007 10338+#endif /* _VSERVER_HISTORY_H */
f19bd705
AM
10339diff -NurpP --minimal linux-4.4.111/include/linux/vserver/inode.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/inode.h
10340--- linux-4.4.111/include/linux/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
10341+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/inode.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10342@@ -0,0 +1,19 @@
10343+#ifndef _VSERVER_INODE_H
10344+#define _VSERVER_INODE_H
d337f35e 10345+
4bf69007 10346+#include <uapi/vserver/inode.h>
d337f35e 10347+
d337f35e 10348+
d33d7b00
AM
10349+#ifdef CONFIG_VSERVER_PROC_SECURE
10350+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
10351+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10352+#else
10353+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
10354+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
10355+#endif
d337f35e 10356+
d33d7b00 10357+#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1)
d337f35e 10358+
4bf69007 10359+#else /* _VSERVER_INODE_H */
3bac966d 10360+#warning duplicate inclusion
4bf69007 10361+#endif /* _VSERVER_INODE_H */
f19bd705
AM
10362diff -NurpP --minimal linux-4.4.111/include/linux/vserver/inode_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/inode_cmd.h
10363--- linux-4.4.111/include/linux/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
10364+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/inode_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10365@@ -0,0 +1,36 @@
10366+#ifndef _VSERVER_INODE_CMD_H
10367+#define _VSERVER_INODE_CMD_H
d337f35e 10368+
4bf69007 10369+#include <uapi/vserver/inode_cmd.h>
d337f35e 10370+
d337f35e
JR
10371+
10372+
d33d7b00 10373+#ifdef CONFIG_COMPAT
d337f35e 10374+
d33d7b00 10375+#include <asm/compat.h>
d337f35e 10376+
d33d7b00
AM
10377+struct vcmd_ctx_iattr_v1_x32 {
10378+ compat_uptr_t name_ptr;
10379+ uint32_t tag;
10380+ uint32_t flags;
10381+ uint32_t mask;
10382+};
d337f35e 10383+
d33d7b00 10384+#endif /* CONFIG_COMPAT */
d337f35e 10385+
d33d7b00 10386+#include <linux/compiler.h>
d337f35e 10387+
d33d7b00
AM
10388+extern int vc_get_iattr(void __user *);
10389+extern int vc_set_iattr(void __user *);
d337f35e 10390+
d33d7b00
AM
10391+extern int vc_fget_iattr(uint32_t, void __user *);
10392+extern int vc_fset_iattr(uint32_t, void __user *);
d337f35e 10393+
d33d7b00 10394+#ifdef CONFIG_COMPAT
d337f35e 10395+
d33d7b00
AM
10396+extern int vc_get_iattr_x32(void __user *);
10397+extern int vc_set_iattr_x32(void __user *);
d337f35e 10398+
d33d7b00 10399+#endif /* CONFIG_COMPAT */
d337f35e 10400+
4bf69007 10401+#endif /* _VSERVER_INODE_CMD_H */
f19bd705
AM
10402diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit.h
10403--- linux-4.4.111/include/linux/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
10404+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit.h 2018-01-09 16:36:32.000000000 +0000
927ca606 10405@@ -0,0 +1,67 @@
4bf69007
AM
10406+#ifndef _VSERVER_LIMIT_H
10407+#define _VSERVER_LIMIT_H
d337f35e 10408+
4bf69007 10409+#include <uapi/vserver/limit.h>
d337f35e 10410+
d337f35e 10411+
d33d7b00 10412+#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
d337f35e 10413+
d33d7b00 10414+/* keep in sync with CRLIM_INFINITY */
d337f35e 10415+
d33d7b00 10416+#define VLIM_INFINITY (~0ULL)
d337f35e 10417+
d33d7b00
AM
10418+#include <asm/atomic.h>
10419+#include <asm/resource.h>
d337f35e 10420+
d33d7b00
AM
10421+#ifndef RLIM_INFINITY
10422+#warning RLIM_INFINITY is undefined
10423+#endif
d337f35e 10424+
d33d7b00 10425+#define __rlim_val(l, r, v) ((l)->res[r].v)
d337f35e 10426+
d33d7b00
AM
10427+#define __rlim_soft(l, r) __rlim_val(l, r, soft)
10428+#define __rlim_hard(l, r) __rlim_val(l, r, hard)
d337f35e 10429+
d33d7b00
AM
10430+#define __rlim_rcur(l, r) __rlim_val(l, r, rcur)
10431+#define __rlim_rmin(l, r) __rlim_val(l, r, rmin)
10432+#define __rlim_rmax(l, r) __rlim_val(l, r, rmax)
d337f35e 10433+
d33d7b00
AM
10434+#define __rlim_lhit(l, r) __rlim_val(l, r, lhit)
10435+#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r))
d337f35e 10436+
d33d7b00
AM
10437+typedef atomic_long_t rlim_atomic_t;
10438+typedef unsigned long rlim_t;
d337f35e 10439+
d33d7b00
AM
10440+#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r))
10441+#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v)
10442+#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r))
10443+#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r))
10444+#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r))
10445+#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r))
d337f35e 10446+
d337f35e 10447+
d33d7b00
AM
10448+#if (RLIM_INFINITY == VLIM_INFINITY)
10449+#define VX_VLIM(r) ((long long)(long)(r))
10450+#define VX_RLIM(v) ((rlim_t)(v))
3bac966d 10451+#else
d33d7b00
AM
10452+#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
10453+ ? VLIM_INFINITY : (long long)(r))
10454+#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
10455+ ? RLIM_INFINITY : (rlim_t)(v))
3bac966d 10456+#endif
d337f35e 10457+
d33d7b00 10458+struct sysinfo;
d337f35e 10459+
927ca606 10460+#ifdef CONFIG_MEMCG
d33d7b00
AM
10461+void vx_vsi_meminfo(struct sysinfo *);
10462+void vx_vsi_swapinfo(struct sysinfo *);
10463+long vx_vsi_cached(struct sysinfo *);
927ca606
AM
10464+#else /* !CONFIG_MEMCG */
10465+#define vx_vsi_meminfo(s) do { } while (0)
10466+#define vx_vsi_swapinfo(s) do { } while (0)
10467+#define vx_vsi_cached(s) (0L)
10468+#endif /* !CONFIG_MEMCG */
d337f35e 10469+
d33d7b00 10470+#define NUM_LIMITS 24
d337f35e 10471+
4bf69007 10472+#endif /* _VSERVER_LIMIT_H */
f19bd705
AM
10473diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_cmd.h
10474--- linux-4.4.111/include/linux/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
10475+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10476@@ -0,0 +1,35 @@
10477+#ifndef _VSERVER_LIMIT_CMD_H
10478+#define _VSERVER_LIMIT_CMD_H
d337f35e 10479+
4bf69007 10480+#include <uapi/vserver/limit_cmd.h>
d337f35e 10481+
d337f35e 10482+
d33d7b00 10483+#ifdef CONFIG_IA32_EMULATION
d337f35e 10484+
d33d7b00
AM
10485+struct vcmd_ctx_rlimit_v0_x32 {
10486+ uint32_t id;
10487+ uint64_t minimum;
10488+ uint64_t softlimit;
10489+ uint64_t maximum;
10490+} __attribute__ ((packed));
d337f35e 10491+
d33d7b00 10492+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10493+
d33d7b00 10494+#include <linux/compiler.h>
d337f35e 10495+
d33d7b00
AM
10496+extern int vc_get_rlimit_mask(uint32_t, void __user *);
10497+extern int vc_get_rlimit(struct vx_info *, void __user *);
10498+extern int vc_set_rlimit(struct vx_info *, void __user *);
10499+extern int vc_reset_hits(struct vx_info *, void __user *);
10500+extern int vc_reset_minmax(struct vx_info *, void __user *);
d337f35e 10501+
d33d7b00 10502+extern int vc_rlimit_stat(struct vx_info *, void __user *);
d337f35e 10503+
d33d7b00 10504+#ifdef CONFIG_IA32_EMULATION
d337f35e 10505+
d33d7b00
AM
10506+extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
10507+extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
adc1caaa 10508+
d33d7b00 10509+#endif /* CONFIG_IA32_EMULATION */
d337f35e 10510+
4bf69007 10511+#endif /* _VSERVER_LIMIT_CMD_H */
f19bd705
AM
10512diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_def.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_def.h
10513--- linux-4.4.111/include/linux/vserver/limit_def.h 1970-01-01 00:00:00.000000000 +0000
10514+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_def.h 2018-01-09 16:36:32.000000000 +0000
d33d7b00 10515@@ -0,0 +1,47 @@
4bf69007
AM
10516+#ifndef _VSERVER_LIMIT_DEF_H
10517+#define _VSERVER_LIMIT_DEF_H
d337f35e 10518+
d33d7b00
AM
10519+#include <asm/atomic.h>
10520+#include <asm/resource.h>
d337f35e 10521+
d33d7b00 10522+#include "limit.h"
d337f35e 10523+
d337f35e 10524+
d33d7b00
AM
10525+struct _vx_res_limit {
10526+ rlim_t soft; /* Context soft limit */
10527+ rlim_t hard; /* Context hard limit */
d337f35e 10528+
d33d7b00
AM
10529+ rlim_atomic_t rcur; /* Current value */
10530+ rlim_t rmin; /* Context minimum */
10531+ rlim_t rmax; /* Context maximum */
d337f35e 10532+
d33d7b00
AM
10533+ atomic_t lhit; /* Limit hits */
10534+};
d337f35e 10535+
d33d7b00 10536+/* context sub struct */
2380c486 10537+
d33d7b00
AM
10538+struct _vx_limit {
10539+ struct _vx_res_limit res[NUM_LIMITS];
10540+};
adc1caaa 10541+
d33d7b00 10542+#ifdef CONFIG_VSERVER_DEBUG
adc1caaa 10543+
d33d7b00 10544+static inline void __dump_vx_limit(struct _vx_limit *limit)
3bac966d 10545+{
d33d7b00 10546+ int i;
d337f35e 10547+
d33d7b00
AM
10548+ printk("\t_vx_limit:");
10549+ for (i = 0; i < NUM_LIMITS; i++) {
10550+ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
10551+ i, (unsigned long)__rlim_get(limit, i),
10552+ (unsigned long)__rlim_rmin(limit, i),
10553+ (unsigned long)__rlim_rmax(limit, i),
10554+ (long)__rlim_soft(limit, i),
10555+ (long)__rlim_hard(limit, i),
10556+ atomic_read(&__rlim_lhit(limit, i)));
10557+ }
3bac966d 10558+}
d337f35e 10559+
d33d7b00 10560+#endif
d337f35e 10561+
4bf69007 10562+#endif /* _VSERVER_LIMIT_DEF_H */
f19bd705
AM
10563diff -NurpP --minimal linux-4.4.111/include/linux/vserver/limit_int.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_int.h
10564--- linux-4.4.111/include/linux/vserver/limit_int.h 1970-01-01 00:00:00.000000000 +0000
10565+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/limit_int.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10566@@ -0,0 +1,193 @@
10567+#ifndef _VSERVER_LIMIT_INT_H
10568+#define _VSERVER_LIMIT_INT_H
d337f35e 10569+
d33d7b00
AM
10570+#define VXD_RCRES_COND(r) VXD_CBIT(cres, r)
10571+#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r)
d337f35e 10572+
d33d7b00 10573+extern const char *vlimit_name[NUM_LIMITS];
2380c486 10574+
d33d7b00
AM
10575+static inline void __vx_acc_cres(struct vx_info *vxi,
10576+ int res, int dir, void *_data, char *_file, int _line)
10577+{
10578+ if (VXD_RCRES_COND(res))
10579+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
10580+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10581+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10582+ (dir > 0) ? "++" : "--", _data, _file, _line);
10583+ if (!vxi)
10584+ return;
d337f35e 10585+
d33d7b00
AM
10586+ if (dir > 0)
10587+ __rlim_inc(&vxi->limit, res);
10588+ else
10589+ __rlim_dec(&vxi->limit, res);
10590+}
d337f35e 10591+
d33d7b00
AM
10592+static inline void __vx_add_cres(struct vx_info *vxi,
10593+ int res, int amount, void *_data, char *_file, int _line)
10594+{
10595+ if (VXD_RCRES_COND(res))
10596+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
10597+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10598+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10599+ amount, _data, _file, _line);
10600+ if (amount == 0)
10601+ return;
10602+ if (!vxi)
10603+ return;
10604+ __rlim_add(&vxi->limit, res, amount);
10605+}
d337f35e 10606+
3bac966d 10607+static inline
d33d7b00 10608+int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10609+{
d33d7b00 10610+ int cond = (value > __rlim_rmax(limit, res));
d337f35e 10611+
d33d7b00
AM
10612+ if (cond)
10613+ __rlim_rmax(limit, res) = value;
10614+ return cond;
3bac966d 10615+}
d337f35e 10616+
3bac966d 10617+static inline
d33d7b00 10618+int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10619+{
d33d7b00 10620+ int cond = (value < __rlim_rmin(limit, res));
d337f35e 10621+
d33d7b00
AM
10622+ if (cond)
10623+ __rlim_rmin(limit, res) = value;
10624+ return cond;
3bac966d 10625+}
d337f35e 10626+
3bac966d 10627+static inline
d33d7b00 10628+void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
3bac966d 10629+{
d33d7b00
AM
10630+ if (!__vx_cres_adjust_max(limit, res, value))
10631+ __vx_cres_adjust_min(limit, res, value);
3bac966d 10632+}
d337f35e 10633+
2380c486 10634+
d33d7b00
AM
10635+/* return values:
10636+ +1 ... no limit hit
10637+ -1 ... over soft limit
10638+ 0 ... over hard limit */
d337f35e 10639+
d33d7b00
AM
10640+static inline int __vx_cres_avail(struct vx_info *vxi,
10641+ int res, int num, char *_file, int _line)
3bac966d 10642+{
d33d7b00
AM
10643+ struct _vx_limit *limit;
10644+ rlim_t value;
d337f35e 10645+
d33d7b00
AM
10646+ if (VXD_RLIMIT_COND(res))
10647+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
10648+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
10649+ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
10650+ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
10651+ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
10652+ num, _file, _line);
10653+ if (!vxi)
3bac966d 10654+ return 1;
d337f35e 10655+
d33d7b00
AM
10656+ limit = &vxi->limit;
10657+ value = __rlim_get(limit, res);
d337f35e 10658+
d33d7b00
AM
10659+ if (!__vx_cres_adjust_max(limit, res, value))
10660+ __vx_cres_adjust_min(limit, res, value);
d337f35e 10661+
d33d7b00 10662+ if (num == 0)
3bac966d 10663+ return 1;
d337f35e 10664+
d33d7b00
AM
10665+ if (__rlim_soft(limit, res) == RLIM_INFINITY)
10666+ return -1;
10667+ if (value + num <= __rlim_soft(limit, res))
10668+ return -1;
d337f35e 10669+
d33d7b00 10670+ if (__rlim_hard(limit, res) == RLIM_INFINITY)
3bac966d 10671+ return 1;
d33d7b00 10672+ if (value + num <= __rlim_hard(limit, res))
3bac966d 10673+ return 1;
d33d7b00
AM
10674+
10675+ __rlim_hit(limit, res);
3bac966d
AM
10676+ return 0;
10677+}
d337f35e 10678+
d337f35e 10679+
d33d7b00 10680+static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
d337f35e 10681+
3bac966d 10682+static inline
d33d7b00 10683+rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
3bac966d 10684+{
d33d7b00
AM
10685+ rlim_t value, sum = 0;
10686+ int res;
d337f35e 10687+
d33d7b00
AM
10688+ while ((res = *array++)) {
10689+ value = __rlim_get(limit, res);
10690+ __vx_cres_fixup(limit, res, value);
10691+ sum += value;
10692+ }
10693+ return sum;
3bac966d 10694+}
d337f35e 10695+
3bac966d 10696+static inline
d33d7b00 10697+rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
3bac966d 10698+{
d33d7b00
AM
10699+ rlim_t value = __vx_cres_array_sum(limit, array + 1);
10700+ int res = *array;
d337f35e 10701+
d33d7b00
AM
10702+ if (value == __rlim_get(limit, res))
10703+ return value;
10704+
10705+ __rlim_set(limit, res, value);
10706+ /* now adjust min/max */
10707+ if (!__vx_cres_adjust_max(limit, res, value))
10708+ __vx_cres_adjust_min(limit, res, value);
10709+
10710+ return value;
3bac966d 10711+}
d337f35e 10712+
d33d7b00
AM
10713+static inline int __vx_cres_array_avail(struct vx_info *vxi,
10714+ const int *array, int num, char *_file, int _line)
3bac966d 10715+{
d33d7b00
AM
10716+ struct _vx_limit *limit;
10717+ rlim_t value = 0;
10718+ int res;
10719+
10720+ if (num == 0)
3bac966d 10721+ return 1;
d33d7b00 10722+ if (!vxi)
3bac966d 10723+ return 1;
d337f35e 10724+
d33d7b00
AM
10725+ limit = &vxi->limit;
10726+ res = *array;
10727+ value = __vx_cres_array_sum(limit, array + 1);
d337f35e 10728+
d33d7b00
AM
10729+ __rlim_set(limit, res, value);
10730+ __vx_cres_fixup(limit, res, value);
10731+
10732+ return __vx_cres_avail(vxi, res, num, _file, _line);
3bac966d 10733+}
d337f35e 10734+
d337f35e 10735+
d33d7b00 10736+static inline void vx_limit_fixup(struct _vx_limit *limit, int id)
3bac966d 10737+{
d33d7b00
AM
10738+ rlim_t value;
10739+ int res;
d337f35e 10740+
d33d7b00
AM
10741+ /* complex resources first */
10742+ if ((id < 0) || (id == RLIMIT_RSS))
10743+ __vx_cres_array_fixup(limit, VLA_RSS);
d337f35e 10744+
d33d7b00
AM
10745+ for (res = 0; res < NUM_LIMITS; res++) {
10746+ if ((id > 0) && (res != id))
10747+ continue;
10748+
10749+ value = __rlim_get(limit, res);
10750+ __vx_cres_fixup(limit, res, value);
10751+
10752+ /* not supposed to happen, maybe warn? */
10753+ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
10754+ __rlim_rmax(limit, res) = __rlim_hard(limit, res);
10755+ }
3bac966d 10756+}
d337f35e
JR
10757+
10758+
4bf69007 10759+#endif /* _VSERVER_LIMIT_INT_H */
f19bd705
AM
10760diff -NurpP --minimal linux-4.4.111/include/linux/vserver/monitor.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/monitor.h
10761--- linux-4.4.111/include/linux/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
10762+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/monitor.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10763@@ -0,0 +1,6 @@
10764+#ifndef _VSERVER_MONITOR_H
10765+#define _VSERVER_MONITOR_H
d337f35e 10766+
4bf69007 10767+#include <uapi/vserver/monitor.h>
d337f35e 10768+
4bf69007 10769+#endif /* _VSERVER_MONITOR_H */
f19bd705
AM
10770diff -NurpP --minimal linux-4.4.111/include/linux/vserver/network.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/network.h
10771--- linux-4.4.111/include/linux/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
10772+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/network.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10773@@ -0,0 +1,76 @@
10774+#ifndef _VSERVER_NETWORK_H
10775+#define _VSERVER_NETWORK_H
d337f35e 10776+
d337f35e 10777+
4bf69007
AM
10778+#include <linux/list.h>
10779+#include <linux/spinlock.h>
10780+#include <linux/rcupdate.h>
10781+#include <linux/in.h>
10782+#include <linux/in6.h>
10783+#include <asm/atomic.h>
10784+#include <uapi/vserver/network.h>
d337f35e 10785+
4bf69007
AM
10786+struct nx_addr_v4 {
10787+ struct nx_addr_v4 *next;
10788+ struct in_addr ip[2];
10789+ struct in_addr mask;
10790+ uint16_t type;
10791+ uint16_t flags;
10792+};
d337f35e 10793+
4bf69007
AM
10794+struct nx_addr_v6 {
10795+ struct nx_addr_v6 *next;
10796+ struct in6_addr ip;
10797+ struct in6_addr mask;
10798+ uint32_t prefix;
10799+ uint16_t type;
10800+ uint16_t flags;
10801+};
d337f35e 10802+
4bf69007
AM
10803+struct nx_info {
10804+ struct hlist_node nx_hlist; /* linked list of nxinfos */
61333608 10805+ vnid_t nx_id; /* vnet id */
4bf69007
AM
10806+ atomic_t nx_usecnt; /* usage count */
10807+ atomic_t nx_tasks; /* tasks count */
10808+ int nx_state; /* context state */
d337f35e 10809+
4bf69007
AM
10810+ uint64_t nx_flags; /* network flag word */
10811+ uint64_t nx_ncaps; /* network capabilities */
d337f35e 10812+
4bf69007
AM
10813+ spinlock_t addr_lock; /* protect address changes */
10814+ struct in_addr v4_lback; /* Loopback address */
10815+ struct in_addr v4_bcast; /* Broadcast address */
10816+ struct nx_addr_v4 v4; /* First/Single ipv4 address */
10817+#ifdef CONFIG_IPV6
10818+ struct nx_addr_v6 v6; /* First/Single ipv6 address */
10819+#endif
10820+ char nx_name[65]; /* network context name */
d33d7b00 10821+};
d337f35e 10822+
d337f35e 10823+
4bf69007 10824+/* status flags */
d337f35e 10825+
4bf69007
AM
10826+#define NXS_HASHED 0x0001
10827+#define NXS_SHUTDOWN 0x0100
10828+#define NXS_RELEASED 0x8000
d337f35e 10829+
4bf69007 10830+extern struct nx_info *lookup_nx_info(int);
d337f35e 10831+
4bf69007 10832+extern int get_nid_list(int, unsigned int *, int);
61333608 10833+extern int nid_is_hashed(vnid_t);
d337f35e 10834+
4bf69007 10835+extern int nx_migrate_task(struct task_struct *, struct nx_info *);
d337f35e 10836+
4bf69007 10837+extern long vs_net_change(struct nx_info *, unsigned int);
d337f35e 10838+
4bf69007 10839+struct sock;
d337f35e 10840+
d337f35e 10841+
4bf69007
AM
10842+#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE)
10843+#ifdef CONFIG_IPV6
10844+#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE)
10845+#else
10846+#define NX_IPV6(n) (0)
10847+#endif
d337f35e 10848+
4bf69007 10849+#endif /* _VSERVER_NETWORK_H */
f19bd705
AM
10850diff -NurpP --minimal linux-4.4.111/include/linux/vserver/network_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/network_cmd.h
10851--- linux-4.4.111/include/linux/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
10852+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/network_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10853@@ -0,0 +1,37 @@
10854+#ifndef _VSERVER_NETWORK_CMD_H
10855+#define _VSERVER_NETWORK_CMD_H
d337f35e 10856+
4bf69007 10857+#include <uapi/vserver/network_cmd.h>
d337f35e 10858+
4bf69007 10859+extern int vc_task_nid(uint32_t);
d337f35e 10860+
4bf69007 10861+extern int vc_nx_info(struct nx_info *, void __user *);
d337f35e 10862+
4bf69007
AM
10863+extern int vc_net_create(uint32_t, void __user *);
10864+extern int vc_net_migrate(struct nx_info *, void __user *);
d337f35e 10865+
4bf69007
AM
10866+extern int vc_net_add(struct nx_info *, void __user *);
10867+extern int vc_net_remove(struct nx_info *, void __user *);
d337f35e 10868+
4bf69007
AM
10869+extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *);
10870+extern int vc_net_add_ipv4(struct nx_info *, void __user *);
d337f35e 10871+
4bf69007
AM
10872+extern int vc_net_rem_ipv4_v1(struct nx_info *, void __user *);
10873+extern int vc_net_rem_ipv4(struct nx_info *, void __user *);
d337f35e 10874+
4bf69007
AM
10875+extern int vc_net_add_ipv6(struct nx_info *, void __user *);
10876+extern int vc_net_remove_ipv6(struct nx_info *, void __user *);
d337f35e 10877+
4bf69007
AM
10878+extern int vc_add_match_ipv4(struct nx_info *, void __user *);
10879+extern int vc_get_match_ipv4(struct nx_info *, void __user *);
d33d7b00 10880+
4bf69007
AM
10881+extern int vc_add_match_ipv6(struct nx_info *, void __user *);
10882+extern int vc_get_match_ipv6(struct nx_info *, void __user *);
d337f35e 10883+
4bf69007
AM
10884+extern int vc_get_nflags(struct nx_info *, void __user *);
10885+extern int vc_set_nflags(struct nx_info *, void __user *);
d337f35e 10886+
4bf69007
AM
10887+extern int vc_get_ncaps(struct nx_info *, void __user *);
10888+extern int vc_set_ncaps(struct nx_info *, void __user *);
d337f35e 10889+
4bf69007 10890+#endif /* _VSERVER_CONTEXT_CMD_H */
f19bd705
AM
10891diff -NurpP --minimal linux-4.4.111/include/linux/vserver/percpu.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/percpu.h
10892--- linux-4.4.111/include/linux/vserver/percpu.h 1970-01-01 00:00:00.000000000 +0000
10893+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/percpu.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10894@@ -0,0 +1,14 @@
10895+#ifndef _VSERVER_PERCPU_H
10896+#define _VSERVER_PERCPU_H
d337f35e 10897+
4bf69007
AM
10898+#include "cvirt_def.h"
10899+#include "sched_def.h"
d337f35e 10900+
4bf69007
AM
10901+struct _vx_percpu {
10902+ struct _vx_cvirt_pc cvirt;
10903+ struct _vx_sched_pc sched;
10904+};
9795bf04 10905+
4bf69007 10906+#define PERCPU_PERCTX (sizeof(struct _vx_percpu))
d337f35e 10907+
4bf69007 10908+#endif /* _VSERVER_PERCPU_H */
f19bd705
AM
10909diff -NurpP --minimal linux-4.4.111/include/linux/vserver/pid.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/pid.h
10910--- linux-4.4.111/include/linux/vserver/pid.h 1970-01-01 00:00:00.000000000 +0000
10911+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/pid.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10912@@ -0,0 +1,51 @@
10913+#ifndef _VSERVER_PID_H
10914+#define _VSERVER_PID_H
d337f35e 10915+
4bf69007 10916+/* pid faking stuff */
d337f35e 10917+
4bf69007
AM
10918+#define vx_info_map_pid(v, p) \
10919+ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__)
10920+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
10921+#define vx_map_pid(p) vx_info_map_pid(current_vx_info(), p)
10922+#define vx_map_tgid(p) vx_map_pid(p)
d337f35e 10923+
4bf69007
AM
10924+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
10925+ const char *func, const char *file, int line)
10926+{
10927+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
10928+ vxfprintk(VXD_CBIT(cvirt, 2),
10929+ "vx_map_tgid: %p/%llx: %d -> %d",
10930+ vxi, (long long)vxi->vx_flags, pid,
10931+ (pid && pid == vxi->vx_initpid) ? 1 : pid,
10932+ func, file, line);
10933+ if (pid == 0)
10934+ return 0;
10935+ if (pid == vxi->vx_initpid)
10936+ return 1;
10937+ }
10938+ return pid;
10939+}
d337f35e 10940+
4bf69007
AM
10941+#define vx_info_rmap_pid(v, p) \
10942+ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__)
10943+#define vx_rmap_pid(p) vx_info_rmap_pid(current_vx_info(), p)
10944+#define vx_rmap_tgid(p) vx_rmap_pid(p)
d337f35e 10945+
4bf69007
AM
10946+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
10947+ const char *func, const char *file, int line)
10948+{
10949+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
10950+ vxfprintk(VXD_CBIT(cvirt, 2),
10951+ "vx_rmap_tgid: %p/%llx: %d -> %d",
10952+ vxi, (long long)vxi->vx_flags, pid,
10953+ (pid == 1) ? vxi->vx_initpid : pid,
10954+ func, file, line);
10955+ if ((pid == 1) && vxi->vx_initpid)
10956+ return vxi->vx_initpid;
10957+ if (pid == vxi->vx_initpid)
10958+ return ~0U;
10959+ }
10960+ return pid;
10961+}
d337f35e 10962+
4bf69007 10963+#endif
f19bd705
AM
10964diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched.h
10965--- linux-4.4.111/include/linux/vserver/sched.h 1970-01-01 00:00:00.000000000 +0000
10966+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10967@@ -0,0 +1,23 @@
10968+#ifndef _VSERVER_SCHED_H
10969+#define _VSERVER_SCHED_H
d337f35e 10970+
d337f35e 10971+
d33d7b00 10972+#ifdef __KERNEL__
d337f35e 10973+
4bf69007 10974+struct timespec;
d337f35e 10975+
4bf69007 10976+void vx_vsi_uptime(struct timespec *, struct timespec *);
d337f35e
JR
10977+
10978+
4bf69007 10979+struct vx_info;
d337f35e 10980+
4bf69007 10981+void vx_update_load(struct vx_info *);
d337f35e 10982+
d337f35e 10983+
4bf69007
AM
10984+void vx_update_sched_param(struct _vx_sched *sched,
10985+ struct _vx_sched_pc *sched_pc);
d337f35e 10986+
4bf69007
AM
10987+#endif /* __KERNEL__ */
10988+#else /* _VSERVER_SCHED_H */
10989+#warning duplicate inclusion
10990+#endif /* _VSERVER_SCHED_H */
f19bd705
AM
10991diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched_cmd.h
10992--- linux-4.4.111/include/linux/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
10993+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
10994@@ -0,0 +1,11 @@
10995+#ifndef _VSERVER_SCHED_CMD_H
10996+#define _VSERVER_SCHED_CMD_H
2380c486 10997+
2380c486 10998+
4bf69007
AM
10999+#include <linux/compiler.h>
11000+#include <uapi/vserver/sched_cmd.h>
d337f35e 11001+
4bf69007
AM
11002+extern int vc_set_prio_bias(struct vx_info *, void __user *);
11003+extern int vc_get_prio_bias(struct vx_info *, void __user *);
d337f35e 11004+
4bf69007 11005+#endif /* _VSERVER_SCHED_CMD_H */
f19bd705
AM
11006diff -NurpP --minimal linux-4.4.111/include/linux/vserver/sched_def.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched_def.h
11007--- linux-4.4.111/include/linux/vserver/sched_def.h 1970-01-01 00:00:00.000000000 +0000
11008+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/sched_def.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11009@@ -0,0 +1,38 @@
11010+#ifndef _VSERVER_SCHED_DEF_H
11011+#define _VSERVER_SCHED_DEF_H
d33d7b00 11012+
4bf69007
AM
11013+#include <linux/spinlock.h>
11014+#include <linux/jiffies.h>
11015+#include <linux/cpumask.h>
11016+#include <asm/atomic.h>
11017+#include <asm/param.h>
d33d7b00 11018+
d337f35e 11019+
4bf69007 11020+/* context sub struct */
d337f35e 11021+
4bf69007
AM
11022+struct _vx_sched {
11023+ int prio_bias; /* bias offset for priority */
d337f35e 11024+
4bf69007
AM
11025+ cpumask_t update; /* CPUs which should update */
11026+};
d337f35e 11027+
4bf69007
AM
11028+struct _vx_sched_pc {
11029+ int prio_bias; /* bias offset for priority */
d337f35e 11030+
4bf69007
AM
11031+ uint64_t user_ticks; /* token tick events */
11032+ uint64_t sys_ticks; /* token tick events */
11033+ uint64_t hold_ticks; /* token ticks paused */
11034+};
d337f35e 11035+
d337f35e 11036+
4bf69007 11037+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 11038+
4bf69007
AM
11039+static inline void __dump_vx_sched(struct _vx_sched *sched)
11040+{
11041+ printk("\t_vx_sched:\n");
11042+ printk("\t priority = %4d\n", sched->prio_bias);
11043+}
d337f35e 11044+
4bf69007
AM
11045+#endif
11046+
11047+#endif /* _VSERVER_SCHED_DEF_H */
f19bd705
AM
11048diff -NurpP --minimal linux-4.4.111/include/linux/vserver/signal.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/signal.h
11049--- linux-4.4.111/include/linux/vserver/signal.h 1970-01-01 00:00:00.000000000 +0000
11050+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/signal.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11051@@ -0,0 +1,14 @@
11052+#ifndef _VSERVER_SIGNAL_H
11053+#define _VSERVER_SIGNAL_H
d337f35e 11054+
d337f35e 11055+
d33d7b00 11056+#ifdef __KERNEL__
4bf69007
AM
11057+
11058+struct vx_info;
11059+
11060+int vx_info_kill(struct vx_info *, int, int);
d337f35e 11061+
d33d7b00 11062+#endif /* __KERNEL__ */
4bf69007
AM
11063+#else /* _VSERVER_SIGNAL_H */
11064+#warning duplicate inclusion
11065+#endif /* _VSERVER_SIGNAL_H */
f19bd705
AM
11066diff -NurpP --minimal linux-4.4.111/include/linux/vserver/signal_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/signal_cmd.h
11067--- linux-4.4.111/include/linux/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
11068+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/signal_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11069@@ -0,0 +1,14 @@
11070+#ifndef _VSERVER_SIGNAL_CMD_H
11071+#define _VSERVER_SIGNAL_CMD_H
d337f35e 11072+
4bf69007 11073+#include <uapi/vserver/signal_cmd.h>
d337f35e 11074+
d337f35e 11075+
4bf69007
AM
11076+extern int vc_ctx_kill(struct vx_info *, void __user *);
11077+extern int vc_wait_exit(struct vx_info *, void __user *);
d337f35e
JR
11078+
11079+
4bf69007
AM
11080+extern int vc_get_pflags(uint32_t pid, void __user *);
11081+extern int vc_set_pflags(uint32_t pid, void __user *);
adc1caaa 11082+
4bf69007 11083+#endif /* _VSERVER_SIGNAL_CMD_H */
f19bd705
AM
11084diff -NurpP --minimal linux-4.4.111/include/linux/vserver/space.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/space.h
11085--- linux-4.4.111/include/linux/vserver/space.h 1970-01-01 00:00:00.000000000 +0000
11086+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/space.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11087@@ -0,0 +1,12 @@
11088+#ifndef _VSERVER_SPACE_H
11089+#define _VSERVER_SPACE_H
d337f35e 11090+
4bf69007 11091+#include <linux/types.h>
d337f35e 11092+
4bf69007 11093+struct vx_info;
d337f35e 11094+
4bf69007 11095+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index);
9f7054f1 11096+
4bf69007
AM
11097+#else /* _VSERVER_SPACE_H */
11098+#warning duplicate inclusion
11099+#endif /* _VSERVER_SPACE_H */
f19bd705
AM
11100diff -NurpP --minimal linux-4.4.111/include/linux/vserver/space_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/space_cmd.h
11101--- linux-4.4.111/include/linux/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
11102+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/space_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11103@@ -0,0 +1,13 @@
11104+#ifndef _VSERVER_SPACE_CMD_H
11105+#define _VSERVER_SPACE_CMD_H
9f7054f1 11106+
4bf69007 11107+#include <uapi/vserver/space_cmd.h>
d337f35e 11108+
d337f35e 11109+
4bf69007
AM
11110+extern int vc_enter_space_v1(struct vx_info *, void __user *);
11111+extern int vc_set_space_v1(struct vx_info *, void __user *);
11112+extern int vc_enter_space(struct vx_info *, void __user *);
11113+extern int vc_set_space(struct vx_info *, void __user *);
11114+extern int vc_get_space_mask(void __user *, int);
d337f35e 11115+
4bf69007 11116+#endif /* _VSERVER_SPACE_CMD_H */
f19bd705
AM
11117diff -NurpP --minimal linux-4.4.111/include/linux/vserver/switch.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/switch.h
11118--- linux-4.4.111/include/linux/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
11119+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/switch.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11120@@ -0,0 +1,8 @@
11121+#ifndef _VSERVER_SWITCH_H
11122+#define _VSERVER_SWITCH_H
d337f35e 11123+
d337f35e 11124+
4bf69007
AM
11125+#include <linux/errno.h>
11126+#include <uapi/vserver/switch.h>
2380c486 11127+
4bf69007 11128+#endif /* _VSERVER_SWITCH_H */
f19bd705
AM
11129diff -NurpP --minimal linux-4.4.111/include/linux/vserver/tag.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/tag.h
11130--- linux-4.4.111/include/linux/vserver/tag.h 1970-01-01 00:00:00.000000000 +0000
11131+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/tag.h 2018-01-09 16:36:32.000000000 +0000
a4a22af8 11132@@ -0,0 +1,160 @@
4bf69007
AM
11133+#ifndef _DX_TAG_H
11134+#define _DX_TAG_H
d337f35e 11135+
4bf69007 11136+#include <linux/types.h>
a4a22af8 11137+#include <linux/uidgid.h>
d337f35e 11138+
d337f35e 11139+
4bf69007 11140+#define DX_TAG(in) (IS_TAGGED(in))
9f7054f1 11141+
d337f35e 11142+
4bf69007
AM
11143+#ifdef CONFIG_TAG_NFSD
11144+#define DX_TAG_NFSD 1
11145+#else
11146+#define DX_TAG_NFSD 0
11147+#endif
2380c486 11148+
2380c486 11149+
4bf69007 11150+#ifdef CONFIG_TAGGING_NONE
d337f35e 11151+
4bf69007
AM
11152+#define MAX_UID 0xFFFFFFFF
11153+#define MAX_GID 0xFFFFFFFF
d337f35e 11154+
4bf69007 11155+#define INOTAG_TAG(cond, uid, gid, tag) (0)
d337f35e 11156+
4bf69007
AM
11157+#define TAGINO_UID(cond, uid, tag) (uid)
11158+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11159+
4bf69007 11160+#endif
d337f35e 11161+
d337f35e 11162+
4bf69007 11163+#ifdef CONFIG_TAGGING_GID16
d337f35e 11164+
4bf69007
AM
11165+#define MAX_UID 0xFFFFFFFF
11166+#define MAX_GID 0x0000FFFF
d337f35e 11167+
4bf69007
AM
11168+#define INOTAG_TAG(cond, uid, gid, tag) \
11169+ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
d337f35e 11170+
4bf69007
AM
11171+#define TAGINO_UID(cond, uid, tag) (uid)
11172+#define TAGINO_GID(cond, gid, tag) \
11173+ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
d337f35e 11174+
4bf69007 11175+#endif
d337f35e 11176+
d337f35e 11177+
4bf69007 11178+#ifdef CONFIG_TAGGING_ID24
d337f35e 11179+
4bf69007
AM
11180+#define MAX_UID 0x00FFFFFF
11181+#define MAX_GID 0x00FFFFFF
d337f35e 11182+
4bf69007
AM
11183+#define INOTAG_TAG(cond, uid, gid, tag) \
11184+ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
d337f35e 11185+
4bf69007
AM
11186+#define TAGINO_UID(cond, uid, tag) \
11187+ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
11188+#define TAGINO_GID(cond, gid, tag) \
11189+ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
d337f35e 11190+
4bf69007 11191+#endif
d337f35e 11192+
d337f35e 11193+
4bf69007 11194+#ifdef CONFIG_TAGGING_UID16
d337f35e 11195+
4bf69007
AM
11196+#define MAX_UID 0x0000FFFF
11197+#define MAX_GID 0xFFFFFFFF
3bac966d 11198+
4bf69007
AM
11199+#define INOTAG_TAG(cond, uid, gid, tag) \
11200+ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
d337f35e 11201+
4bf69007
AM
11202+#define TAGINO_UID(cond, uid, tag) \
11203+ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
11204+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11205+
d33d7b00 11206+#endif
d337f35e
JR
11207+
11208+
4bf69007 11209+#ifdef CONFIG_TAGGING_INTERN
d337f35e 11210+
4bf69007
AM
11211+#define MAX_UID 0xFFFFFFFF
11212+#define MAX_GID 0xFFFFFFFF
d337f35e 11213+
4bf69007
AM
11214+#define INOTAG_TAG(cond, uid, gid, tag) \
11215+ ((cond) ? (tag) : 0)
d337f35e 11216+
4bf69007
AM
11217+#define TAGINO_UID(cond, uid, tag) (uid)
11218+#define TAGINO_GID(cond, gid, tag) (gid)
d337f35e 11219+
4bf69007 11220+#endif
d337f35e 11221+
d337f35e 11222+
4bf69007
AM
11223+#ifndef CONFIG_TAGGING_NONE
11224+#define dx_current_fstag(sb) \
11225+ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0)
11226+#else
11227+#define dx_current_fstag(sb) (0)
11228+#endif
d337f35e 11229+
4bf69007
AM
11230+#ifndef CONFIG_TAGGING_INTERN
11231+#define TAGINO_TAG(cond, tag) (0)
11232+#else
11233+#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
11234+#endif
d337f35e 11235+
a4a22af8
AM
11236+#define TAGINO_KUID(cond, kuid, ktag) \
11237+ KUIDT_INIT(TAGINO_UID(cond, __kuid_val(kuid), __ktag_val(ktag)))
11238+#define TAGINO_KGID(cond, kgid, ktag) \
11239+ KGIDT_INIT(TAGINO_GID(cond, __kgid_val(kgid), __ktag_val(ktag)))
11240+#define TAGINO_KTAG(cond, ktag) \
11241+ KTAGT_INIT(TAGINO_TAG(cond, __ktag_val(ktag)))
11242+
11243+
4bf69007
AM
11244+#define INOTAG_UID(cond, uid, gid) \
11245+ ((cond) ? ((uid) & MAX_UID) : (uid))
11246+#define INOTAG_GID(cond, uid, gid) \
11247+ ((cond) ? ((gid) & MAX_GID) : (gid))
d337f35e 11248+
a4a22af8
AM
11249+#define INOTAG_KUID(cond, kuid, kgid) \
11250+ KUIDT_INIT(INOTAG_UID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11251+#define INOTAG_KGID(cond, kuid, kgid) \
11252+ KGIDT_INIT(INOTAG_GID(cond, __kuid_val(kuid), __kgid_val(kgid)))
11253+#define INOTAG_KTAG(cond, kuid, kgid, ktag) \
11254+ KTAGT_INIT(INOTAG_TAG(cond, \
11255+ __kuid_val(kuid), __kgid_val(kgid), __ktag_val(ktag)))
11256+
d337f35e 11257+
4bf69007 11258+static inline uid_t dx_map_uid(uid_t uid)
3bac966d 11259+{
4bf69007
AM
11260+ if ((uid > MAX_UID) && (uid != -1))
11261+ uid = -2;
11262+ return (uid & MAX_UID);
d33d7b00 11263+}
d337f35e 11264+
4bf69007
AM
11265+static inline gid_t dx_map_gid(gid_t gid)
11266+{
11267+ if ((gid > MAX_GID) && (gid != -1))
11268+ gid = -2;
11269+ return (gid & MAX_GID);
11270+}
d337f35e 11271+
4bf69007
AM
11272+struct peer_tag {
11273+ int32_t xid;
11274+ int32_t nid;
d33d7b00 11275+};
d337f35e 11276+
4bf69007 11277+#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK))
2380c486 11278+
61333608 11279+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 11280+ unsigned long *flags);
d337f35e 11281+
4bf69007 11282+#ifdef CONFIG_PROPAGATE
d337f35e 11283+
4bf69007 11284+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
d337f35e 11285+
4bf69007 11286+#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i)
d337f35e 11287+
4bf69007
AM
11288+#else
11289+#define dx_propagate_tag(n, i) do { } while (0)
11290+#endif
d337f35e 11291+
4bf69007 11292+#endif /* _DX_TAG_H */
f19bd705
AM
11293diff -NurpP --minimal linux-4.4.111/include/linux/vserver/tag_cmd.h linux-4.4.111-vs2.3.9.1/include/linux/vserver/tag_cmd.h
11294--- linux-4.4.111/include/linux/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
11295+++ linux-4.4.111-vs2.3.9.1/include/linux/vserver/tag_cmd.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11296@@ -0,0 +1,10 @@
11297+#ifndef _VSERVER_TAG_CMD_H
11298+#define _VSERVER_TAG_CMD_H
d337f35e 11299+
4bf69007 11300+#include <uapi/vserver/tag_cmd.h>
d337f35e 11301+
4bf69007 11302+extern int vc_task_tag(uint32_t);
3bac966d 11303+
4bf69007 11304+extern int vc_tag_migrate(uint32_t);
3bac966d 11305+
4bf69007 11306+#endif /* _VSERVER_TAG_CMD_H */
f19bd705
AM
11307diff -NurpP --minimal linux-4.4.111/include/net/addrconf.h linux-4.4.111-vs2.3.9.1/include/net/addrconf.h
11308--- linux-4.4.111/include/net/addrconf.h 2018-01-11 07:57:48.000000000 +0000
11309+++ linux-4.4.111-vs2.3.9.1/include/net/addrconf.h 2018-01-09 16:36:32.000000000 +0000
927ca606 11310@@ -84,7 +84,7 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str
c2e5f7c8
JR
11311
11312 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
11313 const struct in6_addr *daddr, unsigned int srcprefs,
11314- struct in6_addr *saddr);
11315+ struct in6_addr *saddr, struct nx_info *nxi);
11316 int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
bb20add7 11317 u32 banned_flags);
c2e5f7c8 11318 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
f19bd705
AM
11319diff -NurpP --minimal linux-4.4.111/include/net/af_unix.h linux-4.4.111-vs2.3.9.1/include/net/af_unix.h
11320--- linux-4.4.111/include/net/af_unix.h 2018-01-11 07:57:48.000000000 +0000
11321+++ linux-4.4.111-vs2.3.9.1/include/net/af_unix.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11322@@ -4,6 +4,7 @@
11323 #include <linux/socket.h>
11324 #include <linux/un.h>
11325 #include <linux/mutex.h>
927ca606 11326+// #include <linux/vs_base.h>
4bf69007
AM
11327 #include <net/sock.h>
11328
927ca606 11329 void unix_inflight(struct user_struct *user, struct file *fp);
f19bd705
AM
11330diff -NurpP --minimal linux-4.4.111/include/net/inet_timewait_sock.h linux-4.4.111-vs2.3.9.1/include/net/inet_timewait_sock.h
11331--- linux-4.4.111/include/net/inet_timewait_sock.h 2016-07-05 04:15:11.000000000 +0000
11332+++ linux-4.4.111-vs2.3.9.1/include/net/inet_timewait_sock.h 2018-01-09 16:40:17.000000000 +0000
927ca606 11333@@ -71,6 +71,10 @@ struct inet_timewait_sock {
b00e13aa 11334 #define tw_num __tw_common.skc_num
927ca606
AM
11335 #define tw_cookie __tw_common.skc_cookie
11336 #define tw_dr __tw_common.skc_tw_dr
4bf69007
AM
11337+#define tw_xid __tw_common.skc_xid
11338+#define tw_vx_info __tw_common.skc_vx_info
11339+#define tw_nid __tw_common.skc_nid
11340+#define tw_nx_info __tw_common.skc_nx_info
b00e13aa 11341
4bf69007
AM
11342 int tw_timeout;
11343 volatile unsigned char tw_substate;
f19bd705
AM
11344diff -NurpP --minimal linux-4.4.111/include/net/ip6_route.h linux-4.4.111-vs2.3.9.1/include/net/ip6_route.h
11345--- linux-4.4.111/include/net/ip6_route.h 2018-01-11 07:57:49.000000000 +0000
11346+++ linux-4.4.111-vs2.3.9.1/include/net/ip6_route.h 2018-01-09 16:36:32.000000000 +0000
927ca606 11347@@ -90,7 +90,7 @@ int ip6_del_rt(struct rt6_info *);
c2e5f7c8
JR
11348
11349 int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
11350 const struct in6_addr *daddr, unsigned int prefs,
11351- struct in6_addr *saddr);
11352+ struct in6_addr *saddr, struct nx_info *nxi);
11353
11354 struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
11355 const struct in6_addr *saddr, int oif, int flags);
f19bd705
AM
11356diff -NurpP --minimal linux-4.4.111/include/net/route.h linux-4.4.111-vs2.3.9.1/include/net/route.h
11357--- linux-4.4.111/include/net/route.h 2016-07-05 04:15:11.000000000 +0000
11358+++ linux-4.4.111-vs2.3.9.1/include/net/route.h 2018-01-09 16:39:47.000000000 +0000
927ca606 11359@@ -223,6 +223,9 @@ static inline void ip_rt_put(struct rtab
b00e13aa 11360 dst_release(&rt->dst);
4bf69007
AM
11361 }
11362
11363+#include <linux/vs_base.h>
11364+#include <linux/vs_inet.h>
d337f35e 11365+
4bf69007
AM
11366 #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
11367
11368 extern const __u8 ip_tos2prio[16];
927ca606 11369@@ -270,6 +273,9 @@ static inline void ip_route_connect_init
4bf69007
AM
11370 protocol, flow_flags, dst, src, dport, sport);
11371 }
11372
11373+extern struct rtable *ip_v4_find_src(struct net *net, struct nx_info *,
11374+ struct flowi4 *);
d337f35e 11375+
4bf69007
AM
11376 static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
11377 __be32 dst, __be32 src, u32 tos,
11378 int oif, u8 protocol,
927ca606 11379@@ -278,6 +284,7 @@ static inline struct rtable *ip_route_co
4bf69007
AM
11380 {
11381 struct net *net = sock_net(sk);
11382 struct rtable *rt;
11383+ struct nx_info *nx_info = current_nx_info();
11384
11385 ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
f15949f2 11386 sport, dport, sk);
927ca606 11387@@ -291,7 +298,21 @@ static inline struct rtable *ip_route_co
4bf69007 11388
927ca606
AM
11389 src = fl4->saddr;
11390 }
4bf69007 11391- if (!dst || !src) {
927ca606 11392+
4bf69007
AM
11393+ if (sk)
11394+ nx_info = sk->sk_nx_info;
d337f35e 11395+
4bf69007
AM
11396+ vxdprintk(VXD_CBIT(net, 4),
11397+ "ip_route_connect(%p) %p,%p;%lx",
11398+ sk, nx_info, sk->sk_socket,
11399+ (sk->sk_socket?sk->sk_socket->flags:0));
d337f35e 11400+
4bf69007
AM
11401+ rt = ip_v4_find_src(net, nx_info, fl4);
11402+ if (IS_ERR(rt))
11403+ return rt;
11404+ ip_rt_put(rt);
d337f35e 11405+
4bf69007
AM
11406+ if (!fl4->daddr || !fl4->saddr) {
11407 rt = __ip_route_output_key(net, fl4);
11408 if (IS_ERR(rt))
11409 return rt;
f19bd705
AM
11410diff -NurpP --minimal linux-4.4.111/include/net/sock.h linux-4.4.111-vs2.3.9.1/include/net/sock.h
11411--- linux-4.4.111/include/net/sock.h 2018-01-11 07:57:49.000000000 +0000
11412+++ linux-4.4.111-vs2.3.9.1/include/net/sock.h 2018-01-09 16:41:40.000000000 +0000
927ca606
AM
11413@@ -201,6 +201,10 @@ struct sock_common {
11414 struct in6_addr skc_v6_daddr;
11415 struct in6_addr skc_v6_rcv_saddr;
4bf69007 11416 #endif
61333608 11417+ vxid_t skc_xid;
4bf69007 11418+ struct vx_info *skc_vx_info;
61333608 11419+ vnid_t skc_nid;
4bf69007 11420+ struct nx_info *skc_nx_info;
c2e5f7c8 11421
927ca606
AM
11422 atomic64_t skc_cookie;
11423
11424@@ -349,8 +353,12 @@ struct sock {
4bf69007
AM
11425 #define sk_prot __sk_common.skc_prot
11426 #define sk_net __sk_common.skc_net
c2e5f7c8
JR
11427 #define sk_v6_daddr __sk_common.skc_v6_daddr
11428-#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
11429+#define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr
927ca606 11430 #define sk_cookie __sk_common.skc_cookie
4bf69007
AM
11431+#define sk_xid __sk_common.skc_xid
11432+#define sk_vx_info __sk_common.skc_vx_info
11433+#define sk_nid __sk_common.skc_nid
11434+#define sk_nx_info __sk_common.skc_nx_info
927ca606
AM
11435 #define sk_incoming_cpu __sk_common.skc_incoming_cpu
11436 #define sk_flags __sk_common.skc_flags
11437 #define sk_rxhash __sk_common.skc_rxhash
f19bd705
AM
11438diff -NurpP --minimal linux-4.4.111/include/uapi/Kbuild linux-4.4.111-vs2.3.9.1/include/uapi/Kbuild
11439--- linux-4.4.111/include/uapi/Kbuild 2015-04-12 22:12:50.000000000 +0000
11440+++ linux-4.4.111-vs2.3.9.1/include/uapi/Kbuild 2018-01-09 16:36:32.000000000 +0000
bb20add7 11441@@ -13,3 +13,4 @@ header-y += drm/
4bf69007
AM
11442 header-y += xen/
11443 header-y += scsi/
bb20add7 11444 header-y += misc/
4bf69007 11445+header-y += vserver/
f19bd705
AM
11446diff -NurpP --minimal linux-4.4.111/include/uapi/linux/capability.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/capability.h
11447--- linux-4.4.111/include/uapi/linux/capability.h 2015-04-12 22:12:50.000000000 +0000
11448+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/capability.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11449@@ -259,6 +259,7 @@ struct vfs_cap_data {
11450 arbitrary SCSI commands */
11451 /* Allow setting encryption key on loopback filesystem */
11452 /* Allow setting zone reclaim policy */
11453+/* Allow the selection of a security context */
11454
11455 #define CAP_SYS_ADMIN 21
11456
bb20add7 11457@@ -354,7 +355,12 @@ struct vfs_cap_data {
4bf69007 11458
bb20add7 11459 #define CAP_LAST_CAP CAP_AUDIT_READ
4bf69007
AM
11460
11461-#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
11462+/* Allow context manipulations */
11463+/* Allow changing context info on files */
d337f35e 11464+
4bf69007 11465+#define CAP_CONTEXT 63
d337f35e 11466+
4bf69007
AM
11467+#define cap_valid(x) ((x) >= 0 && ((x) <= CAP_LAST_CAP || (x) == CAP_CONTEXT))
11468
11469 /*
11470 * Bit location of each capability (used by user-space library and kernel)
f19bd705
AM
11471diff -NurpP --minimal linux-4.4.111/include/uapi/linux/fs.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/fs.h
11472--- linux-4.4.111/include/uapi/linux/fs.h 2016-07-05 04:15:11.000000000 +0000
11473+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/fs.h 2018-01-09 16:47:48.000000000 +0000
927ca606 11474@@ -91,6 +91,9 @@ struct inodes_stat_t {
4bf69007
AM
11475 #define MS_I_VERSION (1<<23) /* Update inode I_version field */
11476 #define MS_STRICTATIME (1<<24) /* Always perform atime updates */
927ca606 11477 #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
b00e13aa
AM
11478+#define MS_TAGGED (1<<8) /* use generic inode tagging */
11479+#define MS_NOTAGCHECK (1<<9) /* don't check tags */
927ca606 11480+#define MS_TAGID (1<<26) /* use specific tag for this mount */
b00e13aa
AM
11481
11482 /* These sb flags are internal to the kernel */
09be7631 11483 #define MS_NOSEC (1<<28)
927ca606 11484@@ -197,12 +200,15 @@ struct inodes_stat_t {
4bf69007
AM
11485 #define FS_EXTENT_FL 0x00080000 /* Extents */
11486 #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
11487 #define FS_NOCOW_FL 0x00800000 /* Do not cow file */
11488+#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */
927ca606 11489 #define FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
4bf69007
AM
11490 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
11491
11492-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
11493-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
927ca606 11494-
4bf69007
AM
11495+#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
11496+#define FS_COW_FL 0x20000000 /* Copy on Write marker */
927ca606 11497+
4bf69007
AM
11498+#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */
11499+#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */
11500
11501 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
11502 #define SYNC_FILE_RANGE_WRITE 2
f19bd705
AM
11503diff -NurpP --minimal linux-4.4.111/include/uapi/linux/gfs2_ondisk.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/gfs2_ondisk.h
11504--- linux-4.4.111/include/uapi/linux/gfs2_ondisk.h 2015-04-12 22:12:50.000000000 +0000
11505+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/gfs2_ondisk.h 2018-01-09 16:36:32.000000000 +0000
4bf69007
AM
11506@@ -225,6 +225,9 @@ enum {
11507 gfs2fl_Sync = 8,
11508 gfs2fl_System = 9,
11509 gfs2fl_TopLevel = 10,
11510+ gfs2fl_IXUnlink = 16,
11511+ gfs2fl_Barrier = 17,
11512+ gfs2fl_Cow = 18,
11513 gfs2fl_TruncInProg = 29,
11514 gfs2fl_InheritDirectio = 30,
11515 gfs2fl_InheritJdata = 31,
11516@@ -242,6 +245,9 @@ enum {
11517 #define GFS2_DIF_SYNC 0x00000100
11518 #define GFS2_DIF_SYSTEM 0x00000200 /* New in gfs2 */
11519 #define GFS2_DIF_TOPDIR 0x00000400 /* New in gfs2 */
11520+#define GFS2_DIF_IXUNLINK 0x00010000
11521+#define GFS2_DIF_BARRIER 0x00020000
11522+#define GFS2_DIF_COW 0x00040000
11523 #define GFS2_DIF_TRUNC_IN_PROG 0x20000000 /* New in gfs2 */
11524 #define GFS2_DIF_INHERIT_DIRECTIO 0x40000000 /* only in gfs1 */
11525 #define GFS2_DIF_INHERIT_JDATA 0x80000000
f19bd705
AM
11526diff -NurpP --minimal linux-4.4.111/include/uapi/linux/if_tun.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/if_tun.h
11527--- linux-4.4.111/include/uapi/linux/if_tun.h 2015-10-29 09:21:42.000000000 +0000
11528+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/if_tun.h 2018-01-09 16:46:34.000000000 +0000
927ca606
AM
11529@@ -56,6 +56,7 @@
11530 */
11531 #define TUNSETVNETBE _IOW('T', 222, int)
11532 #define TUNGETVNETBE _IOR('T', 223, int)
11533+#define TUNSETNID _IOW('T', 224, int)
4bf69007
AM
11534
11535 /* TUNSETIFF ifr flags */
11536 #define IFF_TUN 0x0001
f19bd705
AM
11537diff -NurpP --minimal linux-4.4.111/include/uapi/linux/major.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/major.h
11538--- linux-4.4.111/include/uapi/linux/major.h 2015-04-12 22:12:50.000000000 +0000
11539+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/major.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11540@@ -15,6 +15,7 @@
11541 #define HD_MAJOR IDE0_MAJOR
11542 #define PTY_SLAVE_MAJOR 3
11543 #define TTY_MAJOR 4
11544+#define VROOT_MAJOR 4
11545 #define TTYAUX_MAJOR 5
11546 #define LP_MAJOR 6
11547 #define VCS_MAJOR 7
f19bd705
AM
11548diff -NurpP --minimal linux-4.4.111/include/uapi/linux/nfs_mount.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/nfs_mount.h
11549--- linux-4.4.111/include/uapi/linux/nfs_mount.h 2015-04-12 22:12:50.000000000 +0000
11550+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/nfs_mount.h 2018-01-09 16:36:33.000000000 +0000
4bf69007 11551@@ -63,7 +63,8 @@ struct nfs_mount_data {
c2e5f7c8 11552 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 non-text parsed mount data only */
4bf69007
AM
11553 #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
11554 #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
11555-#define NFS_MOUNT_FLAGMASK 0xFFFF
11556+#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */
11557+#define NFS_MOUNT_FLAGMASK 0x1FFFF
11558
11559 /* The following are for internal use only */
11560 #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
f19bd705
AM
11561diff -NurpP --minimal linux-4.4.111/include/uapi/linux/reboot.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/reboot.h
11562--- linux-4.4.111/include/uapi/linux/reboot.h 2015-04-12 22:12:50.000000000 +0000
11563+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/reboot.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11564@@ -33,7 +33,7 @@
11565 #define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
11566 #define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
11567 #define LINUX_REBOOT_CMD_KEXEC 0x45584543
11568-
11569+#define LINUX_REBOOT_CMD_OOM 0xDEADBEEF
11570
11571
11572 #endif /* _UAPI_LINUX_REBOOT_H */
f19bd705
AM
11573diff -NurpP --minimal linux-4.4.111/include/uapi/linux/sysctl.h linux-4.4.111-vs2.3.9.1/include/uapi/linux/sysctl.h
11574--- linux-4.4.111/include/uapi/linux/sysctl.h 2015-04-12 22:12:50.000000000 +0000
11575+++ linux-4.4.111-vs2.3.9.1/include/uapi/linux/sysctl.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11576@@ -60,6 +60,7 @@ enum
11577 CTL_ABI=9, /* Binary emulation */
11578 CTL_CPU=10, /* CPU stuff (speed scaling, etc) */
11579 CTL_ARLAN=254, /* arlan wireless driver */
11580+ CTL_VSERVER=4242, /* Linux-VServer debug */
11581 CTL_S390DBF=5677, /* s390 debug */
11582 CTL_SUNRPC=7249, /* sunrpc debug */
11583 CTL_PM=9899, /* frv power management */
11584@@ -94,6 +95,7 @@ enum
11585
11586 KERN_PANIC=15, /* int: panic timeout */
11587 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
11588+ KERN_VSHELPER=17, /* string: path to vshelper policy agent */
11589
11590 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
11591 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
f19bd705
AM
11592diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/Kbuild linux-4.4.111-vs2.3.9.1/include/uapi/vserver/Kbuild
11593--- linux-4.4.111/include/uapi/vserver/Kbuild 1970-01-01 00:00:00.000000000 +0000
11594+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/Kbuild 2018-01-09 16:36:33.000000000 +0000
4bf69007 11595@@ -0,0 +1,9 @@
d337f35e 11596+
4bf69007
AM
11597+header-y += context_cmd.h network_cmd.h space_cmd.h \
11598+ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
11599+ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \
11600+ debug_cmd.h device_cmd.h
2380c486 11601+
4bf69007
AM
11602+header-y += switch.h context.h network.h monitor.h \
11603+ limit.h inode.h device.h
2380c486 11604+
f19bd705
AM
11605diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/cacct_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/cacct_cmd.h
11606--- linux-4.4.111/include/uapi/vserver/cacct_cmd.h 1970-01-01 00:00:00.000000000 +0000
11607+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/cacct_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11608@@ -0,0 +1,15 @@
11609+#ifndef _UAPI_VS_CACCT_CMD_H
11610+#define _UAPI_VS_CACCT_CMD_H
d337f35e
JR
11611+
11612+
4bf69007 11613+/* virtual host info name commands */
d337f35e 11614+
4bf69007 11615+#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
d337f35e 11616+
4bf69007
AM
11617+struct vcmd_sock_stat_v0 {
11618+ uint32_t field;
11619+ uint32_t count[3];
11620+ uint64_t total[3];
11621+};
d337f35e 11622+
4bf69007 11623+#endif /* _UAPI_VS_CACCT_CMD_H */
f19bd705
AM
11624diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/context.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/context.h
11625--- linux-4.4.111/include/uapi/vserver/context.h 1970-01-01 00:00:00.000000000 +0000
11626+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/context.h 2018-01-09 16:36:33.000000000 +0000
b00e13aa 11627@@ -0,0 +1,81 @@
4bf69007
AM
11628+#ifndef _UAPI_VS_CONTEXT_H
11629+#define _UAPI_VS_CONTEXT_H
d337f35e 11630+
4bf69007
AM
11631+#include <linux/types.h>
11632+#include <linux/capability.h>
d337f35e
JR
11633+
11634+
4bf69007 11635+/* context flags */
d337f35e 11636+
4bf69007
AM
11637+#define VXF_INFO_SCHED 0x00000002
11638+#define VXF_INFO_NPROC 0x00000004
11639+#define VXF_INFO_PRIVATE 0x00000008
d337f35e 11640+
4bf69007
AM
11641+#define VXF_INFO_INIT 0x00000010
11642+#define VXF_INFO_HIDE 0x00000020
11643+#define VXF_INFO_ULIMIT 0x00000040
11644+#define VXF_INFO_NSPACE 0x00000080
d337f35e 11645+
4bf69007
AM
11646+#define VXF_SCHED_HARD 0x00000100
11647+#define VXF_SCHED_PRIO 0x00000200
11648+#define VXF_SCHED_PAUSE 0x00000400
2380c486 11649+
4bf69007
AM
11650+#define VXF_VIRT_MEM 0x00010000
11651+#define VXF_VIRT_UPTIME 0x00020000
11652+#define VXF_VIRT_CPU 0x00040000
11653+#define VXF_VIRT_LOAD 0x00080000
11654+#define VXF_VIRT_TIME 0x00100000
d337f35e 11655+
4bf69007
AM
11656+#define VXF_HIDE_MOUNT 0x01000000
11657+/* was VXF_HIDE_NETIF 0x02000000 */
11658+#define VXF_HIDE_VINFO 0x04000000
d337f35e 11659+
4bf69007
AM
11660+#define VXF_STATE_SETUP (1ULL << 32)
11661+#define VXF_STATE_INIT (1ULL << 33)
11662+#define VXF_STATE_ADMIN (1ULL << 34)
d337f35e 11663+
4bf69007
AM
11664+#define VXF_SC_HELPER (1ULL << 36)
11665+#define VXF_REBOOT_KILL (1ULL << 37)
11666+#define VXF_PERSISTENT (1ULL << 38)
d337f35e 11667+
4bf69007
AM
11668+#define VXF_FORK_RSS (1ULL << 48)
11669+#define VXF_PROLIFIC (1ULL << 49)
d337f35e 11670+
4bf69007 11671+#define VXF_IGNEG_NICE (1ULL << 52)
d337f35e 11672+
4bf69007 11673+#define VXF_ONE_TIME (0x0007ULL << 32)
d337f35e 11674+
4bf69007 11675+#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN)
d337f35e
JR
11676+
11677+
4bf69007 11678+/* context migration */
d337f35e 11679+
4bf69007
AM
11680+#define VXM_SET_INIT 0x00000001
11681+#define VXM_SET_REAPER 0x00000002
d337f35e 11682+
4bf69007 11683+/* context caps */
d337f35e 11684+
4bf69007
AM
11685+#define VXC_SET_UTSNAME 0x00000001
11686+#define VXC_SET_RLIMIT 0x00000002
11687+#define VXC_FS_SECURITY 0x00000004
11688+#define VXC_FS_TRUSTED 0x00000008
11689+#define VXC_TIOCSTI 0x00000010
2380c486 11690+
4bf69007
AM
11691+/* was VXC_RAW_ICMP 0x00000100 */
11692+#define VXC_SYSLOG 0x00001000
11693+#define VXC_OOM_ADJUST 0x00002000
11694+#define VXC_AUDIT_CONTROL 0x00004000
d337f35e 11695+
c2e5f7c8
JR
11696+#define VXC_SECURE_MOUNT 0x00010000
11697+/* #define VXC_SECURE_REMOUNT 0x00020000 */
4bf69007 11698+#define VXC_BINARY_MOUNT 0x00040000
b00e13aa 11699+#define VXC_DEV_MOUNT 0x00080000
d337f35e 11700+
4bf69007
AM
11701+#define VXC_QUOTA_CTL 0x00100000
11702+#define VXC_ADMIN_MAPPER 0x00200000
11703+#define VXC_ADMIN_CLOOP 0x00400000
d337f35e 11704+
4bf69007
AM
11705+#define VXC_KTHREAD 0x01000000
11706+#define VXC_NAMESPACE 0x02000000
d337f35e 11707+
4bf69007 11708+#endif /* _UAPI_VS_CONTEXT_H */
f19bd705
AM
11709diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/context_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/context_cmd.h
11710--- linux-4.4.111/include/uapi/vserver/context_cmd.h 1970-01-01 00:00:00.000000000 +0000
11711+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/context_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11712@@ -0,0 +1,115 @@
11713+#ifndef _UAPI_VS_CONTEXT_CMD_H
11714+#define _UAPI_VS_CONTEXT_CMD_H
d33d7b00
AM
11715+
11716+
4bf69007 11717+/* vinfo commands */
3bac966d 11718+
4bf69007 11719+#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
3bac966d 11720+
3bac966d 11721+
4bf69007 11722+#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
3bac966d 11723+
4bf69007
AM
11724+struct vcmd_vx_info_v0 {
11725+ uint32_t xid;
11726+ uint32_t initpid;
11727+ /* more to come */
11728+};
3bac966d
AM
11729+
11730+
4bf69007 11731+#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
3bac966d 11732+
4bf69007
AM
11733+struct vcmd_ctx_stat_v0 {
11734+ uint32_t usecnt;
11735+ uint32_t tasks;
11736+ /* more to come */
11737+};
3bac966d 11738+
3bac966d 11739+
4bf69007 11740+/* context commands */
3bac966d 11741+
4bf69007
AM
11742+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
11743+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
3bac966d 11744+
4bf69007
AM
11745+struct vcmd_ctx_create {
11746+ uint64_t flagword;
11747+};
3bac966d 11748+
4bf69007
AM
11749+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
11750+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
3bac966d 11751+
4bf69007
AM
11752+struct vcmd_ctx_migrate {
11753+ uint64_t flagword;
11754+};
3bac966d 11755+
d33d7b00 11756+
d33d7b00 11757+
4bf69007 11758+/* flag commands */
d33d7b00 11759+
4bf69007
AM
11760+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
11761+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
d33d7b00 11762+
4bf69007
AM
11763+struct vcmd_ctx_flags_v0 {
11764+ uint64_t flagword;
11765+ uint64_t mask;
11766+};
3bac966d
AM
11767+
11768+
3bac966d 11769+
4bf69007 11770+/* context caps commands */
3bac966d 11771+
4bf69007
AM
11772+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
11773+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
d33d7b00 11774+
4bf69007
AM
11775+struct vcmd_ctx_caps_v1 {
11776+ uint64_t ccaps;
11777+ uint64_t cmask;
11778+};
d33d7b00 11779+
d33d7b00
AM
11780+
11781+
4bf69007 11782+/* bcaps commands */
d33d7b00 11783+
4bf69007
AM
11784+#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
11785+#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0)
d33d7b00 11786+
4bf69007
AM
11787+struct vcmd_bcaps {
11788+ uint64_t bcaps;
11789+ uint64_t bmask;
11790+};
3bac966d 11791+
d33d7b00 11792+
d33d7b00 11793+
4bf69007 11794+/* umask commands */
d33d7b00 11795+
4bf69007
AM
11796+#define VCMD_get_umask VC_CMD(FLAGS, 13, 0)
11797+#define VCMD_set_umask VC_CMD(FLAGS, 14, 0)
3bac966d 11798+
4bf69007
AM
11799+struct vcmd_umask {
11800+ uint64_t umask;
11801+ uint64_t mask;
11802+};
d33d7b00 11803+
d33d7b00
AM
11804+
11805+
4bf69007 11806+/* wmask commands */
d33d7b00 11807+
4bf69007
AM
11808+#define VCMD_get_wmask VC_CMD(FLAGS, 15, 0)
11809+#define VCMD_set_wmask VC_CMD(FLAGS, 16, 0)
d33d7b00 11810+
4bf69007
AM
11811+struct vcmd_wmask {
11812+ uint64_t wmask;
11813+ uint64_t mask;
d33d7b00
AM
11814+};
11815+
d33d7b00 11816+
d33d7b00 11817+
4bf69007 11818+/* OOM badness */
d33d7b00 11819+
4bf69007
AM
11820+#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0)
11821+#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0)
d33d7b00 11822+
4bf69007
AM
11823+struct vcmd_badness_v0 {
11824+ int64_t bias;
11825+};
d33d7b00 11826+
4bf69007 11827+#endif /* _UAPI_VS_CONTEXT_CMD_H */
f19bd705
AM
11828diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/cvirt_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/cvirt_cmd.h
11829--- linux-4.4.111/include/uapi/vserver/cvirt_cmd.h 1970-01-01 00:00:00.000000000 +0000
11830+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/cvirt_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11831@@ -0,0 +1,41 @@
11832+#ifndef _UAPI_VS_CVIRT_CMD_H
11833+#define _UAPI_VS_CVIRT_CMD_H
d33d7b00 11834+
d33d7b00 11835+
4bf69007 11836+/* virtual host info name commands */
d33d7b00 11837+
4bf69007
AM
11838+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
11839+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
d33d7b00 11840+
4bf69007
AM
11841+struct vcmd_vhi_name_v0 {
11842+ uint32_t field;
11843+ char name[65];
11844+};
d33d7b00 11845+
d33d7b00 11846+
4bf69007
AM
11847+enum vhi_name_field {
11848+ VHIN_CONTEXT = 0,
11849+ VHIN_SYSNAME,
11850+ VHIN_NODENAME,
11851+ VHIN_RELEASE,
11852+ VHIN_VERSION,
11853+ VHIN_MACHINE,
11854+ VHIN_DOMAINNAME,
11855+};
d33d7b00 11856+
d33d7b00 11857+
d33d7b00 11858+
4bf69007 11859+#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
d33d7b00 11860+
4bf69007
AM
11861+struct vcmd_virt_stat_v0 {
11862+ uint64_t offset;
11863+ uint64_t uptime;
11864+ uint32_t nr_threads;
11865+ uint32_t nr_running;
11866+ uint32_t nr_uninterruptible;
11867+ uint32_t nr_onhold;
11868+ uint32_t nr_forks;
11869+ uint32_t load[3];
11870+};
2380c486 11871+
4bf69007 11872+#endif /* _UAPI_VS_CVIRT_CMD_H */
f19bd705
AM
11873diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/debug_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/debug_cmd.h
11874--- linux-4.4.111/include/uapi/vserver/debug_cmd.h 1970-01-01 00:00:00.000000000 +0000
11875+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/debug_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11876@@ -0,0 +1,24 @@
11877+#ifndef _UAPI_VS_DEBUG_CMD_H
11878+#define _UAPI_VS_DEBUG_CMD_H
537831f9 11879+
537831f9 11880+
4bf69007 11881+/* debug commands */
537831f9 11882+
4bf69007 11883+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
537831f9 11884+
4bf69007
AM
11885+#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
11886+#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
537831f9 11887+
4bf69007
AM
11888+struct vcmd_read_history_v0 {
11889+ uint32_t index;
11890+ uint32_t count;
11891+ char __user *data;
11892+};
537831f9 11893+
4bf69007
AM
11894+struct vcmd_read_monitor_v0 {
11895+ uint32_t index;
11896+ uint32_t count;
11897+ char __user *data;
11898+};
537831f9 11899+
4bf69007 11900+#endif /* _UAPI_VS_DEBUG_CMD_H */
f19bd705
AM
11901diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/device.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/device.h
11902--- linux-4.4.111/include/uapi/vserver/device.h 1970-01-01 00:00:00.000000000 +0000
11903+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/device.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11904@@ -0,0 +1,12 @@
11905+#ifndef _UAPI_VS_DEVICE_H
11906+#define _UAPI_VS_DEVICE_H
d337f35e 11907+
d337f35e 11908+
4bf69007
AM
11909+#define DATTR_CREATE 0x00000001
11910+#define DATTR_OPEN 0x00000002
d337f35e 11911+
4bf69007 11912+#define DATTR_REMAP 0x00000010
d337f35e 11913+
4bf69007 11914+#define DATTR_MASK 0x00000013
ec22aa5c 11915+
4bf69007 11916+#endif /* _UAPI_VS_DEVICE_H */
f19bd705
AM
11917diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/device_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/device_cmd.h
11918--- linux-4.4.111/include/uapi/vserver/device_cmd.h 1970-01-01 00:00:00.000000000 +0000
11919+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/device_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11920@@ -0,0 +1,16 @@
11921+#ifndef _UAPI_VS_DEVICE_CMD_H
11922+#define _UAPI_VS_DEVICE_CMD_H
2380c486 11923+
1163e6ab 11924+
4bf69007 11925+/* device vserver commands */
1163e6ab 11926+
4bf69007
AM
11927+#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
11928+#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0)
e915af4e 11929+
4bf69007
AM
11930+struct vcmd_set_mapping_v0 {
11931+ const char __user *device;
11932+ const char __user *target;
11933+ uint32_t flags;
11934+};
e915af4e 11935+
4bf69007 11936+#endif /* _UAPI_VS_DEVICE_CMD_H */
f19bd705
AM
11937diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/dlimit_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/dlimit_cmd.h
11938--- linux-4.4.111/include/uapi/vserver/dlimit_cmd.h 1970-01-01 00:00:00.000000000 +0000
11939+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/dlimit_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
11940@@ -0,0 +1,67 @@
11941+#ifndef _UAPI_VS_DLIMIT_CMD_H
11942+#define _UAPI_VS_DLIMIT_CMD_H
e915af4e 11943+
42bc425c 11944+
4bf69007 11945+/* dlimit vserver commands */
d337f35e 11946+
4bf69007
AM
11947+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
11948+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
d337f35e 11949+
4bf69007
AM
11950+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
11951+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
d337f35e 11952+
4bf69007
AM
11953+struct vcmd_ctx_dlimit_base_v0 {
11954+ const char __user *name;
11955+ uint32_t flags;
11956+};
11957+
11958+struct vcmd_ctx_dlimit_v0 {
11959+ const char __user *name;
11960+ uint32_t space_used; /* used space in kbytes */
11961+ uint32_t space_total; /* maximum space in kbytes */
11962+ uint32_t inodes_used; /* used inodes */
11963+ uint32_t inodes_total; /* maximum inodes */
11964+ uint32_t reserved; /* reserved for root in % */
11965+ uint32_t flags;
11966+};
11967+
11968+#define CDLIM_UNSET ((uint32_t)0UL)
11969+#define CDLIM_INFINITY ((uint32_t)~0UL)
11970+#define CDLIM_KEEP ((uint32_t)~1UL)
11971+
11972+#define DLIME_UNIT 0
11973+#define DLIME_KILO 1
11974+#define DLIME_MEGA 2
11975+#define DLIME_GIGA 3
11976+
11977+#define DLIMF_SHIFT 0x10
11978+
11979+#define DLIMS_USED 0
11980+#define DLIMS_TOTAL 2
11981+
11982+static inline
11983+uint64_t dlimit_space_32to64(uint32_t val, uint32_t flags, int shift)
2380c486 11984+{
4bf69007
AM
11985+ int exp = (flags & DLIMF_SHIFT) ?
11986+ (flags >> shift) & DLIME_GIGA : DLIME_KILO;
11987+ return ((uint64_t)val) << (10 * exp);
2380c486
JR
11988+}
11989+
4bf69007
AM
11990+static inline
11991+uint32_t dlimit_space_64to32(uint64_t val, uint32_t *flags, int shift)
2380c486 11992+{
4bf69007 11993+ int exp = 0;
ec22aa5c 11994+
4bf69007
AM
11995+ if (*flags & DLIMF_SHIFT) {
11996+ while (val > (1LL << 32) && (exp < 3)) {
11997+ val >>= 10;
11998+ exp++;
11999+ }
12000+ *flags &= ~(DLIME_GIGA << shift);
12001+ *flags |= exp << shift;
12002+ } else
12003+ val >>= 10;
12004+ return val;
2380c486
JR
12005+}
12006+
4bf69007 12007+#endif /* _UAPI_VS_DLIMIT_CMD_H */
f19bd705
AM
12008diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/inode.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/inode.h
12009--- linux-4.4.111/include/uapi/vserver/inode.h 1970-01-01 00:00:00.000000000 +0000
12010+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/inode.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12011@@ -0,0 +1,23 @@
12012+#ifndef _UAPI_VS_INODE_H
12013+#define _UAPI_VS_INODE_H
2380c486 12014+
d337f35e 12015+
4bf69007 12016+#define IATTR_TAG 0x01000000
2380c486 12017+
4bf69007
AM
12018+#define IATTR_ADMIN 0x00000001
12019+#define IATTR_WATCH 0x00000002
12020+#define IATTR_HIDE 0x00000004
12021+#define IATTR_FLAGS 0x00000007
2380c486 12022+
4bf69007
AM
12023+#define IATTR_BARRIER 0x00010000
12024+#define IATTR_IXUNLINK 0x00020000
12025+#define IATTR_IMMUTABLE 0x00040000
12026+#define IATTR_COW 0x00080000
d337f35e 12027+
ec22aa5c 12028+
4bf69007 12029+/* inode ioctls */
ec22aa5c 12030+
4bf69007
AM
12031+#define FIOC_GETXFLG _IOR('x', 5, long)
12032+#define FIOC_SETXFLG _IOW('x', 6, long)
d337f35e 12033+
4bf69007 12034+#endif /* _UAPI_VS_INODE_H */
f19bd705
AM
12035diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/inode_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/inode_cmd.h
12036--- linux-4.4.111/include/uapi/vserver/inode_cmd.h 1970-01-01 00:00:00.000000000 +0000
12037+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/inode_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12038@@ -0,0 +1,26 @@
12039+#ifndef _UAPI_VS_INODE_CMD_H
12040+#define _UAPI_VS_INODE_CMD_H
d337f35e 12041+
db55b927 12042+
4bf69007 12043+/* inode vserver commands */
2c8c5bc5 12044+
4bf69007
AM
12045+#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
12046+#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
2bf5ad28 12047+
4bf69007
AM
12048+#define VCMD_fget_iattr VC_CMD(INODE, 3, 0)
12049+#define VCMD_fset_iattr VC_CMD(INODE, 4, 0)
4a036bed 12050+
4bf69007
AM
12051+struct vcmd_ctx_iattr_v1 {
12052+ const char __user *name;
12053+ uint32_t tag;
12054+ uint32_t flags;
12055+ uint32_t mask;
12056+};
4a036bed 12057+
4bf69007
AM
12058+struct vcmd_ctx_fiattr_v0 {
12059+ uint32_t tag;
12060+ uint32_t flags;
12061+ uint32_t mask;
12062+};
4a036bed 12063+
4bf69007 12064+#endif /* _UAPI_VS_INODE_CMD_H */
f19bd705
AM
12065diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/limit.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/limit.h
12066--- linux-4.4.111/include/uapi/vserver/limit.h 1970-01-01 00:00:00.000000000 +0000
12067+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/limit.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12068@@ -0,0 +1,14 @@
12069+#ifndef _UAPI_VS_LIMIT_H
12070+#define _UAPI_VS_LIMIT_H
4a036bed 12071+
42bc425c 12072+
4bf69007
AM
12073+#define VLIMIT_NSOCK 16
12074+#define VLIMIT_OPENFD 17
12075+#define VLIMIT_ANON 18
12076+#define VLIMIT_SHMEM 19
12077+#define VLIMIT_SEMARY 20
12078+#define VLIMIT_NSEMS 21
12079+#define VLIMIT_DENTRY 22
12080+#define VLIMIT_MAPPED 23
adc1caaa 12081+
4bf69007 12082+#endif /* _UAPI_VS_LIMIT_H */
f19bd705
AM
12083diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/limit_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/limit_cmd.h
12084--- linux-4.4.111/include/uapi/vserver/limit_cmd.h 1970-01-01 00:00:00.000000000 +0000
12085+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/limit_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12086@@ -0,0 +1,40 @@
12087+#ifndef _UAPI_VS_LIMIT_CMD_H
12088+#define _UAPI_VS_LIMIT_CMD_H
adc1caaa 12089+
adc1caaa 12090+
4bf69007 12091+/* rlimit vserver commands */
adc1caaa 12092+
4bf69007
AM
12093+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
12094+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
12095+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
12096+#define VCMD_reset_hits VC_CMD(RLIMIT, 7, 0)
12097+#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
adc1caaa 12098+
4bf69007
AM
12099+struct vcmd_ctx_rlimit_v0 {
12100+ uint32_t id;
12101+ uint64_t minimum;
12102+ uint64_t softlimit;
12103+ uint64_t maximum;
12104+};
d33d7b00 12105+
4bf69007
AM
12106+struct vcmd_ctx_rlimit_mask_v0 {
12107+ uint32_t minimum;
12108+ uint32_t softlimit;
12109+ uint32_t maximum;
12110+};
d33d7b00 12111+
4bf69007 12112+#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
d33d7b00 12113+
4bf69007
AM
12114+struct vcmd_rlimit_stat_v0 {
12115+ uint32_t id;
12116+ uint32_t hits;
12117+ uint64_t value;
12118+ uint64_t minimum;
12119+ uint64_t maximum;
12120+};
d33d7b00 12121+
4bf69007
AM
12122+#define CRLIM_UNSET (0ULL)
12123+#define CRLIM_INFINITY (~0ULL)
12124+#define CRLIM_KEEP (~1ULL)
d33d7b00 12125+
4bf69007 12126+#endif /* _UAPI_VS_LIMIT_CMD_H */
f19bd705
AM
12127diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/monitor.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/monitor.h
12128--- linux-4.4.111/include/uapi/vserver/monitor.h 1970-01-01 00:00:00.000000000 +0000
12129+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/monitor.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12130@@ -0,0 +1,96 @@
12131+#ifndef _UAPI_VS_MONITOR_H
12132+#define _UAPI_VS_MONITOR_H
d33d7b00 12133+
4bf69007 12134+#include <linux/types.h>
d33d7b00 12135+
d33d7b00 12136+
4bf69007
AM
12137+enum {
12138+ VXM_UNUSED = 0,
d33d7b00 12139+
4bf69007 12140+ VXM_SYNC = 0x10,
d33d7b00 12141+
4bf69007
AM
12142+ VXM_UPDATE = 0x20,
12143+ VXM_UPDATE_1,
12144+ VXM_UPDATE_2,
d33d7b00 12145+
4bf69007
AM
12146+ VXM_RQINFO_1 = 0x24,
12147+ VXM_RQINFO_2,
d33d7b00 12148+
4bf69007
AM
12149+ VXM_ACTIVATE = 0x40,
12150+ VXM_DEACTIVATE,
12151+ VXM_IDLE,
d33d7b00 12152+
4bf69007
AM
12153+ VXM_HOLD = 0x44,
12154+ VXM_UNHOLD,
d33d7b00 12155+
4bf69007
AM
12156+ VXM_MIGRATE = 0x48,
12157+ VXM_RESCHED,
d33d7b00 12158+
4bf69007
AM
12159+ /* all other bits are flags */
12160+ VXM_SCHED = 0x80,
12161+};
d33d7b00 12162+
4bf69007
AM
12163+struct _vxm_update_1 {
12164+ uint32_t tokens_max;
12165+ uint32_t fill_rate;
12166+ uint32_t interval;
12167+};
d33d7b00 12168+
4bf69007
AM
12169+struct _vxm_update_2 {
12170+ uint32_t tokens_min;
12171+ uint32_t fill_rate;
12172+ uint32_t interval;
12173+};
d33d7b00 12174+
4bf69007
AM
12175+struct _vxm_rqinfo_1 {
12176+ uint16_t running;
12177+ uint16_t onhold;
12178+ uint16_t iowait;
12179+ uint16_t uintr;
12180+ uint32_t idle_tokens;
12181+};
d33d7b00 12182+
4bf69007
AM
12183+struct _vxm_rqinfo_2 {
12184+ uint32_t norm_time;
12185+ uint32_t idle_time;
12186+ uint32_t idle_skip;
12187+};
d33d7b00 12188+
4bf69007
AM
12189+struct _vxm_sched {
12190+ uint32_t tokens;
12191+ uint32_t norm_time;
12192+ uint32_t idle_time;
12193+};
d33d7b00 12194+
4bf69007
AM
12195+struct _vxm_task {
12196+ uint16_t pid;
12197+ uint16_t state;
12198+};
d33d7b00 12199+
4bf69007
AM
12200+struct _vxm_event {
12201+ uint32_t jif;
12202+ union {
12203+ uint32_t seq;
12204+ uint32_t sec;
12205+ };
12206+ union {
12207+ uint32_t tokens;
12208+ uint32_t nsec;
12209+ struct _vxm_task tsk;
12210+ };
12211+};
61b0c03f 12212+
4bf69007
AM
12213+struct _vx_mon_entry {
12214+ uint16_t type;
12215+ uint16_t xid;
12216+ union {
12217+ struct _vxm_event ev;
12218+ struct _vxm_sched sd;
12219+ struct _vxm_update_1 u1;
12220+ struct _vxm_update_2 u2;
12221+ struct _vxm_rqinfo_1 q1;
12222+ struct _vxm_rqinfo_2 q2;
12223+ };
12224+};
d33d7b00 12225+
4bf69007 12226+#endif /* _UAPI_VS_MONITOR_H */
f19bd705
AM
12227diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/network.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/network.h
12228--- linux-4.4.111/include/uapi/vserver/network.h 1970-01-01 00:00:00.000000000 +0000
12229+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/network.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12230@@ -0,0 +1,76 @@
12231+#ifndef _UAPI_VS_NETWORK_H
12232+#define _UAPI_VS_NETWORK_H
d33d7b00 12233+
4bf69007 12234+#include <linux/types.h>
d33d7b00 12235+
d33d7b00 12236+
4bf69007 12237+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
d33d7b00 12238+
d33d7b00 12239+
4bf69007 12240+/* network flags */
d33d7b00 12241+
4bf69007 12242+#define NXF_INFO_PRIVATE 0x00000008
d33d7b00 12243+
4bf69007
AM
12244+#define NXF_SINGLE_IP 0x00000100
12245+#define NXF_LBACK_REMAP 0x00000200
12246+#define NXF_LBACK_ALLOW 0x00000400
d33d7b00 12247+
4bf69007
AM
12248+#define NXF_HIDE_NETIF 0x02000000
12249+#define NXF_HIDE_LBACK 0x04000000
265d6dcc 12250+
4bf69007
AM
12251+#define NXF_STATE_SETUP (1ULL << 32)
12252+#define NXF_STATE_ADMIN (1ULL << 34)
d33d7b00 12253+
4bf69007
AM
12254+#define NXF_SC_HELPER (1ULL << 36)
12255+#define NXF_PERSISTENT (1ULL << 38)
d33d7b00 12256+
4bf69007 12257+#define NXF_ONE_TIME (0x0005ULL << 32)
d33d7b00 12258+
d33d7b00 12259+
4bf69007 12260+#define NXF_INIT_SET (__nxf_init_set())
d33d7b00 12261+
4bf69007
AM
12262+static inline uint64_t __nxf_init_set(void) {
12263+ return NXF_STATE_ADMIN
12264+#ifdef CONFIG_VSERVER_AUTO_LBACK
12265+ | NXF_LBACK_REMAP
12266+ | NXF_HIDE_LBACK
12267+#endif
12268+#ifdef CONFIG_VSERVER_AUTO_SINGLE
12269+ | NXF_SINGLE_IP
12270+#endif
12271+ | NXF_HIDE_NETIF;
12272+}
d33d7b00 12273+
d33d7b00 12274+
4bf69007 12275+/* network caps */
d33d7b00 12276+
4bf69007 12277+#define NXC_TUN_CREATE 0x00000001
d33d7b00 12278+
4bf69007 12279+#define NXC_RAW_ICMP 0x00000100
d33d7b00 12280+
4bf69007 12281+#define NXC_MULTICAST 0x00001000
d33d7b00 12282+
adc1caaa 12283+
4bf69007 12284+/* address types */
adc1caaa 12285+
4bf69007
AM
12286+#define NXA_TYPE_IPV4 0x0001
12287+#define NXA_TYPE_IPV6 0x0002
adc1caaa 12288+
4bf69007
AM
12289+#define NXA_TYPE_NONE 0x0000
12290+#define NXA_TYPE_ANY 0x00FF
adc1caaa 12291+
4bf69007
AM
12292+#define NXA_TYPE_ADDR 0x0010
12293+#define NXA_TYPE_MASK 0x0020
12294+#define NXA_TYPE_RANGE 0x0040
adc1caaa 12295+
4bf69007 12296+#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE)
adc1caaa 12297+
4bf69007
AM
12298+#define NXA_MOD_BCAST 0x0100
12299+#define NXA_MOD_LBACK 0x0200
adc1caaa 12300+
4bf69007 12301+#define NXA_LOOPBACK 0x1000
2380c486 12302+
4bf69007
AM
12303+#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK)
12304+#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK)
2380c486 12305+
4bf69007 12306+#endif /* _UAPI_VS_NETWORK_H */
f19bd705
AM
12307diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/network_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/network_cmd.h
12308--- linux-4.4.111/include/uapi/vserver/network_cmd.h 1970-01-01 00:00:00.000000000 +0000
12309+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/network_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12310@@ -0,0 +1,123 @@
12311+#ifndef _UAPI_VS_NETWORK_CMD_H
12312+#define _UAPI_VS_NETWORK_CMD_H
2380c486 12313+
2380c486 12314+
4bf69007 12315+/* vinfo commands */
2380c486 12316+
4bf69007 12317+#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
2380c486 12318+
2380c486 12319+
4bf69007 12320+#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
2380c486 12321+
4bf69007
AM
12322+struct vcmd_nx_info_v0 {
12323+ uint32_t nid;
12324+ /* more to come */
12325+};
2380c486 12326+
2380c486 12327+
4bf69007
AM
12328+#include <linux/in.h>
12329+#include <linux/in6.h>
2380c486 12330+
4bf69007
AM
12331+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
12332+#define VCMD_net_create VC_CMD(VNET, 1, 1)
2380c486 12333+
4bf69007
AM
12334+struct vcmd_net_create {
12335+ uint64_t flagword;
12336+};
2380c486 12337+
4bf69007 12338+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
2380c486 12339+
4bf69007
AM
12340+#define VCMD_net_add VC_CMD(NETALT, 1, 0)
12341+#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
2380c486 12342+
4bf69007
AM
12343+struct vcmd_net_addr_v0 {
12344+ uint16_t type;
12345+ uint16_t count;
12346+ struct in_addr ip[4];
12347+ struct in_addr mask[4];
12348+};
2380c486 12349+
4bf69007
AM
12350+#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1)
12351+#define VCMD_net_rem_ipv4_v1 VC_CMD(NETALT, 2, 1)
2380c486 12352+
4bf69007
AM
12353+struct vcmd_net_addr_ipv4_v1 {
12354+ uint16_t type;
12355+ uint16_t flags;
12356+ struct in_addr ip;
12357+ struct in_addr mask;
12358+};
2380c486 12359+
4bf69007
AM
12360+#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2)
12361+#define VCMD_net_rem_ipv4 VC_CMD(NETALT, 2, 2)
2380c486 12362+
4bf69007
AM
12363+struct vcmd_net_addr_ipv4_v2 {
12364+ uint16_t type;
12365+ uint16_t flags;
12366+ struct in_addr ip;
12367+ struct in_addr ip2;
12368+ struct in_addr mask;
12369+};
2380c486 12370+
4bf69007
AM
12371+#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1)
12372+#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1)
2380c486 12373+
4bf69007
AM
12374+struct vcmd_net_addr_ipv6_v1 {
12375+ uint16_t type;
12376+ uint16_t flags;
12377+ uint32_t prefix;
12378+ struct in6_addr ip;
12379+ struct in6_addr mask;
12380+};
2380c486 12381+
4bf69007
AM
12382+#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0)
12383+#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0)
2380c486 12384+
4bf69007
AM
12385+struct vcmd_match_ipv4_v0 {
12386+ uint16_t type;
12387+ uint16_t flags;
12388+ uint16_t parent;
12389+ uint16_t prefix;
12390+ struct in_addr ip;
12391+ struct in_addr ip2;
12392+ struct in_addr mask;
12393+};
2380c486 12394+
4bf69007
AM
12395+#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0)
12396+#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0)
2380c486 12397+
4bf69007
AM
12398+struct vcmd_match_ipv6_v0 {
12399+ uint16_t type;
12400+ uint16_t flags;
12401+ uint16_t parent;
12402+ uint16_t prefix;
12403+ struct in6_addr ip;
12404+ struct in6_addr ip2;
12405+ struct in6_addr mask;
12406+};
2380c486 12407+
2380c486 12408+
2380c486 12409+
2380c486 12410+
4bf69007 12411+/* flag commands */
2380c486 12412+
4bf69007
AM
12413+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
12414+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
2380c486 12415+
4bf69007
AM
12416+struct vcmd_net_flags_v0 {
12417+ uint64_t flagword;
12418+ uint64_t mask;
12419+};
2380c486 12420+
2380c486 12421+
ab30d09f 12422+
4bf69007 12423+/* network caps commands */
ab30d09f 12424+
4bf69007
AM
12425+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
12426+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
ec22aa5c 12427+
4bf69007
AM
12428+struct vcmd_net_caps_v0 {
12429+ uint64_t ncaps;
12430+ uint64_t cmask;
12431+};
3bac966d 12432+
4bf69007 12433+#endif /* _UAPI_VS_NETWORK_CMD_H */
f19bd705
AM
12434diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/sched_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/sched_cmd.h
12435--- linux-4.4.111/include/uapi/vserver/sched_cmd.h 1970-01-01 00:00:00.000000000 +0000
12436+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/sched_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12437@@ -0,0 +1,13 @@
12438+#ifndef _UAPI_VS_SCHED_CMD_H
12439+#define _UAPI_VS_SCHED_CMD_H
d337f35e 12440+
d337f35e 12441+
4bf69007
AM
12442+struct vcmd_prio_bias {
12443+ int32_t cpu_id;
12444+ int32_t prio_bias;
12445+};
2380c486 12446+
4bf69007
AM
12447+#define VCMD_set_prio_bias VC_CMD(SCHED, 4, 0)
12448+#define VCMD_get_prio_bias VC_CMD(SCHED, 5, 0)
d337f35e 12449+
4bf69007 12450+#endif /* _UAPI_VS_SCHED_CMD_H */
f19bd705
AM
12451diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/signal_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/signal_cmd.h
12452--- linux-4.4.111/include/uapi/vserver/signal_cmd.h 1970-01-01 00:00:00.000000000 +0000
12453+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/signal_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12454@@ -0,0 +1,31 @@
12455+#ifndef _UAPI_VS_SIGNAL_CMD_H
12456+#define _UAPI_VS_SIGNAL_CMD_H
d337f35e 12457+
d337f35e 12458+
4bf69007 12459+/* signalling vserver commands */
d337f35e 12460+
4bf69007
AM
12461+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
12462+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
d337f35e 12463+
4bf69007
AM
12464+struct vcmd_ctx_kill_v0 {
12465+ int32_t pid;
12466+ int32_t sig;
12467+};
d337f35e 12468+
4bf69007
AM
12469+struct vcmd_wait_exit_v0 {
12470+ int32_t reboot_cmd;
12471+ int32_t exit_code;
12472+};
d337f35e 12473+
d337f35e 12474+
4bf69007 12475+/* process alteration commands */
ab30d09f 12476+
4bf69007
AM
12477+#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
12478+#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
d337f35e 12479+
4bf69007
AM
12480+struct vcmd_pflags_v0 {
12481+ uint32_t flagword;
12482+ uint32_t mask;
12483+};
3bac966d 12484+
4bf69007 12485+#endif /* _UAPI_VS_SIGNAL_CMD_H */
f19bd705
AM
12486diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/space_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/space_cmd.h
12487--- linux-4.4.111/include/uapi/vserver/space_cmd.h 1970-01-01 00:00:00.000000000 +0000
12488+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/space_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12489@@ -0,0 +1,28 @@
12490+#ifndef _UAPI_VS_SPACE_CMD_H
12491+#define _UAPI_VS_SPACE_CMD_H
d337f35e 12492+
d337f35e 12493+
4bf69007
AM
12494+#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
12495+#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1)
12496+#define VCMD_enter_space VC_CMD(PROCALT, 1, 2)
2380c486 12497+
4bf69007
AM
12498+#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
12499+#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1)
12500+#define VCMD_set_space VC_CMD(PROCALT, 3, 2)
d337f35e 12501+
4bf69007 12502+#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0)
d337f35e 12503+
4bf69007
AM
12504+#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1)
12505+#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0)
d337f35e 12506+
d337f35e 12507+
4bf69007
AM
12508+struct vcmd_space_mask_v1 {
12509+ uint64_t mask;
12510+};
d337f35e 12511+
4bf69007
AM
12512+struct vcmd_space_mask_v2 {
12513+ uint64_t mask;
12514+ uint32_t index;
12515+};
d337f35e 12516+
4bf69007 12517+#endif /* _UAPI_VS_SPACE_CMD_H */
f19bd705
AM
12518diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/switch.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/switch.h
12519--- linux-4.4.111/include/uapi/vserver/switch.h 1970-01-01 00:00:00.000000000 +0000
12520+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/switch.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12521@@ -0,0 +1,90 @@
12522+#ifndef _UAPI_VS_SWITCH_H
12523+#define _UAPI_VS_SWITCH_H
d337f35e 12524+
4bf69007 12525+#include <linux/types.h>
d337f35e 12526+
d337f35e 12527+
4bf69007
AM
12528+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
12529+#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
12530+#define VC_VERSION(c) ((c) & 0xFFF)
d337f35e 12531+
4bf69007
AM
12532+#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
12533+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
d337f35e 12534+
4bf69007 12535+/*
d337f35e 12536+
4bf69007 12537+ Syscall Matrix V2.8
d337f35e 12538+
4bf69007
AM
12539+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
12540+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
12541+ |INFO |SETUP | |MOVE | | | | | |
12542+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12543+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
12544+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
12545+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12546+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
12547+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
12548+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12549+ MEMORY | | | | |MEMCTRL| | |SWAP | |
12550+ | 16| 17| 18| 19| 20| 21| | 22| 23|
12551+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12552+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
12553+ | 24| 25| 26| 27| 28| 29| | 30| 31|
12554+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12555+ DISK | | | |TAGMIG |DLIMIT | | |INODE | |
12556+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
12557+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12558+ OTHER |VSTAT | | | | | | |VINFO | |
12559+ | 40| 41| 42| 43| 44| 45| | 46| 47|
12560+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
12561+ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | |
12562+ | 48| 49| 50| 51| 52| 53| | 54| 55|
12563+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
12564+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
12565+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
12566+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
d337f35e 12567+
4bf69007 12568+*/
d337f35e 12569+
4bf69007 12570+#define VC_CAT_VERSION 0
d337f35e 12571+
4bf69007
AM
12572+#define VC_CAT_VSETUP 1
12573+#define VC_CAT_VHOST 2
d337f35e 12574+
4bf69007 12575+#define VC_CAT_DEVICE 6
d337f35e 12576+
4bf69007
AM
12577+#define VC_CAT_VPROC 9
12578+#define VC_CAT_PROCALT 10
12579+#define VC_CAT_PROCMIG 11
12580+#define VC_CAT_PROCTRL 12
d337f35e 12581+
4bf69007
AM
12582+#define VC_CAT_SCHED 14
12583+#define VC_CAT_MEMCTRL 20
d337f35e 12584+
4bf69007
AM
12585+#define VC_CAT_VNET 25
12586+#define VC_CAT_NETALT 26
12587+#define VC_CAT_NETMIG 27
12588+#define VC_CAT_NETCTRL 28
d337f35e 12589+
4bf69007
AM
12590+#define VC_CAT_TAGMIG 35
12591+#define VC_CAT_DLIMIT 36
12592+#define VC_CAT_INODE 38
d337f35e 12593+
4bf69007
AM
12594+#define VC_CAT_VSTAT 40
12595+#define VC_CAT_VINFO 46
12596+#define VC_CAT_EVENT 48
d337f35e 12597+
4bf69007
AM
12598+#define VC_CAT_FLAGS 52
12599+#define VC_CAT_VSPACE 54
12600+#define VC_CAT_DEBUG 56
12601+#define VC_CAT_RLIMIT 60
d337f35e 12602+
4bf69007
AM
12603+#define VC_CAT_SYSTEST 61
12604+#define VC_CAT_COMPAT 63
d337f35e 12605+
4bf69007 12606+/* query version */
d337f35e 12607+
4bf69007
AM
12608+#define VCMD_get_version VC_CMD(VERSION, 0, 0)
12609+#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
2380c486 12610+
4bf69007 12611+#endif /* _UAPI_VS_SWITCH_H */
f19bd705
AM
12612diff -NurpP --minimal linux-4.4.111/include/uapi/vserver/tag_cmd.h linux-4.4.111-vs2.3.9.1/include/uapi/vserver/tag_cmd.h
12613--- linux-4.4.111/include/uapi/vserver/tag_cmd.h 1970-01-01 00:00:00.000000000 +0000
12614+++ linux-4.4.111-vs2.3.9.1/include/uapi/vserver/tag_cmd.h 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12615@@ -0,0 +1,14 @@
12616+#ifndef _UAPI_VS_TAG_CMD_H
12617+#define _UAPI_VS_TAG_CMD_H
d337f35e 12618+
d337f35e 12619+
4bf69007 12620+/* vinfo commands */
d337f35e 12621+
4bf69007 12622+#define VCMD_task_tag VC_CMD(VINFO, 3, 0)
d337f35e
JR
12623+
12624+
4bf69007 12625+/* context commands */
d337f35e 12626+
4bf69007 12627+#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0)
2380c486 12628+
4bf69007 12629+#endif /* _UAPI_VS_TAG_CMD_H */
f19bd705
AM
12630diff -NurpP --minimal linux-4.4.111/init/Kconfig linux-4.4.111-vs2.3.9.1/init/Kconfig
12631--- linux-4.4.111/init/Kconfig 2016-07-05 04:15:12.000000000 +0000
12632+++ linux-4.4.111-vs2.3.9.1/init/Kconfig 2018-01-09 16:36:33.000000000 +0000
927ca606 12633@@ -927,6 +927,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED
4bf69007 12634 menuconfig CGROUPS
927ca606 12635 bool "Control Group support"
265de2f7 12636 select KERNFS
4bf69007
AM
12637+ default y
12638 help
12639 This option adds support for grouping sets of processes together, for
12640 use with process control subsystems such as Cpusets, CFS, memory
f19bd705
AM
12641diff -NurpP --minimal linux-4.4.111/init/main.c linux-4.4.111-vs2.3.9.1/init/main.c
12642--- linux-4.4.111/init/main.c 2018-01-11 07:57:51.000000000 +0000
12643+++ linux-4.4.111-vs2.3.9.1/init/main.c 2018-01-09 16:58:21.000000000 +0000
927ca606
AM
12644@@ -82,6 +82,7 @@
12645 #include <linux/proc_ns.h>
12646 #include <linux/io.h>
12647 #include <linux/kaiser.h>
4bf69007
AM
12648+#include <linux/vserver/percpu.h>
12649
12650 #include <asm/io.h>
12651 #include <asm/bugs.h>
f19bd705
AM
12652diff -NurpP --minimal linux-4.4.111/ipc/mqueue.c linux-4.4.111-vs2.3.9.1/ipc/mqueue.c
12653--- linux-4.4.111/ipc/mqueue.c 2018-01-11 07:57:51.000000000 +0000
12654+++ linux-4.4.111-vs2.3.9.1/ipc/mqueue.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12655@@ -35,6 +35,8 @@
12656 #include <linux/ipc_namespace.h>
12657 #include <linux/user_namespace.h>
12658 #include <linux/slab.h>
12659+#include <linux/vs_context.h>
12660+#include <linux/vs_limit.h>
12661
12662 #include <net/sock.h>
12663 #include "util.h"
927ca606 12664@@ -75,6 +77,7 @@ struct mqueue_inode_info {
bb20add7 12665 struct pid *notify_owner;
4bf69007
AM
12666 struct user_namespace *notify_user_ns;
12667 struct user_struct *user; /* user who created, for accounting */
12668+ struct vx_info *vxi;
12669 struct sock *notify_sock;
12670 struct sk_buff *notify_cookie;
12671
927ca606 12672@@ -230,6 +233,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12673 if (S_ISREG(mode)) {
12674 struct mqueue_inode_info *info;
12675 unsigned long mq_bytes, mq_treesize;
12676+ struct vx_info *vxi = current_vx_info();
12677
12678 inode->i_fop = &mqueue_file_operations;
12679 inode->i_size = FILENT_SIZE;
927ca606 12680@@ -243,6 +247,7 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12681 info->notify_user_ns = NULL;
12682 info->qsize = 0;
12683 info->user = NULL; /* set when all is ok */
12684+ info->vxi = NULL;
12685 info->msg_tree = RB_ROOT;
12686 info->node_cache = NULL;
12687 memset(&info->attr, 0, sizeof(info->attr));
927ca606 12688@@ -276,17 +281,20 @@ static struct inode *mqueue_get_inode(st
4bf69007
AM
12689
12690 spin_lock(&mq_lock);
12691 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
12692- u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
12693+ u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE) ||
12694+ !vx_ipcmsg_avail(vxi, mq_bytes)) {
12695 spin_unlock(&mq_lock);
12696 /* mqueue_evict_inode() releases info->messages */
12697 ret = -EMFILE;
12698 goto out_inode;
12699 }
12700 u->mq_bytes += mq_bytes;
12701+ vx_ipcmsg_add(vxi, u, mq_bytes);
12702 spin_unlock(&mq_lock);
12703
12704 /* all is ok */
12705 info->user = get_uid(u);
12706+ info->vxi = get_vx_info(vxi);
12707 } else if (S_ISDIR(mode)) {
12708 inc_nlink(inode);
12709 /* Some things misbehave if size == 0 on a directory */
927ca606 12710@@ -398,8 +406,11 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12711
12712 user = info->user;
12713 if (user) {
12714+ struct vx_info *vxi = info->vxi;
d337f35e 12715+
4bf69007
AM
12716 spin_lock(&mq_lock);
12717 user->mq_bytes -= mq_bytes;
12718+ vx_ipcmsg_sub(vxi, user, mq_bytes);
12719 /*
12720 * get_ns_from_inode() ensures that the
12721 * (ipc_ns = sb->s_fs_info) is either a valid ipc_ns
927ca606 12722@@ -409,6 +420,7 @@ static void mqueue_evict_inode(struct in
4bf69007
AM
12723 if (ipc_ns)
12724 ipc_ns->mq_queues_count--;
12725 spin_unlock(&mq_lock);
12726+ put_vx_info(vxi);
12727 free_uid(user);
12728 }
12729 if (ipc_ns)
f19bd705
AM
12730diff -NurpP --minimal linux-4.4.111/ipc/msg.c linux-4.4.111-vs2.3.9.1/ipc/msg.c
12731--- linux-4.4.111/ipc/msg.c 2018-01-11 07:57:51.000000000 +0000
12732+++ linux-4.4.111-vs2.3.9.1/ipc/msg.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12733@@ -37,6 +37,7 @@
12734 #include <linux/rwsem.h>
12735 #include <linux/nsproxy.h>
12736 #include <linux/ipc_namespace.h>
12737+#include <linux/vs_base.h>
12738
12739 #include <asm/current.h>
bb20add7
AM
12740 #include <linux/uaccess.h>
12741@@ -129,6 +130,7 @@ static int newque(struct ipc_namespace *
4bf69007
AM
12742
12743 msq->q_perm.mode = msgflg & S_IRWXUGO;
12744 msq->q_perm.key = key;
12745+ msq->q_perm.xid = vx_current_xid();
12746
12747 msq->q_perm.security = NULL;
12748 retval = security_msg_queue_alloc(msq);
f19bd705
AM
12749diff -NurpP --minimal linux-4.4.111/ipc/sem.c linux-4.4.111-vs2.3.9.1/ipc/sem.c
12750--- linux-4.4.111/ipc/sem.c 2018-01-11 07:57:51.000000000 +0000
12751+++ linux-4.4.111-vs2.3.9.1/ipc/sem.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 12752@@ -85,6 +85,8 @@
4bf69007
AM
12753 #include <linux/rwsem.h>
12754 #include <linux/nsproxy.h>
12755 #include <linux/ipc_namespace.h>
12756+#include <linux/vs_base.h>
12757+#include <linux/vs_limit.h>
12758
bb20add7 12759 #include <linux/uaccess.h>
4bf69007 12760 #include "util.h"
927ca606 12761@@ -533,6 +535,7 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12762
12763 sma->sem_perm.mode = (semflg & S_IRWXUGO);
12764 sma->sem_perm.key = key;
12765+ sma->sem_perm.xid = vx_current_xid();
12766
12767 sma->sem_perm.security = NULL;
12768 retval = security_sem_alloc(sma);
927ca606 12769@@ -563,6 +566,9 @@ static int newary(struct ipc_namespace *
4bf69007
AM
12770 return id;
12771 }
12772 ns->used_sems += nsems;
12773+ /* FIXME: obsoleted? */
12774+ vx_semary_inc(sma);
12775+ vx_nsems_add(sma, nsems);
12776
bb20add7
AM
12777 sem_unlock(sma, -1);
12778 rcu_read_unlock();
927ca606 12779@@ -1151,6 +1157,9 @@ static void freeary(struct ipc_namespace
4bf69007
AM
12780
12781 wake_up_sem_queue_do(&tasks);
12782 ns->used_sems -= sma->sem_nsems;
12783+ /* FIXME: obsoleted? */
12784+ vx_nsems_sub(sma, sma->sem_nsems);
12785+ vx_semary_dec(sma);
926e38e0 12786 ipc_rcu_putref(sma, sem_rcu_free);
4bf69007 12787 }
926e38e0 12788
f19bd705
AM
12789diff -NurpP --minimal linux-4.4.111/ipc/shm.c linux-4.4.111-vs2.3.9.1/ipc/shm.c
12790--- linux-4.4.111/ipc/shm.c 2018-01-11 07:57:51.000000000 +0000
12791+++ linux-4.4.111-vs2.3.9.1/ipc/shm.c 2018-01-09 16:36:33.000000000 +0000
c2e5f7c8 12792@@ -42,6 +42,8 @@
4bf69007
AM
12793 #include <linux/nsproxy.h>
12794 #include <linux/mount.h>
12795 #include <linux/ipc_namespace.h>
12796+#include <linux/vs_context.h>
12797+#include <linux/vs_limit.h>
12798
bb20add7 12799 #include <linux/uaccess.h>
4bf69007 12800
927ca606 12801@@ -228,10 +230,14 @@ static void shm_open(struct vm_area_stru
4bf69007
AM
12802 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
12803 {
c2e5f7c8 12804 struct file *shm_file;
4bf69007
AM
12805+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
12806+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
c2e5f7c8
JR
12807
12808 shm_file = shp->shm_file;
12809 shp->shm_file = NULL;
12810- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
4bf69007
AM
12811+ vx_ipcshm_sub(vxi, shp, numpages);
12812+ ns->shm_tot -= numpages;
d337f35e 12813+
4bf69007
AM
12814 shm_rmid(ns, shp);
12815 shm_unlock(shp);
c2e5f7c8 12816 if (!is_file_hugepages(shm_file))
927ca606
AM
12817@@ -240,6 +246,7 @@ static void shm_destroy(struct ipc_names
12818 user_shm_unlock(i_size_read(file_inode(shm_file)),
12819 shp->mlock_user);
c2e5f7c8 12820 fput(shm_file);
4bf69007 12821+ put_vx_info(vxi);
926e38e0 12822 ipc_rcu_putref(shp, shm_rcu_free);
4bf69007
AM
12823 }
12824
927ca606 12825@@ -537,11 +544,15 @@ static int newseg(struct ipc_namespace *
bb20add7 12826 ns->shm_tot + numpages > ns->shm_ctlall)
4bf69007
AM
12827 return -ENOSPC;
12828
12829+ if (!vx_ipcshm_avail(current_vx_info(), numpages))
12830+ return -ENOSPC;
d337f35e 12831+
4bf69007
AM
12832 shp = ipc_rcu_alloc(sizeof(*shp));
12833 if (!shp)
12834 return -ENOMEM;
12835
12836 shp->shm_perm.key = key;
12837+ shp->shm_perm.xid = vx_current_xid();
12838 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
12839 shp->mlock_user = NULL;
12840
927ca606 12841@@ -612,6 +623,7 @@ static int newseg(struct ipc_namespace *
926e38e0
JR
12842
12843 ipc_unlock_object(&shp->shm_perm);
12844 rcu_read_unlock();
4bf69007
AM
12845+ vx_ipcshm_add(current_vx_info(), key, numpages);
12846 return error;
12847
12848 no_id:
f19bd705
AM
12849diff -NurpP --minimal linux-4.4.111/kernel/Makefile linux-4.4.111-vs2.3.9.1/kernel/Makefile
12850--- linux-4.4.111/kernel/Makefile 2016-07-05 04:12:38.000000000 +0000
12851+++ linux-4.4.111-vs2.3.9.1/kernel/Makefile 2018-01-09 16:36:33.000000000 +0000
927ca606 12852@@ -29,6 +29,7 @@ obj-y += printk/
c2e5f7c8
JR
12853 obj-y += irq/
12854 obj-y += rcu/
927ca606 12855 obj-y += livepatch/
4bf69007
AM
12856+obj-y += vserver/
12857
b00e13aa
AM
12858 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
12859 obj-$(CONFIG_FREEZER) += freezer.o
f19bd705
AM
12860diff -NurpP --minimal linux-4.4.111/kernel/auditsc.c linux-4.4.111-vs2.3.9.1/kernel/auditsc.c
12861--- linux-4.4.111/kernel/auditsc.c 2018-01-11 07:57:51.000000000 +0000
12862+++ linux-4.4.111-vs2.3.9.1/kernel/auditsc.c 2018-01-09 16:36:33.000000000 +0000
927ca606 12863@@ -1962,7 +1962,7 @@ static int audit_set_loginuid_perm(kuid_
c2e5f7c8 12864 if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE))
4bf69007 12865 return -EPERM;
c2e5f7c8 12866 /* it is set, you need permission */
4bf69007
AM
12867- if (!capable(CAP_AUDIT_CONTROL))
12868+ if (!vx_capable(CAP_AUDIT_CONTROL, VXC_AUDIT_CONTROL))
12869 return -EPERM;
c2e5f7c8
JR
12870 /* reject if this is not an unset and we don't allow that */
12871 if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid))
f19bd705
AM
12872diff -NurpP --minimal linux-4.4.111/kernel/capability.c linux-4.4.111-vs2.3.9.1/kernel/capability.c
12873--- linux-4.4.111/kernel/capability.c 2018-01-11 07:57:51.000000000 +0000
12874+++ linux-4.4.111-vs2.3.9.1/kernel/capability.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 12875@@ -17,6 +17,7 @@
4bf69007
AM
12876 #include <linux/syscalls.h>
12877 #include <linux/pid_namespace.h>
12878 #include <linux/user_namespace.h>
12879+#include <linux/vs_context.h>
12880 #include <asm/uaccess.h>
12881
12882 /*
927ca606 12883@@ -107,6 +108,7 @@ static int cap_validate_magic(cap_user_h
4bf69007
AM
12884 return 0;
12885 }
12886
2380c486 12887+
4bf69007
AM
12888 /*
12889 * The only thing that can change the capabilities of the current
12890 * process is the current process. As such, we can't be in this code
927ca606 12891@@ -344,6 +346,8 @@ bool has_ns_capability_noaudit(struct ta
4bf69007
AM
12892 return (ret == 0);
12893 }
12894
12895+#include <linux/vserver/base.h>
d337f35e 12896+
4bf69007
AM
12897 /**
12898 * has_capability_noaudit - Does a task have a capability (unaudited) in the
12899 * initial user ns
f19bd705
AM
12900diff -NurpP --minimal linux-4.4.111/kernel/compat.c linux-4.4.111-vs2.3.9.1/kernel/compat.c
12901--- linux-4.4.111/kernel/compat.c 2015-07-06 20:41:43.000000000 +0000
12902+++ linux-4.4.111-vs2.3.9.1/kernel/compat.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
12903@@ -27,6 +27,7 @@
12904 #include <linux/times.h>
12905 #include <linux/ptrace.h>
12906 #include <linux/gfp.h>
12907+#include <linux/vs_time.h>
12908
12909 #include <asm/uaccess.h>
12910
927ca606 12911@@ -1059,7 +1060,7 @@ COMPAT_SYSCALL_DEFINE1(stime, compat_tim
4bf69007
AM
12912 if (err)
12913 return err;
12914
12915- do_settimeofday(&tv);
12916+ vx_settimeofday(&tv);
12917 return 0;
12918 }
12919
f19bd705
AM
12920diff -NurpP --minimal linux-4.4.111/kernel/cred.c linux-4.4.111-vs2.3.9.1/kernel/cred.c
12921--- linux-4.4.111/kernel/cred.c 2018-01-11 07:57:51.000000000 +0000
12922+++ linux-4.4.111-vs2.3.9.1/kernel/cred.c 2018-01-09 16:36:33.000000000 +0000
927ca606 12923@@ -64,31 +64,6 @@ struct cred init_cred = {
b00e13aa 12924 .group_info = &init_groups,
4bf69007
AM
12925 };
12926
12927-static inline void set_cred_subscribers(struct cred *cred, int n)
12928-{
12929-#ifdef CONFIG_DEBUG_CREDENTIALS
12930- atomic_set(&cred->subscribers, n);
12931-#endif
12932-}
12933-
12934-static inline int read_cred_subscribers(const struct cred *cred)
12935-{
12936-#ifdef CONFIG_DEBUG_CREDENTIALS
12937- return atomic_read(&cred->subscribers);
12938-#else
12939- return 0;
12940-#endif
12941-}
12942-
12943-static inline void alter_cred_subscribers(const struct cred *_cred, int n)
12944-{
12945-#ifdef CONFIG_DEBUG_CREDENTIALS
12946- struct cred *cred = (struct cred *) _cred;
12947-
12948- atomic_add(n, &cred->subscribers);
12949-#endif
12950-}
12951-
12952 /*
b00e13aa 12953 * The RCU callback to actually dispose of a set of credentials
4bf69007 12954 */
927ca606 12955@@ -240,21 +215,16 @@ error:
4bf69007
AM
12956 *
12957 * Call commit_creds() or abort_creds() to clean up.
12958 */
12959-struct cred *prepare_creds(void)
12960+struct cred *__prepare_creds(const struct cred *old)
12961 {
12962- struct task_struct *task = current;
12963- const struct cred *old;
12964 struct cred *new;
12965
12966- validate_process_creds();
12967-
12968 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
12969 if (!new)
12970 return NULL;
12971
12972 kdebug("prepare_creds() alloc %p", new);
12973
12974- old = task->cred;
12975 memcpy(new, old, sizeof(struct cred));
12976
12977 atomic_set(&new->usage, 1);
927ca606 12978@@ -283,6 +253,13 @@ error:
4bf69007
AM
12979 abort_creds(new);
12980 return NULL;
12981 }
d337f35e 12982+
4bf69007 12983+struct cred *prepare_creds(void)
2380c486 12984+{
4bf69007 12985+ validate_process_creds();
d337f35e 12986+
4bf69007 12987+ return __prepare_creds(current->cred);
2380c486 12988+}
4bf69007
AM
12989 EXPORT_SYMBOL(prepare_creds);
12990
12991 /*
f19bd705
AM
12992diff -NurpP --minimal linux-4.4.111/kernel/exit.c linux-4.4.111-vs2.3.9.1/kernel/exit.c
12993--- linux-4.4.111/kernel/exit.c 2018-01-11 07:57:51.000000000 +0000
12994+++ linux-4.4.111-vs2.3.9.1/kernel/exit.c 2018-01-09 16:59:03.000000000 +0000
4bf69007
AM
12995@@ -48,6 +48,10 @@
12996 #include <linux/fs_struct.h>
12997 #include <linux/init_task.h>
12998 #include <linux/perf_event.h>
12999+#include <linux/vs_limit.h>
13000+#include <linux/vs_context.h>
13001+#include <linux/vs_network.h>
13002+#include <linux/vs_pid.h>
13003 #include <trace/events/sched.h>
13004 #include <linux/hw_breakpoint.h>
13005 #include <linux/oom.h>
927ca606 13006@@ -456,14 +460,24 @@ static struct task_struct *find_child_re
4bf69007
AM
13007 {
13008 struct pid_namespace *pid_ns = task_active_pid_ns(father);
927ca606 13009 struct task_struct *reaper = pid_ns->child_reaper;
4bf69007 13010+ struct vx_info *vxi = task_get_vx_info(father);
d337f35e 13011+
4bf69007
AM
13012+ if (vxi) {
13013+ BUG_ON(!vxi->vx_reaper);
13014+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
927ca606 13015+ vxi->vx_reaper != father) {
4bf69007 13016+ reaper = vxi->vx_reaper;
927ca606
AM
13017+ goto out_put;
13018+ }
13019+ }
4bf69007 13020
927ca606
AM
13021 if (likely(reaper != father))
13022- return reaper;
13023+ goto out_put;
13024
13025 reaper = find_alive_thread(father);
13026 if (reaper) {
13027 pid_ns->child_reaper = reaper;
13028- return reaper;
13029+ goto out_put;
4bf69007
AM
13030 }
13031
927ca606
AM
13032 write_unlock_irq(&tasklist_lock);
13033@@ -474,7 +488,10 @@ static struct task_struct *find_child_re
13034 zap_pid_ns_processes(pid_ns);
13035 write_lock_irq(&tasklist_lock);
13036
13037- return father;
13038+ reaper = father;
4bf69007
AM
13039+out_put:
13040+ put_vx_info(vxi);
13041+ return reaper;
13042 }
13043
13044 /*
927ca606
AM
13045@@ -562,9 +579,13 @@ static void forget_original_parent(struc
13046 return;
bb20add7 13047
927ca606
AM
13048 reaper = find_new_reaper(father, reaper);
13049- list_for_each_entry(p, &father->children, sibling) {
13050+ for (p = list_first_entry(&father->children, struct task_struct, sibling);
13051+ &p->sibling != &father->children; ) {
13052+ struct task_struct *next, *this_reaper = reaper;
13053+ if (p == reaper)
13054+ this_reaper = task_active_pid_ns(reaper)->child_reaper;
13055 for_each_thread(p, t) {
4bf69007 13056- t->real_parent = reaper;
927ca606
AM
13057+ t->real_parent = this_reaper;
13058 BUG_ON((!t->ptrace) != (t->parent == father));
13059 if (likely(!t->ptrace))
13060 t->parent = t->real_parent;
13061@@ -576,10 +597,13 @@ static void forget_original_parent(struc
13062 * If this is a threaded reparent there is no need to
13063 * notify anyone anything has happened.
13064 */
13065- if (!same_thread_group(reaper, father))
13066+ if (!same_thread_group(this_reaper, father))
13067 reparent_leader(father, p, dead);
13068+ next = list_next_entry(p, sibling);
13069+ list_add(&p->sibling, &this_reaper->children);
13070+ p = next;
13071 }
13072- list_splice_tail_init(&father->children, &reaper->children);
13073+ INIT_LIST_HEAD(&father->children);
13074 }
13075
13076 /*
13077@@ -763,6 +787,9 @@ void do_exit(long code)
4bf69007 13078 */
c2e5f7c8 13079 flush_ptrace_hw_breakpoint(tsk);
4bf69007
AM
13080
13081+ /* needs to stay before exit_notify() */
13082+ exit_vx_info_early(tsk, code);
d337f35e 13083+
927ca606 13084 TASKS_RCU(preempt_disable());
bb20add7 13085 TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
927ca606
AM
13086 TASKS_RCU(preempt_enable());
13087@@ -822,10 +849,15 @@ void do_exit(long code)
4bf69007
AM
13088 smp_mb();
13089 raw_spin_unlock_wait(&tsk->pi_lock);
13090
13091+ /* needs to stay after exit_notify() */
13092+ exit_vx_info(tsk, code);
13093+ exit_nx_info(tsk);
d337f35e 13094+
4bf69007
AM
13095 /* causes final put_task_struct in finish_task_switch(). */
13096 tsk->state = TASK_DEAD;
13097 tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */
13098 schedule();
13099+ printk("bad task: %p [%lx]\n", current, current->state);
13100 BUG();
13101 /* Avoid "noreturn function does return". */
13102 for (;;)
f19bd705
AM
13103diff -NurpP --minimal linux-4.4.111/kernel/fork.c linux-4.4.111-vs2.3.9.1/kernel/fork.c
13104--- linux-4.4.111/kernel/fork.c 2018-01-11 07:57:51.000000000 +0000
13105+++ linux-4.4.111-vs2.3.9.1/kernel/fork.c 2018-01-09 17:00:00.000000000 +0000
927ca606 13106@@ -76,6 +76,9 @@
09be7631 13107 #include <linux/aio.h>
265de2f7 13108 #include <linux/compiler.h>
927ca606 13109 #include <linux/sysctl.h>
4bf69007
AM
13110+#include <linux/vs_context.h>
13111+#include <linux/vs_network.h>
13112+#include <linux/vs_limit.h>
13113
13114 #include <asm/pgtable.h>
13115 #include <asm/pgalloc.h>
927ca606 13116@@ -227,6 +230,8 @@ void free_task(struct task_struct *tsk)
4bf69007
AM
13117 arch_release_thread_info(tsk->stack);
13118 free_thread_info(tsk->stack);
13119 rt_mutex_debug_task_free(tsk);
13120+ clr_vx_info(&tsk->vx_info);
13121+ clr_nx_info(&tsk->nx_info);
13122 ftrace_graph_exit_task(tsk);
13123 put_seccomp_filter(tsk);
13124 arch_release_task_struct(tsk);
927ca606 13125@@ -1282,6 +1287,8 @@ static struct task_struct *copy_process(
8d50a2ea 13126 {
4bf69007
AM
13127 int retval;
13128 struct task_struct *p;
4bf69007
AM
13129+ struct vx_info *vxi;
13130+ struct nx_info *nxi;
927ca606 13131 void *cgrp_ss_priv[CGROUP_CANFORK_COUNT] = {};
4bf69007
AM
13132
13133 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
927ca606 13134@@ -1343,7 +1350,12 @@ static struct task_struct *copy_process(
4bf69007
AM
13135 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
13136 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
13137 #endif
13138+ init_vx_info(&p->vx_info, current_vx_info());
13139+ init_nx_info(&p->nx_info, current_nx_info());
13140+
13141 retval = -EAGAIN;
13142+ if (!vx_nproc_avail(1))
13143+ goto bad_fork_free;
13144 if (atomic_read(&p->real_cred->user->processes) >=
13145 task_rlimit(p, RLIMIT_NPROC)) {
c2e5f7c8 13146 if (p->real_cred->user != INIT_USER &&
927ca606 13147@@ -1640,6 +1652,18 @@ static struct task_struct *copy_process(
4bf69007
AM
13148 total_forks++;
13149 spin_unlock(&current->sighand->siglock);
bb20add7 13150 syscall_tracepoint_update(p);
4bf69007
AM
13151+
13152+ /* p is copy of current */
13153+ vxi = p->vx_info;
13154+ if (vxi) {
13155+ claim_vx_info(vxi, p);
13156+ atomic_inc(&vxi->cvirt.nr_threads);
13157+ atomic_inc(&vxi->cvirt.total_forks);
13158+ vx_nproc_inc(p);
2380c486 13159+ }
4bf69007
AM
13160+ nxi = p->nx_info;
13161+ if (nxi)
13162+ claim_nx_info(nxi, p);
13163 write_unlock_irq(&tasklist_lock);
bb20add7 13164
4bf69007 13165 proc_fork_connector(p);
f19bd705
AM
13166diff -NurpP --minimal linux-4.4.111/kernel/kthread.c linux-4.4.111-vs2.3.9.1/kernel/kthread.c
13167--- linux-4.4.111/kernel/kthread.c 2018-01-11 07:57:52.000000000 +0000
13168+++ linux-4.4.111-vs2.3.9.1/kernel/kthread.c 2018-01-09 17:01:06.000000000 +0000
927ca606 13169@@ -19,6 +19,7 @@
4bf69007 13170 #include <linux/ptrace.h>
09be7631 13171 #include <linux/uaccess.h>
927ca606 13172 #include <linux/cgroup.h>
4bf69007
AM
13173+#include <linux/vs_pid.h>
13174 #include <trace/events/sched.h>
13175
13176 static DEFINE_SPINLOCK(kthread_create_lock);
f19bd705
AM
13177diff -NurpP --minimal linux-4.4.111/kernel/nsproxy.c linux-4.4.111-vs2.3.9.1/kernel/nsproxy.c
13178--- linux-4.4.111/kernel/nsproxy.c 2015-04-12 22:12:50.000000000 +0000
13179+++ linux-4.4.111-vs2.3.9.1/kernel/nsproxy.c 2018-01-09 16:36:33.000000000 +0000
4bf69007
AM
13180@@ -20,11 +20,14 @@
13181 #include <linux/mnt_namespace.h>
13182 #include <linux/utsname.h>
13183 #include <linux/pid_namespace.h>
13184+#include <linux/vserver/global.h>
13185+#include <linux/vserver/debug.h>
13186 #include <net/net_namespace.h>
13187 #include <linux/ipc_namespace.h>
09be7631 13188 #include <linux/proc_ns.h>
4bf69007
AM
13189 #include <linux/file.h>
13190 #include <linux/syscalls.h>
13191+#include "../fs/mount.h"
13192
13193 static struct kmem_cache *nsproxy_cachep;
13194
13195@@ -46,8 +49,11 @@ static inline struct nsproxy *create_nsp
13196 struct nsproxy *nsproxy;
13197
13198 nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
13199- if (nsproxy)
13200+ if (nsproxy) {
13201 atomic_set(&nsproxy->count, 1);
13202+ atomic_inc(&vs_global_nsproxy);
13203+ }
13204+ vxdprintk(VXD_CBIT(space, 2), "create_nsproxy = %p[1]", nsproxy);
13205 return nsproxy;
13206 }
13207
b00e13aa 13208@@ -56,9 +62,12 @@ static inline struct nsproxy *create_nsp
4bf69007
AM
13209 * Return the newly created nsproxy. Do not attach this to the task,
13210 * leave it to the caller to do proper locking and attach it to task.
13211 */
13212-static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13213- struct task_struct *tsk, struct user_namespace *user_ns,
13214- struct fs_struct *new_fs)
13215+static struct nsproxy *unshare_namespaces(
13216+ unsigned long flags,
13217+ struct nsproxy *orig,
13218+ struct fs_struct *new_fs,
13219+ struct user_namespace *new_user,
13220+ struct pid_namespace *new_pid)
4bf69007
AM
13221 {
13222 struct nsproxy *new_nsp;
13223 int err;
c2e5f7c8 13224@@ -67,32 +76,31 @@ static struct nsproxy *create_new_namesp
4bf69007
AM
13225 if (!new_nsp)
13226 return ERR_PTR(-ENOMEM);
13227
b00e13aa
AM
13228- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, user_ns, new_fs);
13229+ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_user, new_fs);
4bf69007
AM
13230 if (IS_ERR(new_nsp->mnt_ns)) {
13231 err = PTR_ERR(new_nsp->mnt_ns);
13232 goto out_ns;
13233 }
13234
b00e13aa
AM
13235- new_nsp->uts_ns = copy_utsname(flags, user_ns, tsk->nsproxy->uts_ns);
13236+ new_nsp->uts_ns = copy_utsname(flags, new_user, orig->uts_ns);
4bf69007
AM
13237 if (IS_ERR(new_nsp->uts_ns)) {
13238 err = PTR_ERR(new_nsp->uts_ns);
13239 goto out_uts;
13240 }
13241
b00e13aa
AM
13242- new_nsp->ipc_ns = copy_ipcs(flags, user_ns, tsk->nsproxy->ipc_ns);
13243+ new_nsp->ipc_ns = copy_ipcs(flags, new_user, orig->ipc_ns);
4bf69007
AM
13244 if (IS_ERR(new_nsp->ipc_ns)) {
13245 err = PTR_ERR(new_nsp->ipc_ns);
13246 goto out_ipc;
13247 }
13248
c2e5f7c8
JR
13249- new_nsp->pid_ns_for_children =
13250- copy_pid_ns(flags, user_ns, tsk->nsproxy->pid_ns_for_children);
13251+ new_nsp->pid_ns_for_children = copy_pid_ns(flags, new_user, new_pid);
13252 if (IS_ERR(new_nsp->pid_ns_for_children)) {
13253 err = PTR_ERR(new_nsp->pid_ns_for_children);
4bf69007
AM
13254 goto out_pid;
13255 }
13256
b00e13aa
AM
13257- new_nsp->net_ns = copy_net_ns(flags, user_ns, tsk->nsproxy->net_ns);
13258+ new_nsp->net_ns = copy_net_ns(flags, new_user, orig->net_ns);
4bf69007
AM
13259 if (IS_ERR(new_nsp->net_ns)) {
13260 err = PTR_ERR(new_nsp->net_ns);
13261 goto out_net;
c2e5f7c8 13262@@ -117,6 +125,41 @@ out_ns:
4bf69007
AM
13263 return ERR_PTR(err);
13264 }
13265
13266+static struct nsproxy *create_new_namespaces(unsigned long flags,
b00e13aa
AM
13267+ struct task_struct *tsk, struct user_namespace *user_ns,
13268+ struct fs_struct *new_fs)
13269+
4bf69007
AM
13270+{
13271+ return unshare_namespaces(flags, tsk->nsproxy,
b00e13aa 13272+ new_fs, user_ns, task_active_pid_ns(tsk));
2380c486 13273+}
d337f35e 13274+
4bf69007
AM
13275+/*
13276+ * copies the nsproxy, setting refcount to 1, and grabbing a
13277+ * reference to all contained namespaces.
13278+ */
13279+struct nsproxy *copy_nsproxy(struct nsproxy *orig)
2380c486 13280+{
4bf69007 13281+ struct nsproxy *ns = create_nsproxy();
d337f35e 13282+
4bf69007
AM
13283+ if (ns) {
13284+ memcpy(ns, orig, sizeof(struct nsproxy));
13285+ atomic_set(&ns->count, 1);
d337f35e 13286+
4bf69007
AM
13287+ if (ns->mnt_ns)
13288+ get_mnt_ns(ns->mnt_ns);
13289+ if (ns->uts_ns)
13290+ get_uts_ns(ns->uts_ns);
13291+ if (ns->ipc_ns)
13292+ get_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13293+ if (ns->pid_ns_for_children)
13294+ get_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13295+ if (ns->net_ns)
13296+ get_net(ns->net_ns);
13297+ }
13298+ return ns;
13299+}
d337f35e 13300+
4bf69007
AM
13301 /*
13302 * called from clone. This now handles copy for nsproxy and all
13303 * namespaces therein.
c2e5f7c8 13304@@ -125,7 +168,10 @@ int copy_namespaces(unsigned long flags,
4bf69007
AM
13305 {
13306 struct nsproxy *old_ns = tsk->nsproxy;
b00e13aa 13307 struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
4bf69007
AM
13308- struct nsproxy *new_ns;
13309+ struct nsproxy *new_ns = NULL;
c2e5f7c8 13310+
4bf69007
AM
13311+ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])",
13312+ flags, tsk, old_ns);
4bf69007 13313
c2e5f7c8
JR
13314 if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
13315 CLONE_NEWPID | CLONE_NEWNET)))) {
13316@@ -133,7 +179,7 @@ int copy_namespaces(unsigned long flags,
4bf69007 13317 return 0;
4bf69007 13318 }
4bf69007 13319
c2e5f7c8
JR
13320- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13321+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, flags))
13322 return -EPERM;
13323
13324 /*
13325@@ -152,6 +198,9 @@ int copy_namespaces(unsigned long flags,
13326 return PTR_ERR(new_ns);
13327
13328 tsk->nsproxy = new_ns;
4bf69007 13329+ vxdprintk(VXD_CBIT(space, 3),
c2e5f7c8
JR
13330+ "copy_namespaces(0x%08lx,%p[%p]) = [%p]",
13331+ flags, tsk, old_ns, new_ns);
13332 return 0;
4bf69007
AM
13333 }
13334
c2e5f7c8 13335@@ -165,7 +214,9 @@ void free_nsproxy(struct nsproxy *ns)
4bf69007 13336 put_ipc_ns(ns->ipc_ns);
c2e5f7c8
JR
13337 if (ns->pid_ns_for_children)
13338 put_pid_ns(ns->pid_ns_for_children);
4bf69007
AM
13339- put_net(ns->net_ns);
13340+ if (ns->net_ns)
13341+ put_net(ns->net_ns);
13342+ atomic_dec(&vs_global_nsproxy);
13343 kmem_cache_free(nsproxy_cachep, ns);
13344 }
13345
c2e5f7c8 13346@@ -179,12 +230,16 @@ int unshare_nsproxy_namespaces(unsigned
b00e13aa 13347 struct user_namespace *user_ns;
4bf69007
AM
13348 int err = 0;
13349
13350+ vxdprintk(VXD_CBIT(space, 4),
13351+ "unshare_nsproxy_namespaces(0x%08lx,[%p])",
13352+ unshare_flags, current->nsproxy);
d337f35e 13353+
4bf69007 13354 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
b00e13aa 13355 CLONE_NEWNET | CLONE_NEWPID)))
4bf69007
AM
13356 return 0;
13357
b00e13aa
AM
13358 user_ns = new_cred ? new_cred->user_ns : current_user_ns();
13359- if (!ns_capable(user_ns, CAP_SYS_ADMIN))
13360+ if (!vx_ns_can_unshare(user_ns, CAP_SYS_ADMIN, unshare_flags))
4bf69007
AM
13361 return -EPERM;
13362
b00e13aa 13363 *new_nsp = create_new_namespaces(unshare_flags, current, user_ns,
f19bd705
AM
13364diff -NurpP --minimal linux-4.4.111/kernel/pid.c linux-4.4.111-vs2.3.9.1/kernel/pid.c
13365--- linux-4.4.111/kernel/pid.c 2018-01-11 07:57:52.000000000 +0000
13366+++ linux-4.4.111-vs2.3.9.1/kernel/pid.c 2018-01-09 21:54:23.000000000 +0000
09be7631 13367@@ -38,6 +38,7 @@
4bf69007 13368 #include <linux/syscalls.h>
09be7631 13369 #include <linux/proc_ns.h>
b00e13aa 13370 #include <linux/proc_fs.h>
4bf69007
AM
13371+#include <linux/vs_pid.h>
13372
13373 #define pid_hashfn(nr, ns) \
13374 hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
927ca606 13375@@ -379,7 +380,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns);
4bf69007
AM
13376
13377 struct pid *find_vpid(int nr)
13378 {
b00e13aa
AM
13379- return find_pid_ns(nr, task_active_pid_ns(current));
13380+ return find_pid_ns(vx_rmap_pid(nr), task_active_pid_ns(current));
4bf69007
AM
13381 }
13382 EXPORT_SYMBOL_GPL(find_vpid);
13383
927ca606 13384@@ -435,6 +436,9 @@ void transfer_pid(struct task_struct *ol
4bf69007
AM
13385 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
13386 {
13387 struct task_struct *result = NULL;
d337f35e 13388+
927ca606 13389+ if (type == __PIDTYPE_REALPID)
4bf69007
AM
13390+ type = PIDTYPE_PID;
13391 if (pid) {
13392 struct hlist_node *first;
13393 first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
927ca606
AM
13394@@ -453,7 +457,7 @@ struct task_struct *find_task_by_pid_ns(
13395 {
13396 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
13397 "find_task_by_pid_ns() needs rcu_read_lock() protection");
4bf69007
AM
13398- return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
13399+ return pid_task(find_pid_ns(vx_rmap_pid(nr), ns), PIDTYPE_PID);
13400 }
13401
13402 struct task_struct *find_task_by_vpid(pid_t vnr)
927ca606 13403@@ -497,7 +501,7 @@ struct pid *find_get_pid(pid_t nr)
4bf69007
AM
13404 }
13405 EXPORT_SYMBOL_GPL(find_get_pid);
13406
13407-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
13408+pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns)
13409 {
13410 struct upid *upid;
13411 pid_t nr = 0;
927ca606 13412@@ -511,6 +515,11 @@ pid_t pid_nr_ns(struct pid *pid, struct
4bf69007
AM
13413 }
13414 EXPORT_SYMBOL_GPL(pid_nr_ns);
13415
13416+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
2380c486 13417+{
4bf69007
AM
13418+ return vx_map_pid(pid_unmapped_nr_ns(pid, ns));
13419+}
d337f35e 13420+
4bf69007
AM
13421 pid_t pid_vnr(struct pid *pid)
13422 {
b00e13aa 13423 return pid_nr_ns(pid, task_active_pid_ns(current));
f19bd705
AM
13424diff -NurpP --minimal linux-4.4.111/kernel/pid_namespace.c linux-4.4.111-vs2.3.9.1/kernel/pid_namespace.c
13425--- linux-4.4.111/kernel/pid_namespace.c 2018-01-11 07:57:52.000000000 +0000
13426+++ linux-4.4.111-vs2.3.9.1/kernel/pid_namespace.c 2018-01-09 16:36:33.000000000 +0000
b00e13aa 13427@@ -18,6 +18,7 @@
09be7631 13428 #include <linux/proc_ns.h>
4bf69007
AM
13429 #include <linux/reboot.h>
13430 #include <linux/export.h>
13431+#include <linux/vserver/global.h>
13432
09be7631
JR
13433 struct pid_cache {
13434 int nr_ids;
927ca606
AM
13435@@ -111,6 +112,7 @@ static struct pid_namespace *create_pid_
13436 ns->ns.ops = &pidns_operations;
4bf69007
AM
13437
13438 kref_init(&ns->kref);
13439+ atomic_inc(&vs_global_pid_ns);
13440 ns->level = level;
13441 ns->parent = get_pid_ns(parent_pid_ns);
b00e13aa 13442 ns->user_ns = get_user_ns(user_ns);
927ca606 13443@@ -128,6 +130,7 @@ static struct pid_namespace *create_pid_
c2e5f7c8
JR
13444 out_free_map:
13445 kfree(ns->pidmap[0].page);
13446 out_free:
4bf69007
AM
13447+ atomic_dec(&vs_global_pid_ns);
13448 kmem_cache_free(pid_ns_cachep, ns);
c2e5f7c8
JR
13449 out:
13450 return ERR_PTR(err);
f19bd705
AM
13451diff -NurpP --minimal linux-4.4.111/kernel/printk/printk.c linux-4.4.111-vs2.3.9.1/kernel/printk/printk.c
13452--- linux-4.4.111/kernel/printk/printk.c 2018-01-11 07:57:52.000000000 +0000
13453+++ linux-4.4.111-vs2.3.9.1/kernel/printk/printk.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13454@@ -46,6 +46,7 @@
09be7631 13455 #include <linux/utsname.h>
bb20add7 13456 #include <linux/ctype.h>
927ca606 13457 #include <linux/uio.h>
4bf69007
AM
13458+#include <linux/vs_cvirt.h>
13459
13460 #include <asm/uaccess.h>
13461
927ca606
AM
13462@@ -502,7 +503,7 @@ int check_syslog_permissions(int type, i
13463 goto ok;
4bf69007
AM
13464
13465 if (syslog_action_restricted(type)) {
13466- if (capable(CAP_SYSLOG))
13467+ if (vx_capable(CAP_SYSLOG, VXC_SYSLOG))
927ca606 13468 goto ok;
092a4f51
JR
13469 /*
13470 * For historical reasons, accept CAP_SYS_ADMIN too, with
927ca606 13471@@ -1304,12 +1305,9 @@ int do_syslog(int type, char __user *buf
4bf69007 13472 if (error)
927ca606 13473 goto out;
4bf69007
AM
13474
13475- switch (type) {
13476- case SYSLOG_ACTION_CLOSE: /* Close log */
13477- break;
13478- case SYSLOG_ACTION_OPEN: /* Open log */
13479- break;
13480- case SYSLOG_ACTION_READ: /* Read from log */
13481+ if ((type == SYSLOG_ACTION_READ) ||
13482+ (type == SYSLOG_ACTION_READ_ALL) ||
13483+ (type == SYSLOG_ACTION_READ_CLEAR)) {
13484 error = -EINVAL;
13485 if (!buf || len < 0)
13486 goto out;
927ca606 13487@@ -1320,6 +1318,16 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13488 error = -EFAULT;
13489 goto out;
13490 }
13491+ }
13492+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13493+ return vx_do_syslog(type, buf, len);
d337f35e 13494+
4bf69007
AM
13495+ switch (type) {
13496+ case SYSLOG_ACTION_CLOSE: /* Close log */
13497+ break;
13498+ case SYSLOG_ACTION_OPEN: /* Open log */
13499+ break;
13500+ case SYSLOG_ACTION_READ: /* Read from log */
13501 error = wait_event_interruptible(log_wait,
13502 syslog_seq != log_next_seq);
13503 if (error)
927ca606 13504@@ -1332,16 +1340,6 @@ int do_syslog(int type, char __user *buf
4bf69007
AM
13505 /* FALL THRU */
13506 /* Read last kernel messages */
13507 case SYSLOG_ACTION_READ_ALL:
13508- error = -EINVAL;
13509- if (!buf || len < 0)
13510- goto out;
13511- error = 0;
13512- if (!len)
13513- goto out;
13514- if (!access_ok(VERIFY_WRITE, buf, len)) {
13515- error = -EFAULT;
13516- goto out;
13517- }
13518 error = syslog_print_all(buf, len, clear);
13519 break;
13520 /* Clear ring buffer */
f19bd705
AM
13521diff -NurpP --minimal linux-4.4.111/kernel/ptrace.c linux-4.4.111-vs2.3.9.1/kernel/ptrace.c
13522--- linux-4.4.111/kernel/ptrace.c 2018-01-11 07:57:52.000000000 +0000
13523+++ linux-4.4.111-vs2.3.9.1/kernel/ptrace.c 2018-01-09 16:36:33.000000000 +0000
09be7631 13524@@ -23,6 +23,7 @@
4bf69007
AM
13525 #include <linux/syscalls.h>
13526 #include <linux/uaccess.h>
13527 #include <linux/regset.h>
13528+#include <linux/vs_context.h>
13529 #include <linux/hw_breakpoint.h>
13530 #include <linux/cn_proc.h>
09be7631 13531 #include <linux/compat.h>
927ca606
AM
13532@@ -295,6 +296,11 @@ ok:
13533 !ptrace_has_cap(mm->user_ns, mode)))
13534 return -EPERM;
b00e13aa 13535
4bf69007
AM
13536+ if (!vx_check(task->xid, VS_ADMIN_P|VS_WATCH_P|VS_IDENT))
13537+ return -EPERM;
13538+ if (!vx_check(task->xid, VS_IDENT) &&
13539+ !task_vx_flags(task, VXF_STATE_ADMIN, 0))
13540+ return -EACCES;
4bf69007
AM
13541 return security_ptrace_access_check(task, mode);
13542 }
b00e13aa 13543
f19bd705
AM
13544diff -NurpP --minimal linux-4.4.111/kernel/reboot.c linux-4.4.111-vs2.3.9.1/kernel/reboot.c
13545--- linux-4.4.111/kernel/reboot.c 2016-07-05 04:12:39.000000000 +0000
13546+++ linux-4.4.111-vs2.3.9.1/kernel/reboot.c 2018-01-09 16:36:33.000000000 +0000
c2e5f7c8
JR
13547@@ -16,6 +16,7 @@
13548 #include <linux/syscalls.h>
13549 #include <linux/syscore_ops.h>
13550 #include <linux/uaccess.h>
13551+#include <linux/vs_pid.h>
13552
13553 /*
13554 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
bb20add7 13555@@ -269,6 +270,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
c2e5f7c8
JR
13556
13557 static DEFINE_MUTEX(reboot_mutex);
13558
13559+long vs_reboot(unsigned int, void __user *);
13560+
13561 /*
13562 * Reboot system call: for obvious reasons only root may call it,
13563 * and even root needs to set up some magic numbers in the registers
bb20add7 13564@@ -311,6 +314,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
c2e5f7c8
JR
13565 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
13566 cmd = LINUX_REBOOT_CMD_HALT;
13567
13568+ if (!vx_check(0, VS_ADMIN|VS_WATCH))
13569+ return vs_reboot(cmd, arg);
13570+
13571 mutex_lock(&reboot_mutex);
13572 switch (cmd) {
13573 case LINUX_REBOOT_CMD_RESTART:
f19bd705
AM
13574diff -NurpP --minimal linux-4.4.111/kernel/sched/core.c linux-4.4.111-vs2.3.9.1/kernel/sched/core.c
13575--- linux-4.4.111/kernel/sched/core.c 2018-01-11 07:57:52.000000000 +0000
13576+++ linux-4.4.111-vs2.3.9.1/kernel/sched/core.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13577@@ -74,6 +74,8 @@
4bf69007 13578 #include <linux/binfmts.h>
b00e13aa 13579 #include <linux/context_tracking.h>
265de2f7 13580 #include <linux/compiler.h>
4bf69007
AM
13581+#include <linux/vs_sched.h>
13582+#include <linux/vs_cvirt.h>
13583
13584 #include <asm/switch_to.h>
13585 #include <asm/tlb.h>
927ca606 13586@@ -3558,7 +3560,7 @@ SYSCALL_DEFINE1(nice, int, increment)
4bf69007 13587
bb20add7 13588 nice = clamp_val(nice, MIN_NICE, MAX_NICE);
4bf69007
AM
13589 if (increment < 0 && !can_nice(current, nice))
13590- return -EPERM;
13591+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
13592
13593 retval = security_task_setnice(current, nice);
13594 if (retval)
f19bd705
AM
13595diff -NurpP --minimal linux-4.4.111/kernel/sched/cputime.c linux-4.4.111-vs2.3.9.1/kernel/sched/cputime.c
13596--- linux-4.4.111/kernel/sched/cputime.c 2018-01-11 07:57:52.000000000 +0000
13597+++ linux-4.4.111-vs2.3.9.1/kernel/sched/cputime.c 2018-01-09 16:36:33.000000000 +0000
b00e13aa 13598@@ -4,6 +4,7 @@
4bf69007
AM
13599 #include <linux/kernel_stat.h>
13600 #include <linux/static_key.h>
b00e13aa 13601 #include <linux/context_tracking.h>
4bf69007
AM
13602+#include <linux/vs_sched.h>
13603 #include "sched.h"
13604
13605
bb20add7 13606@@ -135,14 +136,17 @@ static inline void task_group_account_fi
4bf69007
AM
13607 void account_user_time(struct task_struct *p, cputime_t cputime,
13608 cputime_t cputime_scaled)
13609 {
13610+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
ca5d134c 13611+ int nice = (task_nice(p) > 0);
4bf69007
AM
13612 int index;
13613
13614 /* Add user time to process. */
13615 p->utime += cputime;
13616 p->utimescaled += cputime_scaled;
13617+ vx_account_user(vxi, cputime, nice);
13618 account_group_user_time(p, cputime);
13619
ca5d134c 13620- index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
4bf69007
AM
13621+ index = (nice) ? CPUTIME_NICE : CPUTIME_USER;
13622
13623 /* Add user time to cpustat. */
13624 task_group_account_field(p, index, (__force u64) cputime);
bb20add7 13625@@ -189,9 +193,12 @@ static inline
ca5d134c
JR
13626 void __account_system_time(struct task_struct *p, cputime_t cputime,
13627 cputime_t cputime_scaled, int index)
13628 {
13629+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */
13630+
13631 /* Add system time to process. */
13632 p->stime += cputime;
13633 p->stimescaled += cputime_scaled;
13634+ vx_account_system(vxi, cputime, 0 /* do we have idle time? */);
13635 account_group_system_time(p, cputime);
13636
13637 /* Add system time to cpustat. */
f19bd705
AM
13638diff -NurpP --minimal linux-4.4.111/kernel/sched/fair.c linux-4.4.111-vs2.3.9.1/kernel/sched/fair.c
13639--- linux-4.4.111/kernel/sched/fair.c 2018-01-11 07:57:52.000000000 +0000
13640+++ linux-4.4.111-vs2.3.9.1/kernel/sched/fair.c 2018-01-09 16:36:33.000000000 +0000
bb20add7 13641@@ -30,6 +30,7 @@
b00e13aa
AM
13642 #include <linux/mempolicy.h>
13643 #include <linux/migrate.h>
13644 #include <linux/task_work.h>
4bf69007
AM
13645+#include <linux/vs_cvirt.h>
13646
13647 #include <trace/events/sched.h>
13648
927ca606 13649@@ -3055,6 +3056,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13650 __enqueue_entity(cfs_rq, se);
13651 se->on_rq = 1;
13652
13653+ if (entity_is_task(se))
13654+ vx_activate_task(task_of(se));
13655 if (cfs_rq->nr_running == 1) {
13656 list_add_leaf_cfs_rq(cfs_rq);
13657 check_enqueue_throttle(cfs_rq);
927ca606 13658@@ -3136,6 +3139,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st
4bf69007
AM
13659 if (se != cfs_rq->curr)
13660 __dequeue_entity(cfs_rq, se);
13661 se->on_rq = 0;
13662+ if (entity_is_task(se))
13663+ vx_deactivate_task(task_of(se));
4bf69007
AM
13664 account_entity_dequeue(cfs_rq, se);
13665
b00e13aa 13666 /*
f19bd705
AM
13667diff -NurpP --minimal linux-4.4.111/kernel/signal.c linux-4.4.111-vs2.3.9.1/kernel/signal.c
13668--- linux-4.4.111/kernel/signal.c 2018-01-11 07:57:52.000000000 +0000
13669+++ linux-4.4.111-vs2.3.9.1/kernel/signal.c 2018-01-11 08:03:00.000000000 +0000
bb20add7 13670@@ -34,6 +34,8 @@
b00e13aa 13671 #include <linux/compat.h>
09be7631 13672 #include <linux/cn_proc.h>
265de2f7 13673 #include <linux/compiler.h>
4bf69007
AM
13674+#include <linux/vs_context.h>
13675+#include <linux/vs_pid.h>
265de2f7 13676
4bf69007
AM
13677 #define CREATE_TRACE_POINTS
13678 #include <trace/events/signal.h>
f19bd705 13679@@ -726,9 +728,18 @@ static int check_kill_permission(int sig
4bf69007
AM
13680 struct pid *sid;
13681 int error;
13682
13683+ vxdprintk(VXD_CBIT(misc, 7),
13684+ "check_kill_permission(%d,%p,%p[#%u,%u])",
13685+ sig, info, t, vx_task_xid(t), t->pid);
d337f35e 13686+
4bf69007
AM
13687 if (!valid_signal(sig))
13688 return -EINVAL;
13689
13690+/* FIXME: needed? if so, why?
13691+ if ((info != SEND_SIG_NOINFO) &&
13692+ (is_si_special(info) || !si_fromuser(info)))
13693+ goto skip; */
d337f35e 13694+
4bf69007
AM
13695 if (!si_fromuser(info))
13696 return 0;
13697
f19bd705 13698@@ -752,6 +763,20 @@ static int check_kill_permission(int sig
4bf69007
AM
13699 }
13700 }
13701
13702+ error = -EPERM;
13703+ if (t->pid == 1 && current->xid)
13704+ return error;
d337f35e 13705+
4bf69007
AM
13706+ error = -ESRCH;
13707+ /* FIXME: we shouldn't return ESRCH ever, to avoid
13708+ loops, maybe ENOENT or EACCES? */
13709+ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) {
13710+ vxdprintk(current->xid || VXD_CBIT(misc, 7),
13711+ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u",
13712+ sig, info, t, vx_task_xid(t), t->pid, current->xid);
13713+ return error;
2380c486 13714+ }
4bf69007
AM
13715+/* skip: */
13716 return security_task_kill(t, info, sig, 0);
13717 }
13718
f19bd705 13719@@ -1303,8 +1328,14 @@ int kill_pid_info(int sig, struct siginf
927ca606
AM
13720 for (;;) {
13721 rcu_read_lock();
13722 p = pid_task(pid, PIDTYPE_PID);
13723- if (p)
13724- error = group_send_sig_info(sig, info, p);
13725+ if (p) {
13726+ if (vx_check(vx_task_xid(p), VS_IDENT))
13727+ error = group_send_sig_info(sig, info, p);
13728+ else {
13729+ rcu_read_unlock();
13730+ return -ESRCH;
13731+ }
13732+ }
13733 rcu_read_unlock();
13734 if (likely(!p || error != -ESRCH))
13735 return error;
f19bd705 13736@@ -1349,7 +1380,7 @@ int kill_pid_info_as_cred(int sig, struc
4bf69007
AM
13737
13738 rcu_read_lock();
13739 p = pid_task(pid, PIDTYPE_PID);
13740- if (!p) {
13741+ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) {
13742 ret = -ESRCH;
13743 goto out_unlock;
13744 }
f19bd705 13745@@ -1401,8 +1432,10 @@ static int kill_something_info(int sig,
4bf69007
AM
13746 struct task_struct * p;
13747
13748 for_each_process(p) {
13749- if (task_pid_vnr(p) > 1 &&
13750- !same_thread_group(p, current)) {
13751+ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) &&
13752+ task_pid_vnr(p) > 1 &&
13753+ !same_thread_group(p, current) &&
13754+ !vx_current_initpid(p->pid)) {
13755 int err = group_send_sig_info(sig, info, p);
13756 ++count;
13757 if (err != -EPERM)
f19bd705 13758@@ -2255,6 +2288,11 @@ relock:
4bf69007
AM
13759 !sig_kernel_only(signr))
13760 continue;
13761
13762+ /* virtual init is protected against user signals */
bb20add7 13763+ if ((ksig->info.si_code == SI_USER) &&
4bf69007
AM
13764+ vx_current_initpid(current->pid))
13765+ continue;
d337f35e 13766+
4bf69007
AM
13767 if (sig_kernel_stop(signr)) {
13768 /*
13769 * The default action is to stop all threads in
f19bd705
AM
13770diff -NurpP --minimal linux-4.4.111/kernel/softirq.c linux-4.4.111-vs2.3.9.1/kernel/softirq.c
13771--- linux-4.4.111/kernel/softirq.c 2015-04-12 22:12:50.000000000 +0000
13772+++ linux-4.4.111-vs2.3.9.1/kernel/softirq.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 13773@@ -26,6 +26,7 @@
4bf69007
AM
13774 #include <linux/smpboot.h>
13775 #include <linux/tick.h>
265de2f7 13776 #include <linux/irq.h>
4bf69007
AM
13777+#include <linux/vs_context.h>
13778
13779 #define CREATE_TRACE_POINTS
13780 #include <trace/events/irq.h>
f19bd705
AM
13781diff -NurpP --minimal linux-4.4.111/kernel/sys.c linux-4.4.111-vs2.3.9.1/kernel/sys.c
13782--- linux-4.4.111/kernel/sys.c 2018-01-11 07:57:52.000000000 +0000
13783+++ linux-4.4.111-vs2.3.9.1/kernel/sys.c 2018-01-09 17:00:36.000000000 +0000
c2e5f7c8 13784@@ -54,6 +54,7 @@
09be7631 13785 #include <linux/cred.h>
4bf69007
AM
13786
13787 #include <linux/kmsg_dump.h>
b00e13aa 13788+#include <linux/vs_pid.h>
4bf69007 13789 /* Move somewhere else to avoid recompiling? */
b00e13aa
AM
13790 #include <generated/utsrelease.h>
13791
927ca606 13792@@ -157,7 +158,10 @@ static int set_one_prio(struct task_stru
4bf69007
AM
13793 goto out;
13794 }
13795 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
13796- error = -EACCES;
13797+ if (vx_flags(VXF_IGNEG_NICE, 0))
13798+ error = 0;
13799+ else
13800+ error = -EACCES;
13801 goto out;
13802 }
13803 no_nice = security_task_setnice(p, niceval);
927ca606 13804@@ -208,6 +212,8 @@ SYSCALL_DEFINE3(setpriority, int, which,
bb20add7
AM
13805 else
13806 pgrp = task_pgrp(current);
13807 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13808+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13809+ continue;
13810 error = set_one_prio(p, niceval, error);
13811 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
13812 break;
927ca606 13813@@ -274,6 +280,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13814 else
13815 pgrp = task_pgrp(current);
13816 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
13817+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13818+ continue;
13819 niceval = nice_to_rlimit(task_nice(p));
13820 if (niceval > retval)
13821 retval = niceval;
927ca606 13822@@ -290,6 +298,8 @@ SYSCALL_DEFINE2(getpriority, int, which,
bb20add7
AM
13823 goto out_unlock; /* No processes for this user */
13824 }
13825 do_each_thread(g, p) {
13826+ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT))
13827+ continue;
927ca606 13828 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
bb20add7 13829 niceval = nice_to_rlimit(task_nice(p));
4bf69007 13830 if (niceval > retval)
927ca606 13831@@ -1217,7 +1227,8 @@ SYSCALL_DEFINE2(sethostname, char __user
4bf69007
AM
13832 int errno;
13833 char tmp[__NEW_UTS_LEN];
13834
13835- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13836+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13837+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13838 return -EPERM;
13839
13840 if (len < 0 || len > __NEW_UTS_LEN)
927ca606 13841@@ -1268,7 +1279,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
4bf69007
AM
13842 int errno;
13843 char tmp[__NEW_UTS_LEN];
13844
13845- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
13846+ if (!vx_ns_capable(current->nsproxy->uts_ns->user_ns,
13847+ CAP_SYS_ADMIN, VXC_SET_UTSNAME))
13848 return -EPERM;
13849 if (len < 0 || len > __NEW_UTS_LEN)
13850 return -EINVAL;
927ca606 13851@@ -1386,7 +1398,7 @@ int do_prlimit(struct task_struct *tsk,
4bf69007
AM
13852 /* Keep the capable check against init_user_ns until
13853 cgroups can contain all limits */
13854 if (new_rlim->rlim_max > rlim->rlim_max &&
13855- !capable(CAP_SYS_RESOURCE))
13856+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13857 retval = -EPERM;
13858 if (!retval)
13859 retval = security_task_setrlimit(tsk->group_leader,
927ca606 13860@@ -1439,7 +1451,8 @@ static int check_prlimit_permission(stru
4bf69007
AM
13861 gid_eq(cred->gid, tcred->sgid) &&
13862 gid_eq(cred->gid, tcred->gid))
13863 return 0;
13864- if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
13865+ if (vx_ns_capable(tcred->user_ns,
13866+ CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
13867 return 0;
13868
13869 return -EPERM;
f19bd705
AM
13870diff -NurpP --minimal linux-4.4.111/kernel/sysctl.c linux-4.4.111-vs2.3.9.1/kernel/sysctl.c
13871--- linux-4.4.111/kernel/sysctl.c 2018-01-11 07:57:52.000000000 +0000
13872+++ linux-4.4.111-vs2.3.9.1/kernel/sysctl.c 2018-01-09 16:36:34.000000000 +0000
927ca606 13873@@ -87,6 +87,7 @@
4bf69007
AM
13874 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
13875 #include <linux/lockdep.h>
13876 #endif
13877+extern char vshelper_path[];
13878 #ifdef CONFIG_CHR_DEV_SG
13879 #include <scsi/sg.h>
13880 #endif
927ca606 13881@@ -279,6 +280,13 @@ static int max_extfrag_threshold = 1000;
bb20add7
AM
13882
13883 static struct ctl_table kern_table[] = {
13884 {
4bf69007
AM
13885+ .procname = "vshelper",
13886+ .data = &vshelper_path,
13887+ .maxlen = 256,
13888+ .mode = 0644,
bb20add7 13889+ .proc_handler = proc_dostring,
4bf69007 13890+ },
bb20add7
AM
13891+ {
13892 .procname = "sched_child_runs_first",
13893 .data = &sysctl_sched_child_runs_first,
13894 .maxlen = sizeof(unsigned int),
927ca606
AM
13895@@ -1385,7 +1393,6 @@ static struct ctl_table vm_table[] = {
13896 .extra1 = &zero,
13897 .extra2 = &one,
bb20add7
AM
13898 },
13899-
13900 #endif /* CONFIG_COMPACTION */
4bf69007 13901 {
bb20add7 13902 .procname = "min_free_kbytes",
f19bd705
AM
13903diff -NurpP --minimal linux-4.4.111/kernel/sysctl_binary.c linux-4.4.111-vs2.3.9.1/kernel/sysctl_binary.c
13904--- linux-4.4.111/kernel/sysctl_binary.c 2018-01-11 07:57:52.000000000 +0000
13905+++ linux-4.4.111-vs2.3.9.1/kernel/sysctl_binary.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 13906@@ -73,6 +73,7 @@ static const struct bin_table bin_kern_t
4bf69007
AM
13907
13908 { CTL_INT, KERN_PANIC, "panic" },
13909 { CTL_INT, KERN_REALROOTDEV, "real-root-dev" },
13910+ { CTL_STR, KERN_VSHELPER, "vshelper" },
13911
13912 { CTL_STR, KERN_SPARC_REBOOT, "reboot-cmd" },
13913 { CTL_INT, KERN_CTLALTDEL, "ctrl-alt-del" },
f19bd705
AM
13914diff -NurpP --minimal linux-4.4.111/kernel/time/posix-timers.c linux-4.4.111-vs2.3.9.1/kernel/time/posix-timers.c
13915--- linux-4.4.111/kernel/time/posix-timers.c 2018-01-11 07:57:52.000000000 +0000
13916+++ linux-4.4.111-vs2.3.9.1/kernel/time/posix-timers.c 2018-01-09 16:36:34.000000000 +0000
bb20add7
AM
13917@@ -48,6 +48,7 @@
13918 #include <linux/workqueue.h>
13919 #include <linux/export.h>
13920 #include <linux/hashtable.h>
13921+#include <linux/vs_context.h>
4bf69007 13922
bb20add7 13923 #include "timekeeping.h"
4bf69007 13924
927ca606 13925@@ -407,6 +408,7 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
13926 {
13927 struct task_struct *task;
13928 int shared, ret = -1;
13929+
13930 /*
13931 * FIXME: if ->sigq is queued we can race with
13932 * dequeue_signal()->do_schedule_next_timer().
927ca606 13933@@ -423,10 +425,18 @@ int posix_timer_event(struct k_itimer *t
bb20add7
AM
13934 rcu_read_lock();
13935 task = pid_task(timr->it_pid, PIDTYPE_PID);
13936 if (task) {
13937+ struct vx_info_save vxis;
13938+ struct vx_info *vxi;
13939+
13940+ vxi = get_vx_info(task->vx_info);
13941+ enter_vx_info(vxi, &vxis);
13942 shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
13943 ret = send_sigqueue(timr->sigq, task, shared);
13944+ leave_vx_info(&vxis);
13945+ put_vx_info(vxi);
13946 }
13947 rcu_read_unlock();
13948+
13949 /* If we failed to send the signal the timer stops. */
13950 return ret > 0;
4bf69007 13951 }
f19bd705
AM
13952diff -NurpP --minimal linux-4.4.111/kernel/time/time.c linux-4.4.111-vs2.3.9.1/kernel/time/time.c
13953--- linux-4.4.111/kernel/time/time.c 2016-07-05 04:12:39.000000000 +0000
13954+++ linux-4.4.111-vs2.3.9.1/kernel/time/time.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
13955@@ -37,6 +37,7 @@
13956 #include <linux/fs.h>
13957 #include <linux/math64.h>
13958 #include <linux/ptrace.h>
13959+#include <linux/vs_time.h>
13960
13961 #include <asm/uaccess.h>
13962 #include <asm/unistd.h>
bb20add7 13963@@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *,
4bf69007
AM
13964 if (err)
13965 return err;
13966
13967- do_settimeofday(&tv);
13968+ vx_settimeofday(&tv);
13969 return 0;
13970 }
13971
927ca606 13972@@ -186,7 +187,7 @@ int do_sys_settimeofday(const struct tim
4bf69007
AM
13973 }
13974 }
13975 if (tv)
13976- return do_settimeofday(tv);
13977+ return vx_settimeofday(tv);
13978 return 0;
13979 }
13980
f19bd705
AM
13981diff -NurpP --minimal linux-4.4.111/kernel/time/timekeeping.c linux-4.4.111-vs2.3.9.1/kernel/time/timekeeping.c
13982--- linux-4.4.111/kernel/time/timekeeping.c 2018-01-11 07:57:52.000000000 +0000
13983+++ linux-4.4.111-vs2.3.9.1/kernel/time/timekeeping.c 2018-01-09 17:02:47.000000000 +0000
bb20add7
AM
13984@@ -23,6 +23,7 @@
13985 #include <linux/stop_machine.h>
13986 #include <linux/pvclock_gtod.h>
13987 #include <linux/compiler.h>
13988+#include <linux/vs_time.h>
13989
13990 #include "tick-internal.h"
13991 #include "ntp_internal.h"
927ca606 13992@@ -921,7 +922,9 @@ void ktime_get_raw_and_real_ts64(struct
bb20add7
AM
13993 } while (read_seqcount_retry(&tk_core.seq, seq));
13994
927ca606 13995 timespec64_add_ns(ts_raw, nsecs_raw);
bb20add7 13996+ vx_adjust_timespec(ts_raw);
927ca606 13997 timespec64_add_ns(ts_real, nsecs_real);
bb20add7
AM
13998+ vx_adjust_timespec(ts_real);
13999 }
927ca606 14000 EXPORT_SYMBOL(ktime_get_raw_and_real_ts64);
bb20add7 14001
f19bd705
AM
14002diff -NurpP --minimal linux-4.4.111/kernel/time/timer.c linux-4.4.111-vs2.3.9.1/kernel/time/timer.c
14003--- linux-4.4.111/kernel/time/timer.c 2018-01-11 07:57:52.000000000 +0000
14004+++ linux-4.4.111-vs2.3.9.1/kernel/time/timer.c 2018-01-09 16:36:34.000000000 +0000
09be7631 14005@@ -42,6 +42,10 @@
b00e13aa 14006 #include <linux/sched/sysctl.h>
4bf69007 14007 #include <linux/slab.h>
09be7631 14008 #include <linux/compat.h>
4bf69007
AM
14009+#include <linux/vs_base.h>
14010+#include <linux/vs_cvirt.h>
14011+#include <linux/vs_pid.h>
14012+#include <linux/vserver/sched.h>
14013
14014 #include <asm/uaccess.h>
14015 #include <asm/unistd.h>
f19bd705
AM
14016diff -NurpP --minimal linux-4.4.111/kernel/user_namespace.c linux-4.4.111-vs2.3.9.1/kernel/user_namespace.c
14017--- linux-4.4.111/kernel/user_namespace.c 2016-07-05 04:12:39.000000000 +0000
14018+++ linux-4.4.111-vs2.3.9.1/kernel/user_namespace.c 2018-01-09 16:36:34.000000000 +0000
b00e13aa 14019@@ -22,6 +22,7 @@
4bf69007
AM
14020 #include <linux/ctype.h>
14021 #include <linux/projid.h>
b00e13aa 14022 #include <linux/fs_struct.h>
4bf69007
AM
14023+#include <linux/vserver/global.h>
14024
14025 static struct kmem_cache *user_ns_cachep __read_mostly;
bb20add7 14026 static DEFINE_MUTEX(userns_state_mutex);
927ca606 14027@@ -97,6 +98,7 @@ int create_user_ns(struct cred *new)
4bf69007 14028
b00e13aa
AM
14029 atomic_set(&ns->count, 1);
14030 /* Leave the new->user_ns reference with the new user namespace. */
4bf69007
AM
14031+ atomic_inc(&vs_global_user_ns);
14032 ns->parent = parent_ns;
09be7631 14033 ns->level = parent_ns->level + 1;
4bf69007 14034 ns->owner = owner;
927ca606
AM
14035@@ -145,6 +147,7 @@ void free_user_ns(struct user_namespace
14036 key_put(ns->persistent_keyring_register);
14037 #endif
14038 ns_free_inum(&ns->ns);
14039+ atomic_dec(&vs_global_user_ns);
14040 kmem_cache_free(user_ns_cachep, ns);
14041 ns = parent;
14042 } while (atomic_dec_and_test(&parent->count));
14043@@ -358,6 +361,18 @@ gid_t from_kgid_munged(struct user_names
bb20add7
AM
14044 }
14045 EXPORT_SYMBOL(from_kgid_munged);
14046
14047+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
14048+{
14049+ return KTAGT_INIT(tag);
14050+}
14051+EXPORT_SYMBOL(make_ktag);
14052+
14053+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
14054+{
14055+ return __ktag_val(tag);
14056+}
14057+EXPORT_SYMBOL(from_ktag);
14058+
14059 /**
14060 * make_kprojid - Map a user-namespace projid pair into a kprojid.
14061 * @ns: User namespace that the projid is in
f19bd705
AM
14062diff -NurpP --minimal linux-4.4.111/kernel/utsname.c linux-4.4.111-vs2.3.9.1/kernel/utsname.c
14063--- linux-4.4.111/kernel/utsname.c 2015-04-12 22:12:50.000000000 +0000
14064+++ linux-4.4.111-vs2.3.9.1/kernel/utsname.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14065@@ -16,14 +16,17 @@
14066 #include <linux/slab.h>
14067 #include <linux/user_namespace.h>
09be7631 14068 #include <linux/proc_ns.h>
4bf69007
AM
14069+#include <linux/vserver/global.h>
14070
14071 static struct uts_namespace *create_uts_ns(void)
14072 {
14073 struct uts_namespace *uts_ns;
14074
14075 uts_ns = kmalloc(sizeof(struct uts_namespace), GFP_KERNEL);
14076- if (uts_ns)
14077+ if (uts_ns) {
c2e5f7c8 14078 kref_init(&uts_ns->kref);
4bf69007
AM
14079+ atomic_inc(&vs_global_uts_ns);
14080+ }
14081 return uts_ns;
14082 }
14083
927ca606 14084@@ -87,6 +90,7 @@ void free_uts_ns(struct kref *kref)
4bf69007
AM
14085 ns = container_of(kref, struct uts_namespace, kref);
14086 put_user_ns(ns->user_ns);
927ca606 14087 ns_free_inum(&ns->ns);
4bf69007
AM
14088+ atomic_dec(&vs_global_uts_ns);
14089 kfree(ns);
14090 }
14091
f19bd705
AM
14092diff -NurpP --minimal linux-4.4.111/kernel/vserver/Kconfig linux-4.4.111-vs2.3.9.1/kernel/vserver/Kconfig
14093--- linux-4.4.111/kernel/vserver/Kconfig 1970-01-01 00:00:00.000000000 +0000
14094+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/Kconfig 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 14095@@ -0,0 +1,230 @@
4bf69007
AM
14096+#
14097+# Linux VServer configuration
14098+#
d337f35e 14099+
4bf69007 14100+menu "Linux VServer"
d337f35e 14101+
4bf69007
AM
14102+config VSERVER_AUTO_LBACK
14103+ bool "Automatically Assign Loopback IP"
14104+ default y
14105+ help
14106+ Automatically assign a guest specific loopback
14107+ IP and add it to the kernel network stack on
14108+ startup.
d337f35e 14109+
4bf69007
AM
14110+config VSERVER_AUTO_SINGLE
14111+ bool "Automatic Single IP Special Casing"
c2e5f7c8 14112+ default n
4bf69007
AM
14113+ help
14114+ This allows network contexts with a single IP to
14115+ automatically remap 0.0.0.0 bindings to that IP,
14116+ avoiding further network checks and improving
14117+ performance.
d337f35e 14118+
4bf69007
AM
14119+ (note: such guests do not allow to change the ip
14120+ on the fly and do not show loopback addresses)
2380c486 14121+
4bf69007
AM
14122+config VSERVER_COWBL
14123+ bool "Enable COW Immutable Link Breaking"
14124+ default y
14125+ help
14126+ This enables the COW (Copy-On-Write) link break code.
14127+ It allows you to treat unified files like normal files
14128+ when writing to them (which will implicitely break the
14129+ link and create a copy of the unified file)
d337f35e 14130+
4bf69007 14131+config VSERVER_VTIME
c2e5f7c8 14132+ bool "Enable Virtualized Guest Time (EXPERIMENTAL)"
4bf69007
AM
14133+ default n
14134+ help
14135+ This enables per guest time offsets to allow for
14136+ adjusting the system clock individually per guest.
14137+ this adds some overhead to the time functions and
14138+ therefore should not be enabled without good reason.
d337f35e 14139+
4bf69007 14140+config VSERVER_DEVICE
c2e5f7c8 14141+ bool "Enable Guest Device Mapping (EXPERIMENTAL)"
4bf69007
AM
14142+ default n
14143+ help
14144+ This enables generic device remapping.
d337f35e 14145+
4bf69007
AM
14146+config VSERVER_PROC_SECURE
14147+ bool "Enable Proc Security"
14148+ depends on PROC_FS
14149+ default y
14150+ help
14151+ This configures ProcFS security to initially hide
14152+ non-process entries for all contexts except the main and
14153+ spectator context (i.e. for all guests), which is a secure
14154+ default.
d337f35e 14155+
4bf69007 14156+ (note: on 1.2x the entries were visible by default)
d337f35e 14157+
4bf69007
AM
14158+choice
14159+ prompt "Persistent Inode Tagging"
14160+ default TAGGING_ID24
14161+ help
14162+ This adds persistent context information to filesystems
14163+ mounted with the tagxid option. Tagging is a requirement
14164+ for per-context disk limits and per-context quota.
d337f35e 14165+
d337f35e 14166+
4bf69007
AM
14167+config TAGGING_NONE
14168+ bool "Disabled"
14169+ help
14170+ do not store per-context information in inodes.
d337f35e 14171+
4bf69007
AM
14172+config TAGGING_UID16
14173+ bool "UID16/GID32"
14174+ help
14175+ reduces UID to 16 bit, but leaves GID at 32 bit.
d337f35e 14176+
4bf69007
AM
14177+config TAGGING_GID16
14178+ bool "UID32/GID16"
14179+ help
14180+ reduces GID to 16 bit, but leaves UID at 32 bit.
d337f35e 14181+
4bf69007
AM
14182+config TAGGING_ID24
14183+ bool "UID24/GID24"
14184+ help
14185+ uses the upper 8bit from UID and GID for XID tagging
14186+ which leaves 24bit for UID/GID each, which should be
14187+ more than sufficient for normal use.
d337f35e 14188+
4bf69007
AM
14189+config TAGGING_INTERN
14190+ bool "UID32/GID32"
14191+ help
14192+ this uses otherwise reserved inode fields in the on
14193+ disk representation, which limits the use to a few
14194+ filesystems (currently ext2 and ext3)
d337f35e 14195+
4bf69007 14196+endchoice
d337f35e 14197+
4bf69007
AM
14198+config TAG_NFSD
14199+ bool "Tag NFSD User Auth and Files"
14200+ default n
14201+ help
14202+ Enable this if you do want the in-kernel NFS
14203+ Server to use the tagging specified above.
14204+ (will require patched clients too)
2380c486 14205+
4bf69007
AM
14206+config VSERVER_PRIVACY
14207+ bool "Honor Privacy Aspects of Guests"
14208+ default n
14209+ help
14210+ When enabled, most context checks will disallow
14211+ access to structures assigned to a specific context,
14212+ like ptys or loop devices.
2380c486 14213+
4bf69007
AM
14214+config VSERVER_CONTEXTS
14215+ int "Maximum number of Contexts (1-65533)" if EMBEDDED
14216+ range 1 65533
14217+ default "768" if 64BIT
14218+ default "256"
14219+ help
14220+ This setting will optimize certain data structures
14221+ and memory allocations according to the expected
14222+ maximum.
2380c486 14223+
4bf69007 14224+ note: this is not a strict upper limit.
2380c486 14225+
4bf69007
AM
14226+config VSERVER_WARN
14227+ bool "VServer Warnings"
14228+ default y
14229+ help
14230+ This enables various runtime warnings, which will
14231+ notify about potential manipulation attempts or
14232+ resource shortage. It is generally considered to
14233+ be a good idea to have that enabled.
2380c486 14234+
4bf69007
AM
14235+config VSERVER_WARN_DEVPTS
14236+ bool "VServer DevPTS Warnings"
14237+ depends on VSERVER_WARN
14238+ default y
14239+ help
14240+ This enables DevPTS related warnings, issued when a
14241+ process inside a context tries to lookup or access
14242+ a dynamic pts from the host or a different context.
d337f35e 14243+
4bf69007
AM
14244+config VSERVER_DEBUG
14245+ bool "VServer Debugging Code"
14246+ default n
14247+ help
14248+ Set this to yes if you want to be able to activate
14249+ debugging output at runtime. It adds a very small
14250+ overhead to all vserver related functions and
14251+ increases the kernel size by about 20k.
d337f35e 14252+
4bf69007
AM
14253+config VSERVER_HISTORY
14254+ bool "VServer History Tracing"
14255+ depends on VSERVER_DEBUG
14256+ default n
14257+ help
14258+ Set this to yes if you want to record the history of
14259+ linux-vserver activities, so they can be replayed in
14260+ the event of a kernel panic or oops.
d337f35e 14261+
4bf69007
AM
14262+config VSERVER_HISTORY_SIZE
14263+ int "Per-CPU History Size (32-65536)"
14264+ depends on VSERVER_HISTORY
14265+ range 32 65536
14266+ default 64
14267+ help
14268+ This allows you to specify the number of entries in
14269+ the per-CPU history buffer.
d337f35e 14270+
4bf69007
AM
14271+config VSERVER_EXTRA_MNT_CHECK
14272+ bool "Extra Checks for Reachability"
14273+ default n
14274+ help
14275+ Set this to yes if you want to do extra checks for
14276+ vfsmount reachability in the proc filesystem code.
14277+ This shouldn't be required on any setup utilizing
14278+ mnt namespaces.
d337f35e 14279+
4bf69007
AM
14280+choice
14281+ prompt "Quotes used in debug and warn messages"
14282+ default QUOTES_ISO8859
d337f35e 14283+
4bf69007
AM
14284+config QUOTES_ISO8859
14285+ bool "Extended ASCII (ISO 8859) angle quotes"
14286+ help
14287+ This uses the extended ASCII characters \xbb
14288+ and \xab for quoting file and process names.
d337f35e 14289+
4bf69007
AM
14290+config QUOTES_UTF8
14291+ bool "UTF-8 angle quotes"
14292+ help
14293+ This uses the the UTF-8 sequences for angle
14294+ quotes to quote file and process names.
d337f35e 14295+
4bf69007
AM
14296+config QUOTES_ASCII
14297+ bool "ASCII single quotes"
14298+ help
14299+ This uses the ASCII single quote character
14300+ (\x27) to quote file and process names.
d337f35e 14301+
4bf69007 14302+endchoice
d337f35e 14303+
4bf69007 14304+endmenu
d337f35e 14305+
d337f35e 14306+
4bf69007
AM
14307+config VSERVER
14308+ bool
14309+ default y
14310+ select NAMESPACES
14311+ select UTS_NS
14312+ select IPC_NS
14313+# select USER_NS
14314+ select SYSVIPC
d337f35e 14315+
4bf69007
AM
14316+config VSERVER_SECURITY
14317+ bool
14318+ depends on SECURITY
14319+ default y
14320+ select SECURITY_CAPABILITIES
d337f35e 14321+
4bf69007
AM
14322+config VSERVER_DISABLED
14323+ bool
14324+ default n
d337f35e 14325+
f19bd705
AM
14326diff -NurpP --minimal linux-4.4.111/kernel/vserver/Makefile linux-4.4.111-vs2.3.9.1/kernel/vserver/Makefile
14327--- linux-4.4.111/kernel/vserver/Makefile 1970-01-01 00:00:00.000000000 +0000
14328+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/Makefile 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14329@@ -0,0 +1,18 @@
14330+#
14331+# Makefile for the Linux vserver routines.
14332+#
d337f35e 14333+
d337f35e 14334+
4bf69007 14335+obj-y += vserver.o
2380c486 14336+
4bf69007
AM
14337+vserver-y := switch.o context.o space.o sched.o network.o inode.o \
14338+ limit.o cvirt.o cacct.o signal.o helper.o init.o \
14339+ dlimit.o tag.o
d337f35e 14340+
4bf69007
AM
14341+vserver-$(CONFIG_INET) += inet.o
14342+vserver-$(CONFIG_PROC_FS) += proc.o
14343+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
14344+vserver-$(CONFIG_VSERVER_HISTORY) += history.o
14345+vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
14346+vserver-$(CONFIG_VSERVER_DEVICE) += device.o
d337f35e 14347+
f19bd705
AM
14348diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct.c linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct.c
14349--- linux-4.4.111/kernel/vserver/cacct.c 1970-01-01 00:00:00.000000000 +0000
14350+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14351@@ -0,0 +1,42 @@
14352+/*
14353+ * linux/kernel/vserver/cacct.c
14354+ *
14355+ * Virtual Server: Context Accounting
14356+ *
927ca606 14357+ * Copyright (C) 2006-2007 Herbert P?tzl
4bf69007
AM
14358+ *
14359+ * V0.01 added accounting stats
14360+ *
14361+ */
d337f35e 14362+
4bf69007
AM
14363+#include <linux/types.h>
14364+#include <linux/vs_context.h>
14365+#include <linux/vserver/cacct_cmd.h>
14366+#include <linux/vserver/cacct_int.h>
d337f35e 14367+
4bf69007
AM
14368+#include <asm/errno.h>
14369+#include <asm/uaccess.h>
14370+
14371+
14372+int vc_sock_stat(struct vx_info *vxi, void __user *data)
d337f35e 14373+{
4bf69007
AM
14374+ struct vcmd_sock_stat_v0 vc_data;
14375+ int j, field;
d337f35e 14376+
2380c486
JR
14377+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
14378+ return -EFAULT;
14379+
4bf69007
AM
14380+ field = vc_data.field;
14381+ if ((field < 0) || (field >= VXA_SOCK_SIZE))
14382+ return -EINVAL;
7e46296a 14383+
4bf69007
AM
14384+ for (j = 0; j < 3; j++) {
14385+ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
14386+ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
14387+ }
7e46296a
AM
14388+
14389+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
14390+ return -EFAULT;
14391+ return 0;
14392+}
14393+
f19bd705
AM
14394diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct_init.h linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct_init.h
14395--- linux-4.4.111/kernel/vserver/cacct_init.h 1970-01-01 00:00:00.000000000 +0000
14396+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 14397@@ -0,0 +1,25 @@
7e46296a
AM
14398+
14399+
4bf69007 14400+static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
265d6dcc 14401+{
4bf69007 14402+ int i, j;
265d6dcc 14403+
265d6dcc 14404+
4bf69007
AM
14405+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14406+ for (j = 0; j < 3; j++) {
14407+ atomic_long_set(&cacct->sock[i][j].count, 0);
14408+ atomic_long_set(&cacct->sock[i][j].total, 0);
14409+ }
14410+ }
14411+ for (i = 0; i < 8; i++)
14412+ atomic_set(&cacct->slab[i], 0);
14413+ for (i = 0; i < 5; i++)
14414+ for (j = 0; j < 4; j++)
14415+ atomic_set(&cacct->page[i][j], 0);
265d6dcc
JR
14416+}
14417+
4bf69007 14418+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
265d6dcc 14419+{
4bf69007 14420+ return;
265d6dcc
JR
14421+}
14422+
f19bd705
AM
14423diff -NurpP --minimal linux-4.4.111/kernel/vserver/cacct_proc.h linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct_proc.h
14424--- linux-4.4.111/kernel/vserver/cacct_proc.h 1970-01-01 00:00:00.000000000 +0000
14425+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cacct_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
14426@@ -0,0 +1,53 @@
14427+#ifndef _VX_CACCT_PROC_H
14428+#define _VX_CACCT_PROC_H
265d6dcc 14429+
4bf69007 14430+#include <linux/vserver/cacct_int.h>
d337f35e 14431+
d337f35e 14432+
4bf69007
AM
14433+#define VX_SOCKA_TOP \
14434+ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
d337f35e 14435+
4bf69007 14436+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
d337f35e 14437+{
4bf69007
AM
14438+ int i, j, length = 0;
14439+ static char *type[VXA_SOCK_SIZE] = {
14440+ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER"
14441+ };
d337f35e 14442+
4bf69007
AM
14443+ length += sprintf(buffer + length, VX_SOCKA_TOP);
14444+ for (i = 0; i < VXA_SOCK_SIZE; i++) {
14445+ length += sprintf(buffer + length, "%s:", type[i]);
14446+ for (j = 0; j < 3; j++) {
14447+ length += sprintf(buffer + length,
14448+ "\t%10lu/%-10lu",
14449+ vx_sock_count(cacct, i, j),
14450+ vx_sock_total(cacct, i, j));
14451+ }
14452+ buffer[length++] = '\n';
14453+ }
d337f35e 14454+
4bf69007
AM
14455+ length += sprintf(buffer + length, "\n");
14456+ length += sprintf(buffer + length,
14457+ "slab:\t %8u %8u %8u %8u\n",
14458+ atomic_read(&cacct->slab[1]),
14459+ atomic_read(&cacct->slab[4]),
14460+ atomic_read(&cacct->slab[0]),
14461+ atomic_read(&cacct->slab[2]));
d337f35e 14462+
4bf69007
AM
14463+ length += sprintf(buffer + length, "\n");
14464+ for (i = 0; i < 5; i++) {
14465+ length += sprintf(buffer + length,
14466+ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i,
14467+ atomic_read(&cacct->page[i][0]),
14468+ atomic_read(&cacct->page[i][1]),
14469+ atomic_read(&cacct->page[i][2]),
14470+ atomic_read(&cacct->page[i][3]),
14471+ atomic_read(&cacct->page[i][4]),
14472+ atomic_read(&cacct->page[i][5]),
14473+ atomic_read(&cacct->page[i][6]),
14474+ atomic_read(&cacct->page[i][7]));
14475+ }
14476+ return length;
14477+}
d337f35e 14478+
4bf69007 14479+#endif /* _VX_CACCT_PROC_H */
f19bd705
AM
14480diff -NurpP --minimal linux-4.4.111/kernel/vserver/context.c linux-4.4.111-vs2.3.9.1/kernel/vserver/context.c
14481--- linux-4.4.111/kernel/vserver/context.c 1970-01-01 00:00:00.000000000 +0000
14482+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/context.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 14483@@ -0,0 +1,1119 @@
2380c486 14484+/*
4bf69007 14485+ * linux/kernel/vserver/context.c
2380c486 14486+ *
4bf69007 14487+ * Virtual Server: Context Support
2380c486 14488+ *
927ca606 14489+ * Copyright (C) 2003-2011 Herbert P?tzl
2380c486 14490+ *
4bf69007
AM
14491+ * V0.01 context helper
14492+ * V0.02 vx_ctx_kill syscall command
14493+ * V0.03 replaced context_info calls
14494+ * V0.04 redesign of struct (de)alloc
14495+ * V0.05 rlimit basic implementation
14496+ * V0.06 task_xid and info commands
14497+ * V0.07 context flags and caps
14498+ * V0.08 switch to RCU based hash
14499+ * V0.09 revert to non RCU for now
14500+ * V0.10 and back to working RCU hash
14501+ * V0.11 and back to locking again
14502+ * V0.12 referenced context store
14503+ * V0.13 separate per cpu data
14504+ * V0.14 changed vcmds to vxi arg
14505+ * V0.15 added context stat
14506+ * V0.16 have __create claim() the vxi
14507+ * V0.17 removed older and legacy stuff
14508+ * V0.18 added user credentials
14509+ * V0.19 added warn mask
2380c486
JR
14510+ *
14511+ */
d337f35e 14512+
4bf69007 14513+#include <linux/slab.h>
2380c486 14514+#include <linux/types.h>
4bf69007
AM
14515+#include <linux/security.h>
14516+#include <linux/pid_namespace.h>
14517+#include <linux/capability.h>
1e8b8f9b 14518+
4bf69007
AM
14519+#include <linux/vserver/context.h>
14520+#include <linux/vserver/network.h>
14521+#include <linux/vserver/debug.h>
14522+#include <linux/vserver/limit.h>
14523+#include <linux/vserver/limit_int.h>
14524+#include <linux/vserver/space.h>
14525+#include <linux/init_task.h>
14526+#include <linux/fs_struct.h>
14527+#include <linux/cred.h>
1e8b8f9b 14528+
4bf69007
AM
14529+#include <linux/vs_context.h>
14530+#include <linux/vs_limit.h>
14531+#include <linux/vs_pid.h>
14532+#include <linux/vserver/context_cmd.h>
d337f35e 14533+
4bf69007
AM
14534+#include "cvirt_init.h"
14535+#include "cacct_init.h"
14536+#include "limit_init.h"
14537+#include "sched_init.h"
d337f35e 14538+
d337f35e 14539+
4bf69007
AM
14540+atomic_t vx_global_ctotal = ATOMIC_INIT(0);
14541+atomic_t vx_global_cactive = ATOMIC_INIT(0);
d337f35e 14542+
d337f35e 14543+
4bf69007 14544+/* now inactive context structures */
d337f35e 14545+
4bf69007 14546+static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
2380c486 14547+
4bf69007 14548+static DEFINE_SPINLOCK(vx_info_inactive_lock);
d337f35e 14549+
2380c486 14550+
4bf69007 14551+/* __alloc_vx_info()
d337f35e 14552+
4bf69007
AM
14553+ * allocate an initialized vx_info struct
14554+ * doesn't make it visible (hash) */
d337f35e 14555+
61333608 14556+static struct vx_info *__alloc_vx_info(vxid_t xid)
4bf69007
AM
14557+{
14558+ struct vx_info *new = NULL;
14559+ int cpu, index;
d337f35e 14560+
4bf69007 14561+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
d337f35e 14562+
4bf69007
AM
14563+ /* would this benefit from a slab cache? */
14564+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
14565+ if (!new)
14566+ return 0;
2380c486 14567+
4bf69007
AM
14568+ memset(new, 0, sizeof(struct vx_info));
14569+#ifdef CONFIG_SMP
14570+ new->ptr_pc = alloc_percpu(struct _vx_info_pc);
14571+ if (!new->ptr_pc)
14572+ goto error;
14573+#endif
14574+ new->vx_id = xid;
14575+ INIT_HLIST_NODE(&new->vx_hlist);
14576+ atomic_set(&new->vx_usecnt, 0);
14577+ atomic_set(&new->vx_tasks, 0);
14578+ new->vx_parent = NULL;
14579+ new->vx_state = 0;
14580+ init_waitqueue_head(&new->vx_wait);
2380c486 14581+
4bf69007
AM
14582+ /* prepare reaper */
14583+ get_task_struct(init_pid_ns.child_reaper);
14584+ new->vx_reaper = init_pid_ns.child_reaper;
14585+ new->vx_badness_bias = 0;
d337f35e 14586+
4bf69007
AM
14587+ /* rest of init goes here */
14588+ vx_info_init_limit(&new->limit);
14589+ vx_info_init_sched(&new->sched);
14590+ vx_info_init_cvirt(&new->cvirt);
14591+ vx_info_init_cacct(&new->cacct);
d337f35e 14592+
4bf69007
AM
14593+ /* per cpu data structures */
14594+ for_each_possible_cpu(cpu) {
14595+ vx_info_init_sched_pc(
14596+ &vx_per_cpu(new, sched_pc, cpu), cpu);
14597+ vx_info_init_cvirt_pc(
14598+ &vx_per_cpu(new, cvirt_pc, cpu), cpu);
14599+ }
d337f35e 14600+
4bf69007
AM
14601+ new->vx_flags = VXF_INIT_SET;
14602+ new->vx_bcaps = CAP_FULL_SET; // maybe ~CAP_SETPCAP
14603+ new->vx_ccaps = 0;
14604+ new->vx_umask = 0;
14605+ new->vx_wmask = 0;
d337f35e 14606+
4bf69007
AM
14607+ new->reboot_cmd = 0;
14608+ new->exit_code = 0;
d337f35e 14609+
4bf69007
AM
14610+ // preconfig spaces
14611+ for (index = 0; index < VX_SPACES; index++) {
14612+ struct _vx_space *space = &new->space[index];
d337f35e 14613+
4bf69007
AM
14614+ // filesystem
14615+ spin_lock(&init_fs.lock);
14616+ init_fs.users++;
14617+ spin_unlock(&init_fs.lock);
14618+ space->vx_fs = &init_fs;
2380c486 14619+
4bf69007
AM
14620+ /* FIXME: do we want defaults? */
14621+ // space->vx_real_cred = 0;
14622+ // space->vx_cred = 0;
2380c486 14623+ }
4bf69007
AM
14624+
14625+
14626+ vxdprintk(VXD_CBIT(xid, 0),
14627+ "alloc_vx_info(%d) = %p", xid, new);
14628+ vxh_alloc_vx_info(new);
14629+ atomic_inc(&vx_global_ctotal);
14630+ return new;
14631+#ifdef CONFIG_SMP
14632+error:
14633+ kfree(new);
14634+ return 0;
14635+#endif
d337f35e
JR
14636+}
14637+
4bf69007 14638+/* __dealloc_vx_info()
d337f35e 14639+
4bf69007 14640+ * final disposal of vx_info */
d337f35e 14641+
4bf69007 14642+static void __dealloc_vx_info(struct vx_info *vxi)
d337f35e 14643+{
4bf69007
AM
14644+#ifdef CONFIG_VSERVER_WARN
14645+ struct vx_info_save vxis;
14646+ int cpu;
14647+#endif
14648+ vxdprintk(VXD_CBIT(xid, 0),
14649+ "dealloc_vx_info(%p)", vxi);
14650+ vxh_dealloc_vx_info(vxi);
d337f35e 14651+
4bf69007
AM
14652+#ifdef CONFIG_VSERVER_WARN
14653+ enter_vx_info(vxi, &vxis);
14654+ vx_info_exit_limit(&vxi->limit);
14655+ vx_info_exit_sched(&vxi->sched);
14656+ vx_info_exit_cvirt(&vxi->cvirt);
14657+ vx_info_exit_cacct(&vxi->cacct);
d337f35e 14658+
4bf69007
AM
14659+ for_each_possible_cpu(cpu) {
14660+ vx_info_exit_sched_pc(
14661+ &vx_per_cpu(vxi, sched_pc, cpu), cpu);
14662+ vx_info_exit_cvirt_pc(
14663+ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
14664+ }
14665+ leave_vx_info(&vxis);
14666+#endif
d337f35e 14667+
4bf69007
AM
14668+ vxi->vx_id = -1;
14669+ vxi->vx_state |= VXS_RELEASED;
d337f35e 14670+
4bf69007
AM
14671+#ifdef CONFIG_SMP
14672+ free_percpu(vxi->ptr_pc);
14673+#endif
14674+ kfree(vxi);
14675+ atomic_dec(&vx_global_ctotal);
d337f35e
JR
14676+}
14677+
4bf69007 14678+static void __shutdown_vx_info(struct vx_info *vxi)
d337f35e 14679+{
4bf69007
AM
14680+ struct nsproxy *nsproxy;
14681+ struct fs_struct *fs;
14682+ struct cred *cred;
14683+ int index, kill;
d337f35e 14684+
4bf69007 14685+ might_sleep();
d337f35e 14686+
4bf69007
AM
14687+ vxi->vx_state |= VXS_SHUTDOWN;
14688+ vs_state_change(vxi, VSC_SHUTDOWN);
d337f35e 14689+
4bf69007
AM
14690+ for (index = 0; index < VX_SPACES; index++) {
14691+ struct _vx_space *space = &vxi->space[index];
d337f35e 14692+
4bf69007
AM
14693+ nsproxy = xchg(&space->vx_nsproxy, NULL);
14694+ if (nsproxy)
14695+ put_nsproxy(nsproxy);
2380c486 14696+
4bf69007
AM
14697+ fs = xchg(&space->vx_fs, NULL);
14698+ spin_lock(&fs->lock);
14699+ kill = !--fs->users;
14700+ spin_unlock(&fs->lock);
14701+ if (kill)
14702+ free_fs_struct(fs);
d337f35e 14703+
4bf69007
AM
14704+ cred = (struct cred *)xchg(&space->vx_cred, NULL);
14705+ if (cred)
14706+ abort_creds(cred);
14707+ }
d337f35e
JR
14708+}
14709+
4bf69007 14710+/* exported stuff */
d337f35e 14711+
4bf69007 14712+void free_vx_info(struct vx_info *vxi)
d337f35e 14713+{
4bf69007
AM
14714+ unsigned long flags;
14715+ unsigned index;
d337f35e 14716+
4bf69007
AM
14717+ /* check for reference counts first */
14718+ BUG_ON(atomic_read(&vxi->vx_usecnt));
14719+ BUG_ON(atomic_read(&vxi->vx_tasks));
2380c486 14720+
4bf69007
AM
14721+ /* context must not be hashed */
14722+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14723+
4bf69007
AM
14724+ /* context shutdown is mandatory */
14725+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
d337f35e 14726+
4bf69007
AM
14727+ /* spaces check */
14728+ for (index = 0; index < VX_SPACES; index++) {
14729+ struct _vx_space *space = &vxi->space[index];
d337f35e 14730+
4bf69007
AM
14731+ BUG_ON(space->vx_nsproxy);
14732+ BUG_ON(space->vx_fs);
14733+ // BUG_ON(space->vx_real_cred);
14734+ // BUG_ON(space->vx_cred);
14735+ }
d337f35e 14736+
4bf69007
AM
14737+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14738+ hlist_del(&vxi->vx_hlist);
14739+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
d337f35e 14740+
4bf69007
AM
14741+ __dealloc_vx_info(vxi);
14742+}
eab5a9a6 14743+
d337f35e 14744+
4bf69007 14745+/* hash table for vx_info hash */
93de0823 14746+
4bf69007 14747+#define VX_HASH_SIZE 13
d337f35e 14748+
4bf69007
AM
14749+static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
14750+ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
d337f35e 14751+
4bf69007 14752+static DEFINE_SPINLOCK(vx_info_hash_lock);
d337f35e 14753+
93de0823 14754+
61333608 14755+static inline unsigned int __hashval(vxid_t xid)
4bf69007
AM
14756+{
14757+ return (xid % VX_HASH_SIZE);
d337f35e
JR
14758+}
14759+
14760+
d337f35e 14761+
4bf69007 14762+/* __hash_vx_info()
d337f35e 14763+
4bf69007
AM
14764+ * add the vxi to the global hash table
14765+ * requires the hash_lock to be held */
d337f35e 14766+
4bf69007 14767+static inline void __hash_vx_info(struct vx_info *vxi)
d337f35e 14768+{
4bf69007 14769+ struct hlist_head *head;
d337f35e 14770+
4bf69007
AM
14771+ vxd_assert_lock(&vx_info_hash_lock);
14772+ vxdprintk(VXD_CBIT(xid, 4),
14773+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
14774+ vxh_hash_vx_info(vxi);
d337f35e 14775+
4bf69007
AM
14776+ /* context must not be hashed */
14777+ BUG_ON(vx_info_state(vxi, VXS_HASHED));
d337f35e 14778+
4bf69007
AM
14779+ vxi->vx_state |= VXS_HASHED;
14780+ head = &vx_info_hash[__hashval(vxi->vx_id)];
14781+ hlist_add_head(&vxi->vx_hlist, head);
14782+ atomic_inc(&vx_global_cactive);
2380c486 14783+}
d337f35e 14784+
4bf69007 14785+/* __unhash_vx_info()
d337f35e 14786+
4bf69007
AM
14787+ * remove the vxi from the global hash table
14788+ * requires the hash_lock to be held */
d337f35e 14789+
4bf69007 14790+static inline void __unhash_vx_info(struct vx_info *vxi)
d337f35e 14791+{
4bf69007
AM
14792+ unsigned long flags;
14793+
14794+ vxd_assert_lock(&vx_info_hash_lock);
14795+ vxdprintk(VXD_CBIT(xid, 4),
14796+ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id,
14797+ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks));
14798+ vxh_unhash_vx_info(vxi);
14799+
14800+ /* context must be hashed */
14801+ BUG_ON(!vx_info_state(vxi, VXS_HASHED));
14802+ /* but without tasks */
14803+ BUG_ON(atomic_read(&vxi->vx_tasks));
14804+
14805+ vxi->vx_state &= ~VXS_HASHED;
14806+ hlist_del_init(&vxi->vx_hlist);
14807+ spin_lock_irqsave(&vx_info_inactive_lock, flags);
14808+ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
14809+ spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
14810+ atomic_dec(&vx_global_cactive);
2380c486 14811+}
d337f35e 14812+
d337f35e 14813+
4bf69007 14814+/* __lookup_vx_info()
d337f35e 14815+
4bf69007
AM
14816+ * requires the hash_lock to be held
14817+ * doesn't increment the vx_refcnt */
2380c486 14818+
61333608 14819+static inline struct vx_info *__lookup_vx_info(vxid_t xid)
d337f35e 14820+{
4bf69007
AM
14821+ struct hlist_head *head = &vx_info_hash[__hashval(xid)];
14822+ struct hlist_node *pos;
14823+ struct vx_info *vxi;
d337f35e 14824+
4bf69007
AM
14825+ vxd_assert_lock(&vx_info_hash_lock);
14826+ hlist_for_each(pos, head) {
14827+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
d337f35e 14828+
4bf69007
AM
14829+ if (vxi->vx_id == xid)
14830+ goto found;
14831+ }
14832+ vxi = NULL;
14833+found:
14834+ vxdprintk(VXD_CBIT(xid, 0),
14835+ "__lookup_vx_info(#%u): %p[#%u]",
14836+ xid, vxi, vxi ? vxi->vx_id : 0);
14837+ vxh_lookup_vx_info(vxi, xid);
14838+ return vxi;
14839+}
d337f35e 14840+
d337f35e 14841+
4bf69007 14842+/* __create_vx_info()
d337f35e 14843+
4bf69007
AM
14844+ * create the requested context
14845+ * get(), claim() and hash it */
2380c486 14846+
4bf69007
AM
14847+static struct vx_info *__create_vx_info(int id)
14848+{
14849+ struct vx_info *new, *vxi = NULL;
2380c486 14850+
4bf69007 14851+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
d337f35e 14852+
4bf69007
AM
14853+ if (!(new = __alloc_vx_info(id)))
14854+ return ERR_PTR(-ENOMEM);
d337f35e 14855+
4bf69007
AM
14856+ /* required to make dynamic xids unique */
14857+ spin_lock(&vx_info_hash_lock);
d337f35e 14858+
4bf69007
AM
14859+ /* static context requested */
14860+ if ((vxi = __lookup_vx_info(id))) {
14861+ vxdprintk(VXD_CBIT(xid, 0),
14862+ "create_vx_info(%d) = %p (already there)", id, vxi);
14863+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
14864+ vxi = ERR_PTR(-EBUSY);
14865+ else
14866+ vxi = ERR_PTR(-EEXIST);
14867+ goto out_unlock;
14868+ }
14869+ /* new context */
14870+ vxdprintk(VXD_CBIT(xid, 0),
14871+ "create_vx_info(%d) = %p (new)", id, new);
14872+ claim_vx_info(new, NULL);
14873+ __hash_vx_info(get_vx_info(new));
14874+ vxi = new, new = NULL;
d337f35e 14875+
4bf69007
AM
14876+out_unlock:
14877+ spin_unlock(&vx_info_hash_lock);
14878+ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id);
14879+ if (new)
14880+ __dealloc_vx_info(new);
14881+ return vxi;
14882+}
d337f35e 14883+
d337f35e 14884+
4bf69007 14885+/* exported stuff */
d337f35e 14886+
d337f35e 14887+
4bf69007 14888+void unhash_vx_info(struct vx_info *vxi)
d337f35e 14889+{
4bf69007
AM
14890+ spin_lock(&vx_info_hash_lock);
14891+ __unhash_vx_info(vxi);
14892+ spin_unlock(&vx_info_hash_lock);
14893+ __shutdown_vx_info(vxi);
14894+ __wakeup_vx_info(vxi);
2380c486 14895+}
d337f35e 14896+
2380c486 14897+
4bf69007 14898+/* lookup_vx_info()
2380c486 14899+
4bf69007
AM
14900+ * search for a vx_info and get() it
14901+ * negative id means current */
2380c486 14902+
4bf69007 14903+struct vx_info *lookup_vx_info(int id)
2380c486 14904+{
4bf69007
AM
14905+ struct vx_info *vxi = NULL;
14906+
14907+ if (id < 0) {
14908+ vxi = get_vx_info(current_vx_info());
14909+ } else if (id > 1) {
14910+ spin_lock(&vx_info_hash_lock);
14911+ vxi = get_vx_info(__lookup_vx_info(id));
14912+ spin_unlock(&vx_info_hash_lock);
2380c486 14913+ }
4bf69007 14914+ return vxi;
d337f35e
JR
14915+}
14916+
4bf69007 14917+/* xid_is_hashed()
d337f35e 14918+
4bf69007 14919+ * verify that xid is still hashed */
d337f35e 14920+
61333608 14921+int xid_is_hashed(vxid_t xid)
4bf69007
AM
14922+{
14923+ int hashed;
d337f35e 14924+
4bf69007
AM
14925+ spin_lock(&vx_info_hash_lock);
14926+ hashed = (__lookup_vx_info(xid) != NULL);
14927+ spin_unlock(&vx_info_hash_lock);
14928+ return hashed;
14929+}
d337f35e 14930+
4bf69007 14931+#ifdef CONFIG_PROC_FS
d337f35e 14932+
4bf69007 14933+/* get_xid_list()
d337f35e 14934+
4bf69007
AM
14935+ * get a subset of hashed xids for proc
14936+ * assumes size is at least one */
d337f35e 14937+
4bf69007
AM
14938+int get_xid_list(int index, unsigned int *xids, int size)
14939+{
14940+ int hindex, nr_xids = 0;
d337f35e 14941+
4bf69007
AM
14942+ /* only show current and children */
14943+ if (!vx_check(0, VS_ADMIN | VS_WATCH)) {
14944+ if (index > 0)
14945+ return 0;
14946+ xids[nr_xids] = vx_current_xid();
14947+ return 1;
14948+ }
d337f35e 14949+
4bf69007
AM
14950+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
14951+ struct hlist_head *head = &vx_info_hash[hindex];
14952+ struct hlist_node *pos;
d337f35e 14953+
4bf69007
AM
14954+ spin_lock(&vx_info_hash_lock);
14955+ hlist_for_each(pos, head) {
14956+ struct vx_info *vxi;
d337f35e 14957+
4bf69007
AM
14958+ if (--index > 0)
14959+ continue;
d337f35e 14960+
4bf69007
AM
14961+ vxi = hlist_entry(pos, struct vx_info, vx_hlist);
14962+ xids[nr_xids] = vxi->vx_id;
14963+ if (++nr_xids >= size) {
14964+ spin_unlock(&vx_info_hash_lock);
14965+ goto out;
14966+ }
14967+ }
14968+ /* keep the lock time short */
14969+ spin_unlock(&vx_info_hash_lock);
14970+ }
14971+out:
14972+ return nr_xids;
14973+}
14974+#endif
d337f35e 14975+
4bf69007 14976+#ifdef CONFIG_VSERVER_DEBUG
d337f35e 14977+
4bf69007 14978+void dump_vx_info_inactive(int level)
d337f35e 14979+{
4bf69007 14980+ struct hlist_node *entry, *next;
d337f35e 14981+
4bf69007
AM
14982+ hlist_for_each_safe(entry, next, &vx_info_inactive) {
14983+ struct vx_info *vxi =
14984+ list_entry(entry, struct vx_info, vx_hlist);
d337f35e 14985+
4bf69007
AM
14986+ dump_vx_info(vxi, level);
14987+ }
d337f35e
JR
14988+}
14989+
4bf69007 14990+#endif
d337f35e 14991+
4bf69007
AM
14992+#if 0
14993+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
d337f35e 14994+{
4bf69007 14995+ struct user_struct *new_user, *old_user;
d337f35e 14996+
4bf69007
AM
14997+ if (!p || !vxi)
14998+ BUG();
d337f35e 14999+
4bf69007
AM
15000+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
15001+ return -EACCES;
d337f35e 15002+
4bf69007
AM
15003+ new_user = alloc_uid(vxi->vx_id, p->uid);
15004+ if (!new_user)
15005+ return -ENOMEM;
d337f35e 15006+
4bf69007
AM
15007+ old_user = p->user;
15008+ if (new_user != old_user) {
15009+ atomic_inc(&new_user->processes);
15010+ atomic_dec(&old_user->processes);
15011+ p->user = new_user;
d337f35e 15012+ }
4bf69007
AM
15013+ free_uid(old_user);
15014+ return 0;
d337f35e 15015+}
4bf69007 15016+#endif
d337f35e 15017+
4bf69007
AM
15018+#if 0
15019+void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
d337f35e 15020+{
4bf69007
AM
15021+ // p->cap_effective &= vxi->vx_cap_bset;
15022+ p->cap_effective =
15023+ cap_intersect(p->cap_effective, vxi->cap_bset);
15024+ // p->cap_inheritable &= vxi->vx_cap_bset;
15025+ p->cap_inheritable =
15026+ cap_intersect(p->cap_inheritable, vxi->cap_bset);
15027+ // p->cap_permitted &= vxi->vx_cap_bset;
15028+ p->cap_permitted =
15029+ cap_intersect(p->cap_permitted, vxi->cap_bset);
15030+}
15031+#endif
d337f35e
JR
15032+
15033+
4bf69007
AM
15034+#include <linux/file.h>
15035+#include <linux/fdtable.h>
d337f35e 15036+
4bf69007
AM
15037+static int vx_openfd_task(struct task_struct *tsk)
15038+{
15039+ struct files_struct *files = tsk->files;
15040+ struct fdtable *fdt;
15041+ const unsigned long *bptr;
15042+ int count, total;
d337f35e 15043+
4bf69007
AM
15044+ /* no rcu_read_lock() because of spin_lock() */
15045+ spin_lock(&files->file_lock);
15046+ fdt = files_fdtable(files);
15047+ bptr = fdt->open_fds;
15048+ count = fdt->max_fds / (sizeof(unsigned long) * 8);
15049+ for (total = 0; count > 0; count--) {
15050+ if (*bptr)
15051+ total += hweight_long(*bptr);
15052+ bptr++;
15053+ }
15054+ spin_unlock(&files->file_lock);
15055+ return total;
d337f35e
JR
15056+}
15057+
d337f35e 15058+
4bf69007
AM
15059+/* for *space compatibility */
15060+
15061+asmlinkage long sys_unshare(unsigned long);
15062+
15063+/*
15064+ * migrate task to new context
15065+ * gets vxi, puts old_vxi on change
15066+ * optionally unshares namespaces (hack)
2380c486 15067+ */
4bf69007
AM
15068+
15069+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
2380c486 15070+{
4bf69007
AM
15071+ struct vx_info *old_vxi;
15072+ int ret = 0;
d337f35e 15073+
4bf69007
AM
15074+ if (!p || !vxi)
15075+ BUG();
d337f35e 15076+
4bf69007
AM
15077+ vxdprintk(VXD_CBIT(xid, 5),
15078+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
15079+ vxi->vx_id, atomic_read(&vxi->vx_usecnt));
d337f35e 15080+
4bf69007
AM
15081+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
15082+ !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
15083+ return -EACCES;
2380c486 15084+
4bf69007
AM
15085+ if (vx_info_state(vxi, VXS_SHUTDOWN))
15086+ return -EFAULT;
d337f35e 15087+
4bf69007
AM
15088+ old_vxi = task_get_vx_info(p);
15089+ if (old_vxi == vxi)
15090+ goto out;
d337f35e 15091+
4bf69007
AM
15092+// if (!(ret = vx_migrate_user(p, vxi))) {
15093+ {
15094+ int openfd;
d337f35e 15095+
4bf69007
AM
15096+ task_lock(p);
15097+ openfd = vx_openfd_task(p);
15098+
15099+ if (old_vxi) {
15100+ atomic_dec(&old_vxi->cvirt.nr_threads);
15101+ atomic_dec(&old_vxi->cvirt.nr_running);
15102+ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
15103+ /* FIXME: what about the struct files here? */
15104+ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
15105+ /* account for the executable */
15106+ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
2380c486 15107+ }
4bf69007
AM
15108+ atomic_inc(&vxi->cvirt.nr_threads);
15109+ atomic_inc(&vxi->cvirt.nr_running);
15110+ __rlim_inc(&vxi->limit, RLIMIT_NPROC);
15111+ /* FIXME: what about the struct files here? */
15112+ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
15113+ /* account for the executable */
15114+ __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
2380c486 15115+
4bf69007
AM
15116+ if (old_vxi) {
15117+ release_vx_info(old_vxi, p);
15118+ clr_vx_info(&p->vx_info);
15119+ }
15120+ claim_vx_info(vxi, p);
15121+ set_vx_info(&p->vx_info, vxi);
15122+ p->xid = vxi->vx_id;
d337f35e 15123+
4bf69007
AM
15124+ vxdprintk(VXD_CBIT(xid, 5),
15125+ "moved task %p into vxi:%p[#%d]",
15126+ p, vxi, vxi->vx_id);
d337f35e 15127+
4bf69007
AM
15128+ // vx_mask_cap_bset(vxi, p);
15129+ task_unlock(p);
d337f35e 15130+
4bf69007
AM
15131+ /* hack for *spaces to provide compatibility */
15132+ if (unshare) {
15133+ struct nsproxy *old_nsp, *new_nsp;
d337f35e 15134+
4bf69007
AM
15135+ ret = unshare_nsproxy_namespaces(
15136+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER,
b00e13aa 15137+ &new_nsp, NULL, NULL);
4bf69007
AM
15138+ if (ret)
15139+ goto out;
d337f35e 15140+
4bf69007
AM
15141+ old_nsp = xchg(&p->nsproxy, new_nsp);
15142+ vx_set_space(vxi,
15143+ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0);
15144+ put_nsproxy(old_nsp);
15145+ }
15146+ }
15147+out:
15148+ put_vx_info(old_vxi);
2380c486
JR
15149+ return ret;
15150+}
d337f35e 15151+
4bf69007 15152+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
d337f35e 15153+{
4bf69007
AM
15154+ struct task_struct *old_reaper;
15155+ struct vx_info *reaper_vxi;
d337f35e 15156+
4bf69007
AM
15157+ if (!vxi)
15158+ return -EINVAL;
d337f35e 15159+
4bf69007
AM
15160+ vxdprintk(VXD_CBIT(xid, 6),
15161+ "vx_set_reaper(%p[#%d],%p[#%d,%d])",
15162+ vxi, vxi->vx_id, p, p->xid, p->pid);
d337f35e 15163+
4bf69007
AM
15164+ old_reaper = vxi->vx_reaper;
15165+ if (old_reaper == p)
15166+ return 0;
d337f35e 15167+
4bf69007
AM
15168+ reaper_vxi = task_get_vx_info(p);
15169+ if (reaper_vxi && reaper_vxi != vxi) {
15170+ vxwprintk(1,
15171+ "Unsuitable reaper [" VS_Q("%s") ",%u:#%u] "
15172+ "for [xid #%u]",
15173+ p->comm, p->pid, p->xid, vx_current_xid());
2380c486
JR
15174+ goto out;
15175+ }
4bf69007
AM
15176+
15177+ /* set new child reaper */
15178+ get_task_struct(p);
15179+ vxi->vx_reaper = p;
15180+ put_task_struct(old_reaper);
2380c486 15181+out:
4bf69007
AM
15182+ put_vx_info(reaper_vxi);
15183+ return 0;
2380c486 15184+}
d337f35e 15185+
4bf69007 15186+int vx_set_init(struct vx_info *vxi, struct task_struct *p)
d337f35e 15187+{
4bf69007
AM
15188+ if (!vxi)
15189+ return -EINVAL;
d337f35e 15190+
4bf69007
AM
15191+ vxdprintk(VXD_CBIT(xid, 6),
15192+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
15193+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
d337f35e 15194+
4bf69007
AM
15195+ vxi->vx_flags &= ~VXF_STATE_INIT;
15196+ // vxi->vx_initpid = p->tgid;
15197+ vxi->vx_initpid = p->pid;
2380c486 15198+ return 0;
d337f35e
JR
15199+}
15200+
4bf69007 15201+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
d337f35e 15202+{
4bf69007
AM
15203+ vxdprintk(VXD_CBIT(xid, 6),
15204+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
15205+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
2380c486 15206+
4bf69007
AM
15207+ vxi->exit_code = code;
15208+ vxi->vx_initpid = 0;
d337f35e
JR
15209+}
15210+
2380c486 15211+
4bf69007 15212+void vx_set_persistent(struct vx_info *vxi)
d337f35e 15213+{
4bf69007
AM
15214+ vxdprintk(VXD_CBIT(xid, 6),
15215+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
2380c486 15216+
4bf69007
AM
15217+ get_vx_info(vxi);
15218+ claim_vx_info(vxi, NULL);
d337f35e
JR
15219+}
15220+
4bf69007 15221+void vx_clear_persistent(struct vx_info *vxi)
2380c486 15222+{
4bf69007
AM
15223+ vxdprintk(VXD_CBIT(xid, 6),
15224+ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
d337f35e 15225+
4bf69007
AM
15226+ release_vx_info(vxi, NULL);
15227+ put_vx_info(vxi);
2380c486 15228+}
d337f35e 15229+
4bf69007 15230+void vx_update_persistent(struct vx_info *vxi)
d337f35e 15231+{
4bf69007
AM
15232+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
15233+ vx_set_persistent(vxi);
2380c486 15234+ else
4bf69007 15235+ vx_clear_persistent(vxi);
2380c486 15236+}
d337f35e 15237+
d337f35e 15238+
4bf69007
AM
15239+/* task must be current or locked */
15240+
15241+void exit_vx_info(struct task_struct *p, int code)
2380c486 15242+{
4bf69007 15243+ struct vx_info *vxi = p->vx_info;
d337f35e 15244+
4bf69007
AM
15245+ if (vxi) {
15246+ atomic_dec(&vxi->cvirt.nr_threads);
15247+ vx_nproc_dec(p);
d337f35e 15248+
4bf69007
AM
15249+ vxi->exit_code = code;
15250+ release_vx_info(vxi, p);
15251+ }
2380c486 15252+}
d337f35e 15253+
4bf69007 15254+void exit_vx_info_early(struct task_struct *p, int code)
2380c486 15255+{
4bf69007 15256+ struct vx_info *vxi = p->vx_info;
d337f35e 15257+
4bf69007
AM
15258+ if (vxi) {
15259+ if (vxi->vx_initpid == p->pid)
15260+ vx_exit_init(vxi, p, code);
15261+ if (vxi->vx_reaper == p)
15262+ vx_set_reaper(vxi, init_pid_ns.child_reaper);
15263+ }
d337f35e
JR
15264+}
15265+
15266+
4bf69007 15267+/* vserver syscall commands below here */
d337f35e 15268+
4bf69007 15269+/* taks xid and vx_info functions */
d337f35e 15270+
4bf69007 15271+#include <asm/uaccess.h>
d337f35e 15272+
d337f35e 15273+
4bf69007 15274+int vc_task_xid(uint32_t id)
d337f35e 15275+{
61333608 15276+ vxid_t xid;
d337f35e 15277+
4bf69007
AM
15278+ if (id) {
15279+ struct task_struct *tsk;
d337f35e 15280+
4bf69007
AM
15281+ rcu_read_lock();
15282+ tsk = find_task_by_real_pid(id);
15283+ xid = (tsk) ? tsk->xid : -ESRCH;
15284+ rcu_read_unlock();
15285+ } else
15286+ xid = vx_current_xid();
15287+ return xid;
d337f35e
JR
15288+}
15289+
d337f35e 15290+
4bf69007
AM
15291+int vc_vx_info(struct vx_info *vxi, void __user *data)
15292+{
15293+ struct vcmd_vx_info_v0 vc_data;
d337f35e 15294+
4bf69007
AM
15295+ vc_data.xid = vxi->vx_id;
15296+ vc_data.initpid = vxi->vx_initpid;
d337f35e 15297+
4bf69007
AM
15298+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15299+ return -EFAULT;
15300+ return 0;
15301+}
d337f35e 15302+
d337f35e 15303+
4bf69007 15304+int vc_ctx_stat(struct vx_info *vxi, void __user *data)
d337f35e 15305+{
4bf69007 15306+ struct vcmd_ctx_stat_v0 vc_data;
d337f35e 15307+
4bf69007
AM
15308+ vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
15309+ vc_data.tasks = atomic_read(&vxi->vx_tasks);
d337f35e 15310+
4bf69007
AM
15311+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15312+ return -EFAULT;
15313+ return 0;
d337f35e
JR
15314+}
15315+
d337f35e 15316+
4bf69007 15317+/* context functions */
d337f35e 15318+
4bf69007 15319+int vc_ctx_create(uint32_t xid, void __user *data)
d337f35e 15320+{
4bf69007
AM
15321+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
15322+ struct vx_info *new_vxi;
15323+ int ret;
d337f35e 15324+
4bf69007
AM
15325+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15326+ return -EFAULT;
d337f35e 15327+
4bf69007
AM
15328+ if ((xid > MAX_S_CONTEXT) || (xid < 2))
15329+ return -EINVAL;
d337f35e 15330+
4bf69007
AM
15331+ new_vxi = __create_vx_info(xid);
15332+ if (IS_ERR(new_vxi))
15333+ return PTR_ERR(new_vxi);
d337f35e 15334+
4bf69007
AM
15335+ /* initial flags */
15336+ new_vxi->vx_flags = vc_data.flagword;
d337f35e 15337+
4bf69007
AM
15338+ ret = -ENOEXEC;
15339+ if (vs_state_change(new_vxi, VSC_STARTUP))
15340+ goto out;
d337f35e 15341+
4bf69007
AM
15342+ ret = vx_migrate_task(current, new_vxi, (!data));
15343+ if (ret)
15344+ goto out;
d337f35e 15345+
4bf69007
AM
15346+ /* return context id on success */
15347+ ret = new_vxi->vx_id;
d337f35e 15348+
4bf69007
AM
15349+ /* get a reference for persistent contexts */
15350+ if ((vc_data.flagword & VXF_PERSISTENT))
15351+ vx_set_persistent(new_vxi);
15352+out:
15353+ release_vx_info(new_vxi, NULL);
15354+ put_vx_info(new_vxi);
15355+ return ret;
15356+}
d337f35e
JR
15357+
15358+
4bf69007 15359+int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
d337f35e 15360+{
4bf69007
AM
15361+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
15362+ int ret;
d337f35e 15363+
4bf69007
AM
15364+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
15365+ return -EFAULT;
d337f35e 15366+
4bf69007
AM
15367+ ret = vx_migrate_task(current, vxi, 0);
15368+ if (ret)
15369+ return ret;
15370+ if (vc_data.flagword & VXM_SET_INIT)
15371+ ret = vx_set_init(vxi, current);
15372+ if (ret)
15373+ return ret;
15374+ if (vc_data.flagword & VXM_SET_REAPER)
15375+ ret = vx_set_reaper(vxi, current);
15376+ return ret;
15377+}
d337f35e 15378+
d337f35e 15379+
4bf69007 15380+int vc_get_cflags(struct vx_info *vxi, void __user *data)
d337f35e 15381+{
4bf69007 15382+ struct vcmd_ctx_flags_v0 vc_data;
d337f35e 15383+
4bf69007 15384+ vc_data.flagword = vxi->vx_flags;
d337f35e 15385+
4bf69007
AM
15386+ /* special STATE flag handling */
15387+ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME);
d337f35e 15388+
4bf69007
AM
15389+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15390+ return -EFAULT;
15391+ return 0;
d337f35e
JR
15392+}
15393+
4bf69007
AM
15394+int vc_set_cflags(struct vx_info *vxi, void __user *data)
15395+{
15396+ struct vcmd_ctx_flags_v0 vc_data;
15397+ uint64_t mask, trigger;
d337f35e 15398+
4bf69007
AM
15399+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15400+ return -EFAULT;
d337f35e 15401+
4bf69007
AM
15402+ /* special STATE flag handling */
15403+ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
15404+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
d337f35e 15405+
4bf69007
AM
15406+ if (vxi == current_vx_info()) {
15407+ /* if (trigger & VXF_STATE_SETUP)
15408+ vx_mask_cap_bset(vxi, current); */
15409+ if (trigger & VXF_STATE_INIT) {
15410+ int ret;
d337f35e 15411+
4bf69007
AM
15412+ ret = vx_set_init(vxi, current);
15413+ if (ret)
15414+ return ret;
15415+ ret = vx_set_reaper(vxi, current);
15416+ if (ret)
15417+ return ret;
d337f35e
JR
15418+ }
15419+ }
4bf69007
AM
15420+
15421+ vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
15422+ vc_data.flagword, mask);
15423+ if (trigger & VXF_PERSISTENT)
15424+ vx_update_persistent(vxi);
15425+
15426+ return 0;
d337f35e
JR
15427+}
15428+
15429+
4bf69007 15430+static inline uint64_t caps_from_cap_t(kernel_cap_t c)
d337f35e 15431+{
4bf69007 15432+ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32);
d337f35e 15433+
4bf69007
AM
15434+ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v);
15435+ return v;
d337f35e
JR
15436+}
15437+
4bf69007 15438+static inline kernel_cap_t cap_t_from_caps(uint64_t v)
d337f35e 15439+{
4bf69007 15440+ kernel_cap_t c = __cap_empty_set;
d337f35e 15441+
4bf69007
AM
15442+ c.cap[0] = v & 0xFFFFFFFF;
15443+ c.cap[1] = (v >> 32) & 0xFFFFFFFF;
d337f35e 15444+
4bf69007
AM
15445+ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]);
15446+ return c;
d337f35e
JR
15447+}
15448+
15449+
4bf69007 15450+static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
d337f35e 15451+{
4bf69007
AM
15452+ if (bcaps)
15453+ *bcaps = caps_from_cap_t(vxi->vx_bcaps);
15454+ if (ccaps)
15455+ *ccaps = vxi->vx_ccaps;
d337f35e 15456+
4bf69007
AM
15457+ return 0;
15458+}
d337f35e 15459+
4bf69007
AM
15460+int vc_get_ccaps(struct vx_info *vxi, void __user *data)
15461+{
15462+ struct vcmd_ctx_caps_v1 vc_data;
15463+ int ret;
d337f35e 15464+
4bf69007
AM
15465+ ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
15466+ if (ret)
15467+ return ret;
15468+ vc_data.cmask = ~0ULL;
d337f35e 15469+
4bf69007
AM
15470+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15471+ return -EFAULT;
15472+ return 0;
d337f35e
JR
15473+}
15474+
4bf69007
AM
15475+static int do_set_caps(struct vx_info *vxi,
15476+ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
d337f35e 15477+{
4bf69007 15478+ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps);
d337f35e 15479+
4bf69007
AM
15480+#if 0
15481+ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n",
15482+ bcaps, bmask, ccaps, cmask);
15483+#endif
15484+ vxi->vx_bcaps = cap_t_from_caps(
15485+ vs_mask_flags(bcold, bcaps, bmask));
15486+ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
d337f35e 15487+
4bf69007 15488+ return 0;
d337f35e
JR
15489+}
15490+
4bf69007 15491+int vc_set_ccaps(struct vx_info *vxi, void __user *data)
d337f35e 15492+{
4bf69007 15493+ struct vcmd_ctx_caps_v1 vc_data;
d337f35e 15494+
2380c486 15495+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15496+ return -EFAULT;
15497+
4bf69007 15498+ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
d337f35e
JR
15499+}
15500+
4bf69007 15501+int vc_get_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15502+{
4bf69007
AM
15503+ struct vcmd_bcaps vc_data;
15504+ int ret;
d337f35e 15505+
4bf69007
AM
15506+ ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
15507+ if (ret)
15508+ return ret;
15509+ vc_data.bmask = ~0ULL;
d337f35e 15510+
4bf69007
AM
15511+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15512+ return -EFAULT;
15513+ return 0;
d337f35e
JR
15514+}
15515+
4bf69007 15516+int vc_set_bcaps(struct vx_info *vxi, void __user *data)
d337f35e 15517+{
4bf69007 15518+ struct vcmd_bcaps vc_data;
d337f35e 15519+
2380c486 15520+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15521+ return -EFAULT;
15522+
4bf69007 15523+ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
d337f35e
JR
15524+}
15525+
d337f35e 15526+
4bf69007 15527+int vc_get_umask(struct vx_info *vxi, void __user *data)
d337f35e 15528+{
4bf69007 15529+ struct vcmd_umask vc_data;
7e46296a 15530+
4bf69007
AM
15531+ vc_data.umask = vxi->vx_umask;
15532+ vc_data.mask = ~0ULL;
d337f35e 15533+
4bf69007
AM
15534+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15535+ return -EFAULT;
15536+ return 0;
15537+}
d337f35e 15538+
4bf69007
AM
15539+int vc_set_umask(struct vx_info *vxi, void __user *data)
15540+{
15541+ struct vcmd_umask vc_data;
d337f35e 15542+
4bf69007
AM
15543+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15544+ return -EFAULT;
7e46296a 15545+
4bf69007
AM
15546+ vxi->vx_umask = vs_mask_flags(vxi->vx_umask,
15547+ vc_data.umask, vc_data.mask);
15548+ return 0;
15549+}
7e46296a 15550+
d337f35e 15551+
4bf69007
AM
15552+int vc_get_wmask(struct vx_info *vxi, void __user *data)
15553+{
15554+ struct vcmd_wmask vc_data;
d337f35e 15555+
4bf69007
AM
15556+ vc_data.wmask = vxi->vx_wmask;
15557+ vc_data.mask = ~0ULL;
d337f35e 15558+
4bf69007
AM
15559+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15560+ return -EFAULT;
15561+ return 0;
d337f35e
JR
15562+}
15563+
4bf69007 15564+int vc_set_wmask(struct vx_info *vxi, void __user *data)
d337f35e 15565+{
4bf69007 15566+ struct vcmd_wmask vc_data;
d337f35e 15567+
2380c486 15568+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15569+ return -EFAULT;
15570+
4bf69007
AM
15571+ vxi->vx_wmask = vs_mask_flags(vxi->vx_wmask,
15572+ vc_data.wmask, vc_data.mask);
15573+ return 0;
d337f35e
JR
15574+}
15575+
d337f35e 15576+
4bf69007 15577+int vc_get_badness(struct vx_info *vxi, void __user *data)
d337f35e 15578+{
4bf69007
AM
15579+ struct vcmd_badness_v0 vc_data;
15580+
15581+ vc_data.bias = vxi->vx_badness_bias;
15582+
15583+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15584+ return -EFAULT;
15585+ return 0;
15586+}
15587+
15588+int vc_set_badness(struct vx_info *vxi, void __user *data)
15589+{
15590+ struct vcmd_badness_v0 vc_data;
d337f35e 15591+
2380c486 15592+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
15593+ return -EFAULT;
15594+
4bf69007
AM
15595+ vxi->vx_badness_bias = vc_data.bias;
15596+ return 0;
d337f35e
JR
15597+}
15598+
4bf69007 15599+#include <linux/module.h>
d337f35e 15600+
4bf69007 15601+EXPORT_SYMBOL_GPL(free_vx_info);
d337f35e 15602+
f19bd705
AM
15603diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt.c linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt.c
15604--- linux-4.4.111/kernel/vserver/cvirt.c 1970-01-01 00:00:00.000000000 +0000
15605+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt.c 2018-01-09 22:27:39.000000000 +0000
4bf69007
AM
15606@@ -0,0 +1,313 @@
15607+/*
15608+ * linux/kernel/vserver/cvirt.c
15609+ *
15610+ * Virtual Server: Context Virtualization
15611+ *
927ca606 15612+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
15613+ *
15614+ * V0.01 broken out from limit.c
15615+ * V0.02 added utsname stuff
15616+ * V0.03 changed vcmds to vxi arg
15617+ *
15618+ */
d337f35e 15619+
4bf69007
AM
15620+#include <linux/types.h>
15621+#include <linux/utsname.h>
15622+#include <linux/vs_cvirt.h>
15623+#include <linux/vserver/switch.h>
15624+#include <linux/vserver/cvirt_cmd.h>
d337f35e 15625+
4bf69007 15626+#include <asm/uaccess.h>
d337f35e 15627+
d337f35e 15628+
4bf69007
AM
15629+void vx_vsi_boottime(struct timespec *boottime)
15630+{
15631+ struct vx_info *vxi = current_vx_info();
d337f35e 15632+
4bf69007
AM
15633+ set_normalized_timespec(boottime,
15634+ boottime->tv_sec + vxi->cvirt.bias_uptime.tv_sec,
15635+ boottime->tv_nsec + vxi->cvirt.bias_uptime.tv_nsec);
15636+ return;
d337f35e
JR
15637+}
15638+
4bf69007 15639+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
d337f35e 15640+{
4bf69007 15641+ struct vx_info *vxi = current_vx_info();
d337f35e 15642+
4bf69007
AM
15643+ set_normalized_timespec(uptime,
15644+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
15645+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
15646+ if (!idle)
15647+ return;
15648+ set_normalized_timespec(idle,
15649+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
15650+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
15651+ return;
d337f35e
JR
15652+}
15653+
4bf69007 15654+uint64_t vx_idle_jiffies(void)
d337f35e 15655+{
4bf69007 15656+ return init_task.utime + init_task.stime;
d337f35e
JR
15657+}
15658+
d337f35e
JR
15659+
15660+
4bf69007
AM
15661+static inline uint32_t __update_loadavg(uint32_t load,
15662+ int wsize, int delta, int n)
d337f35e 15663+{
4bf69007 15664+ unsigned long long calc, prev;
d337f35e 15665+
4bf69007
AM
15666+ /* just set it to n */
15667+ if (unlikely(delta >= wsize))
15668+ return (n << FSHIFT);
d337f35e 15669+
4bf69007
AM
15670+ calc = delta * n;
15671+ calc <<= FSHIFT;
15672+ prev = (wsize - delta);
15673+ prev *= load;
15674+ calc += prev;
15675+ do_div(calc, wsize);
15676+ return calc;
15677+}
d337f35e 15678+
d337f35e 15679+
4bf69007
AM
15680+void vx_update_load(struct vx_info *vxi)
15681+{
15682+ uint32_t now, last, delta;
15683+ unsigned int nr_running, nr_uninterruptible;
15684+ unsigned int total;
15685+ unsigned long flags;
d337f35e 15686+
4bf69007 15687+ spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
d337f35e 15688+
4bf69007
AM
15689+ now = jiffies;
15690+ last = vxi->cvirt.load_last;
15691+ delta = now - last;
d337f35e 15692+
4bf69007
AM
15693+ if (delta < 5*HZ)
15694+ goto out;
d337f35e 15695+
4bf69007
AM
15696+ nr_running = atomic_read(&vxi->cvirt.nr_running);
15697+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
15698+ total = nr_running + nr_uninterruptible;
d337f35e 15699+
4bf69007
AM
15700+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
15701+ 60*HZ, delta, total);
15702+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
15703+ 5*60*HZ, delta, total);
15704+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
15705+ 15*60*HZ, delta, total);
d337f35e 15706+
4bf69007
AM
15707+ vxi->cvirt.load_last = now;
15708+out:
15709+ atomic_inc(&vxi->cvirt.load_updates);
15710+ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
d337f35e
JR
15711+}
15712+
d337f35e 15713+
d337f35e 15714+/*
4bf69007 15715+ * Commands to do_syslog:
d337f35e 15716+ *
4bf69007
AM
15717+ * 0 -- Close the log. Currently a NOP.
15718+ * 1 -- Open the log. Currently a NOP.
15719+ * 2 -- Read from the log.
15720+ * 3 -- Read all messages remaining in the ring buffer.
15721+ * 4 -- Read and clear all messages remaining in the ring buffer
15722+ * 5 -- Clear ring buffer.
15723+ * 6 -- Disable printk's to console
15724+ * 7 -- Enable printk's to console
15725+ * 8 -- Set level of messages printed to console
15726+ * 9 -- Return number of unread characters in the log buffer
15727+ * 10 -- Return size of the log buffer
d337f35e 15728+ */
4bf69007
AM
15729+int vx_do_syslog(int type, char __user *buf, int len)
15730+{
15731+ int error = 0;
15732+ int do_clear = 0;
15733+ struct vx_info *vxi = current_vx_info();
15734+ struct _vx_syslog *log;
d337f35e 15735+
4bf69007
AM
15736+ if (!vxi)
15737+ return -EINVAL;
15738+ log = &vxi->cvirt.syslog;
15739+
15740+ switch (type) {
15741+ case 0: /* Close log */
15742+ case 1: /* Open log */
15743+ break;
15744+ case 2: /* Read from log */
15745+ error = wait_event_interruptible(log->log_wait,
15746+ (log->log_start - log->log_end));
15747+ if (error)
15748+ break;
15749+ spin_lock_irq(&log->logbuf_lock);
15750+ spin_unlock_irq(&log->logbuf_lock);
15751+ break;
15752+ case 4: /* Read/clear last kernel messages */
15753+ do_clear = 1;
15754+ /* fall through */
15755+ case 3: /* Read last kernel messages */
15756+ return 0;
d337f35e 15757+
4bf69007
AM
15758+ case 5: /* Clear ring buffer */
15759+ return 0;
d337f35e 15760+
4bf69007
AM
15761+ case 6: /* Disable logging to console */
15762+ case 7: /* Enable logging to console */
15763+ case 8: /* Set level of messages printed to console */
15764+ break;
d337f35e 15765+
4bf69007
AM
15766+ case 9: /* Number of chars in the log buffer */
15767+ return 0;
15768+ case 10: /* Size of the log buffer */
15769+ return 0;
15770+ default:
15771+ error = -EINVAL;
15772+ break;
15773+ }
15774+ return error;
1e8b8f9b 15775+}
d337f35e 15776+
4bf69007
AM
15777+
15778+/* virtual host info names */
15779+
15780+static char *vx_vhi_name(struct vx_info *vxi, int id)
d337f35e 15781+{
4bf69007
AM
15782+ struct nsproxy *nsproxy;
15783+ struct uts_namespace *uts;
d337f35e 15784+
4bf69007
AM
15785+ if (id == VHIN_CONTEXT)
15786+ return vxi->vx_name;
15787+
15788+ nsproxy = vxi->space[0].vx_nsproxy;
15789+ if (!nsproxy)
15790+ return NULL;
15791+
15792+ uts = nsproxy->uts_ns;
15793+ if (!uts)
15794+ return NULL;
15795+
15796+ switch (id) {
15797+ case VHIN_SYSNAME:
15798+ return uts->name.sysname;
15799+ case VHIN_NODENAME:
15800+ return uts->name.nodename;
15801+ case VHIN_RELEASE:
15802+ return uts->name.release;
15803+ case VHIN_VERSION:
15804+ return uts->name.version;
15805+ case VHIN_MACHINE:
15806+ return uts->name.machine;
15807+ case VHIN_DOMAINNAME:
15808+ return uts->name.domainname;
15809+ default:
15810+ return NULL;
d337f35e 15811+ }
4bf69007 15812+ return NULL;
d337f35e
JR
15813+}
15814+
4bf69007 15815+int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
d337f35e 15816+{
4bf69007
AM
15817+ struct vcmd_vhi_name_v0 vc_data;
15818+ char *name;
d337f35e 15819+
4bf69007
AM
15820+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15821+ return -EFAULT;
d337f35e 15822+
4bf69007
AM
15823+ name = vx_vhi_name(vxi, vc_data.field);
15824+ if (!name)
15825+ return -EINVAL;
d337f35e 15826+
4bf69007
AM
15827+ memcpy(name, vc_data.name, 65);
15828+ return 0;
15829+}
d337f35e 15830+
4bf69007
AM
15831+int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
15832+{
15833+ struct vcmd_vhi_name_v0 vc_data;
15834+ char *name;
d337f35e 15835+
4bf69007
AM
15836+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
15837+ return -EFAULT;
d337f35e 15838+
4bf69007
AM
15839+ name = vx_vhi_name(vxi, vc_data.field);
15840+ if (!name)
15841+ return -EINVAL;
d337f35e 15842+
4bf69007
AM
15843+ memcpy(vc_data.name, name, 65);
15844+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15845+ return -EFAULT;
15846+ return 0;
15847+}
d337f35e 15848+
d337f35e 15849+
4bf69007
AM
15850+int vc_virt_stat(struct vx_info *vxi, void __user *data)
15851+{
15852+ struct vcmd_virt_stat_v0 vc_data;
15853+ struct _vx_cvirt *cvirt = &vxi->cvirt;
15854+ struct timespec uptime;
99a884b4 15855+
927ca606 15856+ ktime_get_ts(&uptime);
4bf69007
AM
15857+ set_normalized_timespec(&uptime,
15858+ uptime.tv_sec - cvirt->bias_uptime.tv_sec,
15859+ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
d337f35e 15860+
4bf69007
AM
15861+ vc_data.offset = timespec_to_ns(&cvirt->bias_ts);
15862+ vc_data.uptime = timespec_to_ns(&uptime);
15863+ vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
15864+ vc_data.nr_running = atomic_read(&cvirt->nr_running);
15865+ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
15866+ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
15867+ vc_data.nr_forks = atomic_read(&cvirt->total_forks);
15868+ vc_data.load[0] = cvirt->load[0];
15869+ vc_data.load[1] = cvirt->load[1];
15870+ vc_data.load[2] = cvirt->load[2];
15871+
15872+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
15873+ return -EFAULT;
15874+ return 0;
d337f35e
JR
15875+}
15876+
15877+
4bf69007
AM
15878+#ifdef CONFIG_VSERVER_VTIME
15879+
15880+/* virtualized time base */
15881+
15882+void vx_adjust_timespec(struct timespec *ts)
d337f35e 15883+{
4bf69007 15884+ struct vx_info *vxi;
d337f35e 15885+
4bf69007
AM
15886+ if (!vx_flags(VXF_VIRT_TIME, 0))
15887+ return;
d337f35e 15888+
4bf69007
AM
15889+ vxi = current_vx_info();
15890+ ts->tv_sec += vxi->cvirt.bias_ts.tv_sec;
15891+ ts->tv_nsec += vxi->cvirt.bias_ts.tv_nsec;
d337f35e 15892+
4bf69007
AM
15893+ if (ts->tv_nsec >= NSEC_PER_SEC) {
15894+ ts->tv_sec++;
15895+ ts->tv_nsec -= NSEC_PER_SEC;
15896+ } else if (ts->tv_nsec < 0) {
15897+ ts->tv_sec--;
15898+ ts->tv_nsec += NSEC_PER_SEC;
d337f35e 15899+ }
d337f35e
JR
15900+}
15901+
4bf69007 15902+int vx_settimeofday(const struct timespec *ts)
99a884b4 15903+{
4bf69007
AM
15904+ struct timespec ats, delta;
15905+ struct vx_info *vxi;
99a884b4 15906+
4bf69007
AM
15907+ if (!vx_flags(VXF_VIRT_TIME, 0))
15908+ return do_settimeofday(ts);
99a884b4 15909+
4bf69007
AM
15910+ getnstimeofday(&ats);
15911+ delta = timespec_sub(*ts, ats);
99a884b4 15912+
4bf69007
AM
15913+ vxi = current_vx_info();
15914+ vxi->cvirt.bias_ts = timespec_add(vxi->cvirt.bias_ts, delta);
99a884b4
AM
15915+ return 0;
15916+}
d337f35e 15917+
4bf69007 15918+#endif
d337f35e 15919+
f19bd705
AM
15920diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt_init.h linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt_init.h
15921--- linux-4.4.111/kernel/vserver/cvirt_init.h 1970-01-01 00:00:00.000000000 +0000
15922+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt_init.h 2018-01-09 22:16:00.000000000 +0000
4bf69007 15923@@ -0,0 +1,70 @@
d337f35e 15924+
d337f35e 15925+
4bf69007 15926+extern uint64_t vx_idle_jiffies(void);
d337f35e 15927+
4bf69007
AM
15928+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
15929+{
15930+ uint64_t idle_jiffies = vx_idle_jiffies();
15931+ uint64_t nsuptime;
d337f35e 15932+
927ca606 15933+ ktime_get_ts(&cvirt->bias_uptime);
4bf69007
AM
15934+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
15935+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
15936+ cvirt->bias_clock = nsec_to_clock_t(nsuptime);
15937+ cvirt->bias_ts.tv_sec = 0;
15938+ cvirt->bias_ts.tv_nsec = 0;
d337f35e 15939+
4bf69007
AM
15940+ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
15941+ atomic_set(&cvirt->nr_threads, 0);
15942+ atomic_set(&cvirt->nr_running, 0);
15943+ atomic_set(&cvirt->nr_uninterruptible, 0);
15944+ atomic_set(&cvirt->nr_onhold, 0);
d337f35e 15945+
4bf69007
AM
15946+ spin_lock_init(&cvirt->load_lock);
15947+ cvirt->load_last = jiffies;
15948+ atomic_set(&cvirt->load_updates, 0);
15949+ cvirt->load[0] = 0;
15950+ cvirt->load[1] = 0;
15951+ cvirt->load[2] = 0;
15952+ atomic_set(&cvirt->total_forks, 0);
d337f35e 15953+
4bf69007
AM
15954+ spin_lock_init(&cvirt->syslog.logbuf_lock);
15955+ init_waitqueue_head(&cvirt->syslog.log_wait);
15956+ cvirt->syslog.log_start = 0;
15957+ cvirt->syslog.log_end = 0;
15958+ cvirt->syslog.con_start = 0;
15959+ cvirt->syslog.logged_chars = 0;
15960+}
15961+
15962+static inline
15963+void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
d337f35e 15964+{
4bf69007
AM
15965+ // cvirt_pc->cpustat = { 0 };
15966+}
d337f35e 15967+
4bf69007
AM
15968+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
15969+{
15970+#ifdef CONFIG_VSERVER_WARN
15971+ int value;
15972+#endif
15973+ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)),
15974+ "!!! cvirt: %p[nr_threads] = %d on exit.",
15975+ cvirt, value);
15976+ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)),
15977+ "!!! cvirt: %p[nr_running] = %d on exit.",
15978+ cvirt, value);
15979+ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)),
15980+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
15981+ cvirt, value);
15982+ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)),
15983+ "!!! cvirt: %p[nr_onhold] = %d on exit.",
15984+ cvirt, value);
15985+ return;
15986+}
d337f35e 15987+
4bf69007
AM
15988+static inline
15989+void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
15990+{
15991+ return;
15992+}
d337f35e 15993+
f19bd705
AM
15994diff -NurpP --minimal linux-4.4.111/kernel/vserver/cvirt_proc.h linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt_proc.h
15995--- linux-4.4.111/kernel/vserver/cvirt_proc.h 1970-01-01 00:00:00.000000000 +0000
15996+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/cvirt_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
15997@@ -0,0 +1,123 @@
15998+#ifndef _VX_CVIRT_PROC_H
15999+#define _VX_CVIRT_PROC_H
d337f35e 16000+
4bf69007
AM
16001+#include <linux/nsproxy.h>
16002+#include <linux/mnt_namespace.h>
16003+#include <linux/ipc_namespace.h>
16004+#include <linux/utsname.h>
16005+#include <linux/ipc.h>
d337f35e 16006+
4bf69007 16007+extern int vx_info_mnt_namespace(struct mnt_namespace *, char *);
d337f35e 16008+
4bf69007
AM
16009+static inline
16010+int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
16011+{
16012+ struct mnt_namespace *ns;
16013+ struct uts_namespace *uts;
16014+ struct ipc_namespace *ipc;
16015+ int length = 0;
d337f35e 16016+
4bf69007
AM
16017+ if (!nsproxy)
16018+ goto out;
d337f35e 16019+
4bf69007
AM
16020+ length += sprintf(buffer + length,
16021+ "NSProxy:\t%p [%p,%p,%p]\n",
16022+ nsproxy, nsproxy->mnt_ns,
16023+ nsproxy->uts_ns, nsproxy->ipc_ns);
d337f35e 16024+
4bf69007
AM
16025+ ns = nsproxy->mnt_ns;
16026+ if (!ns)
16027+ goto skip_ns;
d337f35e 16028+
4bf69007 16029+ length += vx_info_mnt_namespace(ns, buffer + length);
d337f35e 16030+
4bf69007 16031+skip_ns:
d337f35e 16032+
4bf69007
AM
16033+ uts = nsproxy->uts_ns;
16034+ if (!uts)
16035+ goto skip_uts;
d337f35e 16036+
4bf69007
AM
16037+ length += sprintf(buffer + length,
16038+ "SysName:\t%.*s\n"
16039+ "NodeName:\t%.*s\n"
16040+ "Release:\t%.*s\n"
16041+ "Version:\t%.*s\n"
16042+ "Machine:\t%.*s\n"
16043+ "DomainName:\t%.*s\n",
16044+ __NEW_UTS_LEN, uts->name.sysname,
16045+ __NEW_UTS_LEN, uts->name.nodename,
16046+ __NEW_UTS_LEN, uts->name.release,
16047+ __NEW_UTS_LEN, uts->name.version,
16048+ __NEW_UTS_LEN, uts->name.machine,
16049+ __NEW_UTS_LEN, uts->name.domainname);
16050+skip_uts:
d337f35e 16051+
4bf69007
AM
16052+ ipc = nsproxy->ipc_ns;
16053+ if (!ipc)
16054+ goto skip_ipc;
d337f35e 16055+
4bf69007
AM
16056+ length += sprintf(buffer + length,
16057+ "SEMS:\t\t%d %d %d %d %d\n"
16058+ "MSG:\t\t%d %d %d\n"
b00e13aa 16059+ "SHM:\t\t%lu %lu %d %ld\n",
4bf69007
AM
16060+ ipc->sem_ctls[0], ipc->sem_ctls[1],
16061+ ipc->sem_ctls[2], ipc->sem_ctls[3],
16062+ ipc->used_sems,
16063+ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni,
16064+ (unsigned long)ipc->shm_ctlmax,
16065+ (unsigned long)ipc->shm_ctlall,
16066+ ipc->shm_ctlmni, ipc->shm_tot);
16067+skip_ipc:
16068+out:
16069+ return length;
16070+}
d337f35e
JR
16071+
16072+
4bf69007 16073+#include <linux/sched.h>
d337f35e 16074+
4bf69007
AM
16075+#define LOAD_INT(x) ((x) >> FSHIFT)
16076+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
d337f35e 16077+
4bf69007
AM
16078+static inline
16079+int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
d337f35e 16080+{
4bf69007
AM
16081+ int length = 0;
16082+ int a, b, c;
d337f35e 16083+
4bf69007
AM
16084+ length += sprintf(buffer + length,
16085+ "BiasUptime:\t%lu.%02lu\n",
16086+ (unsigned long)cvirt->bias_uptime.tv_sec,
16087+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
d337f35e 16088+
4bf69007
AM
16089+ a = cvirt->load[0] + (FIXED_1 / 200);
16090+ b = cvirt->load[1] + (FIXED_1 / 200);
16091+ c = cvirt->load[2] + (FIXED_1 / 200);
16092+ length += sprintf(buffer + length,
16093+ "nr_threads:\t%d\n"
16094+ "nr_running:\t%d\n"
16095+ "nr_unintr:\t%d\n"
16096+ "nr_onhold:\t%d\n"
16097+ "load_updates:\t%d\n"
16098+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
16099+ "total_forks:\t%d\n",
16100+ atomic_read(&cvirt->nr_threads),
16101+ atomic_read(&cvirt->nr_running),
16102+ atomic_read(&cvirt->nr_uninterruptible),
16103+ atomic_read(&cvirt->nr_onhold),
16104+ atomic_read(&cvirt->load_updates),
16105+ LOAD_INT(a), LOAD_FRAC(a),
16106+ LOAD_INT(b), LOAD_FRAC(b),
16107+ LOAD_INT(c), LOAD_FRAC(c),
16108+ atomic_read(&cvirt->total_forks));
16109+ return length;
d337f35e
JR
16110+}
16111+
4bf69007
AM
16112+static inline
16113+int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
16114+ char *buffer, int cpu)
16115+{
16116+ int length = 0;
16117+ return length;
16118+}
d337f35e 16119+
4bf69007 16120+#endif /* _VX_CVIRT_PROC_H */
f19bd705
AM
16121diff -NurpP --minimal linux-4.4.111/kernel/vserver/debug.c linux-4.4.111-vs2.3.9.1/kernel/vserver/debug.c
16122--- linux-4.4.111/kernel/vserver/debug.c 1970-01-01 00:00:00.000000000 +0000
16123+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/debug.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
16124@@ -0,0 +1,32 @@
16125+/*
16126+ * kernel/vserver/debug.c
16127+ *
927ca606 16128+ * Copyright (C) 2005-2007 Herbert P?tzl
4bf69007
AM
16129+ *
16130+ * V0.01 vx_info dump support
16131+ *
16132+ */
d337f35e 16133+
4bf69007 16134+#include <linux/module.h>
d337f35e 16135+
4bf69007 16136+#include <linux/vserver/context.h>
d337f35e 16137+
d337f35e 16138+
4bf69007 16139+void dump_vx_info(struct vx_info *vxi, int level)
d337f35e 16140+{
4bf69007
AM
16141+ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
16142+ atomic_read(&vxi->vx_usecnt),
16143+ atomic_read(&vxi->vx_tasks),
16144+ vxi->vx_state);
16145+ if (level > 0) {
16146+ __dump_vx_limit(&vxi->limit);
16147+ __dump_vx_sched(&vxi->sched);
16148+ __dump_vx_cvirt(&vxi->cvirt);
16149+ __dump_vx_cacct(&vxi->cacct);
16150+ }
16151+ printk("---\n");
16152+}
d337f35e 16153+
d337f35e 16154+
4bf69007 16155+EXPORT_SYMBOL_GPL(dump_vx_info);
d337f35e 16156+
f19bd705
AM
16157diff -NurpP --minimal linux-4.4.111/kernel/vserver/device.c linux-4.4.111-vs2.3.9.1/kernel/vserver/device.c
16158--- linux-4.4.111/kernel/vserver/device.c 1970-01-01 00:00:00.000000000 +0000
16159+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/device.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
16160@@ -0,0 +1,443 @@
16161+/*
16162+ * linux/kernel/vserver/device.c
16163+ *
16164+ * Linux-VServer: Device Support
16165+ *
927ca606 16166+ * Copyright (C) 2006 Herbert P?tzl
4bf69007
AM
16167+ * Copyright (C) 2007 Daniel Hokka Zakrisson
16168+ *
16169+ * V0.01 device mapping basics
16170+ * V0.02 added defaults
16171+ *
16172+ */
d337f35e 16173+
4bf69007
AM
16174+#include <linux/slab.h>
16175+#include <linux/rcupdate.h>
16176+#include <linux/fs.h>
16177+#include <linux/namei.h>
16178+#include <linux/hash.h>
d337f35e 16179+
4bf69007
AM
16180+#include <asm/errno.h>
16181+#include <asm/uaccess.h>
16182+#include <linux/vserver/base.h>
16183+#include <linux/vserver/debug.h>
16184+#include <linux/vserver/context.h>
16185+#include <linux/vserver/device.h>
16186+#include <linux/vserver/device_cmd.h>
d337f35e 16187+
d337f35e 16188+
4bf69007 16189+#define DMAP_HASH_BITS 4
d337f35e 16190+
d337f35e 16191+
4bf69007
AM
16192+struct vs_mapping {
16193+ union {
16194+ struct hlist_node hlist;
16195+ struct list_head list;
16196+ } u;
16197+#define dm_hlist u.hlist
16198+#define dm_list u.list
61333608 16199+ vxid_t xid;
4bf69007
AM
16200+ dev_t device;
16201+ struct vx_dmap_target target;
16202+};
d337f35e 16203+
d337f35e 16204+
4bf69007 16205+static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS];
d337f35e 16206+
4bf69007 16207+static DEFINE_SPINLOCK(dmap_main_hash_lock);
d337f35e 16208+
4bf69007
AM
16209+static struct vx_dmap_target dmap_defaults[2] = {
16210+ { .flags = DATTR_OPEN },
16211+ { .flags = DATTR_OPEN },
16212+};
d337f35e
JR
16213+
16214+
4bf69007 16215+struct kmem_cache *dmap_cachep __read_mostly;
d337f35e 16216+
4bf69007
AM
16217+int __init dmap_cache_init(void)
16218+{
16219+ dmap_cachep = kmem_cache_create("dmap_cache",
16220+ sizeof(struct vs_mapping), 0,
16221+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
16222+ return 0;
16223+}
16224+
4bf69007 16225+__initcall(dmap_cache_init);
d337f35e 16226+
4bf69007
AM
16227+
16228+static inline unsigned int __hashval(dev_t dev, int bits)
d337f35e 16229+{
4bf69007
AM
16230+ return hash_long((unsigned long)dev, bits);
16231+}
d337f35e 16232+
d337f35e 16233+
4bf69007
AM
16234+/* __hash_mapping()
16235+ * add the mapping to the hash table
16236+ */
16237+static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm)
16238+{
16239+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16240+ struct hlist_head *head, *hash = dmap_main_hash;
16241+ int device = vdm->device;
d337f35e 16242+
4bf69007
AM
16243+ spin_lock(hash_lock);
16244+ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x",
16245+ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target);
d337f35e 16246+
4bf69007
AM
16247+ head = &hash[__hashval(device, DMAP_HASH_BITS)];
16248+ hlist_add_head(&vdm->dm_hlist, head);
16249+ spin_unlock(hash_lock);
16250+}
16251+
16252+
16253+static inline int __mode_to_default(umode_t mode)
16254+{
16255+ switch (mode) {
16256+ case S_IFBLK:
16257+ return 0;
16258+ case S_IFCHR:
16259+ return 1;
16260+ default:
16261+ BUG();
d337f35e 16262+ }
d337f35e
JR
16263+}
16264+
4bf69007
AM
16265+
16266+/* __set_default()
16267+ * set a default
16268+ */
16269+static inline void __set_default(struct vx_info *vxi, umode_t mode,
16270+ struct vx_dmap_target *vdmt)
d337f35e 16271+{
4bf69007
AM
16272+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16273+ spin_lock(hash_lock);
d337f35e 16274+
4bf69007
AM
16275+ if (vxi)
16276+ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt;
16277+ else
16278+ dmap_defaults[__mode_to_default(mode)] = *vdmt;
d337f35e 16279+
d337f35e 16280+
4bf69007 16281+ spin_unlock(hash_lock);
d337f35e 16282+
4bf69007
AM
16283+ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x",
16284+ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags);
d337f35e
JR
16285+}
16286+
d337f35e 16287+
4bf69007
AM
16288+/* __remove_default()
16289+ * remove a default
16290+ */
16291+static inline int __remove_default(struct vx_info *vxi, umode_t mode)
d337f35e 16292+{
4bf69007
AM
16293+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16294+ spin_lock(hash_lock);
d337f35e 16295+
4bf69007
AM
16296+ if (vxi)
16297+ vxi->dmap.targets[__mode_to_default(mode)].flags = 0;
16298+ else /* remove == reset */
16299+ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode;
d337f35e 16300+
4bf69007
AM
16301+ spin_unlock(hash_lock);
16302+ return 0;
d337f35e
JR
16303+}
16304+
d337f35e 16305+
4bf69007
AM
16306+/* __find_mapping()
16307+ * find a mapping in the hash table
16308+ *
16309+ * caller must hold hash_lock
16310+ */
61333608 16311+static inline int __find_mapping(vxid_t xid, dev_t device, umode_t mode,
4bf69007
AM
16312+ struct vs_mapping **local, struct vs_mapping **global)
16313+{
16314+ struct hlist_head *hash = dmap_main_hash;
16315+ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)];
16316+ struct hlist_node *pos;
16317+ struct vs_mapping *vdm;
d337f35e 16318+
4bf69007
AM
16319+ *local = NULL;
16320+ if (global)
16321+ *global = NULL;
d337f35e 16322+
4bf69007
AM
16323+ hlist_for_each(pos, head) {
16324+ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist);
d337f35e 16325+
4bf69007
AM
16326+ if ((vdm->device == device) &&
16327+ !((vdm->target.flags ^ mode) & S_IFMT)) {
16328+ if (vdm->xid == xid) {
16329+ *local = vdm;
16330+ return 1;
16331+ } else if (global && vdm->xid == 0)
16332+ *global = vdm;
2380c486
JR
16333+ }
16334+ }
16335+
4bf69007
AM
16336+ if (global && *global)
16337+ return 0;
16338+ else
16339+ return -ENOENT;
2380c486
JR
16340+}
16341+
16342+
4bf69007
AM
16343+/* __lookup_mapping()
16344+ * find a mapping and store the result in target and flags
16345+ */
16346+static inline int __lookup_mapping(struct vx_info *vxi,
16347+ dev_t device, dev_t *target, int *flags, umode_t mode)
2380c486 16348+{
4bf69007
AM
16349+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16350+ struct vs_mapping *vdm, *global;
16351+ struct vx_dmap_target *vdmt;
2380c486 16352+ int ret = 0;
61333608 16353+ vxid_t xid = vxi->vx_id;
4bf69007 16354+ int index;
2380c486 16355+
4bf69007
AM
16356+ spin_lock(hash_lock);
16357+ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) {
2380c486 16358+ ret = 1;
4bf69007
AM
16359+ vdmt = &vdm->target;
16360+ goto found;
16361+ }
2380c486 16362+
4bf69007
AM
16363+ index = __mode_to_default(mode);
16364+ if (vxi && vxi->dmap.targets[index].flags) {
16365+ ret = 2;
16366+ vdmt = &vxi->dmap.targets[index];
16367+ } else if (global) {
16368+ ret = 3;
16369+ vdmt = &global->target;
16370+ goto found;
16371+ } else {
16372+ ret = 4;
16373+ vdmt = &dmap_defaults[index];
d337f35e 16374+ }
2380c486 16375+
4bf69007
AM
16376+found:
16377+ if (target && (vdmt->flags & DATTR_REMAP))
16378+ *target = vdmt->target;
16379+ else if (target)
16380+ *target = device;
16381+ if (flags)
16382+ *flags = vdmt->flags;
16383+
16384+ spin_unlock(hash_lock);
2380c486
JR
16385+
16386+ return ret;
d337f35e
JR
16387+}
16388+
16389+
4bf69007
AM
16390+/* __remove_mapping()
16391+ * remove a mapping from the hash table
16392+ */
16393+static inline int __remove_mapping(struct vx_info *vxi, dev_t device,
16394+ umode_t mode)
d337f35e 16395+{
4bf69007
AM
16396+ spinlock_t *hash_lock = &dmap_main_hash_lock;
16397+ struct vs_mapping *vdm = NULL;
d337f35e
JR
16398+ int ret = 0;
16399+
4bf69007
AM
16400+ spin_lock(hash_lock);
16401+
16402+ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm,
16403+ NULL);
16404+ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x",
16405+ vxi, vxi ? vxi->vx_id : 0, device, mode);
16406+ if (ret < 0)
2380c486 16407+ goto out;
4bf69007 16408+ hlist_del(&vdm->dm_hlist);
2380c486 16409+
2380c486 16410+out:
4bf69007
AM
16411+ spin_unlock(hash_lock);
16412+ if (vdm)
16413+ kmem_cache_free(dmap_cachep, vdm);
2380c486
JR
16414+ return ret;
16415+}
16416+
16417+
2380c486 16418+
4bf69007
AM
16419+int vs_map_device(struct vx_info *vxi,
16420+ dev_t device, dev_t *target, umode_t mode)
2380c486 16421+{
4bf69007 16422+ int ret, flags = DATTR_MASK;
2380c486 16423+
4bf69007
AM
16424+ if (!vxi) {
16425+ if (target)
16426+ *target = device;
2380c486 16427+ goto out;
2380c486 16428+ }
4bf69007
AM
16429+ ret = __lookup_mapping(vxi, device, target, &flags, mode);
16430+ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d",
16431+ device, target ? *target : 0, flags, mode, ret);
2380c486 16432+out:
4bf69007 16433+ return (flags & DATTR_MASK);
2380c486
JR
16434+}
16435+
2380c486 16436+
4bf69007
AM
16437+
16438+static int do_set_mapping(struct vx_info *vxi,
16439+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16440+{
4bf69007
AM
16441+ if (device) {
16442+ struct vs_mapping *new;
2380c486 16443+
4bf69007
AM
16444+ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL);
16445+ if (!new)
16446+ return -ENOMEM;
16447+
16448+ INIT_HLIST_NODE(&new->dm_hlist);
16449+ new->device = device;
16450+ new->target.target = target;
16451+ new->target.flags = flags | mode;
16452+ new->xid = (vxi ? vxi->vx_id : 0);
16453+
16454+ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags);
16455+ __hash_mapping(vxi, new);
16456+ } else {
16457+ struct vx_dmap_target new = {
16458+ .target = target,
16459+ .flags = flags | mode,
16460+ };
16461+ __set_default(vxi, mode, &new);
16462+ }
16463+ return 0;
2380c486
JR
16464+}
16465+
4bf69007
AM
16466+
16467+static int do_unset_mapping(struct vx_info *vxi,
16468+ dev_t device, dev_t target, int flags, umode_t mode)
2380c486 16469+{
4bf69007 16470+ int ret = -EINVAL;
763640ca 16471+
4bf69007
AM
16472+ if (device) {
16473+ ret = __remove_mapping(vxi, device, mode);
16474+ if (ret < 0)
16475+ goto out;
16476+ } else {
16477+ ret = __remove_default(vxi, mode);
16478+ if (ret < 0)
16479+ goto out;
16480+ }
2380c486 16481+
4bf69007
AM
16482+out:
16483+ return ret;
16484+}
2380c486 16485+
2380c486 16486+
4bf69007
AM
16487+static inline int __user_device(const char __user *name, dev_t *dev,
16488+ umode_t *mode)
16489+{
927ca606 16490+ struct path path;
4bf69007 16491+ int ret;
2380c486 16492+
4bf69007
AM
16493+ if (!name) {
16494+ *dev = 0;
16495+ return 0;
16496+ }
927ca606 16497+ ret = user_lpath(name, &path);
4bf69007
AM
16498+ if (ret)
16499+ return ret;
927ca606
AM
16500+ if (path.dentry->d_inode) {
16501+ *dev = path.dentry->d_inode->i_rdev;
16502+ *mode = path.dentry->d_inode->i_mode;
4bf69007 16503+ }
927ca606 16504+ path_put(&path);
4bf69007
AM
16505+ return 0;
16506+}
2380c486 16507+
4bf69007
AM
16508+static inline int __mapping_mode(dev_t device, dev_t target,
16509+ umode_t device_mode, umode_t target_mode, umode_t *mode)
16510+{
16511+ if (device)
16512+ *mode = device_mode & S_IFMT;
16513+ else if (target)
16514+ *mode = target_mode & S_IFMT;
16515+ else
16516+ return -EINVAL;
2380c486 16517+
4bf69007
AM
16518+ /* if both given, device and target mode have to match */
16519+ if (device && target &&
16520+ ((device_mode ^ target_mode) & S_IFMT))
16521+ return -EINVAL;
16522+ return 0;
16523+}
d337f35e 16524+
d337f35e 16525+
4bf69007
AM
16526+static inline int do_mapping(struct vx_info *vxi, const char __user *device_path,
16527+ const char __user *target_path, int flags, int set)
16528+{
16529+ dev_t device = ~0, target = ~0;
16530+ umode_t device_mode = 0, target_mode = 0, mode;
16531+ int ret;
2380c486 16532+
4bf69007
AM
16533+ ret = __user_device(device_path, &device, &device_mode);
16534+ if (ret)
16535+ return ret;
16536+ ret = __user_device(target_path, &target, &target_mode);
16537+ if (ret)
16538+ return ret;
2380c486 16539+
4bf69007
AM
16540+ ret = __mapping_mode(device, target,
16541+ device_mode, target_mode, &mode);
16542+ if (ret)
16543+ return ret;
2380c486 16544+
4bf69007
AM
16545+ if (set)
16546+ return do_set_mapping(vxi, device, target,
16547+ flags, mode);
16548+ else
16549+ return do_unset_mapping(vxi, device, target,
16550+ flags, mode);
d337f35e
JR
16551+}
16552+
d337f35e 16553+
4bf69007
AM
16554+int vc_set_mapping(struct vx_info *vxi, void __user *data)
16555+{
16556+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16557+
4bf69007
AM
16558+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16559+ return -EFAULT;
d337f35e 16560+
4bf69007
AM
16561+ return do_mapping(vxi, vc_data.device, vc_data.target,
16562+ vc_data.flags, 1);
16563+}
d337f35e 16564+
4bf69007 16565+int vc_unset_mapping(struct vx_info *vxi, void __user *data)
d337f35e 16566+{
4bf69007 16567+ struct vcmd_set_mapping_v0 vc_data;
d337f35e 16568+
4bf69007
AM
16569+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16570+ return -EFAULT;
16571+
16572+ return do_mapping(vxi, vc_data.device, vc_data.target,
16573+ vc_data.flags, 0);
d337f35e
JR
16574+}
16575+
16576+
4bf69007
AM
16577+#ifdef CONFIG_COMPAT
16578+
16579+int vc_set_mapping_x32(struct vx_info *vxi, void __user *data)
d337f35e 16580+{
4bf69007 16581+ struct vcmd_set_mapping_v0_x32 vc_data;
d337f35e 16582+
4bf69007
AM
16583+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16584+ return -EFAULT;
16585+
16586+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16587+ compat_ptr(vc_data.target_ptr), vc_data.flags, 1);
d337f35e
JR
16588+}
16589+
4bf69007
AM
16590+int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data)
16591+{
16592+ struct vcmd_set_mapping_v0_x32 vc_data;
16593+
16594+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16595+ return -EFAULT;
d337f35e 16596+
4bf69007
AM
16597+ return do_mapping(vxi, compat_ptr(vc_data.device_ptr),
16598+ compat_ptr(vc_data.target_ptr), vc_data.flags, 0);
16599+}
d337f35e 16600+
4bf69007 16601+#endif /* CONFIG_COMPAT */
d337f35e 16602+
4bf69007 16603+
f19bd705
AM
16604diff -NurpP --minimal linux-4.4.111/kernel/vserver/dlimit.c linux-4.4.111-vs2.3.9.1/kernel/vserver/dlimit.c
16605--- linux-4.4.111/kernel/vserver/dlimit.c 1970-01-01 00:00:00.000000000 +0000
16606+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/dlimit.c 2018-01-09 16:36:34.000000000 +0000
b00e13aa 16607@@ -0,0 +1,528 @@
d337f35e 16608+/*
4bf69007 16609+ * linux/kernel/vserver/dlimit.c
d337f35e 16610+ *
4bf69007 16611+ * Virtual Server: Context Disk Limits
d337f35e 16612+ *
927ca606 16613+ * Copyright (C) 2004-2009 Herbert P?tzl
d337f35e 16614+ *
4bf69007
AM
16615+ * V0.01 initial version
16616+ * V0.02 compat32 splitup
16617+ * V0.03 extended interface
d337f35e
JR
16618+ *
16619+ */
16620+
4bf69007
AM
16621+#include <linux/statfs.h>
16622+#include <linux/sched.h>
2380c486 16623+#include <linux/namei.h>
d337f35e 16624+#include <linux/vs_tag.h>
4bf69007
AM
16625+#include <linux/vs_dlimit.h>
16626+#include <linux/vserver/dlimit_cmd.h>
16627+#include <linux/slab.h>
16628+// #include <linux/gfp.h>
d337f35e 16629+
d337f35e
JR
16630+#include <asm/uaccess.h>
16631+
4bf69007 16632+/* __alloc_dl_info()
d337f35e 16633+
4bf69007
AM
16634+ * allocate an initialized dl_info struct
16635+ * doesn't make it visible (hash) */
d337f35e 16636+
61333608 16637+static struct dl_info *__alloc_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16638+{
16639+ struct dl_info *new = NULL;
d337f35e 16640+
4bf69007
AM
16641+ vxdprintk(VXD_CBIT(dlim, 5),
16642+ "alloc_dl_info(%p,%d)*", sb, tag);
d337f35e 16643+
4bf69007
AM
16644+ /* would this benefit from a slab cache? */
16645+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
16646+ if (!new)
16647+ return 0;
d337f35e 16648+
4bf69007
AM
16649+ memset(new, 0, sizeof(struct dl_info));
16650+ new->dl_tag = tag;
16651+ new->dl_sb = sb;
16652+ // INIT_RCU_HEAD(&new->dl_rcu);
16653+ INIT_HLIST_NODE(&new->dl_hlist);
16654+ spin_lock_init(&new->dl_lock);
16655+ atomic_set(&new->dl_refcnt, 0);
16656+ atomic_set(&new->dl_usecnt, 0);
d337f35e 16657+
4bf69007 16658+ /* rest of init goes here */
d337f35e 16659+
4bf69007
AM
16660+ vxdprintk(VXD_CBIT(dlim, 4),
16661+ "alloc_dl_info(%p,%d) = %p", sb, tag, new);
16662+ return new;
16663+}
d4263eb0 16664+
4bf69007 16665+/* __dealloc_dl_info()
d337f35e 16666+
4bf69007 16667+ * final disposal of dl_info */
d337f35e 16668+
4bf69007 16669+static void __dealloc_dl_info(struct dl_info *dli)
adc1caaa 16670+{
4bf69007
AM
16671+ vxdprintk(VXD_CBIT(dlim, 4),
16672+ "dealloc_dl_info(%p)", dli);
2380c486 16673+
4bf69007
AM
16674+ dli->dl_hlist.next = LIST_POISON1;
16675+ dli->dl_tag = -1;
16676+ dli->dl_sb = 0;
2380c486 16677+
4bf69007
AM
16678+ BUG_ON(atomic_read(&dli->dl_usecnt));
16679+ BUG_ON(atomic_read(&dli->dl_refcnt));
2380c486 16680+
4bf69007 16681+ kfree(dli);
adc1caaa 16682+}
2380c486 16683+
2380c486 16684+
4bf69007 16685+/* hash table for dl_info hash */
2380c486 16686+
4bf69007 16687+#define DL_HASH_SIZE 13
2380c486 16688+
4bf69007 16689+struct hlist_head dl_info_hash[DL_HASH_SIZE];
2380c486 16690+
4bf69007 16691+static DEFINE_SPINLOCK(dl_info_hash_lock);
2380c486 16692+
d33d7b00 16693+
61333608 16694+static inline unsigned int __hashval(struct super_block *sb, vtag_t tag)
adc1caaa 16695+{
4bf69007
AM
16696+ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
16697+}
2380c486 16698+
2380c486 16699+
2380c486 16700+
4bf69007 16701+/* __hash_dl_info()
2380c486 16702+
4bf69007
AM
16703+ * add the dli to the global hash table
16704+ * requires the hash_lock to be held */
2380c486 16705+
4bf69007
AM
16706+static inline void __hash_dl_info(struct dl_info *dli)
16707+{
16708+ struct hlist_head *head;
d337f35e 16709+
4bf69007
AM
16710+ vxdprintk(VXD_CBIT(dlim, 6),
16711+ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
16712+ get_dl_info(dli);
16713+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
16714+ hlist_add_head_rcu(&dli->dl_hlist, head);
16715+}
d337f35e 16716+
4bf69007 16717+/* __unhash_dl_info()
3bac966d 16718+
4bf69007
AM
16719+ * remove the dli from the global hash table
16720+ * requires the hash_lock to be held */
3bac966d 16721+
4bf69007
AM
16722+static inline void __unhash_dl_info(struct dl_info *dli)
16723+{
16724+ vxdprintk(VXD_CBIT(dlim, 6),
16725+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
16726+ hlist_del_rcu(&dli->dl_hlist);
16727+ put_dl_info(dli);
16728+}
3bac966d 16729+
3bac966d 16730+
4bf69007 16731+/* __lookup_dl_info()
3bac966d 16732+
4bf69007
AM
16733+ * requires the rcu_read_lock()
16734+ * doesn't increment the dl_refcnt */
3bac966d 16735+
61333608 16736+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16737+{
16738+ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
4bf69007 16739+ struct dl_info *dli;
3bac966d 16740+
b00e13aa
AM
16741+ hlist_for_each_entry_rcu(dli, head, dl_hlist) {
16742+ if (dli->dl_tag == tag && dli->dl_sb == sb)
4bf69007 16743+ return dli;
d33d7b00 16744+ }
4bf69007
AM
16745+ return NULL;
16746+}
3bac966d 16747+
3bac966d 16748+
61333608 16749+struct dl_info *locate_dl_info(struct super_block *sb, vtag_t tag)
4bf69007
AM
16750+{
16751+ struct dl_info *dli;
16752+
16753+ rcu_read_lock();
16754+ dli = get_dl_info(__lookup_dl_info(sb, tag));
16755+ vxdprintk(VXD_CBIT(dlim, 7),
16756+ "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
16757+ rcu_read_unlock();
16758+ return dli;
d33d7b00 16759+}
3bac966d 16760+
4bf69007 16761+void rcu_free_dl_info(struct rcu_head *head)
d33d7b00 16762+{
4bf69007
AM
16763+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
16764+ int usecnt, refcnt;
3bac966d 16765+
4bf69007 16766+ BUG_ON(!dli || !head);
3bac966d 16767+
4bf69007
AM
16768+ usecnt = atomic_read(&dli->dl_usecnt);
16769+ BUG_ON(usecnt < 0);
3bac966d 16770+
4bf69007
AM
16771+ refcnt = atomic_read(&dli->dl_refcnt);
16772+ BUG_ON(refcnt < 0);
16773+
16774+ vxdprintk(VXD_CBIT(dlim, 3),
16775+ "rcu_free_dl_info(%p)", dli);
16776+ if (!usecnt)
16777+ __dealloc_dl_info(dli);
16778+ else
16779+ printk("!!! rcu didn't free\n");
d33d7b00 16780+}
3bac966d 16781+
3bac966d 16782+
4bf69007
AM
16783+
16784+
16785+static int do_addrem_dlimit(uint32_t id, const char __user *name,
16786+ uint32_t flags, int add)
d33d7b00
AM
16787+{
16788+ struct path path;
d33d7b00 16789+ int ret;
3bac966d 16790+
4bf69007 16791+ ret = user_lpath(name, &path);
d33d7b00 16792+ if (!ret) {
4bf69007
AM
16793+ struct super_block *sb;
16794+ struct dl_info *dli;
16795+
16796+ ret = -EINVAL;
16797+ if (!path.dentry->d_inode)
16798+ goto out_release;
16799+ if (!(sb = path.dentry->d_inode->i_sb))
16800+ goto out_release;
16801+
16802+ if (add) {
16803+ dli = __alloc_dl_info(sb, id);
16804+ spin_lock(&dl_info_hash_lock);
16805+
16806+ ret = -EEXIST;
16807+ if (__lookup_dl_info(sb, id))
16808+ goto out_unlock;
16809+ __hash_dl_info(dli);
16810+ dli = NULL;
16811+ } else {
16812+ spin_lock(&dl_info_hash_lock);
16813+ dli = __lookup_dl_info(sb, id);
16814+
16815+ ret = -ESRCH;
16816+ if (!dli)
16817+ goto out_unlock;
16818+ __unhash_dl_info(dli);
16819+ }
16820+ ret = 0;
16821+ out_unlock:
16822+ spin_unlock(&dl_info_hash_lock);
16823+ if (add && dli)
16824+ __dealloc_dl_info(dli);
16825+ out_release:
d33d7b00
AM
16826+ path_put(&path);
16827+ }
d33d7b00
AM
16828+ return ret;
16829+}
3bac966d 16830+
4bf69007 16831+int vc_add_dlimit(uint32_t id, void __user *data)
d33d7b00 16832+{
4bf69007 16833+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16834+
d33d7b00
AM
16835+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16836+ return -EFAULT;
3bac966d 16837+
4bf69007
AM
16838+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
16839+}
3bac966d 16840+
4bf69007
AM
16841+int vc_rem_dlimit(uint32_t id, void __user *data)
16842+{
16843+ struct vcmd_ctx_dlimit_base_v0 vc_data;
3bac966d 16844+
4bf69007 16845+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d33d7b00 16846+ return -EFAULT;
4bf69007
AM
16847+
16848+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
d33d7b00 16849+}
3bac966d 16850+
4bf69007 16851+#ifdef CONFIG_COMPAT
3bac966d 16852+
4bf69007
AM
16853+int vc_add_dlimit_x32(uint32_t id, void __user *data)
16854+{
16855+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
3bac966d 16856+
4bf69007
AM
16857+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16858+ return -EFAULT;
d337f35e 16859+
4bf69007
AM
16860+ return do_addrem_dlimit(id,
16861+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
16862+}
d337f35e 16863+
4bf69007 16864+int vc_rem_dlimit_x32(uint32_t id, void __user *data)
d33d7b00 16865+{
4bf69007 16866+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
d337f35e 16867+
4bf69007
AM
16868+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16869+ return -EFAULT;
16870+
16871+ return do_addrem_dlimit(id,
16872+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
d33d7b00 16873+}
d337f35e 16874+
4bf69007
AM
16875+#endif /* CONFIG_COMPAT */
16876+
16877+
16878+static inline
16879+int do_set_dlimit(uint32_t id, const char __user *name,
16880+ uint32_t space_used, uint32_t space_total,
16881+ uint32_t inodes_used, uint32_t inodes_total,
16882+ uint32_t reserved, uint32_t flags)
d33d7b00 16883+{
4bf69007
AM
16884+ struct path path;
16885+ int ret;
ba86f833 16886+
4bf69007
AM
16887+ ret = user_lpath(name, &path);
16888+ if (!ret) {
16889+ struct super_block *sb;
16890+ struct dl_info *dli;
d337f35e 16891+
4bf69007
AM
16892+ ret = -EINVAL;
16893+ if (!path.dentry->d_inode)
16894+ goto out_release;
16895+ if (!(sb = path.dentry->d_inode->i_sb))
16896+ goto out_release;
d337f35e 16897+
4bf69007
AM
16898+ /* sanity checks */
16899+ if ((reserved != CDLIM_KEEP &&
16900+ reserved > 100) ||
16901+ (inodes_used != CDLIM_KEEP &&
16902+ inodes_used > inodes_total) ||
16903+ (space_used != CDLIM_KEEP &&
16904+ space_used > space_total))
16905+ goto out_release;
d337f35e 16906+
4bf69007
AM
16907+ ret = -ESRCH;
16908+ dli = locate_dl_info(sb, id);
16909+ if (!dli)
16910+ goto out_release;
ba86f833 16911+
4bf69007 16912+ spin_lock(&dli->dl_lock);
d337f35e 16913+
4bf69007
AM
16914+ if (inodes_used != CDLIM_KEEP)
16915+ dli->dl_inodes_used = inodes_used;
16916+ if (inodes_total != CDLIM_KEEP)
16917+ dli->dl_inodes_total = inodes_total;
16918+ if (space_used != CDLIM_KEEP)
16919+ dli->dl_space_used = dlimit_space_32to64(
16920+ space_used, flags, DLIMS_USED);
d337f35e 16921+
4bf69007
AM
16922+ if (space_total == CDLIM_INFINITY)
16923+ dli->dl_space_total = DLIM_INFINITY;
16924+ else if (space_total != CDLIM_KEEP)
16925+ dli->dl_space_total = dlimit_space_32to64(
16926+ space_total, flags, DLIMS_TOTAL);
78865d5b 16927+
4bf69007
AM
16928+ if (reserved != CDLIM_KEEP)
16929+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
78865d5b 16930+
4bf69007 16931+ spin_unlock(&dli->dl_lock);
d337f35e 16932+
4bf69007
AM
16933+ put_dl_info(dli);
16934+ ret = 0;
d337f35e 16935+
4bf69007
AM
16936+ out_release:
16937+ path_put(&path);
16938+ }
16939+ return ret;
16940+}
d337f35e 16941+
4bf69007
AM
16942+int vc_set_dlimit(uint32_t id, void __user *data)
16943+{
16944+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e 16945+
4bf69007
AM
16946+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16947+ return -EFAULT;
d337f35e 16948+
4bf69007
AM
16949+ return do_set_dlimit(id, vc_data.name,
16950+ vc_data.space_used, vc_data.space_total,
16951+ vc_data.inodes_used, vc_data.inodes_total,
16952+ vc_data.reserved, vc_data.flags);
16953+}
d337f35e 16954+
4bf69007 16955+#ifdef CONFIG_COMPAT
d337f35e 16956+
4bf69007
AM
16957+int vc_set_dlimit_x32(uint32_t id, void __user *data)
16958+{
16959+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e 16960+
4bf69007
AM
16961+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
16962+ return -EFAULT;
d337f35e 16963+
4bf69007
AM
16964+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
16965+ vc_data.space_used, vc_data.space_total,
16966+ vc_data.inodes_used, vc_data.inodes_total,
16967+ vc_data.reserved, vc_data.flags);
16968+}
d337f35e 16969+
4bf69007 16970+#endif /* CONFIG_COMPAT */
d337f35e 16971+
d337f35e 16972+
4bf69007
AM
16973+static inline
16974+int do_get_dlimit(uint32_t id, const char __user *name,
16975+ uint32_t *space_used, uint32_t *space_total,
16976+ uint32_t *inodes_used, uint32_t *inodes_total,
16977+ uint32_t *reserved, uint32_t *flags)
16978+{
16979+ struct path path;
16980+ int ret;
d337f35e 16981+
4bf69007
AM
16982+ ret = user_lpath(name, &path);
16983+ if (!ret) {
16984+ struct super_block *sb;
16985+ struct dl_info *dli;
d337f35e 16986+
4bf69007
AM
16987+ ret = -EINVAL;
16988+ if (!path.dentry->d_inode)
16989+ goto out_release;
16990+ if (!(sb = path.dentry->d_inode->i_sb))
16991+ goto out_release;
d337f35e 16992+
4bf69007
AM
16993+ ret = -ESRCH;
16994+ dli = locate_dl_info(sb, id);
16995+ if (!dli)
16996+ goto out_release;
d337f35e 16997+
4bf69007
AM
16998+ spin_lock(&dli->dl_lock);
16999+ *inodes_used = dli->dl_inodes_used;
17000+ *inodes_total = dli->dl_inodes_total;
d337f35e 17001+
4bf69007
AM
17002+ *space_used = dlimit_space_64to32(
17003+ dli->dl_space_used, flags, DLIMS_USED);
d337f35e 17004+
4bf69007
AM
17005+ if (dli->dl_space_total == DLIM_INFINITY)
17006+ *space_total = CDLIM_INFINITY;
17007+ else
17008+ *space_total = dlimit_space_64to32(
17009+ dli->dl_space_total, flags, DLIMS_TOTAL);
d337f35e 17010+
4bf69007
AM
17011+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
17012+ spin_unlock(&dli->dl_lock);
d337f35e 17013+
4bf69007
AM
17014+ put_dl_info(dli);
17015+ ret = -EFAULT;
d337f35e 17016+
4bf69007
AM
17017+ ret = 0;
17018+ out_release:
17019+ path_put(&path);
17020+ }
17021+ return ret;
d337f35e
JR
17022+}
17023+
4bf69007
AM
17024+
17025+int vc_get_dlimit(uint32_t id, void __user *data)
d337f35e 17026+{
4bf69007 17027+ struct vcmd_ctx_dlimit_v0 vc_data;
d337f35e
JR
17028+ int ret;
17029+
2380c486 17030+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17031+ return -EFAULT;
17032+
4bf69007
AM
17033+ ret = do_get_dlimit(id, vc_data.name,
17034+ &vc_data.space_used, &vc_data.space_total,
17035+ &vc_data.inodes_used, &vc_data.inodes_total,
17036+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17037+ if (ret)
17038+ return ret;
17039+
2380c486 17040+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17041+ return -EFAULT;
17042+ return 0;
17043+}
17044+
4bf69007 17045+#ifdef CONFIG_COMPAT
d337f35e 17046+
4bf69007 17047+int vc_get_dlimit_x32(uint32_t id, void __user *data)
d337f35e 17048+{
4bf69007 17049+ struct vcmd_ctx_dlimit_v0_x32 vc_data;
d337f35e
JR
17050+ int ret;
17051+
2380c486 17052+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
17053+ return -EFAULT;
17054+
4bf69007
AM
17055+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
17056+ &vc_data.space_used, &vc_data.space_total,
17057+ &vc_data.inodes_used, &vc_data.inodes_total,
17058+ &vc_data.reserved, &vc_data.flags);
d337f35e
JR
17059+ if (ret)
17060+ return ret;
17061+
2380c486 17062+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
17063+ return -EFAULT;
17064+ return 0;
17065+}
17066+
4bf69007 17067+#endif /* CONFIG_COMPAT */
ec22aa5c
AM
17068+
17069+
4bf69007 17070+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
ec22aa5c 17071+{
4bf69007
AM
17072+ struct dl_info *dli;
17073+ __u64 blimit, bfree, bavail;
17074+ __u32 ifree;
ec22aa5c 17075+
4bf69007
AM
17076+ dli = locate_dl_info(sb, dx_current_tag());
17077+ if (!dli)
17078+ return;
ec22aa5c 17079+
4bf69007
AM
17080+ spin_lock(&dli->dl_lock);
17081+ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
17082+ goto no_ilim;
ec22aa5c 17083+
4bf69007
AM
17084+ /* reduce max inodes available to limit */
17085+ if (buf->f_files > dli->dl_inodes_total)
17086+ buf->f_files = dli->dl_inodes_total;
ec22aa5c 17087+
4bf69007
AM
17088+ ifree = dli->dl_inodes_total - dli->dl_inodes_used;
17089+ /* reduce free inodes to min */
17090+ if (ifree < buf->f_ffree)
17091+ buf->f_ffree = ifree;
b2252bc2 17092+
4bf69007
AM
17093+no_ilim:
17094+ if (dli->dl_space_total == DLIM_INFINITY)
17095+ goto no_blim;
d337f35e 17096+
4bf69007 17097+ blimit = dli->dl_space_total >> sb->s_blocksize_bits;
d337f35e 17098+
4bf69007
AM
17099+ if (dli->dl_space_total < dli->dl_space_used)
17100+ bfree = 0;
17101+ else
17102+ bfree = (dli->dl_space_total - dli->dl_space_used)
17103+ >> sb->s_blocksize_bits;
d337f35e 17104+
4bf69007
AM
17105+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
17106+ if (bavail < dli->dl_space_used)
17107+ bavail = 0;
17108+ else
17109+ bavail = (bavail - dli->dl_space_used)
17110+ >> sb->s_blocksize_bits;
d337f35e 17111+
4bf69007
AM
17112+ /* reduce max space available to limit */
17113+ if (buf->f_blocks > blimit)
17114+ buf->f_blocks = blimit;
d337f35e 17115+
4bf69007
AM
17116+ /* reduce free space to min */
17117+ if (bfree < buf->f_bfree)
17118+ buf->f_bfree = bfree;
d337f35e 17119+
4bf69007
AM
17120+ /* reduce avail space to min */
17121+ if (bavail < buf->f_bavail)
17122+ buf->f_bavail = bavail;
d337f35e 17123+
4bf69007
AM
17124+no_blim:
17125+ spin_unlock(&dli->dl_lock);
17126+ put_dl_info(dli);
d337f35e 17127+
4bf69007 17128+ return;
d337f35e
JR
17129+}
17130+
4bf69007 17131+#include <linux/module.h>
d337f35e 17132+
4bf69007
AM
17133+EXPORT_SYMBOL_GPL(locate_dl_info);
17134+EXPORT_SYMBOL_GPL(rcu_free_dl_info);
e3afe727 17135+
f19bd705
AM
17136diff -NurpP --minimal linux-4.4.111/kernel/vserver/helper.c linux-4.4.111-vs2.3.9.1/kernel/vserver/helper.c
17137--- linux-4.4.111/kernel/vserver/helper.c 1970-01-01 00:00:00.000000000 +0000
17138+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/helper.c 2018-01-09 16:36:34.000000000 +0000
09be7631 17139@@ -0,0 +1,242 @@
4bf69007
AM
17140+/*
17141+ * linux/kernel/vserver/helper.c
17142+ *
17143+ * Virtual Context Support
17144+ *
927ca606 17145+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17146+ *
17147+ * V0.01 basic helper
17148+ *
17149+ */
e3afe727 17150+
4bf69007
AM
17151+#include <linux/kmod.h>
17152+#include <linux/reboot.h>
17153+#include <linux/vs_context.h>
17154+#include <linux/vs_network.h>
17155+#include <linux/vserver/signal.h>
e3afe727 17156+
4bf69007
AM
17157+
17158+char vshelper_path[255] = "/sbin/vshelper";
17159+
17160+static int vshelper_init(struct subprocess_info *info, struct cred *new_cred)
17161+{
09be7631 17162+ current->flags &= ~PF_NO_SETAFFINITY;
4bf69007 17163+ return 0;
d337f35e
JR
17164+}
17165+
09be7631
JR
17166+static int vs_call_usermodehelper(char *path, char **argv, char **envp, int wait)
17167+{
17168+ struct subprocess_info *info;
17169+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
17170+
17171+ info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
17172+ vshelper_init, NULL, NULL);
17173+ if (info == NULL)
17174+ return -ENOMEM;
17175+
17176+ return call_usermodehelper_exec(info, wait);
17177+}
17178+
4bf69007 17179+static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
d337f35e 17180+{
4bf69007 17181+ int ret;
e3afe727 17182+
09be7631
JR
17183+ if ((ret = vs_call_usermodehelper(name, argv, envp,
17184+ sync ? UMH_WAIT_PROC : UMH_WAIT_EXEC))) {
4bf69007
AM
17185+ printk(KERN_WARNING "%s: (%s %s) returned %s with %d\n",
17186+ name, argv[1], argv[2],
17187+ sync ? "sync" : "async", ret);
17188+ }
17189+ vxdprintk(VXD_CBIT(switch, 4),
17190+ "%s: (%s %s) returned %s with %d",
17191+ name, argv[1], argv[2], sync ? "sync" : "async", ret);
17192+ return ret;
17193+}
e3afe727 17194+
4bf69007
AM
17195+/*
17196+ * vshelper path is set via /proc/sys
17197+ * invoked by vserver sys_reboot(), with
17198+ * the following arguments
17199+ *
17200+ * argv [0] = vshelper_path;
17201+ * argv [1] = action: "restart", "halt", "poweroff", ...
17202+ * argv [2] = context identifier
17203+ *
17204+ * envp [*] = type-specific parameters
17205+ */
e3afe727 17206+
4bf69007
AM
17207+long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
17208+{
17209+ char id_buf[8], cmd_buf[16];
17210+ char uid_buf[16], pid_buf[16];
17211+ int ret;
e3afe727 17212+
4bf69007
AM
17213+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17214+ char *envp[] = {"HOME=/", "TERM=linux",
17215+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
17216+ uid_buf, pid_buf, cmd_buf, 0};
e3afe727 17217+
4bf69007
AM
17218+ if (vx_info_state(vxi, VXS_HELPER))
17219+ return -EAGAIN;
17220+ vxi->vx_state |= VXS_HELPER;
7b17263b 17221+
4bf69007 17222+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
d337f35e 17223+
4bf69007 17224+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
8ce283e1
AM
17225+ snprintf(uid_buf, sizeof(uid_buf), "VS_UID=%d",
17226+ from_kuid(&init_user_ns, current_uid()));
4bf69007 17227+ snprintf(pid_buf, sizeof(pid_buf), "VS_PID=%d", current->pid);
e3afe727 17228+
4bf69007
AM
17229+ switch (cmd) {
17230+ case LINUX_REBOOT_CMD_RESTART:
17231+ argv[1] = "restart";
17232+ break;
07a627a5 17233+
4bf69007
AM
17234+ case LINUX_REBOOT_CMD_HALT:
17235+ argv[1] = "halt";
17236+ break;
e3afe727 17237+
4bf69007
AM
17238+ case LINUX_REBOOT_CMD_POWER_OFF:
17239+ argv[1] = "poweroff";
17240+ break;
d337f35e 17241+
4bf69007
AM
17242+ case LINUX_REBOOT_CMD_SW_SUSPEND:
17243+ argv[1] = "swsusp";
17244+ break;
d337f35e 17245+
4bf69007
AM
17246+ case LINUX_REBOOT_CMD_OOM:
17247+ argv[1] = "oom";
17248+ break;
d337f35e 17249+
4bf69007
AM
17250+ default:
17251+ vxi->vx_state &= ~VXS_HELPER;
17252+ return 0;
d337f35e 17253+ }
4bf69007
AM
17254+
17255+ ret = do_vshelper(vshelper_path, argv, envp, 0);
17256+ vxi->vx_state &= ~VXS_HELPER;
17257+ __wakeup_vx_info(vxi);
17258+ return (ret) ? -EPERM : 0;
d337f35e
JR
17259+}
17260+
4bf69007
AM
17261+
17262+long vs_reboot(unsigned int cmd, void __user *arg)
d337f35e 17263+{
4bf69007
AM
17264+ struct vx_info *vxi = current_vx_info();
17265+ long ret = 0;
d337f35e 17266+
4bf69007
AM
17267+ vxdprintk(VXD_CBIT(misc, 5),
17268+ "vs_reboot(%p[#%d],%u)",
17269+ vxi, vxi ? vxi->vx_id : 0, cmd);
17270+
17271+ ret = vs_reboot_helper(vxi, cmd, arg);
17272+ if (ret)
17273+ return ret;
17274+
17275+ vxi->reboot_cmd = cmd;
17276+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17277+ switch (cmd) {
17278+ case LINUX_REBOOT_CMD_RESTART:
17279+ case LINUX_REBOOT_CMD_HALT:
17280+ case LINUX_REBOOT_CMD_POWER_OFF:
17281+ vx_info_kill(vxi, 0, SIGKILL);
17282+ vx_info_kill(vxi, 1, SIGKILL);
17283+ default:
17284+ break;
17285+ }
d337f35e 17286+ }
4bf69007 17287+ return 0;
d337f35e
JR
17288+}
17289+
4bf69007
AM
17290+long vs_oom_action(unsigned int cmd)
17291+{
17292+ struct vx_info *vxi = current_vx_info();
17293+ long ret = 0;
d337f35e 17294+
4bf69007
AM
17295+ vxdprintk(VXD_CBIT(misc, 5),
17296+ "vs_oom_action(%p[#%d],%u)",
17297+ vxi, vxi ? vxi->vx_id : 0, cmd);
d337f35e 17298+
4bf69007
AM
17299+ ret = vs_reboot_helper(vxi, cmd, NULL);
17300+ if (ret)
17301+ return ret;
d337f35e 17302+
4bf69007
AM
17303+ vxi->reboot_cmd = cmd;
17304+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
17305+ vx_info_kill(vxi, 0, SIGKILL);
17306+ vx_info_kill(vxi, 1, SIGKILL);
17307+ }
17308+ return 0;
17309+}
d337f35e 17310+
4bf69007
AM
17311+/*
17312+ * argv [0] = vshelper_path;
17313+ * argv [1] = action: "startup", "shutdown"
17314+ * argv [2] = context identifier
17315+ *
17316+ * envp [*] = type-specific parameters
17317+ */
d337f35e 17318+
4bf69007 17319+long vs_state_change(struct vx_info *vxi, unsigned int cmd)
d337f35e 17320+{
4bf69007
AM
17321+ char id_buf[8], cmd_buf[16];
17322+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17323+ char *envp[] = {"HOME=/", "TERM=linux",
17324+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17325+
17326+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
17327+ return 0;
17328+
17329+ snprintf(id_buf, sizeof(id_buf), "%d", vxi->vx_id);
17330+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17331+
17332+ switch (cmd) {
17333+ case VSC_STARTUP:
17334+ argv[1] = "startup";
17335+ break;
17336+ case VSC_SHUTDOWN:
17337+ argv[1] = "shutdown";
17338+ break;
17339+ default:
17340+ return 0;
17341+ }
17342+
17343+ return do_vshelper(vshelper_path, argv, envp, 1);
d337f35e
JR
17344+}
17345+
d337f35e 17346+
4bf69007
AM
17347+/*
17348+ * argv [0] = vshelper_path;
17349+ * argv [1] = action: "netup", "netdown"
17350+ * argv [2] = context identifier
17351+ *
17352+ * envp [*] = type-specific parameters
17353+ */
17354+
17355+long vs_net_change(struct nx_info *nxi, unsigned int cmd)
17356+{
17357+ char id_buf[8], cmd_buf[16];
17358+ char *argv[] = {vshelper_path, NULL, id_buf, 0};
17359+ char *envp[] = {"HOME=/", "TERM=linux",
17360+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
17361+
17362+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
17363+ return 0;
17364+
17365+ snprintf(id_buf, sizeof(id_buf), "%d", nxi->nx_id);
17366+ snprintf(cmd_buf, sizeof(cmd_buf), "VS_CMD=%08x", cmd);
17367+
17368+ switch (cmd) {
17369+ case VSC_NETUP:
17370+ argv[1] = "netup";
17371+ break;
17372+ case VSC_NETDOWN:
17373+ argv[1] = "netdown";
17374+ break;
17375+ default:
17376+ return 0;
17377+ }
17378+
17379+ return do_vshelper(vshelper_path, argv, envp, 1);
17380+}
d337f35e 17381+
f19bd705
AM
17382diff -NurpP --minimal linux-4.4.111/kernel/vserver/history.c linux-4.4.111-vs2.3.9.1/kernel/vserver/history.c
17383--- linux-4.4.111/kernel/vserver/history.c 1970-01-01 00:00:00.000000000 +0000
17384+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/history.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 17385@@ -0,0 +1,258 @@
d337f35e 17386+/*
4bf69007 17387+ * kernel/vserver/history.c
d337f35e 17388+ *
4bf69007 17389+ * Virtual Context History Backtrace
d337f35e 17390+ *
927ca606 17391+ * Copyright (C) 2004-2007 Herbert P?tzl
d337f35e 17392+ *
4bf69007
AM
17393+ * V0.01 basic structure
17394+ * V0.02 hash/unhash and trace
17395+ * V0.03 preemption fixes
d337f35e
JR
17396+ *
17397+ */
17398+
4bf69007
AM
17399+#include <linux/module.h>
17400+#include <asm/uaccess.h>
d337f35e 17401+
4bf69007
AM
17402+#include <linux/vserver/context.h>
17403+#include <linux/vserver/debug.h>
17404+#include <linux/vserver/debug_cmd.h>
17405+#include <linux/vserver/history.h>
d337f35e
JR
17406+
17407+
4bf69007
AM
17408+#ifdef CONFIG_VSERVER_HISTORY
17409+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
17410+#else
17411+#define VXH_SIZE 64
17412+#endif
d337f35e 17413+
4bf69007
AM
17414+struct _vx_history {
17415+ unsigned int counter;
2380c486 17416+
4bf69007
AM
17417+ struct _vx_hist_entry entry[VXH_SIZE + 1];
17418+};
2380c486 17419+
2380c486 17420+
4bf69007 17421+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
2380c486 17422+
4bf69007 17423+unsigned volatile int vxh_active = 1;
2380c486 17424+
4bf69007 17425+static atomic_t sequence = ATOMIC_INIT(0);
2380c486 17426+
2380c486 17427+
4bf69007 17428+/* vxh_advance()
2380c486 17429+
4bf69007
AM
17430+ * requires disabled preemption */
17431+
17432+struct _vx_hist_entry *vxh_advance(void *loc)
2380c486 17433+{
4bf69007
AM
17434+ unsigned int cpu = smp_processor_id();
17435+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17436+ struct _vx_hist_entry *entry;
17437+ unsigned int index;
17438+
17439+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
17440+ entry = &hist->entry[index];
17441+
17442+ entry->seq = atomic_inc_return(&sequence);
17443+ entry->loc = loc;
17444+ return entry;
2380c486
JR
17445+}
17446+
4bf69007 17447+EXPORT_SYMBOL_GPL(vxh_advance);
2380c486 17448+
2380c486 17449+
4bf69007 17450+#define VXH_LOC_FMTS "(#%04x,*%d):%p"
2380c486 17451+
4bf69007 17452+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
2380c486 17453+
2380c486 17454+
4bf69007 17455+#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
2380c486 17456+
4bf69007
AM
17457+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
17458+ (e)->vxi.ptr ? (e)->vxi.xid : 0, \
17459+ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \
17460+ (e)->vxi.ptr ? (e)->vxi.tasks : 0
17461+
17462+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
2380c486 17463+{
4bf69007
AM
17464+ switch (e->type) {
17465+ case VXH_THROW_OOPS:
17466+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
17467+ break;
2380c486 17468+
4bf69007
AM
17469+ case VXH_GET_VX_INFO:
17470+ case VXH_PUT_VX_INFO:
17471+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17472+ VXH_LOC_ARGS(e),
17473+ (e->type == VXH_GET_VX_INFO) ? "get" : "put",
17474+ VXH_VXI_ARGS(e));
17475+ break;
2380c486 17476+
4bf69007
AM
17477+ case VXH_INIT_VX_INFO:
17478+ case VXH_SET_VX_INFO:
17479+ case VXH_CLR_VX_INFO:
17480+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17481+ VXH_LOC_ARGS(e),
17482+ (e->type == VXH_INIT_VX_INFO) ? "init" :
17483+ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"),
17484+ VXH_VXI_ARGS(e), e->sc.data);
17485+ break;
2380c486 17486+
4bf69007
AM
17487+ case VXH_CLAIM_VX_INFO:
17488+ case VXH_RELEASE_VX_INFO:
17489+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
17490+ VXH_LOC_ARGS(e),
17491+ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release",
17492+ VXH_VXI_ARGS(e), e->sc.data);
17493+ break;
2380c486 17494+
4bf69007
AM
17495+ case VXH_ALLOC_VX_INFO:
17496+ case VXH_DEALLOC_VX_INFO:
17497+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
17498+ VXH_LOC_ARGS(e),
17499+ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc",
17500+ VXH_VXI_ARGS(e));
17501+ break;
2380c486 17502+
4bf69007
AM
17503+ case VXH_HASH_VX_INFO:
17504+ case VXH_UNHASH_VX_INFO:
17505+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
17506+ VXH_LOC_ARGS(e),
17507+ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash",
17508+ VXH_VXI_ARGS(e));
17509+ break;
2380c486 17510+
4bf69007
AM
17511+ case VXH_LOC_VX_INFO:
17512+ case VXH_LOOKUP_VX_INFO:
17513+ case VXH_CREATE_VX_INFO:
17514+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
17515+ VXH_LOC_ARGS(e),
17516+ (e->type == VXH_CREATE_VX_INFO) ? "create" :
17517+ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"),
17518+ e->ll.arg, VXH_VXI_ARGS(e));
17519+ break;
2380c486
JR
17520+ }
17521+}
17522+
4bf69007
AM
17523+static void __vxh_dump_history(void)
17524+{
17525+ unsigned int i, cpu;
d337f35e 17526+
4bf69007
AM
17527+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
17528+ atomic_read(&sequence), NR_CPUS);
d337f35e 17529+
4bf69007
AM
17530+ for (i = 0; i < VXH_SIZE; i++) {
17531+ for_each_online_cpu(cpu) {
17532+ struct _vx_history *hist =
17533+ &per_cpu(vx_history_buffer, cpu);
17534+ unsigned int index = (hist->counter - i) % VXH_SIZE;
17535+ struct _vx_hist_entry *entry = &hist->entry[index];
d337f35e 17536+
4bf69007
AM
17537+ vxh_dump_entry(entry, cpu);
17538+ }
17539+ }
17540+}
d337f35e 17541+
4bf69007
AM
17542+void vxh_dump_history(void)
17543+{
17544+ vxh_active = 0;
17545+#ifdef CONFIG_SMP
17546+ local_irq_enable();
17547+ smp_send_stop();
17548+ local_irq_disable();
17549+#endif
17550+ __vxh_dump_history();
17551+}
d337f35e 17552+
d337f35e 17553+
4bf69007 17554+/* vserver syscall commands below here */
d337f35e 17555+
d337f35e 17556+
4bf69007
AM
17557+int vc_dump_history(uint32_t id)
17558+{
17559+ vxh_active = 0;
17560+ __vxh_dump_history();
17561+ vxh_active = 1;
2380c486 17562+
4bf69007 17563+ return 0;
d337f35e
JR
17564+}
17565+
d337f35e 17566+
4bf69007
AM
17567+int do_read_history(struct __user _vx_hist_entry *data,
17568+ int cpu, uint32_t *index, uint32_t *count)
d337f35e 17569+{
4bf69007
AM
17570+ int pos, ret = 0;
17571+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
17572+ int end = hist->counter;
17573+ int start = end - VXH_SIZE + 2;
17574+ int idx = *index;
d337f35e 17575+
4bf69007
AM
17576+ /* special case: get current pos */
17577+ if (!*count) {
17578+ *index = end;
17579+ return 0;
17580+ }
d337f35e 17581+
4bf69007
AM
17582+ /* have we lost some data? */
17583+ if (idx < start)
17584+ idx = start;
d337f35e 17585+
4bf69007
AM
17586+ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
17587+ struct _vx_hist_entry *entry =
17588+ &hist->entry[idx % VXH_SIZE];
2380c486 17589+
4bf69007
AM
17590+ /* send entry to userspace */
17591+ ret = copy_to_user(&data[pos], entry, sizeof(*entry));
17592+ if (ret)
17593+ break;
17594+ }
17595+ /* save new index and count */
17596+ *index = idx;
17597+ *count = pos;
17598+ return ret ? ret : (*index < end);
d337f35e
JR
17599+}
17600+
4bf69007 17601+int vc_read_history(uint32_t id, void __user *data)
d337f35e 17602+{
4bf69007
AM
17603+ struct vcmd_read_history_v0 vc_data;
17604+ int ret;
d337f35e 17605+
4bf69007
AM
17606+ if (id >= NR_CPUS)
17607+ return -EINVAL;
d337f35e 17608+
4bf69007
AM
17609+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17610+ return -EFAULT;
d337f35e 17611+
4bf69007
AM
17612+ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
17613+ id, &vc_data.index, &vc_data.count);
d337f35e 17614+
4bf69007
AM
17615+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17616+ return -EFAULT;
17617+ return ret;
d337f35e
JR
17618+}
17619+
4bf69007 17620+#ifdef CONFIG_COMPAT
d337f35e 17621+
4bf69007 17622+int vc_read_history_x32(uint32_t id, void __user *data)
d337f35e 17623+{
4bf69007
AM
17624+ struct vcmd_read_history_v0_x32 vc_data;
17625+ int ret;
d337f35e 17626+
4bf69007
AM
17627+ if (id >= NR_CPUS)
17628+ return -EINVAL;
d337f35e 17629+
4bf69007
AM
17630+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
17631+ return -EFAULT;
2380c486 17632+
4bf69007
AM
17633+ ret = do_read_history((struct __user _vx_hist_entry *)
17634+ compat_ptr(vc_data.data_ptr),
17635+ id, &vc_data.index, &vc_data.count);
d337f35e 17636+
4bf69007
AM
17637+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
17638+ return -EFAULT;
17639+ return ret;
17640+}
d337f35e 17641+
4bf69007 17642+#endif /* CONFIG_COMPAT */
d337f35e 17643+
f19bd705
AM
17644diff -NurpP --minimal linux-4.4.111/kernel/vserver/inet.c linux-4.4.111-vs2.3.9.1/kernel/vserver/inet.c
17645--- linux-4.4.111/kernel/vserver/inet.c 1970-01-01 00:00:00.000000000 +0000
17646+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/inet.c 2018-01-09 16:36:34.000000000 +0000
7a9e40b8 17647@@ -0,0 +1,236 @@
d337f35e 17648+
4bf69007
AM
17649+#include <linux/in.h>
17650+#include <linux/inetdevice.h>
17651+#include <linux/export.h>
17652+#include <linux/vs_inet.h>
17653+#include <linux/vs_inet6.h>
17654+#include <linux/vserver/debug.h>
17655+#include <net/route.h>
17656+#include <net/addrconf.h>
d337f35e
JR
17657+
17658+
4bf69007 17659+int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17660+{
4bf69007
AM
17661+ int ret = 0;
17662+
17663+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17664+ ret = 1;
17665+ else {
17666+ struct nx_addr_v4 *ptr;
7a9e40b8 17667+ unsigned long irqflags;
d337f35e 17668+
7a9e40b8 17669+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17670+ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) {
17671+ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17672+ ret = 1;
17673+ break;
17674+ }
17675+ }
7a9e40b8 17676+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17677+ }
d337f35e 17678+
4bf69007
AM
17679+ vxdprintk(VXD_CBIT(net, 2),
17680+ "nx_v4_addr_conflict(%p,%p): %d",
17681+ nxi1, nxi2, ret);
d337f35e 17682+
4bf69007
AM
17683+ return ret;
17684+}
d337f35e 17685+
d337f35e 17686+
4bf69007
AM
17687+#ifdef CONFIG_IPV6
17688+
17689+int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2)
d337f35e 17690+{
4bf69007 17691+ int ret = 0;
d337f35e 17692+
4bf69007
AM
17693+ if (!nxi1 || !nxi2 || nxi1 == nxi2)
17694+ ret = 1;
17695+ else {
17696+ struct nx_addr_v6 *ptr;
7a9e40b8 17697+ unsigned long irqflags;
d337f35e 17698+
7a9e40b8 17699+ spin_lock_irqsave(&nxi1->addr_lock, irqflags);
4bf69007
AM
17700+ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) {
17701+ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) {
17702+ ret = 1;
17703+ break;
17704+ }
17705+ }
7a9e40b8 17706+ spin_unlock_irqrestore(&nxi1->addr_lock, irqflags);
4bf69007 17707+ }
d337f35e 17708+
4bf69007
AM
17709+ vxdprintk(VXD_CBIT(net, 2),
17710+ "nx_v6_addr_conflict(%p,%p): %d",
17711+ nxi1, nxi2, ret);
d337f35e 17712+
4bf69007
AM
17713+ return ret;
17714+}
d337f35e 17715+
4bf69007 17716+#endif
d337f35e 17717+
4bf69007 17718+int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17719+{
4bf69007
AM
17720+ struct in_device *in_dev;
17721+ struct in_ifaddr **ifap;
17722+ struct in_ifaddr *ifa;
17723+ int ret = 0;
d337f35e 17724+
4bf69007
AM
17725+ if (!dev)
17726+ goto out;
17727+ in_dev = in_dev_get(dev);
17728+ if (!in_dev)
17729+ goto out;
d337f35e 17730+
4bf69007
AM
17731+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
17732+ ifap = &ifa->ifa_next) {
17733+ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) {
17734+ ret = 1;
17735+ break;
17736+ }
17737+ }
17738+ in_dev_put(in_dev);
17739+out:
17740+ return ret;
d337f35e
JR
17741+}
17742+
17743+
4bf69007 17744+#ifdef CONFIG_IPV6
d337f35e 17745+
4bf69007 17746+int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
d337f35e 17747+{
4bf69007
AM
17748+ struct inet6_dev *in_dev;
17749+ struct inet6_ifaddr *ifa;
17750+ int ret = 0;
d337f35e 17751+
4bf69007
AM
17752+ if (!dev)
17753+ goto out;
17754+ in_dev = in6_dev_get(dev);
17755+ if (!in_dev)
17756+ goto out;
d337f35e 17757+
4bf69007
AM
17758+ // for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL;
17759+ list_for_each_entry(ifa, &in_dev->addr_list, if_list) {
17760+ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) {
17761+ ret = 1;
17762+ break;
17763+ }
d337f35e 17764+ }
4bf69007
AM
17765+ in6_dev_put(in_dev);
17766+out:
17767+ return ret;
d337f35e
JR
17768+}
17769+
4bf69007 17770+#endif
d337f35e 17771+
4bf69007
AM
17772+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
17773+{
17774+ int ret = 1;
d337f35e 17775+
4bf69007
AM
17776+ if (!nxi)
17777+ goto out;
17778+ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi))
17779+ goto out;
17780+#ifdef CONFIG_IPV6
17781+ ret = 2;
17782+ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi))
17783+ goto out;
17784+#endif
17785+ ret = 0;
17786+out:
17787+ vxdprintk(VXD_CBIT(net, 3),
17788+ "dev_in_nx_info(%p,%p[#%d]) = %d",
17789+ dev, nxi, nxi ? nxi->nx_id : 0, ret);
17790+ return ret;
17791+}
d337f35e 17792+
4bf69007
AM
17793+struct rtable *ip_v4_find_src(struct net *net, struct nx_info *nxi,
17794+ struct flowi4 *fl4)
d337f35e 17795+{
4bf69007 17796+ struct rtable *rt;
d337f35e 17797+
4bf69007
AM
17798+ if (!nxi)
17799+ return NULL;
d337f35e 17800+
4bf69007
AM
17801+ /* FIXME: handle lback only case */
17802+ if (!NX_IPV4(nxi))
17803+ return ERR_PTR(-EPERM);
d337f35e 17804+
4bf69007
AM
17805+ vxdprintk(VXD_CBIT(net, 4),
17806+ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT,
17807+ nxi, nxi ? nxi->nx_id : 0,
17808+ NIPQUAD(fl4->saddr), NIPQUAD(fl4->daddr));
d337f35e 17809+
4bf69007
AM
17810+ /* single IP is unconditional */
17811+ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) &&
17812+ (fl4->saddr == INADDR_ANY))
17813+ fl4->saddr = nxi->v4.ip[0].s_addr;
d337f35e 17814+
4bf69007
AM
17815+ if (fl4->saddr == INADDR_ANY) {
17816+ struct nx_addr_v4 *ptr;
17817+ __be32 found = 0;
17818+
17819+ rt = __ip_route_output_key(net, fl4);
17820+ if (!IS_ERR(rt)) {
17821+ found = fl4->saddr;
17822+ ip_rt_put(rt);
17823+ vxdprintk(VXD_CBIT(net, 4),
17824+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17825+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(found));
17826+ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND))
17827+ goto found;
17828+ }
d337f35e 17829+
8d50a2ea 17830+ WARN_ON_ONCE(in_irq());
b00e13aa 17831+ spin_lock_bh(&nxi->addr_lock);
4bf69007
AM
17832+ for (ptr = &nxi->v4; ptr; ptr = ptr->next) {
17833+ __be32 primary = ptr->ip[0].s_addr;
17834+ __be32 mask = ptr->mask.s_addr;
17835+ __be32 neta = primary & mask;
d337f35e 17836+
4bf69007
AM
17837+ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: "
17838+ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT,
17839+ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary),
17840+ NIPQUAD(mask), NIPQUAD(neta));
17841+ if ((found & mask) != neta)
17842+ continue;
d337f35e 17843+
4bf69007
AM
17844+ fl4->saddr = primary;
17845+ rt = __ip_route_output_key(net, fl4);
17846+ vxdprintk(VXD_CBIT(net, 4),
17847+ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT,
17848+ nxi, nxi ? nxi->nx_id : 0, fl4->flowi4_oif, NIPQUAD(primary));
17849+ if (!IS_ERR(rt)) {
17850+ found = fl4->saddr;
17851+ ip_rt_put(rt);
17852+ if (found == primary)
5cb1760b 17853+ goto found_unlock;
4bf69007
AM
17854+ }
17855+ }
17856+ /* still no source ip? */
17857+ found = ipv4_is_loopback(fl4->daddr)
17858+ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr;
5cb1760b 17859+ found_unlock:
b00e13aa 17860+ spin_unlock_bh(&nxi->addr_lock);
4bf69007
AM
17861+ found:
17862+ /* assign src ip to flow */
17863+ fl4->saddr = found;
17864+
17865+ } else {
17866+ if (!v4_addr_in_nx_info(nxi, fl4->saddr, NXA_MASK_BIND))
17867+ return ERR_PTR(-EPERM);
17868+ }
d337f35e 17869+
4bf69007
AM
17870+ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) {
17871+ if (ipv4_is_loopback(fl4->daddr))
17872+ fl4->daddr = nxi->v4_lback.s_addr;
17873+ if (ipv4_is_loopback(fl4->saddr))
17874+ fl4->saddr = nxi->v4_lback.s_addr;
17875+ } else if (ipv4_is_loopback(fl4->daddr) &&
17876+ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0))
17877+ return ERR_PTR(-EPERM);
d337f35e 17878+
4bf69007 17879+ return NULL;
d337f35e
JR
17880+}
17881+
4bf69007 17882+EXPORT_SYMBOL_GPL(ip_v4_find_src);
d337f35e 17883+
f19bd705
AM
17884diff -NurpP --minimal linux-4.4.111/kernel/vserver/init.c linux-4.4.111-vs2.3.9.1/kernel/vserver/init.c
17885--- linux-4.4.111/kernel/vserver/init.c 1970-01-01 00:00:00.000000000 +0000
17886+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/init.c 2018-01-09 22:31:39.000000000 +0000
927ca606 17887@@ -0,0 +1,46 @@
4bf69007
AM
17888+/*
17889+ * linux/kernel/init.c
17890+ *
17891+ * Virtual Server Init
17892+ *
927ca606 17893+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17894+ *
17895+ * V0.01 basic structure
17896+ *
17897+ */
d337f35e 17898+
4bf69007 17899+#include <linux/init.h>
927ca606 17900+#include <linux/module.h>
4bf69007
AM
17901+
17902+int vserver_register_sysctl(void);
17903+void vserver_unregister_sysctl(void);
17904+
17905+
17906+static int __init init_vserver(void)
d337f35e 17907+{
4bf69007 17908+ int ret = 0;
d337f35e 17909+
4bf69007
AM
17910+#ifdef CONFIG_VSERVER_DEBUG
17911+ vserver_register_sysctl();
17912+#endif
17913+ return ret;
d337f35e
JR
17914+}
17915+
d337f35e 17916+
4bf69007 17917+static void __exit exit_vserver(void)
d337f35e 17918+{
d337f35e 17919+
4bf69007
AM
17920+#ifdef CONFIG_VSERVER_DEBUG
17921+ vserver_unregister_sysctl();
17922+#endif
17923+ return;
d337f35e
JR
17924+}
17925+
4bf69007
AM
17926+/* FIXME: GFP_ZONETYPES gone
17927+long vx_slab[GFP_ZONETYPES]; */
17928+long vx_area;
d337f35e 17929+
d337f35e 17930+
4bf69007
AM
17931+module_init(init_vserver);
17932+module_exit(exit_vserver);
d337f35e 17933+
f19bd705
AM
17934diff -NurpP --minimal linux-4.4.111/kernel/vserver/inode.c linux-4.4.111-vs2.3.9.1/kernel/vserver/inode.c
17935--- linux-4.4.111/kernel/vserver/inode.c 1970-01-01 00:00:00.000000000 +0000
17936+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/inode.c 2018-01-09 22:24:56.000000000 +0000
09be7631 17937@@ -0,0 +1,440 @@
4bf69007
AM
17938+/*
17939+ * linux/kernel/vserver/inode.c
17940+ *
17941+ * Virtual Server: File System Support
17942+ *
927ca606 17943+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
17944+ *
17945+ * V0.01 separated from vcontext V0.05
17946+ * V0.02 moved to tag (instead of xid)
17947+ *
17948+ */
d337f35e 17949+
4bf69007
AM
17950+#include <linux/tty.h>
17951+#include <linux/proc_fs.h>
17952+#include <linux/devpts_fs.h>
17953+#include <linux/fs.h>
17954+#include <linux/file.h>
17955+#include <linux/mount.h>
17956+#include <linux/parser.h>
17957+#include <linux/namei.h>
09be7631
JR
17958+#include <linux/magic.h>
17959+#include <linux/slab.h>
4bf69007
AM
17960+#include <linux/vserver/inode.h>
17961+#include <linux/vserver/inode_cmd.h>
17962+#include <linux/vs_base.h>
17963+#include <linux/vs_tag.h>
d337f35e 17964+
4bf69007 17965+#include <asm/uaccess.h>
09be7631 17966+#include <../../fs/proc/internal.h>
d337f35e 17967+
d337f35e 17968+
4bf69007 17969+static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
d337f35e 17970+{
4bf69007 17971+ struct proc_dir_entry *entry;
d337f35e 17972+
4bf69007
AM
17973+ if (!in || !in->i_sb)
17974+ return -ESRCH;
d337f35e 17975+
4bf69007
AM
17976+ *flags = IATTR_TAG
17977+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0)
17978+ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0)
17979+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
17980+ | (IS_COW(in) ? IATTR_COW : 0);
17981+ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE | IATTR_COW;
d337f35e 17982+
4bf69007
AM
17983+ if (S_ISDIR(in->i_mode))
17984+ *mask |= IATTR_BARRIER;
d337f35e 17985+
4bf69007
AM
17986+ if (IS_TAGGED(in)) {
17987+ *tag = i_tag_read(in);
17988+ *mask |= IATTR_TAG;
17989+ }
2380c486 17990+
4bf69007
AM
17991+ switch (in->i_sb->s_magic) {
17992+ case PROC_SUPER_MAGIC:
17993+ entry = PROC_I(in)->pde;
d337f35e 17994+
4bf69007
AM
17995+ /* check for specific inodes? */
17996+ if (entry)
17997+ *mask |= IATTR_FLAGS;
17998+ if (entry)
17999+ *flags |= (entry->vx_flags & IATTR_FLAGS);
18000+ else
18001+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
18002+ break;
d337f35e 18003+
4bf69007
AM
18004+ case DEVPTS_SUPER_MAGIC:
18005+ *tag = i_tag_read(in);
18006+ *mask |= IATTR_TAG;
18007+ break;
d337f35e 18008+
4bf69007
AM
18009+ default:
18010+ break;
18011+ }
18012+ return 0;
d337f35e
JR
18013+}
18014+
4bf69007 18015+int vc_get_iattr(void __user *data)
d337f35e 18016+{
4bf69007
AM
18017+ struct path path;
18018+ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 };
18019+ int ret;
d337f35e 18020+
4bf69007
AM
18021+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18022+ return -EFAULT;
d337f35e 18023+
4bf69007
AM
18024+ ret = user_lpath(vc_data.name, &path);
18025+ if (!ret) {
18026+ ret = __vc_get_iattr(path.dentry->d_inode,
18027+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18028+ path_put(&path);
18029+ }
18030+ if (ret)
18031+ return ret;
d337f35e 18032+
4bf69007
AM
18033+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18034+ ret = -EFAULT;
18035+ return ret;
d337f35e
JR
18036+}
18037+
4bf69007 18038+#ifdef CONFIG_COMPAT
d337f35e 18039+
4bf69007 18040+int vc_get_iattr_x32(void __user *data)
d337f35e 18041+{
4bf69007
AM
18042+ struct path path;
18043+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 };
18044+ int ret;
d337f35e 18045+
4bf69007
AM
18046+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18047+ return -EFAULT;
d337f35e 18048+
4bf69007
AM
18049+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18050+ if (!ret) {
18051+ ret = __vc_get_iattr(path.dentry->d_inode,
18052+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18053+ path_put(&path);
18054+ }
18055+ if (ret)
18056+ return ret;
d337f35e 18057+
2380c486 18058+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
18059+ ret = -EFAULT;
18060+ return ret;
d337f35e
JR
18061+}
18062+
4bf69007 18063+#endif /* CONFIG_COMPAT */
d337f35e 18064+
d337f35e 18065+
4bf69007 18066+int vc_fget_iattr(uint32_t fd, void __user *data)
d337f35e 18067+{
4bf69007
AM
18068+ struct file *filp;
18069+ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 };
d337f35e
JR
18070+ int ret;
18071+
4bf69007 18072+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18073+ return -EFAULT;
18074+
4bf69007 18075+ filp = fget(fd);
927ca606 18076+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18077+ return -EBADF;
2380c486 18078+
927ca606 18079+ ret = __vc_get_iattr(filp->f_path.dentry->d_inode,
4bf69007 18080+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
2380c486 18081+
4bf69007 18082+ fput(filp);
2380c486 18083+
4bf69007
AM
18084+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18085+ ret = -EFAULT;
d337f35e
JR
18086+ return ret;
18087+}
18088+
18089+
4bf69007 18090+static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
2380c486 18091+{
4bf69007
AM
18092+ struct inode *in = de->d_inode;
18093+ int error = 0, is_proc = 0, has_tag = 0;
18094+ struct iattr attr = { 0 };
2380c486 18095+
4bf69007
AM
18096+ if (!in || !in->i_sb)
18097+ return -ESRCH;
2380c486 18098+
4bf69007
AM
18099+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
18100+ if ((*mask & IATTR_FLAGS) && !is_proc)
18101+ return -EINVAL;
2380c486 18102+
4bf69007
AM
18103+ has_tag = IS_TAGGED(in) ||
18104+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
18105+ if ((*mask & IATTR_TAG) && !has_tag)
18106+ return -EINVAL;
2380c486 18107+
4bf69007
AM
18108+ mutex_lock(&in->i_mutex);
18109+ if (*mask & IATTR_TAG) {
8ce283e1 18110+ attr.ia_tag = make_ktag(&init_user_ns, *tag);
4bf69007 18111+ attr.ia_valid |= ATTR_TAG;
2380c486
JR
18112+ }
18113+
4bf69007
AM
18114+ if (*mask & IATTR_FLAGS) {
18115+ struct proc_dir_entry *entry = PROC_I(in)->pde;
18116+ unsigned int iflags = PROC_I(in)->vx_flags;
2380c486 18117+
4bf69007
AM
18118+ iflags = (iflags & ~(*mask & IATTR_FLAGS))
18119+ | (*flags & IATTR_FLAGS);
18120+ PROC_I(in)->vx_flags = iflags;
18121+ if (entry)
18122+ entry->vx_flags = iflags;
18123+ }
9f7054f1 18124+
4bf69007
AM
18125+ if (*mask & (IATTR_IMMUTABLE | IATTR_IXUNLINK |
18126+ IATTR_BARRIER | IATTR_COW)) {
18127+ int iflags = in->i_flags;
18128+ int vflags = in->i_vflags;
9f7054f1 18129+
4bf69007
AM
18130+ if (*mask & IATTR_IMMUTABLE) {
18131+ if (*flags & IATTR_IMMUTABLE)
18132+ iflags |= S_IMMUTABLE;
18133+ else
18134+ iflags &= ~S_IMMUTABLE;
18135+ }
18136+ if (*mask & IATTR_IXUNLINK) {
18137+ if (*flags & IATTR_IXUNLINK)
18138+ iflags |= S_IXUNLINK;
18139+ else
18140+ iflags &= ~S_IXUNLINK;
18141+ }
18142+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
18143+ if (*flags & IATTR_BARRIER)
18144+ vflags |= V_BARRIER;
18145+ else
18146+ vflags &= ~V_BARRIER;
18147+ }
18148+ if (S_ISREG(in->i_mode) && (*mask & IATTR_COW)) {
18149+ if (*flags & IATTR_COW)
18150+ vflags |= V_COW;
18151+ else
18152+ vflags &= ~V_COW;
18153+ }
18154+ if (in->i_op && in->i_op->sync_flags) {
18155+ error = in->i_op->sync_flags(in, iflags, vflags);
18156+ if (error)
18157+ goto out;
18158+ }
18159+ }
9f7054f1 18160+
4bf69007
AM
18161+ if (attr.ia_valid) {
18162+ if (in->i_op && in->i_op->setattr)
18163+ error = in->i_op->setattr(de, &attr);
18164+ else {
18165+ error = inode_change_ok(in, &attr);
18166+ if (!error) {
18167+ setattr_copy(in, &attr);
18168+ mark_inode_dirty(in);
18169+ }
18170+ }
9f7054f1 18171+ }
9f7054f1 18172+
4bf69007
AM
18173+out:
18174+ mutex_unlock(&in->i_mutex);
18175+ return error;
18176+}
2380c486 18177+
4bf69007 18178+int vc_set_iattr(void __user *data)
d337f35e 18179+{
4bf69007
AM
18180+ struct path path;
18181+ struct vcmd_ctx_iattr_v1 vc_data;
18182+ int ret;
d337f35e 18183+
4bf69007
AM
18184+ if (!capable(CAP_LINUX_IMMUTABLE))
18185+ return -EPERM;
18186+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
18187+ return -EFAULT;
18188+
4bf69007
AM
18189+ ret = user_lpath(vc_data.name, &path);
18190+ if (!ret) {
18191+ ret = __vc_set_iattr(path.dentry,
18192+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18193+ path_put(&path);
d337f35e 18194+ }
4bf69007
AM
18195+
18196+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18197+ ret = -EFAULT;
d337f35e
JR
18198+ return ret;
18199+}
18200+
4bf69007
AM
18201+#ifdef CONFIG_COMPAT
18202+
18203+int vc_set_iattr_x32(void __user *data)
d337f35e 18204+{
4bf69007
AM
18205+ struct path path;
18206+ struct vcmd_ctx_iattr_v1_x32 vc_data;
18207+ int ret;
d337f35e 18208+
4bf69007
AM
18209+ if (!capable(CAP_LINUX_IMMUTABLE))
18210+ return -EPERM;
18211+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18212+ return -EFAULT;
18213+
4bf69007
AM
18214+ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path);
18215+ if (!ret) {
18216+ ret = __vc_set_iattr(path.dentry,
18217+ &vc_data.tag, &vc_data.flags, &vc_data.mask);
18218+ path_put(&path);
2380c486 18219+ }
4bf69007
AM
18220+
18221+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18222+ ret = -EFAULT;
18223+ return ret;
2380c486
JR
18224+}
18225+
4bf69007 18226+#endif /* CONFIG_COMPAT */
2380c486 18227+
4bf69007 18228+int vc_fset_iattr(uint32_t fd, void __user *data)
2380c486 18229+{
4bf69007
AM
18230+ struct file *filp;
18231+ struct vcmd_ctx_fiattr_v0 vc_data;
18232+ int ret;
2380c486 18233+
4bf69007
AM
18234+ if (!capable(CAP_LINUX_IMMUTABLE))
18235+ return -EPERM;
18236+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
18237+ return -EFAULT;
18238+
4bf69007 18239+ filp = fget(fd);
927ca606 18240+ if (!filp || !filp->f_path.dentry || !filp->f_path.dentry->d_inode)
4bf69007 18241+ return -EBADF;
2380c486 18242+
927ca606 18243+ ret = __vc_set_iattr(filp->f_path.dentry, &vc_data.tag,
4bf69007 18244+ &vc_data.flags, &vc_data.mask);
2380c486 18245+
4bf69007 18246+ fput(filp);
2380c486 18247+
4bf69007
AM
18248+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18249+ return -EFAULT;
18250+ return ret;
2380c486
JR
18251+}
18252+
2380c486 18253+
4bf69007 18254+enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err };
2380c486 18255+
4bf69007
AM
18256+static match_table_t tokens = {
18257+ {Opt_notagcheck, "notagcheck"},
18258+#ifdef CONFIG_PROPAGATE
18259+ {Opt_notag, "notag"},
18260+ {Opt_tag, "tag"},
18261+ {Opt_tagid, "tagid=%u"},
18262+#endif
18263+ {Opt_err, NULL}
18264+};
2380c486 18265+
9f7054f1 18266+
4bf69007
AM
18267+static void __dx_parse_remove(char *string, char *opt)
18268+{
18269+ char *p = strstr(string, opt);
18270+ char *q = p;
2380c486 18271+
4bf69007
AM
18272+ if (p) {
18273+ while (*q != '\0' && *q != ',')
18274+ q++;
18275+ while (*q)
18276+ *p++ = *q++;
18277+ while (*p)
18278+ *p++ = '\0';
2380c486 18279+ }
2380c486
JR
18280+}
18281+
61333608 18282+int dx_parse_tag(char *string, vtag_t *tag, int remove, int *mnt_flags,
4bf69007 18283+ unsigned long *flags)
9f7054f1 18284+{
4bf69007
AM
18285+ int set = 0;
18286+ substring_t args[MAX_OPT_ARGS];
18287+ int token;
18288+ char *s, *p, *opts;
18289+#if defined(CONFIG_PROPAGATE) || defined(CONFIG_VSERVER_DEBUG)
18290+ int option = 0;
18291+#endif
9f7054f1 18292+
4bf69007
AM
18293+ if (!string)
18294+ return 0;
18295+ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC);
18296+ if (!s)
18297+ return 0;
9f7054f1 18298+
4bf69007
AM
18299+ opts = s;
18300+ while ((p = strsep(&opts, ",")) != NULL) {
18301+ token = match_token(p, tokens, args);
9f7054f1 18302+
4bf69007
AM
18303+ switch (token) {
18304+#ifdef CONFIG_PROPAGATE
18305+ case Opt_tag:
18306+ if (tag)
18307+ *tag = 0;
18308+ if (remove)
18309+ __dx_parse_remove(s, "tag");
18310+ *mnt_flags |= MNT_TAGID;
18311+ set |= MNT_TAGID;
18312+ break;
18313+ case Opt_notag:
18314+ if (remove)
18315+ __dx_parse_remove(s, "notag");
18316+ *mnt_flags |= MNT_NOTAG;
18317+ set |= MNT_NOTAG;
18318+ break;
18319+ case Opt_tagid:
18320+ if (tag && !match_int(args, &option))
18321+ *tag = option;
18322+ if (remove)
18323+ __dx_parse_remove(s, "tagid");
18324+ *mnt_flags |= MNT_TAGID;
18325+ set |= MNT_TAGID;
18326+ break;
18327+#endif /* CONFIG_PROPAGATE */
18328+ case Opt_notagcheck:
18329+ if (remove)
18330+ __dx_parse_remove(s, "notagcheck");
18331+ *flags |= MS_NOTAGCHECK;
18332+ set |= MS_NOTAGCHECK;
18333+ break;
18334+ }
18335+ vxdprintk(VXD_CBIT(tag, 7),
18336+ "dx_parse_tag(" VS_Q("%s") "): %d:#%d",
18337+ p, token, option);
18338+ }
18339+ if (set)
18340+ strcpy(string, s);
18341+ kfree(s);
18342+ return set;
9f7054f1 18343+}
2380c486 18344+
4bf69007 18345+#ifdef CONFIG_PROPAGATE
2380c486 18346+
4bf69007 18347+void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
2380c486 18348+{
61333608 18349+ vtag_t new_tag = 0;
4bf69007
AM
18350+ struct vfsmount *mnt;
18351+ int propagate;
2380c486 18352+
4bf69007
AM
18353+ if (!nd)
18354+ return;
18355+ mnt = nd->path.mnt;
18356+ if (!mnt)
18357+ return;
2380c486 18358+
4bf69007
AM
18359+ propagate = (mnt->mnt_flags & MNT_TAGID);
18360+ if (propagate)
18361+ new_tag = mnt->mnt_tag;
2380c486 18362+
4bf69007
AM
18363+ vxdprintk(VXD_CBIT(tag, 7),
18364+ "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
18365+ inode, inode->i_ino, inode->i_tag,
18366+ new_tag, (propagate) ? 1 : 0);
18367+
18368+ if (propagate)
18369+ i_tag_write(inode, new_tag);
2380c486
JR
18370+}
18371+
4bf69007 18372+#include <linux/module.h>
2380c486 18373+
4bf69007 18374+EXPORT_SYMBOL_GPL(__dx_propagate_tag);
2380c486 18375+
4bf69007 18376+#endif /* CONFIG_PROPAGATE */
2380c486 18377+
f19bd705
AM
18378diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit.c linux-4.4.111-vs2.3.9.1/kernel/vserver/limit.c
18379--- linux-4.4.111/kernel/vserver/limit.c 1970-01-01 00:00:00.000000000 +0000
18380+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/limit.c 2018-01-09 16:36:34.000000000 +0000
927ca606 18381@@ -0,0 +1,343 @@
4bf69007
AM
18382+/*
18383+ * linux/kernel/vserver/limit.c
18384+ *
18385+ * Virtual Server: Context Limits
18386+ *
927ca606 18387+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
18388+ *
18389+ * V0.01 broken out from vcontext V0.05
18390+ * V0.02 changed vcmds to vxi arg
18391+ * V0.03 added memory cgroup support
18392+ *
18393+ */
2380c486 18394+
4bf69007
AM
18395+#include <linux/sched.h>
18396+#include <linux/module.h>
18397+#include <linux/memcontrol.h>
927ca606 18398+#include <linux/page_counter.h>
4bf69007
AM
18399+#include <linux/vs_limit.h>
18400+#include <linux/vserver/limit.h>
18401+#include <linux/vserver/limit_cmd.h>
2380c486 18402+
4bf69007 18403+#include <asm/uaccess.h>
d337f35e 18404+
d337f35e 18405+
4bf69007
AM
18406+const char *vlimit_name[NUM_LIMITS] = {
18407+ [RLIMIT_CPU] = "CPU",
18408+ [RLIMIT_NPROC] = "NPROC",
18409+ [RLIMIT_NOFILE] = "NOFILE",
18410+ [RLIMIT_LOCKS] = "LOCKS",
18411+ [RLIMIT_SIGPENDING] = "SIGP",
18412+ [RLIMIT_MSGQUEUE] = "MSGQ",
d337f35e 18413+
4bf69007
AM
18414+ [VLIMIT_NSOCK] = "NSOCK",
18415+ [VLIMIT_OPENFD] = "OPENFD",
18416+ [VLIMIT_SHMEM] = "SHMEM",
18417+ [VLIMIT_DENTRY] = "DENTRY",
18418+};
2380c486 18419+
4bf69007 18420+EXPORT_SYMBOL_GPL(vlimit_name);
2380c486 18421+
4bf69007 18422+#define MASK_ENTRY(x) (1 << (x))
d337f35e 18423+
4bf69007
AM
18424+const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
18425+ /* minimum */
18426+ 0
18427+ , /* softlimit */
18428+ 0
18429+ , /* maximum */
18430+ MASK_ENTRY( RLIMIT_NPROC ) |
18431+ MASK_ENTRY( RLIMIT_NOFILE ) |
18432+ MASK_ENTRY( RLIMIT_LOCKS ) |
18433+ MASK_ENTRY( RLIMIT_MSGQUEUE ) |
d337f35e 18434+
4bf69007
AM
18435+ MASK_ENTRY( VLIMIT_NSOCK ) |
18436+ MASK_ENTRY( VLIMIT_OPENFD ) |
18437+ MASK_ENTRY( VLIMIT_SHMEM ) |
18438+ MASK_ENTRY( VLIMIT_DENTRY ) |
18439+ 0
18440+};
18441+ /* accounting only */
18442+uint32_t account_mask =
18443+ MASK_ENTRY( VLIMIT_SEMARY ) |
18444+ MASK_ENTRY( VLIMIT_NSEMS ) |
18445+ MASK_ENTRY( VLIMIT_MAPPED ) |
18446+ 0;
d337f35e 18447+
4bf69007
AM
18448+
18449+static int is_valid_vlimit(int id)
18450+{
18451+ uint32_t mask = vlimit_mask.minimum |
18452+ vlimit_mask.softlimit | vlimit_mask.maximum;
18453+ return mask & (1 << id);
d337f35e
JR
18454+}
18455+
4bf69007 18456+static int is_accounted_vlimit(int id)
d337f35e 18457+{
4bf69007
AM
18458+ if (is_valid_vlimit(id))
18459+ return 1;
18460+ return account_mask & (1 << id);
18461+}
d337f35e 18462+
d337f35e 18463+
4bf69007
AM
18464+static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
18465+{
18466+ rlim_t limit = __rlim_soft(&vxi->limit, id);
18467+ return VX_VLIM(limit);
18468+}
d337f35e 18469+
4bf69007
AM
18470+static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
18471+{
18472+ rlim_t limit = __rlim_hard(&vxi->limit, id);
18473+ return VX_VLIM(limit);
18474+}
d337f35e 18475+
4bf69007
AM
18476+static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
18477+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
18478+{
18479+ if (!is_valid_vlimit(id))
18480+ return -EINVAL;
18481+
18482+ if (minimum)
18483+ *minimum = CRLIM_UNSET;
18484+ if (softlimit)
18485+ *softlimit = vc_get_soft(vxi, id);
18486+ if (maximum)
18487+ *maximum = vc_get_hard(vxi, id);
d337f35e
JR
18488+ return 0;
18489+}
18490+
4bf69007 18491+int vc_get_rlimit(struct vx_info *vxi, void __user *data)
d337f35e 18492+{
4bf69007
AM
18493+ struct vcmd_ctx_rlimit_v0 vc_data;
18494+ int ret;
d337f35e 18495+
4bf69007
AM
18496+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18497+ return -EFAULT;
18498+
18499+ ret = do_get_rlimit(vxi, vc_data.id,
18500+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18501+ if (ret)
18502+ return ret;
d337f35e 18503+
2380c486 18504+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
d337f35e
JR
18505+ return -EFAULT;
18506+ return 0;
18507+}
18508+
4bf69007
AM
18509+static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
18510+ uint64_t minimum, uint64_t softlimit, uint64_t maximum)
d337f35e 18511+{
4bf69007
AM
18512+ if (!is_valid_vlimit(id))
18513+ return -EINVAL;
d337f35e 18514+
4bf69007
AM
18515+ if (maximum != CRLIM_KEEP)
18516+ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
18517+ if (softlimit != CRLIM_KEEP)
18518+ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
18519+
18520+ /* clamp soft limit */
18521+ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
18522+ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
d337f35e 18523+
d337f35e
JR
18524+ return 0;
18525+}
18526+
4bf69007
AM
18527+int vc_set_rlimit(struct vx_info *vxi, void __user *data)
18528+{
18529+ struct vcmd_ctx_rlimit_v0 vc_data;
d337f35e 18530+
4bf69007
AM
18531+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18532+ return -EFAULT;
d337f35e 18533+
4bf69007
AM
18534+ return do_set_rlimit(vxi, vc_data.id,
18535+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18536+}
d337f35e 18537+
4bf69007 18538+#ifdef CONFIG_IA32_EMULATION
2380c486 18539+
4bf69007
AM
18540+int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
18541+{
18542+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
d337f35e 18543+
4bf69007
AM
18544+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18545+ return -EFAULT;
d337f35e 18546+
4bf69007
AM
18547+ return do_set_rlimit(vxi, vc_data.id,
18548+ vc_data.minimum, vc_data.softlimit, vc_data.maximum);
18549+}
d337f35e 18550+
4bf69007
AM
18551+int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
18552+{
18553+ struct vcmd_ctx_rlimit_v0_x32 vc_data;
18554+ int ret;
d337f35e 18555+
4bf69007
AM
18556+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18557+ return -EFAULT;
d337f35e 18558+
4bf69007
AM
18559+ ret = do_get_rlimit(vxi, vc_data.id,
18560+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
18561+ if (ret)
18562+ return ret;
2380c486 18563+
4bf69007
AM
18564+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18565+ return -EFAULT;
18566+ return 0;
2380c486 18567+}
d337f35e 18568+
4bf69007 18569+#endif /* CONFIG_IA32_EMULATION */
d337f35e
JR
18570+
18571+
4bf69007
AM
18572+int vc_get_rlimit_mask(uint32_t id, void __user *data)
18573+{
18574+ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
18575+ return -EFAULT;
18576+ return 0;
18577+}
d337f35e
JR
18578+
18579+
4bf69007
AM
18580+static inline void vx_reset_hits(struct _vx_limit *limit)
18581+{
18582+ int lim;
d337f35e 18583+
4bf69007
AM
18584+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18585+ atomic_set(&__rlim_lhit(limit, lim), 0);
18586+ }
18587+}
d337f35e 18588+
4bf69007 18589+int vc_reset_hits(struct vx_info *vxi, void __user *data)
d337f35e 18590+{
4bf69007
AM
18591+ vx_reset_hits(&vxi->limit);
18592+ return 0;
d337f35e
JR
18593+}
18594+
4bf69007 18595+static inline void vx_reset_minmax(struct _vx_limit *limit)
d337f35e 18596+{
4bf69007
AM
18597+ rlim_t value;
18598+ int lim;
18599+
18600+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18601+ value = __rlim_get(limit, lim);
18602+ __rlim_rmax(limit, lim) = value;
18603+ __rlim_rmin(limit, lim) = value;
18604+ }
d337f35e
JR
18605+}
18606+
4bf69007 18607+int vc_reset_minmax(struct vx_info *vxi, void __user *data)
d337f35e 18608+{
4bf69007
AM
18609+ vx_reset_minmax(&vxi->limit);
18610+ return 0;
d337f35e
JR
18611+}
18612+
18613+
4bf69007 18614+int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
d337f35e 18615+{
4bf69007
AM
18616+ struct vcmd_rlimit_stat_v0 vc_data;
18617+ struct _vx_limit *limit = &vxi->limit;
18618+ int id;
d337f35e 18619+
4bf69007
AM
18620+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
18621+ return -EFAULT;
d337f35e 18622+
4bf69007
AM
18623+ id = vc_data.id;
18624+ if (!is_accounted_vlimit(id))
18625+ return -EINVAL;
2380c486 18626+
4bf69007
AM
18627+ vx_limit_fixup(limit, id);
18628+ vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
18629+ vc_data.value = __rlim_get(limit, id);
18630+ vc_data.minimum = __rlim_rmin(limit, id);
18631+ vc_data.maximum = __rlim_rmax(limit, id);
2380c486 18632+
4bf69007
AM
18633+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
18634+ return -EFAULT;
18635+ return 0;
d337f35e
JR
18636+}
18637+
d337f35e 18638+
927ca606 18639+#ifdef CONFIG_MEMCG
4bf69007 18640+void vx_vsi_meminfo(struct sysinfo *val)
d337f35e 18641+{
4bf69007
AM
18642+ struct mem_cgroup *mcg;
18643+ u64 res_limit, res_usage;
d337f35e 18644+
4bf69007
AM
18645+ rcu_read_lock();
18646+ mcg = mem_cgroup_from_task(current);
18647+ rcu_read_unlock();
18648+ if (!mcg)
18649+ goto out;
d337f35e 18650+
927ca606
AM
18651+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18652+ res_usage = mem_cgroup_mem_usage_pages(mcg);
2380c486 18653+
927ca606
AM
18654+ if (res_limit != PAGE_COUNTER_MAX)
18655+ val->totalram = res_limit;
18656+ val->freeram = val->totalram - res_usage;
4bf69007
AM
18657+ val->bufferram = 0;
18658+ val->totalhigh = 0;
18659+ val->freehigh = 0;
18660+out:
4bf69007 18661+ return;
d337f35e
JR
18662+}
18663+
4bf69007 18664+void vx_vsi_swapinfo(struct sysinfo *val)
d337f35e 18665+{
4bf69007
AM
18666+#ifdef CONFIG_MEMCG_SWAP
18667+ struct mem_cgroup *mcg;
18668+ u64 res_limit, res_usage, memsw_limit, memsw_usage;
18669+ s64 swap_limit, swap_usage;
d337f35e 18670+
4bf69007
AM
18671+ rcu_read_lock();
18672+ mcg = mem_cgroup_from_task(current);
18673+ rcu_read_unlock();
18674+ if (!mcg)
18675+ goto out;
d337f35e 18676+
927ca606
AM
18677+ res_limit = mem_cgroup_mem_limit_pages(mcg);
18678+ res_usage = mem_cgroup_mem_usage_pages(mcg);
18679+ memsw_limit = mem_cgroup_memsw_limit_pages(mcg);
18680+ memsw_usage = mem_cgroup_memsw_usage_pages(mcg);
d337f35e 18681+
4bf69007 18682+ /* memory unlimited */
927ca606 18683+ if (res_limit == PAGE_COUNTER_MAX)
4bf69007 18684+ goto out;
d337f35e 18685+
4bf69007
AM
18686+ swap_limit = memsw_limit - res_limit;
18687+ /* we have a swap limit? */
927ca606
AM
18688+ if (memsw_limit != PAGE_COUNTER_MAX)
18689+ val->totalswap = swap_limit;
d337f35e 18690+
4bf69007
AM
18691+ /* calculate swap part */
18692+ swap_usage = (memsw_usage > res_usage) ?
18693+ memsw_usage - res_usage : 0;
18694+
18695+ /* total shown minus usage gives free swap */
18696+ val->freeswap = (swap_usage < swap_limit) ?
927ca606 18697+ val->totalswap - swap_usage : 0;
4bf69007
AM
18698+out:
18699+#else /* !CONFIG_MEMCG_SWAP */
18700+ val->totalswap = 0;
18701+ val->freeswap = 0;
18702+#endif /* !CONFIG_MEMCG_SWAP */
4bf69007 18703+ return;
d337f35e
JR
18704+}
18705+
4bf69007 18706+long vx_vsi_cached(struct sysinfo *val)
d337f35e 18707+{
4bf69007 18708+ long cache = 0;
927ca606 18709+#ifdef CONFIG_MEMCG_BROKEN
4bf69007 18710+ struct mem_cgroup *mcg;
d337f35e 18711+
4bf69007
AM
18712+ rcu_read_lock();
18713+ mcg = mem_cgroup_from_task(current);
18714+ rcu_read_unlock();
18715+ if (!mcg)
18716+ goto out;
2380c486 18717+
927ca606 18718+ // cache = mem_cgroup_stat_read_cache(mcg);
4bf69007 18719+out:
2380c486 18720+#endif
4bf69007 18721+ return cache;
d337f35e 18722+}
927ca606 18723+#endif /* !CONFIG_MEMCG */
d337f35e 18724+
f19bd705
AM
18725diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit_init.h linux-4.4.111-vs2.3.9.1/kernel/vserver/limit_init.h
18726--- linux-4.4.111/kernel/vserver/limit_init.h 1970-01-01 00:00:00.000000000 +0000
18727+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/limit_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 18728@@ -0,0 +1,31 @@
d337f35e
JR
18729+
18730+
4bf69007
AM
18731+static inline void vx_info_init_limit(struct _vx_limit *limit)
18732+{
18733+ int lim;
d337f35e 18734+
4bf69007
AM
18735+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18736+ __rlim_soft(limit, lim) = RLIM_INFINITY;
18737+ __rlim_hard(limit, lim) = RLIM_INFINITY;
18738+ __rlim_set(limit, lim, 0);
18739+ atomic_set(&__rlim_lhit(limit, lim), 0);
18740+ __rlim_rmin(limit, lim) = 0;
18741+ __rlim_rmax(limit, lim) = 0;
18742+ }
18743+}
d337f35e 18744+
4bf69007 18745+static inline void vx_info_exit_limit(struct _vx_limit *limit)
d337f35e 18746+{
4bf69007
AM
18747+ rlim_t value;
18748+ int lim;
d337f35e 18749+
4bf69007
AM
18750+ for (lim = 0; lim < NUM_LIMITS; lim++) {
18751+ if ((1 << lim) & VLIM_NOCHECK)
18752+ continue;
18753+ value = __rlim_get(limit, lim);
18754+ vxwprintk_xid(value,
18755+ "!!! limit: %p[%s,%d] = %ld on exit.",
18756+ limit, vlimit_name[lim], lim, (long)value);
18757+ }
18758+}
d337f35e 18759+
f19bd705
AM
18760diff -NurpP --minimal linux-4.4.111/kernel/vserver/limit_proc.h linux-4.4.111-vs2.3.9.1/kernel/vserver/limit_proc.h
18761--- linux-4.4.111/kernel/vserver/limit_proc.h 1970-01-01 00:00:00.000000000 +0000
18762+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/limit_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
18763@@ -0,0 +1,57 @@
18764+#ifndef _VX_LIMIT_PROC_H
18765+#define _VX_LIMIT_PROC_H
d337f35e 18766+
4bf69007 18767+#include <linux/vserver/limit_int.h>
d337f35e 18768+
d337f35e 18769+
4bf69007
AM
18770+#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
18771+#define VX_LIMIT_TOP \
18772+ "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
d337f35e 18773+
4bf69007
AM
18774+#define VX_LIMIT_ARG(r) \
18775+ (unsigned long)__rlim_get(limit, r), \
18776+ (unsigned long)__rlim_rmin(limit, r), \
18777+ (unsigned long)__rlim_rmax(limit, r), \
18778+ VX_VLIM(__rlim_soft(limit, r)), \
18779+ VX_VLIM(__rlim_hard(limit, r)), \
18780+ atomic_read(&__rlim_lhit(limit, r))
d337f35e 18781+
4bf69007
AM
18782+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
18783+{
18784+ vx_limit_fixup(limit, -1);
18785+ return sprintf(buffer, VX_LIMIT_TOP
18786+ "PROC" VX_LIMIT_FMT
18787+ "VM" VX_LIMIT_FMT
18788+ "VML" VX_LIMIT_FMT
18789+ "RSS" VX_LIMIT_FMT
18790+ "ANON" VX_LIMIT_FMT
18791+ "RMAP" VX_LIMIT_FMT
18792+ "FILES" VX_LIMIT_FMT
18793+ "OFD" VX_LIMIT_FMT
18794+ "LOCKS" VX_LIMIT_FMT
18795+ "SOCK" VX_LIMIT_FMT
18796+ "MSGQ" VX_LIMIT_FMT
18797+ "SHM" VX_LIMIT_FMT
18798+ "SEMA" VX_LIMIT_FMT
18799+ "SEMS" VX_LIMIT_FMT
18800+ "DENT" VX_LIMIT_FMT,
18801+ VX_LIMIT_ARG(RLIMIT_NPROC),
18802+ VX_LIMIT_ARG(RLIMIT_AS),
18803+ VX_LIMIT_ARG(RLIMIT_MEMLOCK),
18804+ VX_LIMIT_ARG(RLIMIT_RSS),
18805+ VX_LIMIT_ARG(VLIMIT_ANON),
18806+ VX_LIMIT_ARG(VLIMIT_MAPPED),
18807+ VX_LIMIT_ARG(RLIMIT_NOFILE),
18808+ VX_LIMIT_ARG(VLIMIT_OPENFD),
18809+ VX_LIMIT_ARG(RLIMIT_LOCKS),
18810+ VX_LIMIT_ARG(VLIMIT_NSOCK),
18811+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE),
18812+ VX_LIMIT_ARG(VLIMIT_SHMEM),
18813+ VX_LIMIT_ARG(VLIMIT_SEMARY),
18814+ VX_LIMIT_ARG(VLIMIT_NSEMS),
18815+ VX_LIMIT_ARG(VLIMIT_DENTRY));
d337f35e
JR
18816+}
18817+
4bf69007 18818+#endif /* _VX_LIMIT_PROC_H */
d337f35e 18819+
d337f35e 18820+
f19bd705
AM
18821diff -NurpP --minimal linux-4.4.111/kernel/vserver/network.c linux-4.4.111-vs2.3.9.1/kernel/vserver/network.c
18822--- linux-4.4.111/kernel/vserver/network.c 1970-01-01 00:00:00.000000000 +0000
18823+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/network.c 2018-01-09 16:36:34.000000000 +0000
5cb1760b 18824@@ -0,0 +1,1053 @@
d337f35e 18825+/*
4bf69007 18826+ * linux/kernel/vserver/network.c
d337f35e 18827+ *
4bf69007
AM
18828+ * Virtual Server: Network Support
18829+ *
927ca606 18830+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
18831+ *
18832+ * V0.01 broken out from vcontext V0.05
18833+ * V0.02 cleaned up implementation
18834+ * V0.03 added equiv nx commands
18835+ * V0.04 switch to RCU based hash
18836+ * V0.05 and back to locking again
18837+ * V0.06 changed vcmds to nxi arg
18838+ * V0.07 have __create claim() the nxi
d337f35e 18839+ *
d337f35e 18840+ */
d337f35e 18841+
4bf69007
AM
18842+#include <linux/err.h>
18843+#include <linux/slab.h>
18844+#include <linux/rcupdate.h>
18845+#include <net/ipv6.h>
d337f35e 18846+
4bf69007
AM
18847+#include <linux/vs_network.h>
18848+#include <linux/vs_pid.h>
18849+#include <linux/vserver/network_cmd.h>
d337f35e
JR
18850+
18851+
4bf69007
AM
18852+atomic_t nx_global_ctotal = ATOMIC_INIT(0);
18853+atomic_t nx_global_cactive = ATOMIC_INIT(0);
d337f35e 18854+
4bf69007
AM
18855+static struct kmem_cache *nx_addr_v4_cachep = NULL;
18856+static struct kmem_cache *nx_addr_v6_cachep = NULL;
d337f35e 18857+
d337f35e 18858+
4bf69007 18859+static int __init init_network(void)
d337f35e 18860+{
4bf69007
AM
18861+ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache",
18862+ sizeof(struct nx_addr_v4), 0,
18863+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
18864+ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache",
18865+ sizeof(struct nx_addr_v6), 0,
18866+ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
d337f35e
JR
18867+ return 0;
18868+}
18869+
18870+
4bf69007 18871+/* __alloc_nx_addr_v4() */
d337f35e 18872+
4bf69007 18873+static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void)
d337f35e 18874+{
4bf69007
AM
18875+ struct nx_addr_v4 *nxa = kmem_cache_alloc(
18876+ nx_addr_v4_cachep, GFP_KERNEL);
92598135 18877+
4bf69007
AM
18878+ if (!IS_ERR(nxa))
18879+ memset(nxa, 0, sizeof(*nxa));
18880+ return nxa;
d337f35e
JR
18881+}
18882+
4bf69007 18883+/* __dealloc_nx_addr_v4() */
d337f35e 18884+
4bf69007
AM
18885+static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa)
18886+{
18887+ kmem_cache_free(nx_addr_v4_cachep, nxa);
18888+}
d337f35e 18889+
4bf69007 18890+/* __dealloc_nx_addr_v4_all() */
d337f35e 18891+
4bf69007 18892+static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa)
d337f35e 18893+{
4bf69007
AM
18894+ while (nxa) {
18895+ struct nx_addr_v4 *next = nxa->next;
d337f35e 18896+
4bf69007
AM
18897+ __dealloc_nx_addr_v4(nxa);
18898+ nxa = next;
18899+ }
18900+}
d337f35e 18901+
d337f35e 18902+
4bf69007 18903+#ifdef CONFIG_IPV6
d337f35e 18904+
4bf69007 18905+/* __alloc_nx_addr_v6() */
d337f35e 18906+
4bf69007
AM
18907+static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void)
18908+{
18909+ struct nx_addr_v6 *nxa = kmem_cache_alloc(
18910+ nx_addr_v6_cachep, GFP_KERNEL);
d337f35e 18911+
4bf69007
AM
18912+ if (!IS_ERR(nxa))
18913+ memset(nxa, 0, sizeof(*nxa));
18914+ return nxa;
d337f35e
JR
18915+}
18916+
4bf69007
AM
18917+/* __dealloc_nx_addr_v6() */
18918+
18919+static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa)
d337f35e 18920+{
4bf69007
AM
18921+ kmem_cache_free(nx_addr_v6_cachep, nxa);
18922+}
d337f35e 18923+
4bf69007 18924+/* __dealloc_nx_addr_v6_all() */
d337f35e 18925+
4bf69007
AM
18926+static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa)
18927+{
18928+ while (nxa) {
18929+ struct nx_addr_v6 *next = nxa->next;
d337f35e 18930+
4bf69007
AM
18931+ __dealloc_nx_addr_v6(nxa);
18932+ nxa = next;
18933+ }
18934+}
d337f35e 18935+
4bf69007 18936+#endif /* CONFIG_IPV6 */
d337f35e 18937+
4bf69007 18938+/* __alloc_nx_info()
d337f35e 18939+
4bf69007
AM
18940+ * allocate an initialized nx_info struct
18941+ * doesn't make it visible (hash) */
d337f35e 18942+
61333608 18943+static struct nx_info *__alloc_nx_info(vnid_t nid)
d337f35e 18944+{
4bf69007 18945+ struct nx_info *new = NULL;
d337f35e 18946+
4bf69007 18947+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
d337f35e 18948+
4bf69007
AM
18949+ /* would this benefit from a slab cache? */
18950+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
18951+ if (!new)
18952+ return 0;
d337f35e 18953+
4bf69007
AM
18954+ memset(new, 0, sizeof(struct nx_info));
18955+ new->nx_id = nid;
18956+ INIT_HLIST_NODE(&new->nx_hlist);
18957+ atomic_set(&new->nx_usecnt, 0);
18958+ atomic_set(&new->nx_tasks, 0);
18959+ spin_lock_init(&new->addr_lock);
18960+ new->nx_state = 0;
d337f35e 18961+
4bf69007 18962+ new->nx_flags = NXF_INIT_SET;
d337f35e 18963+
4bf69007 18964+ /* rest of init goes here */
d337f35e 18965+
4bf69007
AM
18966+ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK);
18967+ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST);
18968+
18969+ vxdprintk(VXD_CBIT(nid, 0),
18970+ "alloc_nx_info(%d) = %p", nid, new);
18971+ atomic_inc(&nx_global_ctotal);
18972+ return new;
d337f35e
JR
18973+}
18974+
4bf69007 18975+/* __dealloc_nx_info()
d337f35e 18976+
4bf69007 18977+ * final disposal of nx_info */
d337f35e 18978+
4bf69007
AM
18979+static void __dealloc_nx_info(struct nx_info *nxi)
18980+{
18981+ vxdprintk(VXD_CBIT(nid, 0),
18982+ "dealloc_nx_info(%p)", nxi);
d337f35e 18983+
4bf69007
AM
18984+ nxi->nx_hlist.next = LIST_POISON1;
18985+ nxi->nx_id = -1;
d337f35e 18986+
4bf69007
AM
18987+ BUG_ON(atomic_read(&nxi->nx_usecnt));
18988+ BUG_ON(atomic_read(&nxi->nx_tasks));
18989+
18990+ __dealloc_nx_addr_v4_all(nxi->v4.next);
18991+#ifdef CONFIG_IPV6
18992+ __dealloc_nx_addr_v6_all(nxi->v6.next);
18993+#endif
18994+
18995+ nxi->nx_state |= NXS_RELEASED;
18996+ kfree(nxi);
18997+ atomic_dec(&nx_global_ctotal);
d337f35e
JR
18998+}
18999+
4bf69007
AM
19000+static void __shutdown_nx_info(struct nx_info *nxi)
19001+{
19002+ nxi->nx_state |= NXS_SHUTDOWN;
19003+ vs_net_change(nxi, VSC_NETDOWN);
19004+}
d337f35e 19005+
4bf69007 19006+/* exported stuff */
d337f35e 19007+
4bf69007
AM
19008+void free_nx_info(struct nx_info *nxi)
19009+{
19010+ /* context shutdown is mandatory */
19011+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
d337f35e 19012+
4bf69007
AM
19013+ /* context must not be hashed */
19014+ BUG_ON(nxi->nx_state & NXS_HASHED);
d337f35e 19015+
4bf69007
AM
19016+ BUG_ON(atomic_read(&nxi->nx_usecnt));
19017+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19018+
4bf69007
AM
19019+ __dealloc_nx_info(nxi);
19020+}
d337f35e 19021+
d337f35e 19022+
4bf69007
AM
19023+void __nx_set_lback(struct nx_info *nxi)
19024+{
19025+ int nid = nxi->nx_id;
19026+ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
d337f35e 19027+
4bf69007
AM
19028+ nxi->v4_lback.s_addr = lback;
19029+}
d337f35e 19030+
4bf69007
AM
19031+extern int __nx_inet_add_lback(__be32 addr);
19032+extern int __nx_inet_del_lback(__be32 addr);
d337f35e
JR
19033+
19034+
4bf69007 19035+/* hash table for nx_info hash */
d337f35e 19036+
4bf69007 19037+#define NX_HASH_SIZE 13
d337f35e 19038+
4bf69007
AM
19039+struct hlist_head nx_info_hash[NX_HASH_SIZE];
19040+
19041+static DEFINE_SPINLOCK(nx_info_hash_lock);
19042+
19043+
61333608 19044+static inline unsigned int __hashval(vnid_t nid)
d337f35e 19045+{
4bf69007 19046+ return (nid % NX_HASH_SIZE);
d337f35e
JR
19047+}
19048+
d337f35e 19049+
d337f35e 19050+
4bf69007 19051+/* __hash_nx_info()
d337f35e 19052+
4bf69007
AM
19053+ * add the nxi to the global hash table
19054+ * requires the hash_lock to be held */
19055+
19056+static inline void __hash_nx_info(struct nx_info *nxi)
d337f35e 19057+{
4bf69007 19058+ struct hlist_head *head;
d337f35e 19059+
4bf69007
AM
19060+ vxd_assert_lock(&nx_info_hash_lock);
19061+ vxdprintk(VXD_CBIT(nid, 4),
19062+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
d337f35e 19063+
4bf69007
AM
19064+ /* context must not be hashed */
19065+ BUG_ON(nx_info_state(nxi, NXS_HASHED));
d337f35e 19066+
4bf69007
AM
19067+ nxi->nx_state |= NXS_HASHED;
19068+ head = &nx_info_hash[__hashval(nxi->nx_id)];
19069+ hlist_add_head(&nxi->nx_hlist, head);
19070+ atomic_inc(&nx_global_cactive);
19071+}
d337f35e 19072+
4bf69007 19073+/* __unhash_nx_info()
d337f35e 19074+
4bf69007
AM
19075+ * remove the nxi from the global hash table
19076+ * requires the hash_lock to be held */
d337f35e 19077+
4bf69007
AM
19078+static inline void __unhash_nx_info(struct nx_info *nxi)
19079+{
19080+ vxd_assert_lock(&nx_info_hash_lock);
19081+ vxdprintk(VXD_CBIT(nid, 4),
19082+ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id,
19083+ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks));
d337f35e 19084+
4bf69007
AM
19085+ /* context must be hashed */
19086+ BUG_ON(!nx_info_state(nxi, NXS_HASHED));
19087+ /* but without tasks */
19088+ BUG_ON(atomic_read(&nxi->nx_tasks));
d337f35e 19089+
4bf69007
AM
19090+ nxi->nx_state &= ~NXS_HASHED;
19091+ hlist_del(&nxi->nx_hlist);
19092+ atomic_dec(&nx_global_cactive);
d337f35e
JR
19093+}
19094+
d337f35e 19095+
4bf69007 19096+/* __lookup_nx_info()
d337f35e 19097+
4bf69007
AM
19098+ * requires the hash_lock to be held
19099+ * doesn't increment the nx_refcnt */
d337f35e 19100+
61333608 19101+static inline struct nx_info *__lookup_nx_info(vnid_t nid)
d337f35e 19102+{
4bf69007
AM
19103+ struct hlist_head *head = &nx_info_hash[__hashval(nid)];
19104+ struct hlist_node *pos;
19105+ struct nx_info *nxi;
d337f35e 19106+
4bf69007
AM
19107+ vxd_assert_lock(&nx_info_hash_lock);
19108+ hlist_for_each(pos, head) {
19109+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19110+
19111+ if (nxi->nx_id == nid)
19112+ goto found;
d337f35e 19113+ }
4bf69007
AM
19114+ nxi = NULL;
19115+found:
19116+ vxdprintk(VXD_CBIT(nid, 0),
19117+ "__lookup_nx_info(#%u): %p[#%u]",
19118+ nid, nxi, nxi ? nxi->nx_id : 0);
19119+ return nxi;
d337f35e
JR
19120+}
19121+
19122+
4bf69007 19123+/* __create_nx_info()
d337f35e 19124+
4bf69007
AM
19125+ * create the requested context
19126+ * get(), claim() and hash it */
d337f35e 19127+
4bf69007
AM
19128+static struct nx_info *__create_nx_info(int id)
19129+{
19130+ struct nx_info *new, *nxi = NULL;
d337f35e 19131+
4bf69007 19132+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
d337f35e 19133+
4bf69007
AM
19134+ if (!(new = __alloc_nx_info(id)))
19135+ return ERR_PTR(-ENOMEM);
d337f35e 19136+
4bf69007
AM
19137+ /* required to make dynamic xids unique */
19138+ spin_lock(&nx_info_hash_lock);
d337f35e 19139+
4bf69007
AM
19140+ /* static context requested */
19141+ if ((nxi = __lookup_nx_info(id))) {
19142+ vxdprintk(VXD_CBIT(nid, 0),
19143+ "create_nx_info(%d) = %p (already there)", id, nxi);
19144+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19145+ nxi = ERR_PTR(-EBUSY);
19146+ else
19147+ nxi = ERR_PTR(-EEXIST);
19148+ goto out_unlock;
19149+ }
19150+ /* new context */
19151+ vxdprintk(VXD_CBIT(nid, 0),
19152+ "create_nx_info(%d) = %p (new)", id, new);
19153+ claim_nx_info(new, NULL);
19154+ __nx_set_lback(new);
19155+ __hash_nx_info(get_nx_info(new));
19156+ nxi = new, new = NULL;
d337f35e 19157+
4bf69007
AM
19158+out_unlock:
19159+ spin_unlock(&nx_info_hash_lock);
19160+ if (new)
19161+ __dealloc_nx_info(new);
19162+ return nxi;
19163+}
d337f35e
JR
19164+
19165+
d337f35e 19166+
4bf69007 19167+/* exported stuff */
d337f35e 19168+
d337f35e 19169+
4bf69007
AM
19170+void unhash_nx_info(struct nx_info *nxi)
19171+{
19172+ __shutdown_nx_info(nxi);
19173+ spin_lock(&nx_info_hash_lock);
19174+ __unhash_nx_info(nxi);
19175+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19176+}
19177+
4bf69007 19178+/* lookup_nx_info()
d337f35e 19179+
4bf69007
AM
19180+ * search for a nx_info and get() it
19181+ * negative id means current */
d337f35e 19182+
4bf69007 19183+struct nx_info *lookup_nx_info(int id)
d337f35e 19184+{
4bf69007 19185+ struct nx_info *nxi = NULL;
d337f35e 19186+
4bf69007
AM
19187+ if (id < 0) {
19188+ nxi = get_nx_info(current_nx_info());
19189+ } else if (id > 1) {
19190+ spin_lock(&nx_info_hash_lock);
19191+ nxi = get_nx_info(__lookup_nx_info(id));
19192+ spin_unlock(&nx_info_hash_lock);
d337f35e 19193+ }
4bf69007
AM
19194+ return nxi;
19195+}
d337f35e 19196+
4bf69007 19197+/* nid_is_hashed()
d337f35e 19198+
4bf69007
AM
19199+ * verify that nid is still hashed */
19200+
61333608 19201+int nid_is_hashed(vnid_t nid)
4bf69007
AM
19202+{
19203+ int hashed;
19204+
19205+ spin_lock(&nx_info_hash_lock);
19206+ hashed = (__lookup_nx_info(nid) != NULL);
19207+ spin_unlock(&nx_info_hash_lock);
19208+ return hashed;
d337f35e
JR
19209+}
19210+
19211+
4bf69007 19212+#ifdef CONFIG_PROC_FS
d337f35e 19213+
4bf69007
AM
19214+/* get_nid_list()
19215+
19216+ * get a subset of hashed nids for proc
19217+ * assumes size is at least one */
19218+
19219+int get_nid_list(int index, unsigned int *nids, int size)
d337f35e 19220+{
4bf69007 19221+ int hindex, nr_nids = 0;
d337f35e 19222+
4bf69007
AM
19223+ /* only show current and children */
19224+ if (!nx_check(0, VS_ADMIN | VS_WATCH)) {
19225+ if (index > 0)
19226+ return 0;
19227+ nids[nr_nids] = nx_current_nid();
19228+ return 1;
19229+ }
d337f35e 19230+
4bf69007
AM
19231+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
19232+ struct hlist_head *head = &nx_info_hash[hindex];
19233+ struct hlist_node *pos;
d337f35e 19234+
4bf69007
AM
19235+ spin_lock(&nx_info_hash_lock);
19236+ hlist_for_each(pos, head) {
19237+ struct nx_info *nxi;
19238+
19239+ if (--index > 0)
19240+ continue;
19241+
19242+ nxi = hlist_entry(pos, struct nx_info, nx_hlist);
19243+ nids[nr_nids] = nxi->nx_id;
19244+ if (++nr_nids >= size) {
19245+ spin_unlock(&nx_info_hash_lock);
d337f35e 19246+ goto out;
4bf69007 19247+ }
d337f35e 19248+ }
4bf69007
AM
19249+ /* keep the lock time short */
19250+ spin_unlock(&nx_info_hash_lock);
d337f35e
JR
19251+ }
19252+out:
4bf69007 19253+ return nr_nids;
d337f35e 19254+}
4bf69007 19255+#endif
d337f35e 19256+
4bf69007
AM
19257+
19258+/*
19259+ * migrate task to new network
19260+ * gets nxi, puts old_nxi on change
19261+ */
19262+
19263+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
2380c486 19264+{
4bf69007
AM
19265+ struct nx_info *old_nxi;
19266+ int ret = 0;
2380c486 19267+
4bf69007
AM
19268+ if (!p || !nxi)
19269+ BUG();
d337f35e 19270+
4bf69007
AM
19271+ vxdprintk(VXD_CBIT(nid, 5),
19272+ "nx_migrate_task(%p,%p[#%d.%d.%d])",
19273+ p, nxi, nxi->nx_id,
19274+ atomic_read(&nxi->nx_usecnt),
19275+ atomic_read(&nxi->nx_tasks));
d337f35e 19276+
4bf69007
AM
19277+ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
19278+ !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
19279+ return -EACCES;
d337f35e 19280+
4bf69007
AM
19281+ if (nx_info_state(nxi, NXS_SHUTDOWN))
19282+ return -EFAULT;
d337f35e 19283+
4bf69007
AM
19284+ /* maybe disallow this completely? */
19285+ old_nxi = task_get_nx_info(p);
19286+ if (old_nxi == nxi)
19287+ goto out;
d337f35e 19288+
4bf69007
AM
19289+ task_lock(p);
19290+ if (old_nxi)
19291+ clr_nx_info(&p->nx_info);
19292+ claim_nx_info(nxi, p);
19293+ set_nx_info(&p->nx_info, nxi);
19294+ p->nid = nxi->nx_id;
19295+ task_unlock(p);
d337f35e 19296+
4bf69007
AM
19297+ vxdprintk(VXD_CBIT(nid, 5),
19298+ "moved task %p into nxi:%p[#%d]",
19299+ p, nxi, nxi->nx_id);
d337f35e 19300+
4bf69007
AM
19301+ if (old_nxi)
19302+ release_nx_info(old_nxi, p);
19303+ ret = 0;
19304+out:
19305+ put_nx_info(old_nxi);
19306+ return ret;
19307+}
d337f35e 19308+
d337f35e 19309+
4bf69007
AM
19310+void nx_set_persistent(struct nx_info *nxi)
19311+{
19312+ vxdprintk(VXD_CBIT(nid, 6),
19313+ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id);
d337f35e 19314+
4bf69007
AM
19315+ get_nx_info(nxi);
19316+ claim_nx_info(nxi, NULL);
d337f35e
JR
19317+}
19318+
4bf69007 19319+void nx_clear_persistent(struct nx_info *nxi)
2380c486 19320+{
4bf69007
AM
19321+ vxdprintk(VXD_CBIT(nid, 6),
19322+ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
2380c486 19323+
4bf69007
AM
19324+ release_nx_info(nxi, NULL);
19325+ put_nx_info(nxi);
2380c486 19326+}
d337f35e 19327+
4bf69007
AM
19328+void nx_update_persistent(struct nx_info *nxi)
19329+{
19330+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
19331+ nx_set_persistent(nxi);
19332+ else
19333+ nx_clear_persistent(nxi);
19334+}
d337f35e 19335+
4bf69007
AM
19336+/* vserver syscall commands below here */
19337+
19338+/* taks nid and nx_info functions */
d337f35e 19339+
4bf69007 19340+#include <asm/uaccess.h>
d337f35e
JR
19341+
19342+
4bf69007 19343+int vc_task_nid(uint32_t id)
d337f35e 19344+{
61333608 19345+ vnid_t nid;
d337f35e 19346+
4bf69007
AM
19347+ if (id) {
19348+ struct task_struct *tsk;
d337f35e 19349+
4bf69007
AM
19350+ rcu_read_lock();
19351+ tsk = find_task_by_real_pid(id);
19352+ nid = (tsk) ? tsk->nid : -ESRCH;
19353+ rcu_read_unlock();
19354+ } else
19355+ nid = nx_current_nid();
19356+ return nid;
d337f35e
JR
19357+}
19358+
19359+
4bf69007
AM
19360+int vc_nx_info(struct nx_info *nxi, void __user *data)
19361+{
19362+ struct vcmd_nx_info_v0 vc_data;
d337f35e 19363+
4bf69007 19364+ vc_data.nid = nxi->nx_id;
d337f35e 19365+
4bf69007
AM
19366+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19367+ return -EFAULT;
19368+ return 0;
19369+}
d337f35e 19370+
d337f35e 19371+
4bf69007 19372+/* network functions */
d337f35e 19373+
4bf69007
AM
19374+int vc_net_create(uint32_t nid, void __user *data)
19375+{
19376+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
19377+ struct nx_info *new_nxi;
19378+ int ret;
d337f35e 19379+
4bf69007
AM
19380+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19381+ return -EFAULT;
d337f35e 19382+
4bf69007
AM
19383+ if ((nid > MAX_S_CONTEXT) || (nid < 2))
19384+ return -EINVAL;
d337f35e 19385+
4bf69007
AM
19386+ new_nxi = __create_nx_info(nid);
19387+ if (IS_ERR(new_nxi))
19388+ return PTR_ERR(new_nxi);
d337f35e 19389+
4bf69007
AM
19390+ /* initial flags */
19391+ new_nxi->nx_flags = vc_data.flagword;
d337f35e 19392+
4bf69007
AM
19393+ ret = -ENOEXEC;
19394+ if (vs_net_change(new_nxi, VSC_NETUP))
19395+ goto out;
d337f35e 19396+
4bf69007
AM
19397+ ret = nx_migrate_task(current, new_nxi);
19398+ if (ret)
d337f35e
JR
19399+ goto out;
19400+
4bf69007
AM
19401+ /* return context id on success */
19402+ ret = new_nxi->nx_id;
d337f35e 19403+
4bf69007
AM
19404+ /* get a reference for persistent contexts */
19405+ if ((vc_data.flagword & NXF_PERSISTENT))
19406+ nx_set_persistent(new_nxi);
d337f35e 19407+out:
4bf69007
AM
19408+ release_nx_info(new_nxi, NULL);
19409+ put_nx_info(new_nxi);
19410+ return ret;
d337f35e
JR
19411+}
19412+
d337f35e 19413+
4bf69007
AM
19414+int vc_net_migrate(struct nx_info *nxi, void __user *data)
19415+{
19416+ return nx_migrate_task(current, nxi);
19417+}
d337f35e 19418+
2380c486 19419+
4bf69007
AM
19420+static inline
19421+struct nx_addr_v4 *__find_v4_addr(struct nx_info *nxi,
19422+ __be32 ip, __be32 ip2, __be32 mask, uint16_t type, uint16_t flags,
19423+ struct nx_addr_v4 **prev)
d337f35e 19424+{
4bf69007
AM
19425+ struct nx_addr_v4 *nxa = &nxi->v4;
19426+
19427+ for (; nxa; nxa = nxa->next) {
19428+ if ((nxa->ip[0].s_addr == ip) &&
19429+ (nxa->ip[1].s_addr == ip2) &&
19430+ (nxa->mask.s_addr == mask) &&
19431+ (nxa->type == type) &&
19432+ (nxa->flags == flags))
19433+ return nxa;
19434+
19435+ /* save previous entry */
19436+ if (prev)
19437+ *prev = nxa;
19438+ }
19439+ return NULL;
2380c486
JR
19440+}
19441+
4bf69007
AM
19442+int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19443+ uint16_t type, uint16_t flags)
d337f35e 19444+{
4bf69007
AM
19445+ struct nx_addr_v4 *nxa = NULL;
19446+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
5cb1760b 19447+ unsigned long irqflags;
4bf69007 19448+ int ret = -EEXIST;
d337f35e 19449+
4bf69007
AM
19450+ if (IS_ERR(new))
19451+ return PTR_ERR(new);
d337f35e 19452+
5cb1760b 19453+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19454+ if (__find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa))
19455+ goto out_unlock;
2380c486 19456+
4bf69007
AM
19457+ if (NX_IPV4(nxi)) {
19458+ nxa->next = new;
19459+ nxa = new;
19460+ new = NULL;
19461+
19462+ /* remove single ip for ip list */
19463+ nxi->nx_flags &= ~NXF_SINGLE_IP;
19464+ }
19465+
19466+ nxa->ip[0].s_addr = ip;
19467+ nxa->ip[1].s_addr = ip2;
19468+ nxa->mask.s_addr = mask;
19469+ nxa->type = type;
19470+ nxa->flags = flags;
19471+ ret = 0;
19472+out_unlock:
5cb1760b 19473+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19474+ if (new)
19475+ __dealloc_nx_addr_v4(new);
19476+ return ret;
d337f35e
JR
19477+}
19478+
4bf69007
AM
19479+int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask,
19480+ uint16_t type, uint16_t flags)
2380c486 19481+{
4bf69007
AM
19482+ struct nx_addr_v4 *nxa = NULL;
19483+ struct nx_addr_v4 *old = NULL;
5cb1760b 19484+ unsigned long irqflags;
4bf69007 19485+ int ret = 0;
2380c486 19486+
5cb1760b 19487+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19488+ switch (type) {
19489+ case NXA_TYPE_ADDR:
19490+ old = __find_v4_addr(nxi, ip, ip2, mask, type, flags, &nxa);
19491+ if (old) {
19492+ if (nxa) {
19493+ nxa->next = old->next;
19494+ old->next = NULL;
19495+ } else {
19496+ if (old->next) {
19497+ nxa = old;
19498+ old = old->next;
19499+ *nxa = *old;
19500+ old->next = NULL;
19501+ } else {
19502+ memset(old, 0, sizeof(*old));
19503+ old = NULL;
19504+ }
19505+ }
19506+ } else
19507+ ret = -ESRCH;
19508+ break;
2380c486 19509+
4bf69007
AM
19510+ case NXA_TYPE_ANY:
19511+ nxa = &nxi->v4;
19512+ old = nxa->next;
19513+ memset(nxa, 0, sizeof(*nxa));
19514+ break;
19515+
19516+ default:
19517+ ret = -EINVAL;
19518+ }
5cb1760b 19519+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19520+ __dealloc_nx_addr_v4_all(old);
19521+ return ret;
2380c486
JR
19522+}
19523+
4bf69007
AM
19524+
19525+int vc_net_add(struct nx_info *nxi, void __user *data)
2380c486 19526+{
4bf69007
AM
19527+ struct vcmd_net_addr_v0 vc_data;
19528+ int index, ret = 0;
2380c486 19529+
4bf69007 19530+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486
JR
19531+ return -EFAULT;
19532+
4bf69007
AM
19533+ switch (vc_data.type) {
19534+ case NXA_TYPE_IPV4:
19535+ if ((vc_data.count < 1) || (vc_data.count > 4))
19536+ return -EINVAL;
adc1caaa 19537+
4bf69007
AM
19538+ index = 0;
19539+ while (index < vc_data.count) {
19540+ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0,
19541+ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0);
19542+ if (ret)
19543+ return ret;
19544+ index++;
19545+ }
19546+ ret = index;
19547+ break;
2380c486 19548+
4bf69007
AM
19549+ case NXA_TYPE_IPV4|NXA_MOD_BCAST:
19550+ nxi->v4_bcast = vc_data.ip[0];
19551+ ret = 1;
19552+ break;
2380c486 19553+
4bf69007
AM
19554+ case NXA_TYPE_IPV4|NXA_MOD_LBACK:
19555+ nxi->v4_lback = vc_data.ip[0];
19556+ ret = 1;
19557+ break;
19558+
19559+ default:
19560+ ret = -EINVAL;
19561+ break;
19562+ }
19563+ return ret;
19564+}
19565+
19566+int vc_net_remove(struct nx_info *nxi, void __user *data)
19567+{
19568+ struct vcmd_net_addr_v0 vc_data;
19569+
19570+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
2380c486 19571+ return -EFAULT;
4bf69007
AM
19572+
19573+ switch (vc_data.type) {
19574+ case NXA_TYPE_ANY:
19575+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
19576+ default:
19577+ return -EINVAL;
19578+ }
2380c486
JR
19579+ return 0;
19580+}
19581+
d337f35e 19582+
4bf69007 19583+int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19584+{
4bf69007
AM
19585+ struct vcmd_net_addr_ipv4_v1 vc_data;
19586+
19587+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19588+ return -EFAULT;
19589+
19590+ switch (vc_data.type) {
19591+ case NXA_TYPE_ADDR:
19592+ case NXA_TYPE_MASK:
19593+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0,
19594+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19595+
19596+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19597+ nxi->v4_bcast = vc_data.ip;
19598+ break;
19599+
19600+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19601+ nxi->v4_lback = vc_data.ip;
19602+ break;
19603+
19604+ default:
19605+ return -EINVAL;
19606+ }
19607+ return 0;
d337f35e
JR
19608+}
19609+
4bf69007 19610+int vc_net_add_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19611+{
4bf69007 19612+ struct vcmd_net_addr_ipv4_v2 vc_data;
d337f35e 19613+
4bf69007
AM
19614+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19615+ return -EFAULT;
19616+
19617+ switch (vc_data.type) {
19618+ case NXA_TYPE_ADDR:
19619+ case NXA_TYPE_MASK:
19620+ case NXA_TYPE_RANGE:
19621+ return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19622+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
19623+
19624+ case NXA_TYPE_ADDR | NXA_MOD_BCAST:
19625+ nxi->v4_bcast = vc_data.ip;
19626+ break;
19627+
19628+ case NXA_TYPE_ADDR | NXA_MOD_LBACK:
19629+ nxi->v4_lback = vc_data.ip;
19630+ break;
19631+
19632+ default:
19633+ return -EINVAL;
19634+ }
19635+ return 0;
d337f35e
JR
19636+}
19637+
4bf69007 19638+int vc_net_rem_ipv4_v1(struct nx_info *nxi, void __user *data)
d337f35e 19639+{
4bf69007
AM
19640+ struct vcmd_net_addr_ipv4_v1 vc_data;
19641+
19642+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19643+ return -EFAULT;
19644+
19645+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, 0,
19646+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e
JR
19647+}
19648+
4bf69007 19649+int vc_net_rem_ipv4(struct nx_info *nxi, void __user *data)
d337f35e 19650+{
4bf69007
AM
19651+ struct vcmd_net_addr_ipv4_v2 vc_data;
19652+
19653+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19654+ return -EFAULT;
19655+
19656+ return do_remove_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr,
19657+ vc_data.mask.s_addr, vc_data.type, vc_data.flags);
d337f35e 19658+}
d337f35e 19659+
4bf69007 19660+#ifdef CONFIG_IPV6
d337f35e
JR
19661+
19662+static inline
4bf69007
AM
19663+struct nx_addr_v6 *__find_v6_addr(struct nx_info *nxi,
19664+ struct in6_addr *ip, struct in6_addr *mask,
19665+ uint32_t prefix, uint16_t type, uint16_t flags,
19666+ struct nx_addr_v6 **prev)
d337f35e 19667+{
4bf69007 19668+ struct nx_addr_v6 *nxa = &nxi->v6;
d337f35e 19669+
4bf69007
AM
19670+ for (; nxa; nxa = nxa->next) {
19671+ if (ipv6_addr_equal(&nxa->ip, ip) &&
19672+ ipv6_addr_equal(&nxa->mask, mask) &&
19673+ (nxa->prefix == prefix) &&
19674+ (nxa->type == type) &&
19675+ (nxa->flags == flags))
19676+ return nxa;
19677+
19678+ /* save previous entry */
19679+ if (prev)
19680+ *prev = nxa;
19681+ }
19682+ return NULL;
d337f35e
JR
19683+}
19684+
d337f35e 19685+
4bf69007
AM
19686+int do_add_v6_addr(struct nx_info *nxi,
19687+ struct in6_addr *ip, struct in6_addr *mask,
19688+ uint32_t prefix, uint16_t type, uint16_t flags)
19689+{
19690+ struct nx_addr_v6 *nxa = NULL;
19691+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
5cb1760b 19692+ unsigned long irqflags;
4bf69007 19693+ int ret = -EEXIST;
d337f35e 19694+
4bf69007
AM
19695+ if (IS_ERR(new))
19696+ return PTR_ERR(new);
d337f35e 19697+
5cb1760b 19698+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19699+ if (__find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa))
19700+ goto out_unlock;
d337f35e 19701+
4bf69007
AM
19702+ if (NX_IPV6(nxi)) {
19703+ nxa->next = new;
19704+ nxa = new;
19705+ new = NULL;
19706+ }
d337f35e 19707+
4bf69007
AM
19708+ nxa->ip = *ip;
19709+ nxa->mask = *mask;
19710+ nxa->prefix = prefix;
19711+ nxa->type = type;
19712+ nxa->flags = flags;
19713+ ret = 0;
19714+out_unlock:
5cb1760b 19715+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19716+ if (new)
19717+ __dealloc_nx_addr_v6(new);
19718+ return ret;
19719+}
d337f35e 19720+
4bf69007
AM
19721+int do_remove_v6_addr(struct nx_info *nxi,
19722+ struct in6_addr *ip, struct in6_addr *mask,
19723+ uint32_t prefix, uint16_t type, uint16_t flags)
d337f35e 19724+{
4bf69007
AM
19725+ struct nx_addr_v6 *nxa = NULL;
19726+ struct nx_addr_v6 *old = NULL;
5cb1760b 19727+ unsigned long irqflags;
4bf69007 19728+ int ret = 0;
d337f35e 19729+
5cb1760b 19730+ spin_lock_irqsave(&nxi->addr_lock, irqflags);
4bf69007
AM
19731+ switch (type) {
19732+ case NXA_TYPE_ADDR:
19733+ old = __find_v6_addr(nxi, ip, mask, prefix, type, flags, &nxa);
19734+ if (old) {
19735+ if (nxa) {
19736+ nxa->next = old->next;
19737+ old->next = NULL;
19738+ } else {
19739+ if (old->next) {
19740+ nxa = old;
19741+ old = old->next;
19742+ *nxa = *old;
19743+ old->next = NULL;
19744+ } else {
19745+ memset(old, 0, sizeof(*old));
19746+ old = NULL;
19747+ }
19748+ }
19749+ } else
19750+ ret = -ESRCH;
19751+ break;
d337f35e 19752+
4bf69007
AM
19753+ case NXA_TYPE_ANY:
19754+ nxa = &nxi->v6;
19755+ old = nxa->next;
19756+ memset(nxa, 0, sizeof(*nxa));
d337f35e
JR
19757+ break;
19758+
d337f35e 19759+ default:
4bf69007 19760+ ret = -EINVAL;
d337f35e 19761+ }
5cb1760b 19762+ spin_unlock_irqrestore(&nxi->addr_lock, irqflags);
4bf69007
AM
19763+ __dealloc_nx_addr_v6_all(old);
19764+ return ret;
d337f35e
JR
19765+}
19766+
4bf69007 19767+int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
d337f35e 19768+{
4bf69007 19769+ struct vcmd_net_addr_ipv6_v1 vc_data;
d337f35e 19770+
4bf69007 19771+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
d337f35e
JR
19772+ return -EFAULT;
19773+
4bf69007
AM
19774+ switch (vc_data.type) {
19775+ case NXA_TYPE_ADDR:
19776+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19777+ /* fallthrough */
19778+ case NXA_TYPE_MASK:
19779+ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19780+ vc_data.prefix, vc_data.type, vc_data.flags);
19781+ default:
19782+ return -EINVAL;
19783+ }
19784+ return 0;
19785+}
d337f35e 19786+
4bf69007
AM
19787+int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data)
19788+{
19789+ struct vcmd_net_addr_ipv6_v1 vc_data;
19790+
19791+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
19792+ return -EFAULT;
19793+
19794+ switch (vc_data.type) {
19795+ case NXA_TYPE_ADDR:
19796+ memset(&vc_data.mask, ~0, sizeof(vc_data.mask));
19797+ /* fallthrough */
19798+ case NXA_TYPE_MASK:
19799+ return do_remove_v6_addr(nxi, &vc_data.ip, &vc_data.mask,
19800+ vc_data.prefix, vc_data.type, vc_data.flags);
19801+ case NXA_TYPE_ANY:
19802+ return do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
19803+ default:
19804+ return -EINVAL;
19805+ }
19806+ return 0;
d337f35e
JR
19807+}
19808+
4bf69007 19809+#endif /* CONFIG_IPV6 */
d337f35e 19810+
4bf69007
AM
19811+
19812+int vc_get_nflags(struct nx_info *nxi, void __user *data)
d337f35e 19813+{
4bf69007 19814+ struct vcmd_net_flags_v0 vc_data;
d337f35e 19815+
4bf69007 19816+ vc_data.flagword = nxi->nx_flags;
d337f35e 19817+
4bf69007
AM
19818+ /* special STATE flag handling */
19819+ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME);
d337f35e 19820+
4bf69007
AM
19821+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
19822+ return -EFAULT;
19823+ return 0;
d337f35e
JR
19824+}
19825+
4bf69007
AM
19826+int vc_set_nflags(struct nx_info *nxi, void __user *data)
19827+{
19828+ struct vcmd_net_flags_v0 vc_data;
19829+ uint64_t mask, trigger;
19830+
19831+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19832+ return -EFAULT;
d337f35e 19833+
4bf69007
AM
19834+ /* special STATE flag handling */
19835+ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
19836+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
d337f35e 19837+
4bf69007
AM
19838+ nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
19839+ vc_data.flagword, mask);
19840+ if (trigger & NXF_PERSISTENT)
19841+ nx_update_persistent(nxi);
19842+
19843+ return 0;
19844+}
19845+
19846+int vc_get_ncaps(struct nx_info *nxi, void __user *data)
d337f35e 19847+{
4bf69007 19848+ struct vcmd_net_caps_v0 vc_data;
d337f35e 19849+
4bf69007
AM
19850+ vc_data.ncaps = nxi->nx_ncaps;
19851+ vc_data.cmask = ~0ULL;
d337f35e 19852+
2380c486 19853+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
4bf69007
AM
19854+ return -EFAULT;
19855+ return 0;
d337f35e
JR
19856+}
19857+
4bf69007
AM
19858+int vc_set_ncaps(struct nx_info *nxi, void __user *data)
19859+{
19860+ struct vcmd_net_caps_v0 vc_data;
19861+
19862+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
19863+ return -EFAULT;
19864+
19865+ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
19866+ vc_data.ncaps, vc_data.cmask);
19867+ return 0;
19868+}
19869+
19870+
19871+#include <linux/module.h>
19872+
19873+module_init(init_network);
19874+
19875+EXPORT_SYMBOL_GPL(free_nx_info);
19876+EXPORT_SYMBOL_GPL(unhash_nx_info);
19877+
f19bd705
AM
19878diff -NurpP --minimal linux-4.4.111/kernel/vserver/proc.c linux-4.4.111-vs2.3.9.1/kernel/vserver/proc.c
19879--- linux-4.4.111/kernel/vserver/proc.c 1970-01-01 00:00:00.000000000 +0000
19880+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/proc.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 19881@@ -0,0 +1,1100 @@
d337f35e 19882+/*
4bf69007 19883+ * linux/kernel/vserver/proc.c
d337f35e 19884+ *
4bf69007 19885+ * Virtual Context Support
d337f35e 19886+ *
927ca606 19887+ * Copyright (C) 2003-2011 Herbert P?tzl
d337f35e 19888+ *
4bf69007
AM
19889+ * V0.01 basic structure
19890+ * V0.02 adaptation vs1.3.0
19891+ * V0.03 proc permissions
19892+ * V0.04 locking/generic
19893+ * V0.05 next generation procfs
19894+ * V0.06 inode validation
19895+ * V0.07 generic rewrite vid
19896+ * V0.08 remove inode type
19897+ * V0.09 added u/wmask info
d337f35e
JR
19898+ *
19899+ */
19900+
4bf69007 19901+#include <linux/proc_fs.h>
ec22aa5c 19902+#include <linux/fs_struct.h>
4bf69007
AM
19903+#include <linux/mount.h>
19904+#include <linux/namei.h>
19905+#include <asm/unistd.h>
2380c486 19906+
d337f35e 19907+#include <linux/vs_context.h>
4bf69007
AM
19908+#include <linux/vs_network.h>
19909+#include <linux/vs_cvirt.h>
d337f35e 19910+
4bf69007
AM
19911+#include <linux/in.h>
19912+#include <linux/inetdevice.h>
19913+#include <linux/vs_inet.h>
19914+#include <linux/vs_inet6.h>
d337f35e 19915+
4bf69007 19916+#include <linux/vserver/global.h>
d337f35e 19917+
4bf69007
AM
19918+#include "cvirt_proc.h"
19919+#include "cacct_proc.h"
19920+#include "limit_proc.h"
19921+#include "sched_proc.h"
19922+#include "vci_config.h"
d337f35e 19923+
09be7631
JR
19924+#include <../../fs/proc/internal.h>
19925+
2380c486 19926+
4bf69007
AM
19927+static inline char *print_cap_t(char *buffer, kernel_cap_t *c)
19928+{
19929+ unsigned __capi;
2380c486 19930+
4bf69007
AM
19931+ CAP_FOR_EACH_U32(__capi) {
19932+ buffer += sprintf(buffer, "%08x",
19933+ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
19934+ }
19935+ return buffer;
19936+}
2380c486 19937+
d337f35e 19938+
4bf69007 19939+static struct proc_dir_entry *proc_virtual;
d337f35e 19940+
4bf69007 19941+static struct proc_dir_entry *proc_virtnet;
d337f35e 19942+
d337f35e 19943+
4bf69007 19944+/* first the actual feeds */
d337f35e 19945+
d337f35e 19946+
4bf69007
AM
19947+static int proc_vci(char *buffer)
19948+{
19949+ return sprintf(buffer,
19950+ "VCIVersion:\t%04x:%04x\n"
19951+ "VCISyscall:\t%d\n"
19952+ "VCIKernel:\t%08x\n",
19953+ VCI_VERSION >> 16,
19954+ VCI_VERSION & 0xFFFF,
19955+ __NR_vserver,
19956+ vci_kernel_config());
19957+}
d337f35e 19958+
4bf69007
AM
19959+static int proc_virtual_info(char *buffer)
19960+{
19961+ return proc_vci(buffer);
d337f35e
JR
19962+}
19963+
4bf69007
AM
19964+static int proc_virtual_status(char *buffer)
19965+{
19966+ return sprintf(buffer,
19967+ "#CTotal:\t%d\n"
19968+ "#CActive:\t%d\n"
19969+ "#NSProxy:\t%d\t%d %d %d %d %d %d\n"
19970+ "#InitTask:\t%d\t%d %d\n",
19971+ atomic_read(&vx_global_ctotal),
19972+ atomic_read(&vx_global_cactive),
19973+ atomic_read(&vs_global_nsproxy),
19974+ atomic_read(&vs_global_fs),
19975+ atomic_read(&vs_global_mnt_ns),
19976+ atomic_read(&vs_global_uts_ns),
19977+ atomic_read(&nr_ipc_ns),
19978+ atomic_read(&vs_global_user_ns),
19979+ atomic_read(&vs_global_pid_ns),
19980+ atomic_read(&init_task.usage),
19981+ atomic_read(&init_task.nsproxy->count),
19982+ init_task.fs->users);
19983+}
2380c486 19984+
2380c486 19985+
4bf69007 19986+int proc_vxi_info(struct vx_info *vxi, char *buffer)
d337f35e 19987+{
4bf69007 19988+ int length;
d337f35e 19989+
4bf69007
AM
19990+ length = sprintf(buffer,
19991+ "ID:\t%d\n"
19992+ "Info:\t%p\n"
19993+ "Init:\t%d\n"
19994+ "OOM:\t%lld\n",
19995+ vxi->vx_id,
19996+ vxi,
19997+ vxi->vx_initpid,
19998+ vxi->vx_badness_bias);
19999+ return length;
d337f35e
JR
20000+}
20001+
4bf69007 20002+int proc_vxi_status(struct vx_info *vxi, char *buffer)
d337f35e 20003+{
4bf69007 20004+ char *orig = buffer;
d337f35e 20005+
4bf69007
AM
20006+ buffer += sprintf(buffer,
20007+ "UseCnt:\t%d\n"
20008+ "Tasks:\t%d\n"
20009+ "Flags:\t%016llx\n",
20010+ atomic_read(&vxi->vx_usecnt),
20011+ atomic_read(&vxi->vx_tasks),
20012+ (unsigned long long)vxi->vx_flags);
d337f35e 20013+
4bf69007
AM
20014+ buffer += sprintf(buffer, "BCaps:\t");
20015+ buffer = print_cap_t(buffer, &vxi->vx_bcaps);
20016+ buffer += sprintf(buffer, "\n");
ab30d09f 20017+
4bf69007
AM
20018+ buffer += sprintf(buffer,
20019+ "CCaps:\t%016llx\n"
20020+ "Umask:\t%16llx\n"
20021+ "Wmask:\t%16llx\n"
20022+ "Spaces:\t%08lx %08lx\n",
20023+ (unsigned long long)vxi->vx_ccaps,
20024+ (unsigned long long)vxi->vx_umask,
20025+ (unsigned long long)vxi->vx_wmask,
20026+ vxi->space[0].vx_nsmask, vxi->space[1].vx_nsmask);
20027+ return buffer - orig;
20028+}
ab30d09f 20029+
4bf69007
AM
20030+int proc_vxi_limit(struct vx_info *vxi, char *buffer)
20031+{
20032+ return vx_info_proc_limit(&vxi->limit, buffer);
20033+}
d337f35e 20034+
4bf69007
AM
20035+int proc_vxi_sched(struct vx_info *vxi, char *buffer)
20036+{
20037+ int cpu, length;
d337f35e 20038+
4bf69007
AM
20039+ length = vx_info_proc_sched(&vxi->sched, buffer);
20040+ for_each_online_cpu(cpu) {
20041+ length += vx_info_proc_sched_pc(
20042+ &vx_per_cpu(vxi, sched_pc, cpu),
20043+ buffer + length, cpu);
ec22aa5c 20044+ }
4bf69007
AM
20045+ return length;
20046+}
ec22aa5c 20047+
4bf69007
AM
20048+int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer)
20049+{
20050+ return vx_info_proc_nsproxy(vxi->space[0].vx_nsproxy, buffer);
20051+}
d337f35e 20052+
4bf69007
AM
20053+int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer)
20054+{
20055+ return vx_info_proc_nsproxy(vxi->space[1].vx_nsproxy, buffer);
20056+}
ec22aa5c 20057+
4bf69007
AM
20058+int proc_vxi_cvirt(struct vx_info *vxi, char *buffer)
20059+{
20060+ int cpu, length;
d33d7b00 20061+
4bf69007
AM
20062+ vx_update_load(vxi);
20063+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
20064+ for_each_online_cpu(cpu) {
20065+ length += vx_info_proc_cvirt_pc(
20066+ &vx_per_cpu(vxi, cvirt_pc, cpu),
20067+ buffer + length, cpu);
3bac966d 20068+ }
4bf69007
AM
20069+ return length;
20070+}
3bac966d 20071+
4bf69007
AM
20072+int proc_vxi_cacct(struct vx_info *vxi, char *buffer)
20073+{
20074+ return vx_info_proc_cacct(&vxi->cacct, buffer);
d337f35e
JR
20075+}
20076+
20077+
4bf69007 20078+static int proc_virtnet_info(char *buffer)
d337f35e 20079+{
4bf69007
AM
20080+ return proc_vci(buffer);
20081+}
ab30d09f 20082+
4bf69007
AM
20083+static int proc_virtnet_status(char *buffer)
20084+{
20085+ return sprintf(buffer,
20086+ "#CTotal:\t%d\n"
20087+ "#CActive:\t%d\n",
20088+ atomic_read(&nx_global_ctotal),
20089+ atomic_read(&nx_global_cactive));
20090+}
d337f35e 20091+
4bf69007
AM
20092+int proc_nxi_info(struct nx_info *nxi, char *buffer)
20093+{
20094+ struct nx_addr_v4 *v4a;
20095+#ifdef CONFIG_IPV6
20096+ struct nx_addr_v6 *v6a;
20097+#endif
20098+ int length, i;
ab30d09f 20099+
4bf69007
AM
20100+ length = sprintf(buffer,
20101+ "ID:\t%d\n"
20102+ "Info:\t%p\n"
20103+ "Bcast:\t" NIPQUAD_FMT "\n"
20104+ "Lback:\t" NIPQUAD_FMT "\n",
20105+ nxi->nx_id,
20106+ nxi,
20107+ NIPQUAD(nxi->v4_bcast.s_addr),
20108+ NIPQUAD(nxi->v4_lback.s_addr));
ab30d09f 20109+
4bf69007
AM
20110+ if (!NX_IPV4(nxi))
20111+ goto skip_v4;
20112+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
20113+ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n",
20114+ i, NXAV4(v4a));
20115+skip_v4:
20116+#ifdef CONFIG_IPV6
20117+ if (!NX_IPV6(nxi))
20118+ goto skip_v6;
20119+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
20120+ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n",
20121+ i, NXAV6(v6a));
20122+skip_v6:
20123+#endif
20124+ return length;
20125+}
2380c486 20126+
4bf69007
AM
20127+int proc_nxi_status(struct nx_info *nxi, char *buffer)
20128+{
20129+ int length;
ec22aa5c 20130+
4bf69007
AM
20131+ length = sprintf(buffer,
20132+ "UseCnt:\t%d\n"
20133+ "Tasks:\t%d\n"
20134+ "Flags:\t%016llx\n"
20135+ "NCaps:\t%016llx\n",
20136+ atomic_read(&nxi->nx_usecnt),
20137+ atomic_read(&nxi->nx_tasks),
20138+ (unsigned long long)nxi->nx_flags,
20139+ (unsigned long long)nxi->nx_ncaps);
20140+ return length;
20141+}
ec22aa5c 20142+
ec22aa5c 20143+
d337f35e 20144+
4bf69007 20145+/* here the inode helpers */
d337f35e 20146+
4bf69007
AM
20147+struct vs_entry {
20148+ int len;
20149+ char *name;
20150+ mode_t mode;
20151+ struct inode_operations *iop;
20152+ struct file_operations *fop;
20153+ union proc_op op;
20154+};
d337f35e 20155+
4bf69007
AM
20156+static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
20157+{
20158+ struct inode *inode = new_inode(sb);
3bac966d 20159+
4bf69007
AM
20160+ if (!inode)
20161+ goto out;
3bac966d 20162+
4bf69007
AM
20163+ inode->i_mode = p->mode;
20164+ if (p->iop)
20165+ inode->i_op = p->iop;
20166+ if (p->fop)
20167+ inode->i_fop = p->fop;
3bac966d 20168+
4bf69007
AM
20169+ set_nlink(inode, (p->mode & S_IFDIR) ? 2 : 1);
20170+ inode->i_flags |= S_IMMUTABLE;
3bac966d 20171+
4bf69007 20172+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
2380c486 20173+
8ce283e1
AM
20174+ i_uid_write(inode, 0);
20175+ i_gid_write(inode, 0);
20176+ i_tag_write(inode, 0);
4bf69007
AM
20177+out:
20178+ return inode;
d337f35e
JR
20179+}
20180+
4bf69007
AM
20181+static struct dentry *vs_proc_instantiate(struct inode *dir,
20182+ struct dentry *dentry, int id, void *ptr)
2380c486 20183+{
4bf69007
AM
20184+ struct vs_entry *p = ptr;
20185+ struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
20186+ struct dentry *error = ERR_PTR(-EINVAL);
2380c486 20187+
4bf69007
AM
20188+ if (!inode)
20189+ goto out;
2380c486 20190+
4bf69007
AM
20191+ PROC_I(inode)->op = p->op;
20192+ PROC_I(inode)->fd = id;
20193+ d_add(dentry, inode);
20194+ error = NULL;
20195+out:
20196+ return error;
2380c486
JR
20197+}
20198+
4bf69007 20199+/* Lookups */
2380c486 20200+
09be7631
JR
20201+typedef struct dentry *vx_instantiate_t(struct inode *, struct dentry *, int, void *);
20202+
2380c486 20203+
4bf69007
AM
20204+/*
20205+ * Fill a directory entry.
20206+ *
20207+ * If possible create the dcache entry and derive our inode number and
20208+ * file type from dcache entry.
20209+ *
20210+ * Since all of the proc inode numbers are dynamically generated, the inode
20211+ * numbers do not exist until the inode is cache. This means creating the
c2e5f7c8
JR
20212+ * the dcache entry in iterate is necessary to keep the inode numbers
20213+ * reported by iterate in sync with the inode numbers reported
4bf69007
AM
20214+ * by stat.
20215+ */
c2e5f7c8 20216+static int vx_proc_fill_cache(struct file *filp, struct dir_context *ctx,
09be7631 20217+ char *name, int len, vx_instantiate_t instantiate, int id, void *ptr)
2380c486 20218+{
927ca606 20219+ struct dentry *child, *dir = filp->f_path.dentry;
4bf69007
AM
20220+ struct inode *inode;
20221+ struct qstr qname;
20222+ ino_t ino = 0;
20223+ unsigned type = DT_UNKNOWN;
d337f35e 20224+
4bf69007
AM
20225+ qname.name = name;
20226+ qname.len = len;
20227+ qname.hash = full_name_hash(name, len);
d337f35e 20228+
4bf69007
AM
20229+ child = d_lookup(dir, &qname);
20230+ if (!child) {
20231+ struct dentry *new;
20232+ new = d_alloc(dir, &qname);
20233+ if (new) {
20234+ child = instantiate(dir->d_inode, new, id, ptr);
20235+ if (child)
20236+ dput(new);
20237+ else
20238+ child = new;
20239+ }
20240+ }
20241+ if (!child || IS_ERR(child) || !child->d_inode)
20242+ goto end_instantiate;
20243+ inode = child->d_inode;
20244+ if (inode) {
20245+ ino = inode->i_ino;
20246+ type = inode->i_mode >> 12;
20247+ }
20248+ dput(child);
20249+end_instantiate:
20250+ if (!ino)
4bf69007 20251+ ino = 1;
c2e5f7c8 20252+ return !dir_emit(ctx, name, len, ino, type);
4bf69007 20253+}
d337f35e 20254+
d337f35e 20255+
d337f35e 20256+
4bf69007 20257+/* get and revalidate vx_info/xid */
2380c486 20258+
4bf69007
AM
20259+static inline
20260+struct vx_info *get_proc_vx_info(struct inode *inode)
20261+{
20262+ return lookup_vx_info(PROC_I(inode)->fd);
d337f35e
JR
20263+}
20264+
4bf69007 20265+static int proc_xid_revalidate(struct dentry *dentry, unsigned int flags)
d337f35e 20266+{
4bf69007 20267+ struct inode *inode = dentry->d_inode;
61333608 20268+ vxid_t xid = PROC_I(inode)->fd;
2380c486 20269+
4bf69007
AM
20270+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20271+ return -ECHILD;
2380c486 20272+
4bf69007
AM
20273+ if (!xid || xid_is_hashed(xid))
20274+ return 1;
20275+ d_drop(dentry);
d337f35e
JR
20276+ return 0;
20277+}
20278+
d337f35e 20279+
4bf69007 20280+/* get and revalidate nx_info/nid */
d337f35e 20281+
4bf69007
AM
20282+static int proc_nid_revalidate(struct dentry *dentry, unsigned int flags)
20283+{
20284+ struct inode *inode = dentry->d_inode;
61333608 20285+ vnid_t nid = PROC_I(inode)->fd;
2380c486 20286+
4bf69007
AM
20287+ if (flags & LOOKUP_RCU) /* FIXME: can be dropped? */
20288+ return -ECHILD;
2380c486 20289+
4bf69007
AM
20290+ if (!nid || nid_is_hashed(nid))
20291+ return 1;
20292+ d_drop(dentry);
20293+ return 0;
d337f35e
JR
20294+}
20295+
4bf69007
AM
20296+
20297+
20298+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
20299+
20300+static ssize_t proc_vs_info_read(struct file *file, char __user *buf,
20301+ size_t count, loff_t *ppos)
d337f35e 20302+{
927ca606 20303+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007
AM
20304+ unsigned long page;
20305+ ssize_t length = 0;
20306+
20307+ if (count > PROC_BLOCK_SIZE)
20308+ count = PROC_BLOCK_SIZE;
20309+
20310+ /* fade that out as soon as stable */
20311+ WARN_ON(PROC_I(inode)->fd);
20312+
20313+ if (!(page = __get_free_page(GFP_KERNEL)))
20314+ return -ENOMEM;
20315+
20316+ BUG_ON(!PROC_I(inode)->op.proc_vs_read);
20317+ length = PROC_I(inode)->op.proc_vs_read((char *)page);
20318+
20319+ if (length >= 0)
20320+ length = simple_read_from_buffer(buf, count, ppos,
20321+ (char *)page, length);
20322+
20323+ free_page(page);
20324+ return length;
d337f35e
JR
20325+}
20326+
4bf69007
AM
20327+static ssize_t proc_vx_info_read(struct file *file, char __user *buf,
20328+ size_t count, loff_t *ppos)
20329+{
927ca606 20330+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20331+ struct vx_info *vxi = NULL;
61333608 20332+ vxid_t xid = PROC_I(inode)->fd;
4bf69007
AM
20333+ unsigned long page;
20334+ ssize_t length = 0;
d337f35e 20335+
4bf69007
AM
20336+ if (count > PROC_BLOCK_SIZE)
20337+ count = PROC_BLOCK_SIZE;
20338+
20339+ /* fade that out as soon as stable */
20340+ WARN_ON(!xid);
20341+ vxi = lookup_vx_info(xid);
20342+ if (!vxi)
20343+ goto out;
d337f35e 20344+
4bf69007
AM
20345+ length = -ENOMEM;
20346+ if (!(page = __get_free_page(GFP_KERNEL)))
20347+ goto out_put;
d337f35e 20348+
4bf69007
AM
20349+ BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
20350+ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page);
d337f35e 20351+
4bf69007
AM
20352+ if (length >= 0)
20353+ length = simple_read_from_buffer(buf, count, ppos,
20354+ (char *)page, length);
d337f35e 20355+
4bf69007
AM
20356+ free_page(page);
20357+out_put:
20358+ put_vx_info(vxi);
20359+out:
20360+ return length;
20361+}
20362+
20363+static ssize_t proc_nx_info_read(struct file *file, char __user *buf,
20364+ size_t count, loff_t *ppos)
d337f35e 20365+{
927ca606 20366+ struct inode *inode = file->f_path.dentry->d_inode;
4bf69007 20367+ struct nx_info *nxi = NULL;
61333608 20368+ vnid_t nid = PROC_I(inode)->fd;
4bf69007
AM
20369+ unsigned long page;
20370+ ssize_t length = 0;
d337f35e 20371+
4bf69007
AM
20372+ if (count > PROC_BLOCK_SIZE)
20373+ count = PROC_BLOCK_SIZE;
d337f35e 20374+
4bf69007
AM
20375+ /* fade that out as soon as stable */
20376+ WARN_ON(!nid);
20377+ nxi = lookup_nx_info(nid);
20378+ if (!nxi)
20379+ goto out;
d337f35e 20380+
4bf69007
AM
20381+ length = -ENOMEM;
20382+ if (!(page = __get_free_page(GFP_KERNEL)))
20383+ goto out_put;
d337f35e 20384+
4bf69007
AM
20385+ BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
20386+ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page);
2380c486 20387+
4bf69007
AM
20388+ if (length >= 0)
20389+ length = simple_read_from_buffer(buf, count, ppos,
20390+ (char *)page, length);
d337f35e 20391+
4bf69007
AM
20392+ free_page(page);
20393+out_put:
20394+ put_nx_info(nxi);
20395+out:
20396+ return length;
20397+}
2380c486 20398+
d337f35e 20399+
763640ca 20400+
4bf69007 20401+/* here comes the lower level */
763640ca 20402+
265d6dcc 20403+
4bf69007
AM
20404+#define NOD(NAME, MODE, IOP, FOP, OP) { \
20405+ .len = sizeof(NAME) - 1, \
20406+ .name = (NAME), \
20407+ .mode = MODE, \
20408+ .iop = IOP, \
20409+ .fop = FOP, \
20410+ .op = OP, \
20411+}
d337f35e 20412+
d337f35e 20413+
4bf69007
AM
20414+#define DIR(NAME, MODE, OTYPE) \
20415+ NOD(NAME, (S_IFDIR | (MODE)), \
20416+ &proc_ ## OTYPE ## _inode_operations, \
20417+ &proc_ ## OTYPE ## _file_operations, { } )
d337f35e 20418+
4bf69007
AM
20419+#define INF(NAME, MODE, OTYPE) \
20420+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20421+ &proc_vs_info_file_operations, \
20422+ { .proc_vs_read = &proc_##OTYPE } )
d337f35e 20423+
4bf69007
AM
20424+#define VINF(NAME, MODE, OTYPE) \
20425+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20426+ &proc_vx_info_file_operations, \
20427+ { .proc_vxi_read = &proc_##OTYPE } )
2380c486 20428+
4bf69007
AM
20429+#define NINF(NAME, MODE, OTYPE) \
20430+ NOD(NAME, (S_IFREG | (MODE)), NULL, \
20431+ &proc_nx_info_file_operations, \
20432+ { .proc_nxi_read = &proc_##OTYPE } )
d337f35e 20433+
d337f35e 20434+
4bf69007
AM
20435+static struct file_operations proc_vs_info_file_operations = {
20436+ .read = proc_vs_info_read,
20437+};
d337f35e 20438+
4bf69007
AM
20439+static struct file_operations proc_vx_info_file_operations = {
20440+ .read = proc_vx_info_read,
20441+};
d337f35e 20442+
4bf69007
AM
20443+static struct dentry_operations proc_xid_dentry_operations = {
20444+ .d_revalidate = proc_xid_revalidate,
20445+};
d337f35e 20446+
4bf69007
AM
20447+static struct vs_entry vx_base_stuff[] = {
20448+ VINF("info", S_IRUGO, vxi_info),
20449+ VINF("status", S_IRUGO, vxi_status),
20450+ VINF("limit", S_IRUGO, vxi_limit),
20451+ VINF("sched", S_IRUGO, vxi_sched),
20452+ VINF("nsproxy", S_IRUGO, vxi_nsproxy0),
20453+ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1),
20454+ VINF("cvirt", S_IRUGO, vxi_cvirt),
20455+ VINF("cacct", S_IRUGO, vxi_cacct),
20456+ {}
20457+};
2380c486 20458+
d337f35e 20459+
d337f35e 20460+
d337f35e 20461+
4bf69007
AM
20462+static struct dentry *proc_xid_instantiate(struct inode *dir,
20463+ struct dentry *dentry, int id, void *ptr)
20464+{
20465+ dentry->d_op = &proc_xid_dentry_operations;
20466+ return vs_proc_instantiate(dir, dentry, id, ptr);
20467+}
2380c486 20468+
4bf69007
AM
20469+static struct dentry *proc_xid_lookup(struct inode *dir,
20470+ struct dentry *dentry, unsigned int flags)
20471+{
20472+ struct vs_entry *p = vx_base_stuff;
20473+ struct dentry *error = ERR_PTR(-ENOENT);
2380c486 20474+
4bf69007
AM
20475+ for (; p->name; p++) {
20476+ if (p->len != dentry->d_name.len)
20477+ continue;
20478+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20479+ break;
20480+ }
20481+ if (!p->name)
20482+ goto out;
d337f35e 20483+
4bf69007
AM
20484+ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20485+out:
20486+ return error;
20487+}
9f7054f1 20488+
c2e5f7c8 20489+static int proc_xid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20490+{
927ca606 20491+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20492+ struct inode *inode = dentry->d_inode;
20493+ struct vs_entry *p = vx_base_stuff;
20494+ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20495+ int index;
4bf69007 20496+ u64 ino;
2380c486 20497+
c2e5f7c8 20498+ switch (ctx->pos) {
4bf69007
AM
20499+ case 0:
20500+ ino = inode->i_ino;
c2e5f7c8 20501+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20502+ goto out;
c2e5f7c8 20503+ ctx->pos++;
4bf69007
AM
20504+ /* fall through */
20505+ case 1:
20506+ ino = parent_ino(dentry);
c2e5f7c8 20507+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20508+ goto out;
c2e5f7c8 20509+ ctx->pos++;
4bf69007 20510+ /* fall through */
d337f35e 20511+ default:
c2e5f7c8 20512+ index = ctx->pos - 2;
4bf69007
AM
20513+ if (index >= size)
20514+ goto out;
20515+ for (p += index; p->name; p++) {
c2e5f7c8 20516+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20517+ vs_proc_instantiate, PROC_I(inode)->fd, p))
20518+ goto out;
c2e5f7c8 20519+ ctx->pos++;
4bf69007 20520+ }
d337f35e 20521+ }
4bf69007 20522+out:
4bf69007 20523+ return 1;
d337f35e
JR
20524+}
20525+
20526+
d337f35e 20527+
4bf69007
AM
20528+static struct file_operations proc_nx_info_file_operations = {
20529+ .read = proc_nx_info_read,
20530+};
d337f35e 20531+
4bf69007
AM
20532+static struct dentry_operations proc_nid_dentry_operations = {
20533+ .d_revalidate = proc_nid_revalidate,
20534+};
d337f35e 20535+
4bf69007
AM
20536+static struct vs_entry nx_base_stuff[] = {
20537+ NINF("info", S_IRUGO, nxi_info),
20538+ NINF("status", S_IRUGO, nxi_status),
20539+ {}
20540+};
2380c486 20541+
d337f35e 20542+
4bf69007
AM
20543+static struct dentry *proc_nid_instantiate(struct inode *dir,
20544+ struct dentry *dentry, int id, void *ptr)
d337f35e 20545+{
4bf69007
AM
20546+ dentry->d_op = &proc_nid_dentry_operations;
20547+ return vs_proc_instantiate(dir, dentry, id, ptr);
20548+}
d337f35e 20549+
4bf69007
AM
20550+static struct dentry *proc_nid_lookup(struct inode *dir,
20551+ struct dentry *dentry, unsigned int flags)
20552+{
20553+ struct vs_entry *p = nx_base_stuff;
20554+ struct dentry *error = ERR_PTR(-ENOENT);
d337f35e 20555+
4bf69007
AM
20556+ for (; p->name; p++) {
20557+ if (p->len != dentry->d_name.len)
20558+ continue;
20559+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20560+ break;
20561+ }
20562+ if (!p->name)
20563+ goto out;
d337f35e 20564+
4bf69007
AM
20565+ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
20566+out:
20567+ return error;
20568+}
d337f35e 20569+
c2e5f7c8 20570+static int proc_nid_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20571+{
927ca606 20572+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20573+ struct inode *inode = dentry->d_inode;
20574+ struct vs_entry *p = nx_base_stuff;
20575+ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20576+ int index;
4bf69007 20577+ u64 ino;
d337f35e 20578+
c2e5f7c8 20579+ switch (ctx->pos) {
4bf69007
AM
20580+ case 0:
20581+ ino = inode->i_ino;
c2e5f7c8 20582+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20583+ goto out;
c2e5f7c8 20584+ ctx->pos++;
4bf69007
AM
20585+ /* fall through */
20586+ case 1:
20587+ ino = parent_ino(dentry);
c2e5f7c8 20588+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20589+ goto out;
c2e5f7c8 20590+ ctx->pos++;
4bf69007
AM
20591+ /* fall through */
20592+ default:
c2e5f7c8 20593+ index = ctx->pos - 2;
4bf69007
AM
20594+ if (index >= size)
20595+ goto out;
20596+ for (p += index; p->name; p++) {
c2e5f7c8 20597+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20598+ vs_proc_instantiate, PROC_I(inode)->fd, p))
20599+ goto out;
c2e5f7c8 20600+ ctx->pos++;
4bf69007
AM
20601+ }
20602+ }
20603+out:
4bf69007
AM
20604+ return 1;
20605+}
2380c486 20606+
d337f35e 20607+
4bf69007 20608+#define MAX_MULBY10 ((~0U - 9) / 10)
d337f35e 20609+
4bf69007
AM
20610+static inline int atovid(const char *str, int len)
20611+{
20612+ int vid, c;
d337f35e 20613+
4bf69007
AM
20614+ vid = 0;
20615+ while (len-- > 0) {
20616+ c = *str - '0';
20617+ str++;
20618+ if (c > 9)
20619+ return -1;
20620+ if (vid >= MAX_MULBY10)
20621+ return -1;
20622+ vid *= 10;
20623+ vid += c;
20624+ if (!vid)
20625+ return -1;
20626+ }
20627+ return vid;
20628+}
2380c486 20629+
4bf69007 20630+/* now the upper level (virtual) */
2380c486 20631+
2380c486 20632+
4bf69007
AM
20633+static struct file_operations proc_xid_file_operations = {
20634+ .read = generic_read_dir,
c2e5f7c8 20635+ .iterate = proc_xid_iterate,
4bf69007 20636+};
2380c486 20637+
4bf69007
AM
20638+static struct inode_operations proc_xid_inode_operations = {
20639+ .lookup = proc_xid_lookup,
20640+};
d337f35e 20641+
4bf69007
AM
20642+static struct vs_entry vx_virtual_stuff[] = {
20643+ INF("info", S_IRUGO, virtual_info),
20644+ INF("status", S_IRUGO, virtual_status),
20645+ DIR(NULL, S_IRUGO | S_IXUGO, xid),
20646+};
2380c486 20647+
d337f35e 20648+
4bf69007
AM
20649+static struct dentry *proc_virtual_lookup(struct inode *dir,
20650+ struct dentry *dentry, unsigned int flags)
20651+{
20652+ struct vs_entry *p = vx_virtual_stuff;
20653+ struct dentry *error = ERR_PTR(-ENOENT);
20654+ int id = 0;
d337f35e 20655+
4bf69007
AM
20656+ for (; p->name; p++) {
20657+ if (p->len != dentry->d_name.len)
20658+ continue;
20659+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20660+ break;
20661+ }
20662+ if (p->name)
20663+ goto instantiate;
d337f35e 20664+
4bf69007
AM
20665+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20666+ if ((id < 0) || !xid_is_hashed(id))
d337f35e
JR
20667+ goto out;
20668+
4bf69007
AM
20669+instantiate:
20670+ error = proc_xid_instantiate(dir, dentry, id, p);
20671+out:
20672+ return error;
20673+}
d337f35e 20674+
4bf69007
AM
20675+static struct file_operations proc_nid_file_operations = {
20676+ .read = generic_read_dir,
c2e5f7c8 20677+ .iterate = proc_nid_iterate,
4bf69007 20678+};
d337f35e 20679+
4bf69007
AM
20680+static struct inode_operations proc_nid_inode_operations = {
20681+ .lookup = proc_nid_lookup,
20682+};
d337f35e 20683+
4bf69007
AM
20684+static struct vs_entry nx_virtnet_stuff[] = {
20685+ INF("info", S_IRUGO, virtnet_info),
20686+ INF("status", S_IRUGO, virtnet_status),
20687+ DIR(NULL, S_IRUGO | S_IXUGO, nid),
20688+};
d337f35e 20689+
d337f35e 20690+
4bf69007
AM
20691+static struct dentry *proc_virtnet_lookup(struct inode *dir,
20692+ struct dentry *dentry, unsigned int flags)
20693+{
20694+ struct vs_entry *p = nx_virtnet_stuff;
20695+ struct dentry *error = ERR_PTR(-ENOENT);
20696+ int id = 0;
d337f35e 20697+
4bf69007
AM
20698+ for (; p->name; p++) {
20699+ if (p->len != dentry->d_name.len)
20700+ continue;
20701+ if (!memcmp(dentry->d_name.name, p->name, p->len))
20702+ break;
20703+ }
20704+ if (p->name)
20705+ goto instantiate;
d337f35e 20706+
4bf69007
AM
20707+ id = atovid(dentry->d_name.name, dentry->d_name.len);
20708+ if ((id < 0) || !nid_is_hashed(id))
d337f35e
JR
20709+ goto out;
20710+
4bf69007
AM
20711+instantiate:
20712+ error = proc_nid_instantiate(dir, dentry, id, p);
20713+out:
20714+ return error;
20715+}
2380c486 20716+
d337f35e 20717+
4bf69007
AM
20718+#define PROC_MAXVIDS 32
20719+
c2e5f7c8 20720+int proc_virtual_iterate(struct file *filp, struct dir_context *ctx)
4bf69007 20721+{
927ca606 20722+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20723+ struct inode *inode = dentry->d_inode;
20724+ struct vs_entry *p = vx_virtual_stuff;
20725+ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20726+ int index;
4bf69007
AM
20727+ unsigned int xid_array[PROC_MAXVIDS];
20728+ char buf[PROC_NUMBUF];
20729+ unsigned int nr_xids, i;
20730+ u64 ino;
20731+
c2e5f7c8 20732+ switch (ctx->pos) {
4bf69007
AM
20733+ case 0:
20734+ ino = inode->i_ino;
c2e5f7c8 20735+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20736+ goto out;
c2e5f7c8 20737+ ctx->pos++;
4bf69007
AM
20738+ /* fall through */
20739+ case 1:
20740+ ino = parent_ino(dentry);
c2e5f7c8 20741+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20742+ goto out;
c2e5f7c8 20743+ ctx->pos++;
4bf69007
AM
20744+ /* fall through */
20745+ default:
c2e5f7c8 20746+ index = ctx->pos - 2;
4bf69007
AM
20747+ if (index >= size)
20748+ goto entries;
20749+ for (p += index; p->name; p++) {
c2e5f7c8 20750+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20751+ vs_proc_instantiate, 0, p))
20752+ goto out;
c2e5f7c8 20753+ ctx->pos++;
d337f35e 20754+ }
4bf69007 20755+ entries:
c2e5f7c8 20756+ index = ctx->pos - size;
4bf69007
AM
20757+ p = &vx_virtual_stuff[size - 1];
20758+ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
20759+ for (i = 0; i < nr_xids; i++) {
20760+ int n, xid = xid_array[i];
20761+ unsigned int j = PROC_NUMBUF;
d337f35e 20762+
4bf69007
AM
20763+ n = xid;
20764+ do
20765+ buf[--j] = '0' + (n % 10);
20766+ while (n /= 10);
20767+
c2e5f7c8 20768+ if (vx_proc_fill_cache(filp, ctx,
4bf69007
AM
20769+ buf + j, PROC_NUMBUF - j,
20770+ vs_proc_instantiate, xid, p))
20771+ goto out;
c2e5f7c8 20772+ ctx->pos++;
d337f35e
JR
20773+ }
20774+ }
d337f35e 20775+out:
4bf69007 20776+ return 0;
d337f35e
JR
20777+}
20778+
4bf69007
AM
20779+static int proc_virtual_getattr(struct vfsmount *mnt,
20780+ struct dentry *dentry, struct kstat *stat)
d337f35e 20781+{
4bf69007 20782+ struct inode *inode = dentry->d_inode;
d337f35e 20783+
4bf69007
AM
20784+ generic_fillattr(inode, stat);
20785+ stat->nlink = 2 + atomic_read(&vx_global_cactive);
20786+ return 0;
d337f35e
JR
20787+}
20788+
4bf69007
AM
20789+static struct file_operations proc_virtual_dir_operations = {
20790+ .read = generic_read_dir,
c2e5f7c8 20791+ .iterate = proc_virtual_iterate,
d337f35e
JR
20792+};
20793+
4bf69007
AM
20794+static struct inode_operations proc_virtual_dir_inode_operations = {
20795+ .getattr = proc_virtual_getattr,
20796+ .lookup = proc_virtual_lookup,
20797+};
d337f35e 20798+
d337f35e
JR
20799+
20800+
c2e5f7c8 20801+int proc_virtnet_iterate(struct file *filp, struct dir_context *ctx)
d337f35e 20802+{
927ca606 20803+ struct dentry *dentry = filp->f_path.dentry;
4bf69007
AM
20804+ struct inode *inode = dentry->d_inode;
20805+ struct vs_entry *p = nx_virtnet_stuff;
20806+ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry);
c2e5f7c8 20807+ int index;
4bf69007
AM
20808+ unsigned int nid_array[PROC_MAXVIDS];
20809+ char buf[PROC_NUMBUF];
20810+ unsigned int nr_nids, i;
20811+ u64 ino;
d337f35e 20812+
c2e5f7c8 20813+ switch (ctx->pos) {
4bf69007
AM
20814+ case 0:
20815+ ino = inode->i_ino;
c2e5f7c8 20816+ if (!dir_emit(ctx, ".", 1, ino, DT_DIR) < 0)
4bf69007 20817+ goto out;
c2e5f7c8 20818+ ctx->pos++;
4bf69007
AM
20819+ /* fall through */
20820+ case 1:
20821+ ino = parent_ino(dentry);
c2e5f7c8 20822+ if (!dir_emit(ctx, "..", 2, ino, DT_DIR) < 0)
4bf69007 20823+ goto out;
c2e5f7c8 20824+ ctx->pos++;
4bf69007
AM
20825+ /* fall through */
20826+ default:
c2e5f7c8 20827+ index = ctx->pos - 2;
4bf69007
AM
20828+ if (index >= size)
20829+ goto entries;
20830+ for (p += index; p->name; p++) {
c2e5f7c8 20831+ if (vx_proc_fill_cache(filp, ctx, p->name, p->len,
4bf69007
AM
20832+ vs_proc_instantiate, 0, p))
20833+ goto out;
c2e5f7c8 20834+ ctx->pos++;
4bf69007
AM
20835+ }
20836+ entries:
c2e5f7c8 20837+ index = ctx->pos - size;
4bf69007
AM
20838+ p = &nx_virtnet_stuff[size - 1];
20839+ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
20840+ for (i = 0; i < nr_nids; i++) {
20841+ int n, nid = nid_array[i];
20842+ unsigned int j = PROC_NUMBUF;
d337f35e 20843+
4bf69007
AM
20844+ n = nid;
20845+ do
20846+ buf[--j] = '0' + (n % 10);
20847+ while (n /= 10);
d337f35e 20848+
c2e5f7c8 20849+ if (vx_proc_fill_cache(filp, ctx,
4bf69007
AM
20850+ buf + j, PROC_NUMBUF - j,
20851+ vs_proc_instantiate, nid, p))
20852+ goto out;
c2e5f7c8 20853+ ctx->pos++;
d337f35e
JR
20854+ }
20855+ }
4bf69007 20856+out:
d337f35e
JR
20857+ return 0;
20858+}
20859+
4bf69007
AM
20860+static int proc_virtnet_getattr(struct vfsmount *mnt,
20861+ struct dentry *dentry, struct kstat *stat)
20862+{
20863+ struct inode *inode = dentry->d_inode;
d337f35e 20864+
4bf69007
AM
20865+ generic_fillattr(inode, stat);
20866+ stat->nlink = 2 + atomic_read(&nx_global_cactive);
20867+ return 0;
20868+}
d337f35e 20869+
4bf69007
AM
20870+static struct file_operations proc_virtnet_dir_operations = {
20871+ .read = generic_read_dir,
c2e5f7c8 20872+ .iterate = proc_virtnet_iterate,
d337f35e
JR
20873+};
20874+
4bf69007
AM
20875+static struct inode_operations proc_virtnet_dir_inode_operations = {
20876+ .getattr = proc_virtnet_getattr,
20877+ .lookup = proc_virtnet_lookup,
d337f35e
JR
20878+};
20879+
d337f35e
JR
20880+
20881+
4bf69007 20882+void proc_vx_init(void)
d337f35e 20883+{
4bf69007 20884+ struct proc_dir_entry *ent;
d337f35e 20885+
4bf69007
AM
20886+ ent = proc_mkdir("virtual", 0);
20887+ if (ent) {
20888+ ent->proc_fops = &proc_virtual_dir_operations;
20889+ ent->proc_iops = &proc_virtual_dir_inode_operations;
20890+ }
20891+ proc_virtual = ent;
d337f35e 20892+
4bf69007
AM
20893+ ent = proc_mkdir("virtnet", 0);
20894+ if (ent) {
20895+ ent->proc_fops = &proc_virtnet_dir_operations;
20896+ ent->proc_iops = &proc_virtnet_dir_inode_operations;
d337f35e 20897+ }
4bf69007 20898+ proc_virtnet = ent;
d337f35e
JR
20899+}
20900+
d337f35e 20901+
2380c486 20902+
2380c486 20903+
4bf69007 20904+/* per pid info */
2380c486 20905+
bb20add7
AM
20906+void render_cap_t(struct seq_file *, const char *,
20907+ struct vx_info *, kernel_cap_t *);
20908+
2380c486 20909+
bb20add7
AM
20910+int proc_pid_vx_info(
20911+ struct seq_file *m,
20912+ struct pid_namespace *ns,
20913+ struct pid *pid,
20914+ struct task_struct *p)
2380c486 20915+{
4bf69007 20916+ struct vx_info *vxi;
2380c486 20917+
bb20add7 20918+ seq_printf(m, "XID:\t%d\n", vx_task_xid(p));
2380c486 20919+
4bf69007
AM
20920+ vxi = task_get_vx_info(p);
20921+ if (!vxi)
bb20add7 20922+ return 0;
2380c486 20923+
bb20add7
AM
20924+ render_cap_t(m, "BCaps:\t", vxi, &vxi->vx_bcaps);
20925+ seq_printf(m, "CCaps:\t%016llx\n",
4bf69007 20926+ (unsigned long long)vxi->vx_ccaps);
bb20add7 20927+ seq_printf(m, "CFlags:\t%016llx\n",
4bf69007 20928+ (unsigned long long)vxi->vx_flags);
bb20add7 20929+ seq_printf(m, "CIPid:\t%d\n", vxi->vx_initpid);
4bf69007
AM
20930+
20931+ put_vx_info(vxi);
bb20add7 20932+ return 0;
2380c486
JR
20933+}
20934+
2380c486 20935+
bb20add7
AM
20936+int proc_pid_nx_info(
20937+ struct seq_file *m,
20938+ struct pid_namespace *ns,
20939+ struct pid *pid,
20940+ struct task_struct *p)
4bf69007
AM
20941+{
20942+ struct nx_info *nxi;
20943+ struct nx_addr_v4 *v4a;
20944+#ifdef CONFIG_IPV6
20945+ struct nx_addr_v6 *v6a;
20946+#endif
4bf69007 20947+ int i;
2380c486 20948+
bb20add7 20949+ seq_printf(m, "NID:\t%d\n", nx_task_nid(p));
2380c486 20950+
4bf69007
AM
20951+ nxi = task_get_nx_info(p);
20952+ if (!nxi)
bb20add7 20953+ return 0;
2380c486 20954+
bb20add7 20955+ seq_printf(m, "NCaps:\t%016llx\n",
4bf69007 20956+ (unsigned long long)nxi->nx_ncaps);
bb20add7 20957+ seq_printf(m, "NFlags:\t%016llx\n",
4bf69007
AM
20958+ (unsigned long long)nxi->nx_flags);
20959+
bb20add7 20960+ seq_printf(m, "V4Root[bcast]:\t" NIPQUAD_FMT "\n",
4bf69007 20961+ NIPQUAD(nxi->v4_bcast.s_addr));
bb20add7 20962+ seq_printf(m, "V4Root[lback]:\t" NIPQUAD_FMT "\n",
4bf69007
AM
20963+ NIPQUAD(nxi->v4_lback.s_addr));
20964+ if (!NX_IPV4(nxi))
20965+ goto skip_v4;
20966+ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next)
bb20add7 20967+ seq_printf(m, "V4Root[%d]:\t" NXAV4_FMT "\n",
4bf69007
AM
20968+ i, NXAV4(v4a));
20969+skip_v4:
20970+#ifdef CONFIG_IPV6
20971+ if (!NX_IPV6(nxi))
20972+ goto skip_v6;
20973+ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next)
bb20add7 20974+ seq_printf(m, "V6Root[%d]:\t" NXAV6_FMT "\n",
4bf69007
AM
20975+ i, NXAV6(v6a));
20976+skip_v6:
20977+#endif
20978+ put_nx_info(nxi);
bb20add7 20979+ return 0;
2380c486
JR
20980+}
20981+
f19bd705
AM
20982diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched.c linux-4.4.111-vs2.3.9.1/kernel/vserver/sched.c
20983--- linux-4.4.111/kernel/vserver/sched.c 1970-01-01 00:00:00.000000000 +0000
20984+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/sched.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
20985@@ -0,0 +1,83 @@
20986+/*
20987+ * linux/kernel/vserver/sched.c
20988+ *
20989+ * Virtual Server: Scheduler Support
20990+ *
927ca606 20991+ * Copyright (C) 2004-2010 Herbert P?tzl
4bf69007
AM
20992+ *
20993+ * V0.01 adapted Sam Vilains version to 2.6.3
20994+ * V0.02 removed legacy interface
20995+ * V0.03 changed vcmds to vxi arg
20996+ * V0.04 removed older and legacy interfaces
20997+ * V0.05 removed scheduler code/commands
20998+ *
20999+ */
21000+
21001+#include <linux/vs_context.h>
21002+#include <linux/vs_sched.h>
21003+#include <linux/cpumask.h>
21004+#include <linux/vserver/sched_cmd.h>
2380c486 21005+
4bf69007
AM
21006+#include <asm/uaccess.h>
21007+
21008+
21009+void vx_update_sched_param(struct _vx_sched *sched,
21010+ struct _vx_sched_pc *sched_pc)
2380c486 21011+{
4bf69007 21012+ sched_pc->prio_bias = sched->prio_bias;
2380c486
JR
21013+}
21014+
4bf69007
AM
21015+static int do_set_prio_bias(struct vx_info *vxi, struct vcmd_prio_bias *data)
21016+{
21017+ int cpu;
2380c486 21018+
4bf69007
AM
21019+ if (data->prio_bias > MAX_PRIO_BIAS)
21020+ data->prio_bias = MAX_PRIO_BIAS;
21021+ if (data->prio_bias < MIN_PRIO_BIAS)
21022+ data->prio_bias = MIN_PRIO_BIAS;
2380c486 21023+
4bf69007 21024+ if (data->cpu_id != ~0) {
927ca606 21025+ vxi->sched.update = *get_cpu_mask(data->cpu_id);
4bf69007
AM
21026+ cpumask_and(&vxi->sched.update, &vxi->sched.update,
21027+ cpu_online_mask);
21028+ } else
21029+ cpumask_copy(&vxi->sched.update, cpu_online_mask);
2380c486 21030+
927ca606 21031+ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)vxi->sched.update)
4bf69007
AM
21032+ vx_update_sched_param(&vxi->sched,
21033+ &vx_per_cpu(vxi, sched_pc, cpu));
21034+ return 0;
21035+}
2380c486 21036+
4bf69007
AM
21037+int vc_set_prio_bias(struct vx_info *vxi, void __user *data)
21038+{
21039+ struct vcmd_prio_bias vc_data;
d337f35e 21040+
4bf69007
AM
21041+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21042+ return -EFAULT;
d337f35e 21043+
4bf69007
AM
21044+ return do_set_prio_bias(vxi, &vc_data);
21045+}
d337f35e 21046+
4bf69007
AM
21047+int vc_get_prio_bias(struct vx_info *vxi, void __user *data)
21048+{
21049+ struct vcmd_prio_bias vc_data;
21050+ struct _vx_sched_pc *pcd;
21051+ int cpu;
d337f35e 21052+
4bf69007
AM
21053+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21054+ return -EFAULT;
2380c486 21055+
4bf69007 21056+ cpu = vc_data.cpu_id;
d337f35e 21057+
4bf69007
AM
21058+ if (!cpu_possible(cpu))
21059+ return -EINVAL;
d337f35e 21060+
4bf69007
AM
21061+ pcd = &vx_per_cpu(vxi, sched_pc, cpu);
21062+ vc_data.prio_bias = pcd->prio_bias;
d337f35e 21063+
4bf69007
AM
21064+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21065+ return -EFAULT;
21066+ return 0;
21067+}
d337f35e 21068+
f19bd705
AM
21069diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched_init.h linux-4.4.111-vs2.3.9.1/kernel/vserver/sched_init.h
21070--- linux-4.4.111/kernel/vserver/sched_init.h 1970-01-01 00:00:00.000000000 +0000
21071+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/sched_init.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 21072@@ -0,0 +1,27 @@
2380c486 21073+
4bf69007
AM
21074+static inline void vx_info_init_sched(struct _vx_sched *sched)
21075+{
21076+ /* scheduling; hard code starting values as constants */
21077+ sched->prio_bias = 0;
d337f35e
JR
21078+}
21079+
4bf69007
AM
21080+static inline
21081+void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21082+{
4bf69007
AM
21083+ sched_pc->prio_bias = 0;
21084+
21085+ sched_pc->user_ticks = 0;
21086+ sched_pc->sys_ticks = 0;
21087+ sched_pc->hold_ticks = 0;
e3afe727
AM
21088+}
21089+
4bf69007 21090+static inline void vx_info_exit_sched(struct _vx_sched *sched)
e3afe727 21091+{
4bf69007 21092+ return;
e3afe727
AM
21093+}
21094+
4bf69007
AM
21095+static inline
21096+void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
e3afe727 21097+{
4bf69007 21098+ return;
e3afe727 21099+}
f19bd705
AM
21100diff -NurpP --minimal linux-4.4.111/kernel/vserver/sched_proc.h linux-4.4.111-vs2.3.9.1/kernel/vserver/sched_proc.h
21101--- linux-4.4.111/kernel/vserver/sched_proc.h 1970-01-01 00:00:00.000000000 +0000
21102+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/sched_proc.h 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21103@@ -0,0 +1,32 @@
21104+#ifndef _VX_SCHED_PROC_H
21105+#define _VX_SCHED_PROC_H
e3afe727 21106+
4bf69007
AM
21107+
21108+static inline
21109+int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
e3afe727 21110+{
4bf69007
AM
21111+ int length = 0;
21112+
21113+ length += sprintf(buffer,
21114+ "PrioBias:\t%8d\n",
21115+ sched->prio_bias);
21116+ return length;
e3afe727
AM
21117+}
21118+
4bf69007
AM
21119+static inline
21120+int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
21121+ char *buffer, int cpu)
e3afe727 21122+{
4bf69007 21123+ int length = 0;
e3afe727 21124+
4bf69007
AM
21125+ length += sprintf(buffer + length,
21126+ "cpu %d: %lld %lld %lld", cpu,
21127+ (unsigned long long)sched_pc->user_ticks,
21128+ (unsigned long long)sched_pc->sys_ticks,
21129+ (unsigned long long)sched_pc->hold_ticks);
21130+ length += sprintf(buffer + length,
21131+ " %d\n", sched_pc->prio_bias);
21132+ return length;
21133+}
93de0823 21134+
4bf69007 21135+#endif /* _VX_SCHED_PROC_H */
f19bd705
AM
21136diff -NurpP --minimal linux-4.4.111/kernel/vserver/signal.c linux-4.4.111-vs2.3.9.1/kernel/vserver/signal.c
21137--- linux-4.4.111/kernel/vserver/signal.c 1970-01-01 00:00:00.000000000 +0000
21138+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/signal.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21139@@ -0,0 +1,134 @@
21140+/*
21141+ * linux/kernel/vserver/signal.c
21142+ *
21143+ * Virtual Server: Signal Support
21144+ *
927ca606 21145+ * Copyright (C) 2003-2007 Herbert P?tzl
4bf69007
AM
21146+ *
21147+ * V0.01 broken out from vcontext V0.05
21148+ * V0.02 changed vcmds to vxi arg
21149+ * V0.03 adjusted siginfo for kill
21150+ *
21151+ */
99a884b4 21152+
4bf69007 21153+#include <asm/uaccess.h>
93de0823 21154+
4bf69007
AM
21155+#include <linux/vs_context.h>
21156+#include <linux/vs_pid.h>
21157+#include <linux/vserver/signal_cmd.h>
d337f35e 21158+
d337f35e 21159+
4bf69007
AM
21160+int vx_info_kill(struct vx_info *vxi, int pid, int sig)
21161+{
21162+ int retval, count = 0;
21163+ struct task_struct *p;
21164+ struct siginfo *sip = SEND_SIG_PRIV;
d33d7b00 21165+
4bf69007
AM
21166+ retval = -ESRCH;
21167+ vxdprintk(VXD_CBIT(misc, 4),
21168+ "vx_info_kill(%p[#%d],%d,%d)*",
21169+ vxi, vxi->vx_id, pid, sig);
21170+ read_lock(&tasklist_lock);
21171+ switch (pid) {
21172+ case 0:
21173+ case -1:
21174+ for_each_process(p) {
21175+ int err = 0;
d337f35e 21176+
4bf69007
AM
21177+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
21178+ (pid && vxi->vx_initpid == p->pid))
21179+ continue;
d337f35e 21180+
4bf69007
AM
21181+ err = group_send_sig_info(sig, sip, p);
21182+ ++count;
21183+ if (err != -EPERM)
21184+ retval = err;
21185+ }
21186+ break;
d337f35e 21187+
4bf69007
AM
21188+ case 1:
21189+ if (vxi->vx_initpid) {
21190+ pid = vxi->vx_initpid;
21191+ /* for now, only SIGINT to private init ... */
21192+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21193+ /* ... as long as there are tasks left */
21194+ (atomic_read(&vxi->vx_tasks) > 1))
21195+ sig = SIGINT;
21196+ }
21197+ /* fallthrough */
21198+ default:
21199+ rcu_read_lock();
21200+ p = find_task_by_real_pid(pid);
21201+ rcu_read_unlock();
21202+ if (p) {
21203+ if (vx_task_xid(p) == vxi->vx_id)
21204+ retval = group_send_sig_info(sig, sip, p);
21205+ }
21206+ break;
21207+ }
21208+ read_unlock(&tasklist_lock);
21209+ vxdprintk(VXD_CBIT(misc, 4),
21210+ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d",
21211+ vxi, vxi->vx_id, pid, sig, (long)sip, retval);
21212+ return retval;
21213+}
d337f35e 21214+
4bf69007 21215+int vc_ctx_kill(struct vx_info *vxi, void __user *data)
d337f35e 21216+{
4bf69007 21217+ struct vcmd_ctx_kill_v0 vc_data;
d337f35e 21218+
4bf69007
AM
21219+ if (copy_from_user(&vc_data, data, sizeof(vc_data)))
21220+ return -EFAULT;
d337f35e 21221+
4bf69007
AM
21222+ /* special check to allow guest shutdown */
21223+ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
21224+ /* forbid killall pid=0 when init is present */
21225+ (((vc_data.pid < 1) && vxi->vx_initpid) ||
21226+ (vc_data.pid > 1)))
21227+ return -EACCES;
21228+
21229+ return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
d337f35e
JR
21230+}
21231+
4bf69007
AM
21232+
21233+static int __wait_exit(struct vx_info *vxi)
d337f35e 21234+{
4bf69007
AM
21235+ DECLARE_WAITQUEUE(wait, current);
21236+ int ret = 0;
d337f35e 21237+
4bf69007
AM
21238+ add_wait_queue(&vxi->vx_wait, &wait);
21239+ set_current_state(TASK_INTERRUPTIBLE);
d337f35e 21240+
4bf69007
AM
21241+wait:
21242+ if (vx_info_state(vxi,
21243+ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN)
21244+ goto out;
21245+ if (signal_pending(current)) {
21246+ ret = -ERESTARTSYS;
21247+ goto out;
21248+ }
21249+ schedule();
21250+ goto wait;
21251+
21252+out:
21253+ set_current_state(TASK_RUNNING);
21254+ remove_wait_queue(&vxi->vx_wait, &wait);
21255+ return ret;
d337f35e
JR
21256+}
21257+
4a036bed 21258+
7b17263b 21259+
4bf69007 21260+int vc_wait_exit(struct vx_info *vxi, void __user *data)
7b17263b 21261+{
4bf69007
AM
21262+ struct vcmd_wait_exit_v0 vc_data;
21263+ int ret;
7b17263b 21264+
4bf69007
AM
21265+ ret = __wait_exit(vxi);
21266+ vc_data.reboot_cmd = vxi->reboot_cmd;
21267+ vc_data.exit_code = vxi->exit_code;
21268+
21269+ if (copy_to_user(data, &vc_data, sizeof(vc_data)))
21270+ ret = -EFAULT;
21271+ return ret;
7b17263b 21272+}
2380c486 21273+
f19bd705
AM
21274diff -NurpP --minimal linux-4.4.111/kernel/vserver/space.c linux-4.4.111-vs2.3.9.1/kernel/vserver/space.c
21275--- linux-4.4.111/kernel/vserver/space.c 1970-01-01 00:00:00.000000000 +0000
21276+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/space.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21277@@ -0,0 +1,436 @@
21278+/*
21279+ * linux/kernel/vserver/space.c
21280+ *
21281+ * Virtual Server: Context Space Support
21282+ *
927ca606 21283+ * Copyright (C) 2003-2010 Herbert P?tzl
4bf69007
AM
21284+ *
21285+ * V0.01 broken out from context.c 0.07
21286+ * V0.02 added task locking for namespace
21287+ * V0.03 broken out vx_enter_namespace
21288+ * V0.04 added *space support and commands
21289+ * V0.05 added credential support
21290+ *
21291+ */
21292+
21293+#include <linux/utsname.h>
21294+#include <linux/nsproxy.h>
21295+#include <linux/err.h>
21296+#include <linux/fs_struct.h>
21297+#include <linux/cred.h>
21298+#include <asm/uaccess.h>
d337f35e 21299+
d337f35e 21300+#include <linux/vs_context.h>
4bf69007
AM
21301+#include <linux/vserver/space.h>
21302+#include <linux/vserver/space_cmd.h>
2380c486 21303+
4bf69007
AM
21304+atomic_t vs_global_nsproxy = ATOMIC_INIT(0);
21305+atomic_t vs_global_fs = ATOMIC_INIT(0);
21306+atomic_t vs_global_mnt_ns = ATOMIC_INIT(0);
21307+atomic_t vs_global_uts_ns = ATOMIC_INIT(0);
21308+atomic_t vs_global_user_ns = ATOMIC_INIT(0);
21309+atomic_t vs_global_pid_ns = ATOMIC_INIT(0);
d337f35e 21310+
2380c486 21311+
4bf69007 21312+/* namespace functions */
2380c486 21313+
4bf69007
AM
21314+#include <linux/mnt_namespace.h>
21315+#include <linux/user_namespace.h>
21316+#include <linux/pid_namespace.h>
21317+#include <linux/ipc_namespace.h>
21318+#include <net/net_namespace.h>
21319+#include "../fs/mount.h"
2380c486 21320+
2380c486 21321+
4bf69007
AM
21322+static const struct vcmd_space_mask_v1 space_mask_v0 = {
21323+ .mask = CLONE_FS |
21324+ CLONE_NEWNS |
21325+#ifdef CONFIG_UTS_NS
21326+ CLONE_NEWUTS |
21327+#endif
21328+#ifdef CONFIG_IPC_NS
21329+ CLONE_NEWIPC |
21330+#endif
21331+#ifdef CONFIG_USER_NS
21332+ CLONE_NEWUSER |
21333+#endif
21334+ 0
21335+};
2380c486 21336+
4bf69007
AM
21337+static const struct vcmd_space_mask_v1 space_mask = {
21338+ .mask = CLONE_FS |
21339+ CLONE_NEWNS |
21340+#ifdef CONFIG_UTS_NS
21341+ CLONE_NEWUTS |
21342+#endif
21343+#ifdef CONFIG_IPC_NS
21344+ CLONE_NEWIPC |
21345+#endif
21346+#ifdef CONFIG_USER_NS
21347+ CLONE_NEWUSER |
21348+#endif
21349+#ifdef CONFIG_PID_NS
21350+ CLONE_NEWPID |
21351+#endif
21352+#ifdef CONFIG_NET_NS
21353+ CLONE_NEWNET |
21354+#endif
21355+ 0
21356+};
2380c486 21357+
4bf69007
AM
21358+static const struct vcmd_space_mask_v1 default_space_mask = {
21359+ .mask = CLONE_FS |
21360+ CLONE_NEWNS |
21361+#ifdef CONFIG_UTS_NS
21362+ CLONE_NEWUTS |
21363+#endif
21364+#ifdef CONFIG_IPC_NS
21365+ CLONE_NEWIPC |
21366+#endif
21367+#ifdef CONFIG_USER_NS
bb20add7 21368+// CLONE_NEWUSER |
4bf69007
AM
21369+#endif
21370+#ifdef CONFIG_PID_NS
21371+// CLONE_NEWPID |
21372+#endif
21373+ 0
21374+};
2380c486 21375+
4bf69007
AM
21376+/*
21377+ * build a new nsproxy mix
21378+ * assumes that both proxies are 'const'
21379+ * does not touch nsproxy refcounts
21380+ * will hold a reference on the result.
21381+ */
7b17263b 21382+
4bf69007
AM
21383+struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
21384+ struct nsproxy *new_nsproxy, unsigned long mask)
21385+{
21386+ struct mnt_namespace *old_ns;
21387+ struct uts_namespace *old_uts;
21388+ struct ipc_namespace *old_ipc;
21389+#ifdef CONFIG_PID_NS
21390+ struct pid_namespace *old_pid;
21391+#endif
21392+#ifdef CONFIG_NET_NS
21393+ struct net *old_net;
21394+#endif
21395+ struct nsproxy *nsproxy;
d337f35e 21396+
4bf69007
AM
21397+ nsproxy = copy_nsproxy(old_nsproxy);
21398+ if (!nsproxy)
21399+ goto out;
bd0a9c15 21400+
4bf69007
AM
21401+ if (mask & CLONE_NEWNS) {
21402+ old_ns = nsproxy->mnt_ns;
21403+ nsproxy->mnt_ns = new_nsproxy->mnt_ns;
21404+ if (nsproxy->mnt_ns)
21405+ get_mnt_ns(nsproxy->mnt_ns);
21406+ } else
21407+ old_ns = NULL;
d337f35e 21408+
4bf69007
AM
21409+ if (mask & CLONE_NEWUTS) {
21410+ old_uts = nsproxy->uts_ns;
21411+ nsproxy->uts_ns = new_nsproxy->uts_ns;
21412+ if (nsproxy->uts_ns)
21413+ get_uts_ns(nsproxy->uts_ns);
21414+ } else
21415+ old_uts = NULL;
2380c486 21416+
4bf69007
AM
21417+ if (mask & CLONE_NEWIPC) {
21418+ old_ipc = nsproxy->ipc_ns;
21419+ nsproxy->ipc_ns = new_nsproxy->ipc_ns;
21420+ if (nsproxy->ipc_ns)
21421+ get_ipc_ns(nsproxy->ipc_ns);
21422+ } else
21423+ old_ipc = NULL;
ec22aa5c 21424+
4bf69007
AM
21425+#ifdef CONFIG_PID_NS
21426+ if (mask & CLONE_NEWPID) {
5f23d63e
AM
21427+ old_pid = nsproxy->pid_ns_for_children;
21428+ nsproxy->pid_ns_for_children = new_nsproxy->pid_ns_for_children;
21429+ if (nsproxy->pid_ns_for_children)
21430+ get_pid_ns(nsproxy->pid_ns_for_children);
4bf69007
AM
21431+ } else
21432+ old_pid = NULL;
21433+#endif
21434+#ifdef CONFIG_NET_NS
21435+ if (mask & CLONE_NEWNET) {
21436+ old_net = nsproxy->net_ns;
21437+ nsproxy->net_ns = new_nsproxy->net_ns;
21438+ if (nsproxy->net_ns)
21439+ get_net(nsproxy->net_ns);
21440+ } else
21441+ old_net = NULL;
21442+#endif
21443+ if (old_ns)
21444+ put_mnt_ns(old_ns);
21445+ if (old_uts)
21446+ put_uts_ns(old_uts);
21447+ if (old_ipc)
21448+ put_ipc_ns(old_ipc);
21449+#ifdef CONFIG_PID_NS
21450+ if (old_pid)
21451+ put_pid_ns(old_pid);
21452+#endif
21453+#ifdef CONFIG_NET_NS
21454+ if (old_net)
21455+ put_net(old_net);
21456+#endif
21457+out:
21458+ return nsproxy;
21459+}
2380c486 21460+
bd0a9c15 21461+
4bf69007
AM
21462+/*
21463+ * merge two nsproxy structs into a new one.
21464+ * will hold a reference on the result.
21465+ */
d337f35e 21466+
4bf69007
AM
21467+static inline
21468+struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old,
21469+ struct nsproxy *proxy, unsigned long mask)
21470+{
21471+ struct nsproxy null_proxy = { .mnt_ns = NULL };
2380c486 21472+
4bf69007
AM
21473+ if (!proxy)
21474+ return NULL;
d337f35e 21475+
4bf69007
AM
21476+ if (mask) {
21477+ /* vs_mix_nsproxy returns with reference */
21478+ return vs_mix_nsproxy(old ? old : &null_proxy,
21479+ proxy, mask);
21480+ }
21481+ get_nsproxy(proxy);
21482+ return proxy;
21483+}
2380c486 21484+
ec22aa5c 21485+
4bf69007
AM
21486+int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21487+{
21488+ struct nsproxy *proxy, *proxy_cur, *proxy_new;
21489+ struct fs_struct *fs_cur, *fs = NULL;
21490+ struct _vx_space *space;
21491+ int ret, kill = 0;
2380c486 21492+
4bf69007
AM
21493+ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)",
21494+ vxi, vxi->vx_id, mask, index);
2380c486 21495+
4bf69007
AM
21496+ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
21497+ return -EACCES;
2380c486 21498+
4bf69007
AM
21499+ if (index >= VX_SPACES)
21500+ return -EINVAL;
2380c486 21501+
4bf69007
AM
21502+ space = &vxi->space[index];
21503+
21504+ if (!mask)
21505+ mask = space->vx_nsmask;
21506+
21507+ if ((mask & space->vx_nsmask) != mask)
21508+ return -EINVAL;
21509+
21510+ if (mask & CLONE_FS) {
21511+ fs = copy_fs_struct(space->vx_fs);
21512+ if (!fs)
21513+ return -ENOMEM;
2380c486 21514+ }
4bf69007
AM
21515+ proxy = space->vx_nsproxy;
21516+
21517+ vxdprintk(VXD_CBIT(space, 9),
21518+ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)",
21519+ vxi, vxi->vx_id, mask, index, proxy, fs);
21520+
21521+ task_lock(current);
21522+ fs_cur = current->fs;
21523+
21524+ if (mask & CLONE_FS) {
21525+ spin_lock(&fs_cur->lock);
21526+ current->fs = fs;
21527+ kill = !--fs_cur->users;
21528+ spin_unlock(&fs_cur->lock);
ec22aa5c 21529+ }
ec22aa5c 21530+
4bf69007
AM
21531+ proxy_cur = current->nsproxy;
21532+ get_nsproxy(proxy_cur);
21533+ task_unlock(current);
21534+
21535+ if (kill)
21536+ free_fs_struct(fs_cur);
21537+
21538+ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask);
21539+ if (IS_ERR(proxy_new)) {
21540+ ret = PTR_ERR(proxy_new);
21541+ goto out_put;
eab5a9a6 21542+ }
4bf69007
AM
21543+
21544+ proxy_new = xchg(&current->nsproxy, proxy_new);
21545+
21546+ if (mask & CLONE_NEWUSER) {
21547+ struct cred *cred;
21548+
21549+ vxdprintk(VXD_CBIT(space, 10),
21550+ "vx_enter_space(%p[#%u],%p) cred (%p,%p)",
21551+ vxi, vxi->vx_id, space->vx_cred,
21552+ current->real_cred, current->cred);
21553+
21554+ if (space->vx_cred) {
21555+ cred = __prepare_creds(space->vx_cred);
21556+ if (cred)
21557+ commit_creds(cred);
21558+ }
d337f35e 21559+ }
4bf69007
AM
21560+
21561+ ret = 0;
21562+
21563+ if (proxy_new)
21564+ put_nsproxy(proxy_new);
21565+out_put:
21566+ if (proxy_cur)
21567+ put_nsproxy(proxy_cur);
21568+ return ret;
21569+}
21570+
21571+
21572+int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index)
21573+{
21574+ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new;
21575+ struct fs_struct *fs_vxi, *fs = NULL;
21576+ struct _vx_space *space;
21577+ int ret, kill = 0;
21578+
21579+ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)",
21580+ vxi, vxi->vx_id, mask, index);
21581+
21582+ if ((mask & space_mask.mask) != mask)
21583+ return -EINVAL;
21584+
21585+ if (index >= VX_SPACES)
21586+ return -EINVAL;
21587+
21588+ space = &vxi->space[index];
21589+
21590+ proxy_vxi = space->vx_nsproxy;
21591+ fs_vxi = space->vx_fs;
21592+
21593+ if (mask & CLONE_FS) {
21594+ fs = copy_fs_struct(current->fs);
21595+ if (!fs)
21596+ return -ENOMEM;
2380c486 21597+ }
d337f35e 21598+
4bf69007 21599+ task_lock(current);
2ba6f0dd 21600+
4bf69007
AM
21601+ if (mask & CLONE_FS) {
21602+ spin_lock(&fs_vxi->lock);
21603+ space->vx_fs = fs;
21604+ kill = !--fs_vxi->users;
21605+ spin_unlock(&fs_vxi->lock);
21606+ }
2ba6f0dd 21607+
4bf69007
AM
21608+ proxy_cur = current->nsproxy;
21609+ get_nsproxy(proxy_cur);
21610+ task_unlock(current);
2ba6f0dd 21611+
4bf69007
AM
21612+ if (kill)
21613+ free_fs_struct(fs_vxi);
2ba6f0dd 21614+
4bf69007
AM
21615+ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask);
21616+ if (IS_ERR(proxy_new)) {
21617+ ret = PTR_ERR(proxy_new);
21618+ goto out_put;
21619+ }
2ba6f0dd 21620+
4bf69007
AM
21621+ proxy_new = xchg(&space->vx_nsproxy, proxy_new);
21622+ space->vx_nsmask |= mask;
2ba6f0dd 21623+
4bf69007
AM
21624+ if (mask & CLONE_NEWUSER) {
21625+ struct cred *cred;
2ba6f0dd 21626+
4bf69007
AM
21627+ vxdprintk(VXD_CBIT(space, 10),
21628+ "vx_set_space(%p[#%u],%p) cred (%p,%p)",
21629+ vxi, vxi->vx_id, space->vx_cred,
21630+ current->real_cred, current->cred);
2ba6f0dd 21631+
4bf69007
AM
21632+ cred = prepare_creds();
21633+ cred = (struct cred *)xchg(&space->vx_cred, cred);
21634+ if (cred)
21635+ abort_creds(cred);
21636+ }
2ba6f0dd 21637+
4bf69007 21638+ ret = 0;
2ba6f0dd 21639+
4bf69007
AM
21640+ if (proxy_new)
21641+ put_nsproxy(proxy_new);
21642+out_put:
21643+ if (proxy_cur)
21644+ put_nsproxy(proxy_cur);
21645+ return ret;
21646+}
2ba6f0dd
AM
21647+
21648+
4bf69007
AM
21649+int vc_enter_space_v1(struct vx_info *vxi, void __user *data)
21650+{
21651+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21652+
4bf69007
AM
21653+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21654+ return -EFAULT;
2ba6f0dd 21655+
4bf69007
AM
21656+ return vx_enter_space(vxi, vc_data.mask, 0);
21657+}
2ba6f0dd 21658+
4bf69007
AM
21659+int vc_enter_space(struct vx_info *vxi, void __user *data)
21660+{
21661+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21662+
4bf69007
AM
21663+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21664+ return -EFAULT;
2ba6f0dd 21665+
4bf69007
AM
21666+ if (vc_data.index >= VX_SPACES)
21667+ return -EINVAL;
2ba6f0dd 21668+
4bf69007
AM
21669+ return vx_enter_space(vxi, vc_data.mask, vc_data.index);
21670+}
2ba6f0dd 21671+
4bf69007
AM
21672+int vc_set_space_v1(struct vx_info *vxi, void __user *data)
21673+{
21674+ struct vcmd_space_mask_v1 vc_data = { .mask = 0 };
2ba6f0dd 21675+
4bf69007
AM
21676+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21677+ return -EFAULT;
2ba6f0dd 21678+
4bf69007
AM
21679+ return vx_set_space(vxi, vc_data.mask, 0);
21680+}
2ba6f0dd 21681+
4bf69007
AM
21682+int vc_set_space(struct vx_info *vxi, void __user *data)
21683+{
21684+ struct vcmd_space_mask_v2 vc_data = { .mask = 0 };
2ba6f0dd 21685+
4bf69007
AM
21686+ if (data && copy_from_user(&vc_data, data, sizeof(vc_data)))
21687+ return -EFAULT;
2ba6f0dd 21688+
4bf69007
AM
21689+ if (vc_data.index >= VX_SPACES)
21690+ return -EINVAL;
2ba6f0dd 21691+
4bf69007
AM
21692+ return vx_set_space(vxi, vc_data.mask, vc_data.index);
21693+}
2ba6f0dd 21694+
4bf69007
AM
21695+int vc_get_space_mask(void __user *data, int type)
21696+{
21697+ const struct vcmd_space_mask_v1 *mask;
2ba6f0dd 21698+
4bf69007
AM
21699+ if (type == 0)
21700+ mask = &space_mask_v0;
21701+ else if (type == 1)
21702+ mask = &space_mask;
21703+ else
21704+ mask = &default_space_mask;
2ba6f0dd 21705+
4bf69007
AM
21706+ vxdprintk(VXD_CBIT(space, 10),
21707+ "vc_get_space_mask(%d) = %08llx", type, mask->mask);
2ba6f0dd 21708+
4bf69007
AM
21709+ if (copy_to_user(data, mask, sizeof(*mask)))
21710+ return -EFAULT;
21711+ return 0;
21712+}
2ba6f0dd 21713+
f19bd705
AM
21714diff -NurpP --minimal linux-4.4.111/kernel/vserver/switch.c linux-4.4.111-vs2.3.9.1/kernel/vserver/switch.c
21715--- linux-4.4.111/kernel/vserver/switch.c 1970-01-01 00:00:00.000000000 +0000
21716+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/switch.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
21717@@ -0,0 +1,556 @@
21718+/*
21719+ * linux/kernel/vserver/switch.c
21720+ *
21721+ * Virtual Server: Syscall Switch
21722+ *
927ca606 21723+ * Copyright (C) 2003-2011 Herbert P?tzl
4bf69007
AM
21724+ *
21725+ * V0.01 syscall switch
21726+ * V0.02 added signal to context
21727+ * V0.03 added rlimit functions
21728+ * V0.04 added iattr, task/xid functions
21729+ * V0.05 added debug/history stuff
21730+ * V0.06 added compat32 layer
21731+ * V0.07 vcmd args and perms
21732+ * V0.08 added status commands
21733+ * V0.09 added tag commands
21734+ * V0.10 added oom bias
21735+ * V0.11 added device commands
21736+ * V0.12 added warn mask
21737+ *
21738+ */
2ba6f0dd 21739+
4bf69007
AM
21740+#include <linux/vs_context.h>
21741+#include <linux/vs_network.h>
21742+#include <linux/vserver/switch.h>
2ba6f0dd 21743+
4bf69007 21744+#include "vci_config.h"
2ba6f0dd 21745+
2ba6f0dd 21746+
4bf69007
AM
21747+static inline
21748+int vc_get_version(uint32_t id)
21749+{
21750+ return VCI_VERSION;
21751+}
2ba6f0dd 21752+
4bf69007
AM
21753+static inline
21754+int vc_get_vci(uint32_t id)
21755+{
21756+ return vci_kernel_config();
21757+}
2ba6f0dd 21758+
4bf69007
AM
21759+#include <linux/vserver/context_cmd.h>
21760+#include <linux/vserver/cvirt_cmd.h>
21761+#include <linux/vserver/cacct_cmd.h>
21762+#include <linux/vserver/limit_cmd.h>
21763+#include <linux/vserver/network_cmd.h>
21764+#include <linux/vserver/sched_cmd.h>
21765+#include <linux/vserver/debug_cmd.h>
21766+#include <linux/vserver/inode_cmd.h>
21767+#include <linux/vserver/dlimit_cmd.h>
21768+#include <linux/vserver/signal_cmd.h>
21769+#include <linux/vserver/space_cmd.h>
21770+#include <linux/vserver/tag_cmd.h>
21771+#include <linux/vserver/device_cmd.h>
2ba6f0dd 21772+
4bf69007
AM
21773+#include <linux/vserver/inode.h>
21774+#include <linux/vserver/dlimit.h>
2ba6f0dd 21775+
2ba6f0dd 21776+
4bf69007
AM
21777+#ifdef CONFIG_COMPAT
21778+#define __COMPAT(name, id, data, compat) \
21779+ (compat) ? name ## _x32(id, data) : name(id, data)
21780+#define __COMPAT_NO_ID(name, data, compat) \
21781+ (compat) ? name ## _x32(data) : name(data)
21782+#else
21783+#define __COMPAT(name, id, data, compat) \
21784+ name(id, data)
21785+#define __COMPAT_NO_ID(name, data, compat) \
21786+ name(data)
21787+#endif
2ba6f0dd 21788+
2ba6f0dd 21789+
4bf69007
AM
21790+static inline
21791+long do_vcmd(uint32_t cmd, uint32_t id,
21792+ struct vx_info *vxi, struct nx_info *nxi,
21793+ void __user *data, int compat)
21794+{
21795+ switch (cmd) {
2ba6f0dd 21796+
4bf69007
AM
21797+ case VCMD_get_version:
21798+ return vc_get_version(id);
21799+ case VCMD_get_vci:
21800+ return vc_get_vci(id);
2ba6f0dd 21801+
4bf69007
AM
21802+ case VCMD_task_xid:
21803+ return vc_task_xid(id);
21804+ case VCMD_vx_info:
21805+ return vc_vx_info(vxi, data);
2ba6f0dd 21806+
4bf69007
AM
21807+ case VCMD_task_nid:
21808+ return vc_task_nid(id);
21809+ case VCMD_nx_info:
21810+ return vc_nx_info(nxi, data);
2ba6f0dd 21811+
4bf69007
AM
21812+ case VCMD_task_tag:
21813+ return vc_task_tag(id);
2ba6f0dd 21814+
4bf69007
AM
21815+ case VCMD_set_space_v1:
21816+ return vc_set_space_v1(vxi, data);
21817+ /* this is version 2 */
21818+ case VCMD_set_space:
21819+ return vc_set_space(vxi, data);
2ba6f0dd 21820+
4bf69007
AM
21821+ case VCMD_get_space_mask_v0:
21822+ return vc_get_space_mask(data, 0);
21823+ /* this is version 1 */
21824+ case VCMD_get_space_mask:
21825+ return vc_get_space_mask(data, 1);
2ba6f0dd 21826+
4bf69007
AM
21827+ case VCMD_get_space_default:
21828+ return vc_get_space_mask(data, -1);
2ba6f0dd 21829+
4bf69007
AM
21830+ case VCMD_set_umask:
21831+ return vc_set_umask(vxi, data);
2ba6f0dd 21832+
4bf69007
AM
21833+ case VCMD_get_umask:
21834+ return vc_get_umask(vxi, data);
2ba6f0dd 21835+
4bf69007
AM
21836+ case VCMD_set_wmask:
21837+ return vc_set_wmask(vxi, data);
2ba6f0dd 21838+
4bf69007
AM
21839+ case VCMD_get_wmask:
21840+ return vc_get_wmask(vxi, data);
21841+#ifdef CONFIG_IA32_EMULATION
21842+ case VCMD_get_rlimit:
21843+ return __COMPAT(vc_get_rlimit, vxi, data, compat);
21844+ case VCMD_set_rlimit:
21845+ return __COMPAT(vc_set_rlimit, vxi, data, compat);
21846+#else
21847+ case VCMD_get_rlimit:
21848+ return vc_get_rlimit(vxi, data);
21849+ case VCMD_set_rlimit:
21850+ return vc_set_rlimit(vxi, data);
21851+#endif
21852+ case VCMD_get_rlimit_mask:
21853+ return vc_get_rlimit_mask(id, data);
21854+ case VCMD_reset_hits:
21855+ return vc_reset_hits(vxi, data);
21856+ case VCMD_reset_minmax:
21857+ return vc_reset_minmax(vxi, data);
2ba6f0dd 21858+
4bf69007
AM
21859+ case VCMD_get_vhi_name:
21860+ return vc_get_vhi_name(vxi, data);
21861+ case VCMD_set_vhi_name:
21862+ return vc_set_vhi_name(vxi, data);
2ba6f0dd 21863+
4bf69007
AM
21864+ case VCMD_ctx_stat:
21865+ return vc_ctx_stat(vxi, data);
21866+ case VCMD_virt_stat:
21867+ return vc_virt_stat(vxi, data);
21868+ case VCMD_sock_stat:
21869+ return vc_sock_stat(vxi, data);
21870+ case VCMD_rlimit_stat:
21871+ return vc_rlimit_stat(vxi, data);
2ba6f0dd 21872+
4bf69007
AM
21873+ case VCMD_set_cflags:
21874+ return vc_set_cflags(vxi, data);
21875+ case VCMD_get_cflags:
21876+ return vc_get_cflags(vxi, data);
2ba6f0dd 21877+
4bf69007
AM
21878+ /* this is version 1 */
21879+ case VCMD_set_ccaps:
21880+ return vc_set_ccaps(vxi, data);
21881+ /* this is version 1 */
21882+ case VCMD_get_ccaps:
21883+ return vc_get_ccaps(vxi, data);
21884+ case VCMD_set_bcaps:
21885+ return vc_set_bcaps(vxi, data);
21886+ case VCMD_get_bcaps:
21887+ return vc_get_bcaps(vxi, data);
2ba6f0dd 21888+
4bf69007
AM
21889+ case VCMD_set_badness:
21890+ return vc_set_badness(vxi, data);
21891+ case VCMD_get_badness:
21892+ return vc_get_badness(vxi, data);
2ba6f0dd 21893+
4bf69007
AM
21894+ case VCMD_set_nflags:
21895+ return vc_set_nflags(nxi, data);
21896+ case VCMD_get_nflags:
21897+ return vc_get_nflags(nxi, data);
2ba6f0dd 21898+
4bf69007
AM
21899+ case VCMD_set_ncaps:
21900+ return vc_set_ncaps(nxi, data);
21901+ case VCMD_get_ncaps:
21902+ return vc_get_ncaps(nxi, data);
2ba6f0dd 21903+
4bf69007
AM
21904+ case VCMD_set_prio_bias:
21905+ return vc_set_prio_bias(vxi, data);
21906+ case VCMD_get_prio_bias:
21907+ return vc_get_prio_bias(vxi, data);
21908+ case VCMD_add_dlimit:
21909+ return __COMPAT(vc_add_dlimit, id, data, compat);
21910+ case VCMD_rem_dlimit:
21911+ return __COMPAT(vc_rem_dlimit, id, data, compat);
21912+ case VCMD_set_dlimit:
21913+ return __COMPAT(vc_set_dlimit, id, data, compat);
21914+ case VCMD_get_dlimit:
21915+ return __COMPAT(vc_get_dlimit, id, data, compat);
2ba6f0dd 21916+
4bf69007
AM
21917+ case VCMD_ctx_kill:
21918+ return vc_ctx_kill(vxi, data);
2ba6f0dd 21919+
4bf69007
AM
21920+ case VCMD_wait_exit:
21921+ return vc_wait_exit(vxi, data);
2ba6f0dd 21922+
4bf69007
AM
21923+ case VCMD_get_iattr:
21924+ return __COMPAT_NO_ID(vc_get_iattr, data, compat);
21925+ case VCMD_set_iattr:
21926+ return __COMPAT_NO_ID(vc_set_iattr, data, compat);
2ba6f0dd 21927+
4bf69007
AM
21928+ case VCMD_fget_iattr:
21929+ return vc_fget_iattr(id, data);
21930+ case VCMD_fset_iattr:
21931+ return vc_fset_iattr(id, data);
2ba6f0dd 21932+
4bf69007
AM
21933+ case VCMD_enter_space_v0:
21934+ return vc_enter_space_v1(vxi, NULL);
21935+ case VCMD_enter_space_v1:
21936+ return vc_enter_space_v1(vxi, data);
21937+ /* this is version 2 */
21938+ case VCMD_enter_space:
21939+ return vc_enter_space(vxi, data);
2ba6f0dd 21940+
4bf69007
AM
21941+ case VCMD_ctx_create_v0:
21942+ return vc_ctx_create(id, NULL);
21943+ case VCMD_ctx_create:
21944+ return vc_ctx_create(id, data);
21945+ case VCMD_ctx_migrate_v0:
21946+ return vc_ctx_migrate(vxi, NULL);
21947+ case VCMD_ctx_migrate:
21948+ return vc_ctx_migrate(vxi, data);
2ba6f0dd 21949+
4bf69007
AM
21950+ case VCMD_net_create_v0:
21951+ return vc_net_create(id, NULL);
21952+ case VCMD_net_create:
21953+ return vc_net_create(id, data);
21954+ case VCMD_net_migrate:
21955+ return vc_net_migrate(nxi, data);
2ba6f0dd 21956+
4bf69007
AM
21957+ case VCMD_tag_migrate:
21958+ return vc_tag_migrate(id);
2ba6f0dd 21959+
4bf69007
AM
21960+ case VCMD_net_add:
21961+ return vc_net_add(nxi, data);
21962+ case VCMD_net_remove:
21963+ return vc_net_remove(nxi, data);
2ba6f0dd 21964+
4bf69007
AM
21965+ case VCMD_net_add_ipv4_v1:
21966+ return vc_net_add_ipv4_v1(nxi, data);
21967+ /* this is version 2 */
21968+ case VCMD_net_add_ipv4:
21969+ return vc_net_add_ipv4(nxi, data);
2ba6f0dd 21970+
4bf69007
AM
21971+ case VCMD_net_rem_ipv4_v1:
21972+ return vc_net_rem_ipv4_v1(nxi, data);
21973+ /* this is version 2 */
21974+ case VCMD_net_rem_ipv4:
21975+ return vc_net_rem_ipv4(nxi, data);
21976+#ifdef CONFIG_IPV6
21977+ case VCMD_net_add_ipv6:
21978+ return vc_net_add_ipv6(nxi, data);
21979+ case VCMD_net_remove_ipv6:
21980+ return vc_net_remove_ipv6(nxi, data);
21981+#endif
21982+/* case VCMD_add_match_ipv4:
21983+ return vc_add_match_ipv4(nxi, data);
21984+ case VCMD_get_match_ipv4:
21985+ return vc_get_match_ipv4(nxi, data);
21986+#ifdef CONFIG_IPV6
21987+ case VCMD_add_match_ipv6:
21988+ return vc_add_match_ipv6(nxi, data);
21989+ case VCMD_get_match_ipv6:
21990+ return vc_get_match_ipv6(nxi, data);
21991+#endif */
2ba6f0dd 21992+
4bf69007
AM
21993+#ifdef CONFIG_VSERVER_DEVICE
21994+ case VCMD_set_mapping:
21995+ return __COMPAT(vc_set_mapping, vxi, data, compat);
21996+ case VCMD_unset_mapping:
21997+ return __COMPAT(vc_unset_mapping, vxi, data, compat);
21998+#endif
21999+#ifdef CONFIG_VSERVER_HISTORY
22000+ case VCMD_dump_history:
22001+ return vc_dump_history(id);
22002+ case VCMD_read_history:
22003+ return __COMPAT(vc_read_history, id, data, compat);
22004+#endif
22005+ default:
22006+ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]",
22007+ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
22008+ }
22009+ return -ENOSYS;
22010+}
2ba6f0dd 22011+
2ba6f0dd 22012+
4bf69007
AM
22013+#define __VCMD(vcmd, _perm, _args, _flags) \
22014+ case VCMD_ ## vcmd: perm = _perm; \
22015+ args = _args; flags = _flags; break
2ba6f0dd 22016+
2ba6f0dd 22017+
4bf69007
AM
22018+#define VCA_NONE 0x00
22019+#define VCA_VXI 0x01
22020+#define VCA_NXI 0x02
2ba6f0dd 22021+
4bf69007
AM
22022+#define VCF_NONE 0x00
22023+#define VCF_INFO 0x01
22024+#define VCF_ADMIN 0x02
22025+#define VCF_ARES 0x06 /* includes admin */
22026+#define VCF_SETUP 0x08
2ba6f0dd 22027+
4bf69007 22028+#define VCF_ZIDOK 0x10 /* zero id okay */
2ba6f0dd 22029+
2ba6f0dd
AM
22030+
22031+static inline
4bf69007 22032+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
2ba6f0dd 22033+{
4bf69007
AM
22034+ long ret;
22035+ int permit = -1, state = 0;
22036+ int perm = -1, args = 0, flags = 0;
22037+ struct vx_info *vxi = NULL;
22038+ struct nx_info *nxi = NULL;
2ba6f0dd 22039+
4bf69007
AM
22040+ switch (cmd) {
22041+ /* unpriviledged commands */
22042+ __VCMD(get_version, 0, VCA_NONE, 0);
22043+ __VCMD(get_vci, 0, VCA_NONE, 0);
22044+ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
22045+ __VCMD(get_space_mask_v0,0, VCA_NONE, 0);
22046+ __VCMD(get_space_mask, 0, VCA_NONE, 0);
22047+ __VCMD(get_space_default,0, VCA_NONE, 0);
2ba6f0dd 22048+
4bf69007
AM
22049+ /* info commands */
22050+ __VCMD(task_xid, 2, VCA_NONE, 0);
22051+ __VCMD(reset_hits, 2, VCA_VXI, 0);
22052+ __VCMD(reset_minmax, 2, VCA_VXI, 0);
22053+ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
22054+ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
22055+ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
22056+ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
22057+ __VCMD(get_umask, 3, VCA_VXI, VCF_INFO);
22058+ __VCMD(get_wmask, 3, VCA_VXI, VCF_INFO);
22059+ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO);
22060+ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
22061+ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22062+
4bf69007
AM
22063+ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
22064+ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
22065+ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
22066+ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22067+
4bf69007
AM
22068+ __VCMD(task_nid, 2, VCA_NONE, 0);
22069+ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
22070+ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
22071+ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
2ba6f0dd 22072+
4bf69007 22073+ __VCMD(task_tag, 2, VCA_NONE, 0);
2ba6f0dd 22074+
4bf69007
AM
22075+ __VCMD(get_iattr, 2, VCA_NONE, 0);
22076+ __VCMD(fget_iattr, 2, VCA_NONE, 0);
22077+ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
22078+ __VCMD(get_prio_bias, 3, VCA_VXI, VCF_INFO);
2ba6f0dd 22079+
4bf69007
AM
22080+ /* lower admin commands */
22081+ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
22082+ __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
22083+ __VCMD(ctx_create, 5, VCA_NONE, 0);
22084+ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
22085+ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
22086+ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
22087+ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN);
22088+ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
2ba6f0dd 22089+
4bf69007
AM
22090+ __VCMD(net_create_v0, 5, VCA_NONE, 0);
22091+ __VCMD(net_create, 5, VCA_NONE, 0);
22092+ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
2ba6f0dd 22093+
4bf69007 22094+ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN);
2ba6f0dd 22095+
4bf69007
AM
22096+ /* higher admin commands */
22097+ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
22098+ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22099+ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22100+
4bf69007
AM
22101+ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22102+ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22103+ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22104+ __VCMD(set_umask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22105+ __VCMD(set_wmask, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22106+ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22107+
4bf69007
AM
22108+ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22109+ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
22110+ __VCMD(set_prio_bias, 7, VCA_VXI, VCF_ARES | VCF_SETUP);
2ba6f0dd 22111+
4bf69007
AM
22112+ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22113+ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP);
22114+ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22115+ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22116+ __VCMD(net_add_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22117+ __VCMD(net_rem_ipv4_v1, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22118+ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22119+ __VCMD(net_rem_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22120+#ifdef CONFIG_IPV6
22121+ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22122+ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP);
22123+#endif
22124+ __VCMD(set_iattr, 7, VCA_NONE, 0);
22125+ __VCMD(fset_iattr, 7, VCA_NONE, 0);
22126+ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
22127+ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
22128+ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
2ba6f0dd 22129+
4bf69007
AM
22130+#ifdef CONFIG_VSERVER_DEVICE
22131+ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22132+ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK);
22133+#endif
22134+ /* debug level admin commands */
22135+#ifdef CONFIG_VSERVER_HISTORY
22136+ __VCMD(dump_history, 9, VCA_NONE, 0);
22137+ __VCMD(read_history, 9, VCA_NONE, 0);
22138+#endif
2ba6f0dd 22139+
4bf69007
AM
22140+ default:
22141+ perm = -1;
22142+ }
2ba6f0dd 22143+
4bf69007
AM
22144+ vxdprintk(VXD_CBIT(switch, 0),
22145+ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
22146+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22147+ VC_VERSION(cmd), id, data, compat,
22148+ perm, args, flags);
2ba6f0dd 22149+
4bf69007
AM
22150+ ret = -ENOSYS;
22151+ if (perm < 0)
22152+ goto out;
2ba6f0dd 22153+
4bf69007
AM
22154+ state = 1;
22155+ if (!capable(CAP_CONTEXT))
22156+ goto out;
2ba6f0dd 22157+
4bf69007
AM
22158+ state = 2;
22159+ /* moved here from the individual commands */
22160+ ret = -EPERM;
22161+ if ((perm > 1) && !capable(CAP_SYS_ADMIN))
22162+ goto out;
2ba6f0dd 22163+
4bf69007
AM
22164+ state = 3;
22165+ /* vcmd involves resource management */
22166+ ret = -EPERM;
22167+ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
22168+ goto out;
2ba6f0dd 22169+
4bf69007
AM
22170+ state = 4;
22171+ /* various legacy exceptions */
22172+ switch (cmd) {
22173+ /* will go away when spectator is a cap */
22174+ case VCMD_ctx_migrate_v0:
22175+ case VCMD_ctx_migrate:
22176+ if (id == 1) {
22177+ current->xid = 1;
22178+ ret = 1;
22179+ goto out;
22180+ }
22181+ break;
2ba6f0dd 22182+
4bf69007
AM
22183+ /* will go away when spectator is a cap */
22184+ case VCMD_net_migrate:
22185+ if (id == 1) {
22186+ current->nid = 1;
22187+ ret = 1;
22188+ goto out;
22189+ }
22190+ break;
22191+ }
2ba6f0dd 22192+
4bf69007
AM
22193+ /* vcmds are fine by default */
22194+ permit = 1;
2ba6f0dd 22195+
4bf69007
AM
22196+ /* admin type vcmds require admin ... */
22197+ if (flags & VCF_ADMIN)
22198+ permit = vx_check(0, VS_ADMIN) ? 1 : 0;
2ba6f0dd 22199+
4bf69007
AM
22200+ /* ... but setup type vcmds override that */
22201+ if (!permit && (flags & VCF_SETUP))
22202+ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
2ba6f0dd 22203+
4bf69007
AM
22204+ state = 5;
22205+ ret = -EPERM;
22206+ if (!permit)
22207+ goto out;
2ba6f0dd 22208+
4bf69007
AM
22209+ state = 6;
22210+ if (!id && (flags & VCF_ZIDOK))
22211+ goto skip_id;
2ba6f0dd 22212+
4bf69007
AM
22213+ ret = -ESRCH;
22214+ if (args & VCA_VXI) {
22215+ vxi = lookup_vx_info(id);
22216+ if (!vxi)
22217+ goto out;
2ba6f0dd 22218+
4bf69007
AM
22219+ if ((flags & VCF_ADMIN) &&
22220+ /* special case kill for shutdown */
22221+ (cmd != VCMD_ctx_kill) &&
22222+ /* can context be administrated? */
22223+ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
22224+ ret = -EACCES;
22225+ goto out_vxi;
22226+ }
22227+ }
22228+ state = 7;
22229+ if (args & VCA_NXI) {
22230+ nxi = lookup_nx_info(id);
22231+ if (!nxi)
22232+ goto out_vxi;
2ba6f0dd 22233+
4bf69007
AM
22234+ if ((flags & VCF_ADMIN) &&
22235+ /* can context be administrated? */
22236+ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
22237+ ret = -EACCES;
22238+ goto out_nxi;
22239+ }
22240+ }
22241+skip_id:
22242+ state = 8;
22243+ ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
2ba6f0dd 22244+
4bf69007
AM
22245+out_nxi:
22246+ if ((args & VCA_NXI) && nxi)
22247+ put_nx_info(nxi);
22248+out_vxi:
22249+ if ((args & VCA_VXI) && vxi)
22250+ put_vx_info(vxi);
22251+out:
22252+ vxdprintk(VXD_CBIT(switch, 1),
22253+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
22254+ VC_CATEGORY(cmd), VC_COMMAND(cmd),
22255+ VC_VERSION(cmd), ret, ret, state, permit);
22256+ return ret;
22257+}
2ba6f0dd 22258+
4bf69007
AM
22259+asmlinkage long
22260+sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
22261+{
22262+ return do_vserver(cmd, id, data, 0);
22263+}
2ba6f0dd 22264+
4bf69007 22265+#ifdef CONFIG_COMPAT
2ba6f0dd 22266+
4bf69007
AM
22267+asmlinkage long
22268+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
22269+{
22270+ return do_vserver(cmd, id, data, 1);
22271+}
2ba6f0dd 22272+
4bf69007 22273+#endif /* CONFIG_COMPAT */
f19bd705
AM
22274diff -NurpP --minimal linux-4.4.111/kernel/vserver/sysctl.c linux-4.4.111-vs2.3.9.1/kernel/vserver/sysctl.c
22275--- linux-4.4.111/kernel/vserver/sysctl.c 1970-01-01 00:00:00.000000000 +0000
22276+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/sysctl.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22277@@ -0,0 +1,247 @@
22278+/*
22279+ * kernel/vserver/sysctl.c
22280+ *
22281+ * Virtual Context Support
22282+ *
927ca606 22283+ * Copyright (C) 2004-2007 Herbert P?tzl
4bf69007
AM
22284+ *
22285+ * V0.01 basic structure
22286+ *
22287+ */
2ba6f0dd 22288+
4bf69007
AM
22289+#include <linux/module.h>
22290+#include <linux/ctype.h>
22291+#include <linux/sysctl.h>
22292+#include <linux/parser.h>
22293+#include <asm/uaccess.h>
2ba6f0dd 22294+
4bf69007
AM
22295+enum {
22296+ CTL_DEBUG_ERROR = 0,
22297+ CTL_DEBUG_SWITCH = 1,
22298+ CTL_DEBUG_XID,
22299+ CTL_DEBUG_NID,
22300+ CTL_DEBUG_TAG,
22301+ CTL_DEBUG_NET,
22302+ CTL_DEBUG_LIMIT,
22303+ CTL_DEBUG_CRES,
22304+ CTL_DEBUG_DLIM,
22305+ CTL_DEBUG_QUOTA,
22306+ CTL_DEBUG_CVIRT,
22307+ CTL_DEBUG_SPACE,
22308+ CTL_DEBUG_PERM,
22309+ CTL_DEBUG_MISC,
2ba6f0dd
AM
22310+};
22311+
2ba6f0dd 22312+
4bf69007
AM
22313+unsigned int vs_debug_switch = 0;
22314+unsigned int vs_debug_xid = 0;
22315+unsigned int vs_debug_nid = 0;
22316+unsigned int vs_debug_tag = 0;
22317+unsigned int vs_debug_net = 0;
22318+unsigned int vs_debug_limit = 0;
22319+unsigned int vs_debug_cres = 0;
22320+unsigned int vs_debug_dlim = 0;
22321+unsigned int vs_debug_quota = 0;
22322+unsigned int vs_debug_cvirt = 0;
22323+unsigned int vs_debug_space = 0;
22324+unsigned int vs_debug_perm = 0;
22325+unsigned int vs_debug_misc = 0;
2ba6f0dd 22326+
2ba6f0dd 22327+
4bf69007 22328+static struct ctl_table_header *vserver_table_header;
bb20add7 22329+static struct ctl_table vserver_root_table[];
4bf69007 22330+
2ba6f0dd 22331+
4bf69007
AM
22332+void vserver_register_sysctl(void)
22333+{
22334+ if (!vserver_table_header) {
22335+ vserver_table_header = register_sysctl_table(vserver_root_table);
22336+ }
2ba6f0dd 22337+
4bf69007 22338+}
2ba6f0dd 22339+
4bf69007
AM
22340+void vserver_unregister_sysctl(void)
22341+{
22342+ if (vserver_table_header) {
22343+ unregister_sysctl_table(vserver_table_header);
22344+ vserver_table_header = NULL;
22345+ }
22346+}
2ba6f0dd 22347+
2ba6f0dd 22348+
bb20add7 22349+static int proc_dodebug(struct ctl_table *table, int write,
4bf69007
AM
22350+ void __user *buffer, size_t *lenp, loff_t *ppos)
22351+{
22352+ char tmpbuf[20], *p, c;
22353+ unsigned int value;
22354+ size_t left, len;
2ba6f0dd 22355+
4bf69007
AM
22356+ if ((*ppos && !write) || !*lenp) {
22357+ *lenp = 0;
22358+ return 0;
22359+ }
2ba6f0dd 22360+
4bf69007 22361+ left = *lenp;
2ba6f0dd 22362+
4bf69007
AM
22363+ if (write) {
22364+ if (!access_ok(VERIFY_READ, buffer, left))
22365+ return -EFAULT;
22366+ p = (char *)buffer;
22367+ while (left && __get_user(c, p) >= 0 && isspace(c))
22368+ left--, p++;
22369+ if (!left)
22370+ goto done;
2ba6f0dd 22371+
4bf69007
AM
22372+ if (left > sizeof(tmpbuf) - 1)
22373+ return -EINVAL;
22374+ if (copy_from_user(tmpbuf, p, left))
22375+ return -EFAULT;
22376+ tmpbuf[left] = '\0';
2ba6f0dd 22377+
4bf69007
AM
22378+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
22379+ value = 10 * value + (*p - '0');
22380+ if (*p && !isspace(*p))
22381+ return -EINVAL;
22382+ while (left && isspace(*p))
22383+ left--, p++;
22384+ *(unsigned int *)table->data = value;
22385+ } else {
22386+ if (!access_ok(VERIFY_WRITE, buffer, left))
22387+ return -EFAULT;
22388+ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data);
22389+ if (len > left)
22390+ len = left;
22391+ if (__copy_to_user(buffer, tmpbuf, len))
22392+ return -EFAULT;
22393+ if ((left -= len) > 0) {
22394+ if (put_user('\n', (char *)buffer + len))
22395+ return -EFAULT;
22396+ left--;
22397+ }
22398+ }
2ba6f0dd 22399+
4bf69007
AM
22400+done:
22401+ *lenp -= left;
22402+ *ppos += *lenp;
22403+ return 0;
22404+}
2ba6f0dd 22405+
4bf69007 22406+static int zero;
2ba6f0dd 22407+
4bf69007
AM
22408+#define CTL_ENTRY(ctl, name) \
22409+ { \
22410+ .procname = #name, \
22411+ .data = &vs_ ## name, \
22412+ .maxlen = sizeof(int), \
22413+ .mode = 0644, \
22414+ .proc_handler = &proc_dodebug, \
22415+ .extra1 = &zero, \
22416+ .extra2 = &zero, \
22417+ }
2ba6f0dd 22418+
bb20add7 22419+static struct ctl_table vserver_debug_table[] = {
4bf69007
AM
22420+ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch),
22421+ CTL_ENTRY(CTL_DEBUG_XID, debug_xid),
22422+ CTL_ENTRY(CTL_DEBUG_NID, debug_nid),
22423+ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag),
22424+ CTL_ENTRY(CTL_DEBUG_NET, debug_net),
22425+ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit),
22426+ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres),
22427+ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim),
22428+ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota),
22429+ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt),
22430+ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space),
22431+ CTL_ENTRY(CTL_DEBUG_PERM, debug_perm),
22432+ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc),
22433+ { 0 }
22434+};
2ba6f0dd 22435+
bb20add7 22436+static struct ctl_table vserver_root_table[] = {
4bf69007
AM
22437+ {
22438+ .procname = "vserver",
22439+ .mode = 0555,
22440+ .child = vserver_debug_table
22441+ },
22442+ { 0 }
22443+};
2ba6f0dd 22444+
2ba6f0dd 22445+
4bf69007
AM
22446+static match_table_t tokens = {
22447+ { CTL_DEBUG_SWITCH, "switch=%x" },
22448+ { CTL_DEBUG_XID, "xid=%x" },
22449+ { CTL_DEBUG_NID, "nid=%x" },
22450+ { CTL_DEBUG_TAG, "tag=%x" },
22451+ { CTL_DEBUG_NET, "net=%x" },
22452+ { CTL_DEBUG_LIMIT, "limit=%x" },
22453+ { CTL_DEBUG_CRES, "cres=%x" },
22454+ { CTL_DEBUG_DLIM, "dlim=%x" },
22455+ { CTL_DEBUG_QUOTA, "quota=%x" },
22456+ { CTL_DEBUG_CVIRT, "cvirt=%x" },
22457+ { CTL_DEBUG_SPACE, "space=%x" },
22458+ { CTL_DEBUG_PERM, "perm=%x" },
22459+ { CTL_DEBUG_MISC, "misc=%x" },
22460+ { CTL_DEBUG_ERROR, NULL }
22461+};
2ba6f0dd 22462+
4bf69007
AM
22463+#define HANDLE_CASE(id, name, val) \
22464+ case CTL_DEBUG_ ## id: \
22465+ vs_debug_ ## name = val; \
22466+ printk("vs_debug_" #name "=0x%x\n", val); \
22467+ break
2ba6f0dd 22468+
2ba6f0dd 22469+
4bf69007
AM
22470+static int __init vs_debug_setup(char *str)
22471+{
22472+ char *p;
22473+ int token;
2ba6f0dd 22474+
4bf69007
AM
22475+ printk("vs_debug_setup(%s)\n", str);
22476+ while ((p = strsep(&str, ",")) != NULL) {
22477+ substring_t args[MAX_OPT_ARGS];
22478+ unsigned int value;
2ba6f0dd 22479+
4bf69007
AM
22480+ if (!*p)
22481+ continue;
2ba6f0dd 22482+
4bf69007
AM
22483+ token = match_token(p, tokens, args);
22484+ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0;
2ba6f0dd 22485+
4bf69007
AM
22486+ switch (token) {
22487+ HANDLE_CASE(SWITCH, switch, value);
22488+ HANDLE_CASE(XID, xid, value);
22489+ HANDLE_CASE(NID, nid, value);
22490+ HANDLE_CASE(TAG, tag, value);
22491+ HANDLE_CASE(NET, net, value);
22492+ HANDLE_CASE(LIMIT, limit, value);
22493+ HANDLE_CASE(CRES, cres, value);
22494+ HANDLE_CASE(DLIM, dlim, value);
22495+ HANDLE_CASE(QUOTA, quota, value);
22496+ HANDLE_CASE(CVIRT, cvirt, value);
22497+ HANDLE_CASE(SPACE, space, value);
22498+ HANDLE_CASE(PERM, perm, value);
22499+ HANDLE_CASE(MISC, misc, value);
22500+ default:
22501+ return -EINVAL;
22502+ break;
22503+ }
22504+ }
22505+ return 1;
22506+}
2ba6f0dd 22507+
4bf69007 22508+__setup("vsdebug=", vs_debug_setup);
2ba6f0dd 22509+
2ba6f0dd 22510+
2ba6f0dd 22511+
4bf69007
AM
22512+EXPORT_SYMBOL_GPL(vs_debug_switch);
22513+EXPORT_SYMBOL_GPL(vs_debug_xid);
22514+EXPORT_SYMBOL_GPL(vs_debug_nid);
22515+EXPORT_SYMBOL_GPL(vs_debug_net);
22516+EXPORT_SYMBOL_GPL(vs_debug_limit);
22517+EXPORT_SYMBOL_GPL(vs_debug_cres);
22518+EXPORT_SYMBOL_GPL(vs_debug_dlim);
22519+EXPORT_SYMBOL_GPL(vs_debug_quota);
22520+EXPORT_SYMBOL_GPL(vs_debug_cvirt);
22521+EXPORT_SYMBOL_GPL(vs_debug_space);
22522+EXPORT_SYMBOL_GPL(vs_debug_perm);
22523+EXPORT_SYMBOL_GPL(vs_debug_misc);
2ba6f0dd 22524+
f19bd705
AM
22525diff -NurpP --minimal linux-4.4.111/kernel/vserver/tag.c linux-4.4.111-vs2.3.9.1/kernel/vserver/tag.c
22526--- linux-4.4.111/kernel/vserver/tag.c 1970-01-01 00:00:00.000000000 +0000
22527+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/tag.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22528@@ -0,0 +1,63 @@
22529+/*
22530+ * linux/kernel/vserver/tag.c
22531+ *
22532+ * Virtual Server: Shallow Tag Space
22533+ *
927ca606 22534+ * Copyright (C) 2007 Herbert P?tzl
4bf69007
AM
22535+ *
22536+ * V0.01 basic implementation
22537+ *
22538+ */
2ba6f0dd 22539+
4bf69007
AM
22540+#include <linux/sched.h>
22541+#include <linux/vserver/debug.h>
22542+#include <linux/vs_pid.h>
22543+#include <linux/vs_tag.h>
2ba6f0dd 22544+
4bf69007 22545+#include <linux/vserver/tag_cmd.h>
2ba6f0dd 22546+
2ba6f0dd 22547+
61333608 22548+int dx_migrate_task(struct task_struct *p, vtag_t tag)
4bf69007
AM
22549+{
22550+ if (!p)
22551+ BUG();
2ba6f0dd 22552+
4bf69007
AM
22553+ vxdprintk(VXD_CBIT(tag, 5),
22554+ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag);
2ba6f0dd 22555+
4bf69007
AM
22556+ task_lock(p);
22557+ p->tag = tag;
22558+ task_unlock(p);
2ba6f0dd 22559+
4bf69007
AM
22560+ vxdprintk(VXD_CBIT(tag, 5),
22561+ "moved task %p into [#%d]", p, tag);
22562+ return 0;
22563+}
2ba6f0dd 22564+
4bf69007 22565+/* vserver syscall commands below here */
2ba6f0dd 22566+
4bf69007 22567+/* taks xid and vx_info functions */
2ba6f0dd 22568+
2ba6f0dd 22569+
4bf69007
AM
22570+int vc_task_tag(uint32_t id)
22571+{
61333608 22572+ vtag_t tag;
2ba6f0dd 22573+
4bf69007
AM
22574+ if (id) {
22575+ struct task_struct *tsk;
22576+ rcu_read_lock();
22577+ tsk = find_task_by_real_pid(id);
22578+ tag = (tsk) ? tsk->tag : -ESRCH;
22579+ rcu_read_unlock();
22580+ } else
22581+ tag = dx_current_tag();
22582+ return tag;
22583+}
2ba6f0dd 22584+
2ba6f0dd 22585+
4bf69007
AM
22586+int vc_tag_migrate(uint32_t tag)
22587+{
22588+ return dx_migrate_task(current, tag & 0xFFFF);
22589+}
2ba6f0dd 22590+
2ba6f0dd 22591+
f19bd705
AM
22592diff -NurpP --minimal linux-4.4.111/kernel/vserver/vci_config.h linux-4.4.111-vs2.3.9.1/kernel/vserver/vci_config.h
22593--- linux-4.4.111/kernel/vserver/vci_config.h 1970-01-01 00:00:00.000000000 +0000
22594+++ linux-4.4.111-vs2.3.9.1/kernel/vserver/vci_config.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 22595@@ -0,0 +1,80 @@
2ba6f0dd 22596+
4bf69007 22597+/* interface version */
2ba6f0dd 22598+
4bf69007 22599+#define VCI_VERSION 0x00020308
2ba6f0dd 22600+
2ba6f0dd 22601+
4bf69007
AM
22602+enum {
22603+ VCI_KCBIT_NO_DYNAMIC = 0,
2ba6f0dd 22604+
4bf69007
AM
22605+ VCI_KCBIT_PROC_SECURE = 4,
22606+ /* VCI_KCBIT_HARDCPU = 5, */
22607+ /* VCI_KCBIT_IDLELIMIT = 6, */
22608+ /* VCI_KCBIT_IDLETIME = 7, */
2ba6f0dd 22609+
4bf69007
AM
22610+ VCI_KCBIT_COWBL = 8,
22611+ VCI_KCBIT_FULLCOWBL = 9,
22612+ VCI_KCBIT_SPACES = 10,
22613+ VCI_KCBIT_NETV2 = 11,
22614+ VCI_KCBIT_MEMCG = 12,
22615+ VCI_KCBIT_MEMCG_SWAP = 13,
2ba6f0dd 22616+
4bf69007
AM
22617+ VCI_KCBIT_DEBUG = 16,
22618+ VCI_KCBIT_HISTORY = 20,
22619+ VCI_KCBIT_TAGGED = 24,
22620+ VCI_KCBIT_PPTAG = 28,
2ba6f0dd 22621+
4bf69007 22622+ VCI_KCBIT_MORE = 31,
2ba6f0dd
AM
22623+};
22624+
2ba6f0dd 22625+
4bf69007
AM
22626+static inline uint32_t vci_kernel_config(void)
22627+{
22628+ return
22629+ (1 << VCI_KCBIT_NO_DYNAMIC) |
2ba6f0dd 22630+
4bf69007
AM
22631+ /* configured features */
22632+#ifdef CONFIG_VSERVER_PROC_SECURE
22633+ (1 << VCI_KCBIT_PROC_SECURE) |
22634+#endif
22635+#ifdef CONFIG_VSERVER_COWBL
22636+ (1 << VCI_KCBIT_COWBL) |
22637+ (1 << VCI_KCBIT_FULLCOWBL) |
22638+#endif
22639+ (1 << VCI_KCBIT_SPACES) |
22640+ (1 << VCI_KCBIT_NETV2) |
22641+#ifdef CONFIG_MEMCG
22642+ (1 << VCI_KCBIT_MEMCG) |
22643+#endif
22644+#ifdef CONFIG_MEMCG_SWAP
22645+ (1 << VCI_KCBIT_MEMCG_SWAP) |
22646+#endif
2ba6f0dd 22647+
4bf69007
AM
22648+ /* debug options */
22649+#ifdef CONFIG_VSERVER_DEBUG
22650+ (1 << VCI_KCBIT_DEBUG) |
22651+#endif
22652+#ifdef CONFIG_VSERVER_HISTORY
22653+ (1 << VCI_KCBIT_HISTORY) |
22654+#endif
2ba6f0dd 22655+
4bf69007
AM
22656+ /* inode context tagging */
22657+#if defined(CONFIG_TAGGING_NONE)
22658+ (0 << VCI_KCBIT_TAGGED) |
22659+#elif defined(CONFIG_TAGGING_UID16)
22660+ (1 << VCI_KCBIT_TAGGED) |
22661+#elif defined(CONFIG_TAGGING_GID16)
22662+ (2 << VCI_KCBIT_TAGGED) |
22663+#elif defined(CONFIG_TAGGING_ID24)
22664+ (3 << VCI_KCBIT_TAGGED) |
22665+#elif defined(CONFIG_TAGGING_INTERN)
22666+ (4 << VCI_KCBIT_TAGGED) |
22667+#elif defined(CONFIG_TAGGING_RUNTIME)
22668+ (5 << VCI_KCBIT_TAGGED) |
22669+#else
22670+ (7 << VCI_KCBIT_TAGGED) |
22671+#endif
22672+ (1 << VCI_KCBIT_PPTAG) |
22673+ 0;
22674+}
2ba6f0dd 22675+
f19bd705
AM
22676diff -NurpP --minimal linux-4.4.111/mm/memcontrol.c linux-4.4.111-vs2.3.9.1/mm/memcontrol.c
22677--- linux-4.4.111/mm/memcontrol.c 2018-01-11 07:57:53.000000000 +0000
22678+++ linux-4.4.111-vs2.3.9.1/mm/memcontrol.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
22679@@ -2888,6 +2888,28 @@ static u64 mem_cgroup_read_u64(struct cg
22680 }
4bf69007
AM
22681 }
22682
927ca606 22683+u64 mem_cgroup_mem_usage_pages(struct mem_cgroup *memcg)
4bf69007 22684+{
927ca606 22685+ return mem_cgroup_usage(memcg, false) >> PAGE_SHIFT;
4bf69007 22686+}
2ba6f0dd 22687+
927ca606 22688+u64 mem_cgroup_mem_limit_pages(struct mem_cgroup *memcg)
4bf69007 22689+{
927ca606 22690+ return (u64)memcg->memory.limit;
4bf69007 22691+}
2ba6f0dd 22692+
927ca606 22693+u64 mem_cgroup_memsw_usage_pages(struct mem_cgroup *memcg)
4bf69007 22694+{
927ca606 22695+ return mem_cgroup_usage(memcg, true) >> PAGE_SHIFT;
4bf69007 22696+}
2ba6f0dd 22697+
927ca606 22698+u64 mem_cgroup_memsw_limit_pages(struct mem_cgroup *memcg)
4bf69007 22699+{
927ca606 22700+ return (u64)memcg->memsw.limit;
4bf69007 22701+}
2ba6f0dd
AM
22702+
22703+
927ca606
AM
22704+
22705 #ifdef CONFIG_MEMCG_KMEM
22706 static int memcg_activate_kmem(struct mem_cgroup *memcg,
22707 unsigned long nr_pages)
f19bd705
AM
22708diff -NurpP --minimal linux-4.4.111/mm/oom_kill.c linux-4.4.111-vs2.3.9.1/mm/oom_kill.c
22709--- linux-4.4.111/mm/oom_kill.c 2016-07-05 04:15:13.000000000 +0000
22710+++ linux-4.4.111-vs2.3.9.1/mm/oom_kill.c 2018-01-09 16:56:23.000000000 +0000
4bf69007
AM
22711@@ -35,6 +35,8 @@
22712 #include <linux/freezer.h>
22713 #include <linux/ftrace.h>
22714 #include <linux/ratelimit.h>
22715+#include <linux/reboot.h>
22716+#include <linux/vs_context.h>
22717
22718 #define CREATE_TRACE_POINTS
22719 #include <trace/events/oom.h>
927ca606 22720@@ -131,11 +133,18 @@ static inline bool is_sysrq_oom(struct o
4bf69007 22721 static bool oom_unkillable_task(struct task_struct *p,
927ca606 22722 struct mem_cgroup *memcg, const nodemask_t *nodemask)
4bf69007
AM
22723 {
22724- if (is_global_init(p))
22725+ unsigned xid = vx_current_xid();
2ba6f0dd 22726+
4bf69007
AM
22727+ /* skip the init task, global and per guest */
22728+ if (task_is_init(p))
22729 return true;
22730 if (p->flags & PF_KTHREAD)
22731 return true;
22732
22733+ /* skip other guest and host processes if oom in guest */
22734+ if (xid && vx_task_xid(p) != xid)
22735+ return true;
2ba6f0dd 22736+
4bf69007
AM
22737 /* When mem_cgroup_out_of_memory() and p is not member of the group */
22738 if (memcg && !task_in_mem_cgroup(p, memcg))
22739 return true;
927ca606
AM
22740@@ -534,8 +543,8 @@ void oom_kill_process(struct oom_control
22741 if (__ratelimit(&oom_rs))
22742 dump_header(oc, p, memcg);
4bf69007 22743
927ca606 22744- pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
4bf69007
AM
22745- message, task_pid_nr(p), p->comm, points);
22746+ pr_err("%s: Kill process %d:#%u (%s) score %d or sacrifice child\n",
22747+ message, task_pid_nr(p), p->xid, p->comm, points);
4bf69007
AM
22748
22749 /*
927ca606
AM
22750 * If any of p's children has a different mm and is eligible for kill,
22751@@ -585,8 +594,8 @@ void oom_kill_process(struct oom_control
22752 */
22753 do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
22754 mark_oom_victim(victim);
4bf69007
AM
22755- pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
22756- task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
927ca606 22757+ pr_err("Killed process %d:%u (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
4bf69007
AM
22758+ task_pid_nr(victim), victim->xid, victim->comm, K(victim->mm->total_vm),
22759 K(get_mm_counter(victim->mm, MM_ANONPAGES)),
22760 K(get_mm_counter(victim->mm, MM_FILEPAGES)));
22761 task_unlock(victim);
927ca606 22762@@ -622,6 +631,8 @@ void oom_kill_process(struct oom_control
4bf69007 22763 }
927ca606 22764 #undef K
4bf69007
AM
22765
22766+long vs_oom_action(unsigned int);
2ba6f0dd 22767+
4bf69007 22768 /*
927ca606
AM
22769 * Determines whether the kernel must panic because of the panic_on_oom sysctl.
22770 */
22771@@ -722,7 +733,12 @@ bool out_of_memory(struct oom_control *o
4bf69007 22772 /* Found nothing?!?! Either we hang forever, or we panic. */
927ca606
AM
22773 if (!p && !is_sysrq_oom(oc)) {
22774 dump_header(oc, NULL, NULL);
4bf69007 22775- panic("Out of memory and no killable processes...\n");
2ba6f0dd 22776+
4bf69007
AM
22777+ /* avoid panic for guest OOM */
22778+ if (vx_current_xid())
22779+ vs_oom_action(LINUX_REBOOT_CMD_OOM);
22780+ else
22781+ panic("Out of memory and no killable processes...\n");
22782 }
927ca606
AM
22783 if (p && p != (void *)-1UL) {
22784 oom_kill_process(oc, p, points, totalpages, NULL,
f19bd705
AM
22785diff -NurpP --minimal linux-4.4.111/mm/page_alloc.c linux-4.4.111-vs2.3.9.1/mm/page_alloc.c
22786--- linux-4.4.111/mm/page_alloc.c 2018-01-11 07:57:53.000000000 +0000
22787+++ linux-4.4.111-vs2.3.9.1/mm/page_alloc.c 2018-01-09 16:57:52.000000000 +0000
927ca606 22788@@ -62,6 +62,8 @@
b00e13aa 22789 #include <linux/sched/rt.h>
927ca606
AM
22790 #include <linux/page_owner.h>
22791 #include <linux/kthread.h>
4bf69007
AM
22792+#include <linux/vs_base.h>
22793+#include <linux/vs_limit.h>
22794
c2e5f7c8 22795 #include <asm/sections.h>
4bf69007 22796 #include <asm/tlbflush.h>
927ca606 22797@@ -3661,6 +3663,9 @@ void si_meminfo(struct sysinfo *val)
4bf69007
AM
22798 val->totalhigh = totalhigh_pages;
22799 val->freehigh = nr_free_highpages();
22800 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22801+
4bf69007
AM
22802+ if (vx_flags(VXF_VIRT_MEM, 0))
22803+ vx_vsi_meminfo(val);
22804 }
22805
22806 EXPORT_SYMBOL(si_meminfo);
927ca606 22807@@ -3686,6 +3691,9 @@ void si_meminfo_node(struct sysinfo *val
4bf69007
AM
22808 val->freehigh = 0;
22809 #endif
22810 val->mem_unit = PAGE_SIZE;
2ba6f0dd 22811+
4bf69007
AM
22812+ if (vx_flags(VXF_VIRT_MEM, 0))
22813+ vx_vsi_meminfo(val);
22814 }
22815 #endif
22816
f19bd705
AM
22817diff -NurpP --minimal linux-4.4.111/mm/pgtable-generic.c linux-4.4.111-vs2.3.9.1/mm/pgtable-generic.c
22818--- linux-4.4.111/mm/pgtable-generic.c 2018-01-11 07:57:53.000000000 +0000
22819+++ linux-4.4.111-vs2.3.9.1/mm/pgtable-generic.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22820@@ -6,6 +6,8 @@
22821 * Copyright (C) 2010 Linus Torvalds
22822 */
22823
22824+#include <linux/mm.h>
2ba6f0dd 22825+
4bf69007
AM
22826 #include <linux/pagemap.h>
22827 #include <asm/tlb.h>
22828 #include <asm-generic/pgtable.h>
f19bd705
AM
22829diff -NurpP --minimal linux-4.4.111/mm/shmem.c linux-4.4.111-vs2.3.9.1/mm/shmem.c
22830--- linux-4.4.111/mm/shmem.c 2018-01-11 07:57:53.000000000 +0000
22831+++ linux-4.4.111-vs2.3.9.1/mm/shmem.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22832@@ -2198,7 +2198,7 @@ static int shmem_statfs(struct dentry *d
4bf69007
AM
22833 {
22834 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
22835
22836- buf->f_type = TMPFS_MAGIC;
22837+ buf->f_type = TMPFS_SUPER_MAGIC;
22838 buf->f_bsize = PAGE_CACHE_SIZE;
22839 buf->f_namelen = NAME_MAX;
22840 if (sbinfo->max_blocks) {
927ca606 22841@@ -3044,7 +3044,7 @@ int shmem_fill_super(struct super_block
4bf69007
AM
22842 sb->s_maxbytes = MAX_LFS_FILESIZE;
22843 sb->s_blocksize = PAGE_CACHE_SIZE;
22844 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
22845- sb->s_magic = TMPFS_MAGIC;
22846+ sb->s_magic = TMPFS_SUPER_MAGIC;
22847 sb->s_op = &shmem_ops;
22848 sb->s_time_gran = 1;
22849 #ifdef CONFIG_TMPFS_XATTR
f19bd705
AM
22850diff -NurpP --minimal linux-4.4.111/mm/slab.c linux-4.4.111-vs2.3.9.1/mm/slab.c
22851--- linux-4.4.111/mm/slab.c 2016-07-05 04:15:13.000000000 +0000
22852+++ linux-4.4.111-vs2.3.9.1/mm/slab.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22853@@ -337,6 +337,8 @@ static void kmem_cache_node_init(struct
4bf69007
AM
22854 #define STATS_INC_FREEMISS(x) do { } while (0)
22855 #endif
22856
22857+#include "slab_vs.h"
2ba6f0dd 22858+
4bf69007
AM
22859 #if DEBUG
22860
22861 /*
927ca606 22862@@ -3183,6 +3185,7 @@ slab_alloc_node(struct kmem_cache *cache
4bf69007
AM
22863 /* ___cache_alloc_node can fall back to other nodes */
22864 ptr = ____cache_alloc_node(cachep, flags, nodeid);
22865 out:
22866+ vx_slab_alloc(cachep, flags);
22867 local_irq_restore(save_flags);
22868 ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
22869 kmemleak_alloc_recursive(ptr, cachep->object_size, 1, cachep->flags,
927ca606 22870@@ -3371,6 +3374,7 @@ static inline void __cache_free(struct k
4bf69007
AM
22871 check_irq_off();
22872 kmemleak_free_recursive(objp, cachep->flags);
22873 objp = cache_free_debugcheck(cachep, objp, caller);
22874+ vx_slab_free(cachep);
22875
22876 kmemcheck_slab_free(cachep, objp, cachep->object_size);
22877
f19bd705
AM
22878diff -NurpP --minimal linux-4.4.111/mm/slab_vs.h linux-4.4.111-vs2.3.9.1/mm/slab_vs.h
22879--- linux-4.4.111/mm/slab_vs.h 1970-01-01 00:00:00.000000000 +0000
22880+++ linux-4.4.111-vs2.3.9.1/mm/slab_vs.h 2018-01-09 16:36:34.000000000 +0000
4bf69007 22881@@ -0,0 +1,29 @@
2ba6f0dd 22882+
4bf69007 22883+#include <linux/vserver/context.h>
2ba6f0dd 22884+
4bf69007 22885+#include <linux/vs_context.h>
2ba6f0dd 22886+
4bf69007
AM
22887+static inline
22888+void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
22889+{
22890+ int what = gfp_zone(cachep->allocflags);
22891+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 22892+
4bf69007
AM
22893+ if (!vxi)
22894+ return;
2ba6f0dd 22895+
4bf69007
AM
22896+ atomic_add(cachep->size, &vxi->cacct.slab[what]);
22897+}
2ba6f0dd 22898+
4bf69007
AM
22899+static inline
22900+void vx_slab_free(struct kmem_cache *cachep)
22901+{
22902+ int what = gfp_zone(cachep->allocflags);
22903+ struct vx_info *vxi = current_vx_info();
2ba6f0dd 22904+
4bf69007
AM
22905+ if (!vxi)
22906+ return;
2ba6f0dd 22907+
4bf69007
AM
22908+ atomic_sub(cachep->size, &vxi->cacct.slab[what]);
22909+}
2ba6f0dd 22910+
f19bd705
AM
22911diff -NurpP --minimal linux-4.4.111/mm/swapfile.c linux-4.4.111-vs2.3.9.1/mm/swapfile.c
22912--- linux-4.4.111/mm/swapfile.c 2018-01-11 07:57:53.000000000 +0000
22913+++ linux-4.4.111-vs2.3.9.1/mm/swapfile.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
22914@@ -39,6 +39,7 @@
22915 #include <asm/tlbflush.h>
22916 #include <linux/swapops.h>
927ca606 22917 #include <linux/swap_cgroup.h>
4bf69007
AM
22918+#include <linux/vs_base.h>
22919
22920 static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
22921 unsigned char);
927ca606 22922@@ -2070,6 +2071,16 @@ static int swap_show(struct seq_file *sw
4bf69007
AM
22923
22924 if (si == SEQ_START_TOKEN) {
22925 seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
22926+ if (vx_flags(VXF_VIRT_MEM, 0)) {
927ca606 22927+ struct sysinfo si = { 0 };
2ba6f0dd 22928+
4bf69007
AM
22929+ vx_vsi_swapinfo(&si);
22930+ if (si.totalswap < (1 << 10))
22931+ return 0;
22932+ seq_printf(swap, "%s\t\t\t\t\t%s\t%lu\t%lu\t%d\n",
22933+ "hdv0", "partition", si.totalswap >> 10,
22934+ (si.totalswap - si.freeswap) >> 10, -1);
22935+ }
22936 return 0;
22937 }
22938
927ca606 22939@@ -2609,6 +2620,8 @@ void si_swapinfo(struct sysinfo *val)
b00e13aa 22940 val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
4bf69007
AM
22941 val->totalswap = total_swap_pages + nr_to_be_unused;
22942 spin_unlock(&swap_lock);
22943+ if (vx_flags(VXF_VIRT_MEM, 0))
22944+ vx_vsi_swapinfo(val);
22945 }
22946
22947 /*
f19bd705
AM
22948diff -NurpP --minimal linux-4.4.111/net/bridge/br_multicast.c linux-4.4.111-vs2.3.9.1/net/bridge/br_multicast.c
22949--- linux-4.4.111/net/bridge/br_multicast.c 2018-01-11 07:57:54.000000000 +0000
22950+++ linux-4.4.111-vs2.3.9.1/net/bridge/br_multicast.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22951@@ -462,7 +462,7 @@ static struct sk_buff *br_ip6_multicast_
4bf69007
AM
22952 ip6h->hop_limit = 1;
22953 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
22954 if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
22955- &ip6h->saddr)) {
22956+ &ip6h->saddr, NULL)) {
22957 kfree_skb(skb);
927ca606 22958 br->has_ipv6_addr = 0;
4bf69007 22959 return NULL;
f19bd705
AM
22960diff -NurpP --minimal linux-4.4.111/net/core/dev.c linux-4.4.111-vs2.3.9.1/net/core/dev.c
22961--- linux-4.4.111/net/core/dev.c 2018-01-11 07:57:54.000000000 +0000
22962+++ linux-4.4.111-vs2.3.9.1/net/core/dev.c 2018-01-09 16:36:34.000000000 +0000
927ca606 22963@@ -124,6 +124,7 @@
4bf69007
AM
22964 #include <linux/in.h>
22965 #include <linux/jhash.h>
22966 #include <linux/random.h>
22967+#include <linux/vs_inet.h>
22968 #include <trace/events/napi.h>
22969 #include <trace/events/net.h>
22970 #include <trace/events/skb.h>
927ca606 22971@@ -726,7 +727,8 @@ struct net_device *__dev_get_by_name(str
4bf69007
AM
22972 struct hlist_head *head = dev_name_hash(net, name);
22973
b00e13aa 22974 hlist_for_each_entry(dev, head, name_hlist)
4bf69007
AM
22975- if (!strncmp(dev->name, name, IFNAMSIZ))
22976+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
22977+ nx_dev_visible(current_nx_info(), dev))
22978 return dev;
22979
22980 return NULL;
927ca606 22981@@ -751,7 +753,8 @@ struct net_device *dev_get_by_name_rcu(s
4bf69007
AM
22982 struct hlist_head *head = dev_name_hash(net, name);
22983
b00e13aa 22984 hlist_for_each_entry_rcu(dev, head, name_hlist)
4bf69007
AM
22985- if (!strncmp(dev->name, name, IFNAMSIZ))
22986+ if (!strncmp(dev->name, name, IFNAMSIZ) &&
22987+ nx_dev_visible(current_nx_info(), dev))
22988 return dev;
22989
22990 return NULL;
927ca606 22991@@ -801,7 +804,8 @@ struct net_device *__dev_get_by_index(st
4bf69007
AM
22992 struct hlist_head *head = dev_index_hash(net, ifindex);
22993
b00e13aa 22994 hlist_for_each_entry(dev, head, index_hlist)
4bf69007
AM
22995- if (dev->ifindex == ifindex)
22996+ if ((dev->ifindex == ifindex) &&
22997+ nx_dev_visible(current_nx_info(), dev))
22998 return dev;
22999
23000 return NULL;
927ca606 23001@@ -819,7 +823,7 @@ EXPORT_SYMBOL(__dev_get_by_index);
4bf69007
AM
23002 * about locking. The caller must hold RCU lock.
23003 */
23004
23005-struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23006+struct net_device *dev_get_by_index_real_rcu(struct net *net, int ifindex)
23007 {
4bf69007 23008 struct net_device *dev;
b00e13aa 23009 struct hlist_head *head = dev_index_hash(net, ifindex);
927ca606 23010@@ -830,6 +834,16 @@ struct net_device *dev_get_by_index_rcu(
4bf69007
AM
23011
23012 return NULL;
23013 }
23014+EXPORT_SYMBOL(dev_get_by_index_real_rcu);
2ba6f0dd 23015+
4bf69007
AM
23016+struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
23017+{
23018+ struct net_device *dev = dev_get_by_index_real_rcu(net, ifindex);
2ba6f0dd 23019+
4bf69007
AM
23020+ if (nx_dev_visible(current_nx_info(), dev))
23021+ return dev;
23022+ return NULL;
23023+}
23024 EXPORT_SYMBOL(dev_get_by_index_rcu);
23025
23026
927ca606 23027@@ -912,7 +926,8 @@ struct net_device *dev_getbyhwaddr_rcu(s
4bf69007
AM
23028
23029 for_each_netdev_rcu(net, dev)
23030 if (dev->type == type &&
23031- !memcmp(dev->dev_addr, ha, dev->addr_len))
23032+ !memcmp(dev->dev_addr, ha, dev->addr_len) &&
23033+ nx_dev_visible(current_nx_info(), dev))
23034 return dev;
23035
23036 return NULL;
927ca606 23037@@ -924,9 +939,11 @@ struct net_device *__dev_getfirstbyhwtyp
4bf69007
AM
23038 struct net_device *dev;
23039
23040 ASSERT_RTNL();
23041- for_each_netdev(net, dev)
23042- if (dev->type == type)
23043+ for_each_netdev(net, dev) {
23044+ if ((dev->type == type) &&
23045+ nx_dev_visible(current_nx_info(), dev))
23046 return dev;
23047+ }
23048
23049 return NULL;
23050 }
927ca606 23051@@ -938,7 +955,8 @@ struct net_device *dev_getfirstbyhwtype(
b00e13aa
AM
23052
23053 rcu_read_lock();
23054 for_each_netdev_rcu(net, dev)
23055- if (dev->type == type) {
23056+ if ((dev->type == type) &&
23057+ nx_dev_visible(current_nx_info(), dev)) {
23058 dev_hold(dev);
23059 ret = dev;
23060 break;
927ca606 23061@@ -968,7 +986,8 @@ struct net_device *__dev_get_by_flags(st
b00e13aa
AM
23062
23063 ret = NULL;
bb20add7 23064 for_each_netdev(net, dev) {
b00e13aa
AM
23065- if (((dev->flags ^ if_flags) & mask) == 0) {
23066+ if ((((dev->flags ^ if_flags) & mask) == 0) &&
23067+ nx_dev_visible(current_nx_info(), dev)) {
23068 ret = dev;
23069 break;
23070 }
927ca606 23071@@ -1046,6 +1065,8 @@ static int __dev_alloc_name(struct net *
4bf69007
AM
23072 continue;
23073 if (i < 0 || i >= max_netdevices)
23074 continue;
23075+ if (!nx_dev_visible(current_nx_info(), d))
23076+ continue;
23077
23078 /* avoid cases where sscanf is not exact inverse of printf */
23079 snprintf(buf, IFNAMSIZ, name, i);
f19bd705
AM
23080diff -NurpP --minimal linux-4.4.111/net/core/net-procfs.c linux-4.4.111-vs2.3.9.1/net/core/net-procfs.c
23081--- linux-4.4.111/net/core/net-procfs.c 2015-04-12 22:12:50.000000000 +0000
23082+++ linux-4.4.111-vs2.3.9.1/net/core/net-procfs.c 2018-01-09 16:36:34.000000000 +0000
8ce283e1
AM
23083@@ -1,6 +1,7 @@
23084 #include <linux/netdevice.h>
23085 #include <linux/proc_fs.h>
23086 #include <linux/seq_file.h>
23087+#include <linux/vs_inet.h>
23088 #include <net/wext.h>
23089
23090 #define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
23091@@ -77,8 +78,13 @@ static void dev_seq_stop(struct seq_file
23092 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
23093 {
23094 struct rtnl_link_stats64 temp;
23095- const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
23096+ const struct rtnl_link_stats64 *stats;
23097+
23098+ /* device visible inside network context? */
23099+ if (!nx_dev_visible(current_nx_info(), dev))
23100+ return;
23101
23102+ stats = dev_get_stats(dev, &temp);
23103 seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
23104 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
23105 dev->name, stats->rx_bytes, stats->rx_packets,
f19bd705
AM
23106diff -NurpP --minimal linux-4.4.111/net/core/rtnetlink.c linux-4.4.111-vs2.3.9.1/net/core/rtnetlink.c
23107--- linux-4.4.111/net/core/rtnetlink.c 2018-01-11 07:57:54.000000000 +0000
23108+++ linux-4.4.111-vs2.3.9.1/net/core/rtnetlink.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
23109@@ -1456,6 +1456,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
23110 hlist_for_each_entry(dev, head, index_hlist) {
4bf69007
AM
23111 if (idx < s_idx)
23112 goto cont;
23113+ if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
23114+ continue;
7ed51edd
JR
23115 err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
23116 NETLINK_CB(cb->skb).portid,
23117 cb->nlh->nlmsg_seq, 0,
927ca606
AM
23118@@ -2559,6 +2561,9 @@ void rtmsg_ifinfo(int type, struct net_d
23119 {
23120 struct sk_buff *skb;
4bf69007
AM
23121
23122+ if (!nx_dev_visible(current_nx_info(), dev))
23123+ return;
2ba6f0dd 23124+
927ca606
AM
23125 if (dev->reg_state != NETREG_REGISTERED)
23126 return;
23127
f19bd705
AM
23128diff -NurpP --minimal linux-4.4.111/net/core/sock.c linux-4.4.111-vs2.3.9.1/net/core/sock.c
23129--- linux-4.4.111/net/core/sock.c 2018-01-11 07:57:54.000000000 +0000
23130+++ linux-4.4.111-vs2.3.9.1/net/core/sock.c 2018-01-09 17:15:58.000000000 +0000
927ca606
AM
23131@@ -134,6 +134,10 @@
23132 #include <linux/sock_diag.h>
4bf69007
AM
23133
23134 #include <linux/filter.h>
23135+#include <linux/vs_socket.h>
23136+#include <linux/vs_limit.h>
23137+#include <linux/vs_context.h>
23138+#include <linux/vs_network.h>
23139
23140 #include <trace/events/sock.h>
23141
927ca606 23142@@ -1363,6 +1367,8 @@ static struct sock *sk_prot_alloc(struct
4bf69007
AM
23143 goto out_free_sec;
23144 sk_tx_queue_clear(sk);
23145 }
23146+ sock_vx_init(sk);
23147+ sock_nx_init(sk);
23148
23149 return sk;
23150
927ca606 23151@@ -1469,6 +1475,11 @@ void sk_destruct(struct sock *sk)
4bf69007 23152 put_pid(sk->sk_peer_pid);
927ca606
AM
23153 if (likely(sk->sk_net_refcnt))
23154 put_net(sock_net(sk));
4bf69007
AM
23155+ vx_sock_dec(sk);
23156+ clr_vx_info(&sk->sk_vx_info);
23157+ sk->sk_xid = -1;
23158+ clr_nx_info(&sk->sk_nx_info);
23159+ sk->sk_nid = -1;
23160 sk_prot_free(sk->sk_prot_creator, sk);
23161 }
23162
927ca606 23163@@ -1521,6 +1532,8 @@ struct sock *sk_clone_lock(const struct
4bf69007 23164 /* SANITY */
927ca606
AM
23165 if (likely(newsk->sk_net_refcnt))
23166 get_net(sock_net(newsk));
4bf69007
AM
23167+ sock_vx_init(newsk);
23168+ sock_nx_init(newsk);
23169 sk_node_init(&newsk->sk_node);
23170 sock_lock_init(newsk);
23171 bh_lock_sock(newsk);
927ca606 23172@@ -1586,6 +1599,12 @@ struct sock *sk_clone_lock(const struct
4bf69007
AM
23173 smp_wmb();
23174 atomic_set(&newsk->sk_refcnt, 2);
23175
23176+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
23177+ newsk->sk_xid = sk->sk_xid;
23178+ vx_sock_inc(newsk);
23179+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
23180+ newsk->sk_nid = sk->sk_nid;
2ba6f0dd 23181+
4bf69007
AM
23182 /*
23183 * Increment the counter in the same struct proto as the master
23184 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
927ca606 23185@@ -2424,6 +2443,12 @@ void sock_init_data(struct socket *sock,
4bf69007
AM
23186
23187 sk->sk_stamp = ktime_set(-1L, 0);
23188
23189+ set_vx_info(&sk->sk_vx_info, current_vx_info());
23190+ sk->sk_xid = vx_current_xid();
23191+ vx_sock_inc(sk);
23192+ set_nx_info(&sk->sk_nx_info, current_nx_info());
23193+ sk->sk_nid = nx_current_nid();
2ba6f0dd 23194+
c2e5f7c8
JR
23195 #ifdef CONFIG_NET_RX_BUSY_POLL
23196 sk->sk_napi_id = 0;
23197 sk->sk_ll_usec = sysctl_net_busy_read;
f19bd705
AM
23198diff -NurpP --minimal linux-4.4.111/net/ipv4/af_inet.c linux-4.4.111-vs2.3.9.1/net/ipv4/af_inet.c
23199--- linux-4.4.111/net/ipv4/af_inet.c 2018-01-11 07:57:54.000000000 +0000
23200+++ linux-4.4.111-vs2.3.9.1/net/ipv4/af_inet.c 2018-01-09 17:11:11.000000000 +0000
927ca606 23201@@ -308,10 +308,15 @@ lookup_protocol:
4bf69007
AM
23202 }
23203
23204 err = -EPERM;
23205+ if ((protocol == IPPROTO_ICMP) &&
23206+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
23207+ goto override;
927ca606 23208+
b00e13aa
AM
23209 if (sock->type == SOCK_RAW && !kern &&
23210 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007 23211 goto out_rcu_unlock;
927ca606 23212
a4a22af8
AM
23213+override:
23214 sock->ops = answer->ops;
23215 answer_prot = answer->prot;
bb20add7 23216 answer_flags = answer->flags;
927ca606 23217@@ -425,6 +430,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23218 struct sock *sk = sock->sk;
23219 struct inet_sock *inet = inet_sk(sk);
b00e13aa 23220 struct net *net = sock_net(sk);
927ca606 23221+ struct nx_v4_sock_addr nsa;
4bf69007
AM
23222 unsigned short snum;
23223 int chk_addr_ret;
927ca606
AM
23224 u32 tb_id = RT_TABLE_LOCAL;
23225@@ -450,7 +456,11 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23226 }
23227
927ca606
AM
23228 tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id;
23229- chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id);
4bf69007
AM
23230+ err = v4_map_sock_addr(inet, addr, &nsa);
23231+ if (err)
23232+ goto out;
2ba6f0dd 23233+
927ca606 23234+ chk_addr_ret = inet_addr_type_table(net, nsa.saddr, tb_id);
4bf69007
AM
23235
23236 /* Not specified by any standard per-se, however it breaks too
23237 * many applications when removed. It is unfortunate since
927ca606 23238@@ -462,7 +472,7 @@ int inet_bind(struct socket *sock, struc
4bf69007 23239 err = -EADDRNOTAVAIL;
bb20add7 23240 if (!net->ipv4.sysctl_ip_nonlocal_bind &&
4bf69007
AM
23241 !(inet->freebind || inet->transparent) &&
23242- addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
23243+ nsa.saddr != htonl(INADDR_ANY) &&
23244 chk_addr_ret != RTN_LOCAL &&
23245 chk_addr_ret != RTN_MULTICAST &&
23246 chk_addr_ret != RTN_BROADCAST)
927ca606 23247@@ -488,7 +498,7 @@ int inet_bind(struct socket *sock, struc
4bf69007
AM
23248 if (sk->sk_state != TCP_CLOSE || inet->inet_num)
23249 goto out_release_sock;
23250
23251- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23252+ v4_set_sock_addr(inet, &nsa);
23253 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23254 inet->inet_saddr = 0; /* Use device */
23255
927ca606 23256@@ -708,11 +718,13 @@ int inet_getname(struct socket *sock, st
4bf69007
AM
23257 peer == 1))
23258 return -ENOTCONN;
23259 sin->sin_port = inet->inet_dport;
23260- sin->sin_addr.s_addr = inet->inet_daddr;
23261+ sin->sin_addr.s_addr =
23262+ nx_map_sock_lback(sk->sk_nx_info, inet->inet_daddr);
23263 } else {
23264 __be32 addr = inet->inet_rcv_saddr;
23265 if (!addr)
23266 addr = inet->inet_saddr;
23267+ addr = nx_map_sock_lback(sk->sk_nx_info, addr);
23268 sin->sin_port = inet->inet_sport;
23269 sin->sin_addr.s_addr = addr;
23270 }
927ca606
AM
23271@@ -896,6 +908,7 @@ static int inet_compat_ioctl(struct sock
23272 return err;
23273 }
23274 #endif
23275+#include <linux/vs_limit.h>
23276
23277 const struct proto_ops inet_stream_ops = {
23278 .family = PF_INET,
f19bd705
AM
23279diff -NurpP --minimal linux-4.4.111/net/ipv4/arp.c linux-4.4.111-vs2.3.9.1/net/ipv4/arp.c
23280--- linux-4.4.111/net/ipv4/arp.c 2018-01-11 07:57:54.000000000 +0000
23281+++ linux-4.4.111-vs2.3.9.1/net/ipv4/arp.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23282@@ -1290,6 +1290,7 @@ static void arp_format_neigh_entry(struc
4bf69007
AM
23283 struct net_device *dev = n->dev;
23284 int hatype = dev->type;
23285
23286+ /* FIXME: check for network context */
23287 read_lock(&n->lock);
23288 /* Convert hardware address to XX:XX:XX:XX ... form. */
23289 #if IS_ENABLED(CONFIG_AX25)
927ca606 23290@@ -1321,6 +1322,7 @@ static void arp_format_pneigh_entry(stru
4bf69007
AM
23291 int hatype = dev ? dev->type : 0;
23292 char tbuf[16];
23293
23294+ /* FIXME: check for network context */
23295 sprintf(tbuf, "%pI4", n->key);
23296 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
23297 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
f19bd705
AM
23298diff -NurpP --minimal linux-4.4.111/net/ipv4/devinet.c linux-4.4.111-vs2.3.9.1/net/ipv4/devinet.c
23299--- linux-4.4.111/net/ipv4/devinet.c 2018-01-11 07:57:54.000000000 +0000
23300+++ linux-4.4.111-vs2.3.9.1/net/ipv4/devinet.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23301@@ -538,6 +538,7 @@ struct in_device *inetdev_by_index(struc
4bf69007
AM
23302 }
23303 EXPORT_SYMBOL(inetdev_by_index);
23304
2ba6f0dd 23305+
4bf69007
AM
23306 /* Called only from RTNL semaphored context. No locks. */
23307
23308 struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
927ca606 23309@@ -992,6 +993,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23310
23311 in_dev = __in_dev_get_rtnl(dev);
23312 if (in_dev) {
23313+ struct nx_info *nxi = current_nx_info();
2ba6f0dd 23314+
4bf69007
AM
23315 if (tryaddrmatch) {
23316 /* Matthias Andree */
23317 /* compare label and address (4.4BSD style) */
927ca606 23318@@ -1000,6 +1003,8 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23319 This is checked above. */
23320 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23321 ifap = &ifa->ifa_next) {
23322+ if (!nx_v4_ifa_visible(nxi, ifa))
23323+ continue;
23324 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
23325 sin_orig.sin_addr.s_addr ==
23326 ifa->ifa_local) {
927ca606 23327@@ -1012,9 +1017,12 @@ int devinet_ioctl(struct net *net, unsig
4bf69007
AM
23328 comparing just the label */
23329 if (!ifa) {
23330 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
23331- ifap = &ifa->ifa_next)
23332+ ifap = &ifa->ifa_next) {
23333+ if (!nx_v4_ifa_visible(nxi, ifa))
23334+ continue;
23335 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
23336 break;
23337+ }
23338 }
23339 }
23340
927ca606 23341@@ -1168,6 +1176,8 @@ static int inet_gifconf(struct net_devic
4bf69007
AM
23342 goto out;
23343
23344 for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
23345+ if (!nx_v4_ifa_visible(current_nx_info(), ifa))
23346+ continue;
23347 if (!buf) {
23348 done += sizeof(ifr);
23349 continue;
927ca606 23350@@ -1573,6 +1583,7 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23351 struct net_device *dev;
23352 struct in_device *in_dev;
23353 struct in_ifaddr *ifa;
23354+ struct sock *sk = skb->sk;
23355 struct hlist_head *head;
4bf69007 23356
b00e13aa 23357 s_h = cb->args[0];
927ca606 23358@@ -1596,6 +1607,8 @@ static int inet_dump_ifaddr(struct sk_bu
4bf69007
AM
23359
23360 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
23361 ifa = ifa->ifa_next, ip_idx++) {
23362+ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa))
23363+ continue;
23364 if (ip_idx < s_ip_idx)
23365 continue;
23366 if (inet_fill_ifaddr(skb, ifa,
f19bd705
AM
23367diff -NurpP --minimal linux-4.4.111/net/ipv4/fib_trie.c linux-4.4.111-vs2.3.9.1/net/ipv4/fib_trie.c
23368--- linux-4.4.111/net/ipv4/fib_trie.c 2018-01-11 07:57:54.000000000 +0000
23369+++ linux-4.4.111-vs2.3.9.1/net/ipv4/fib_trie.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
23370@@ -2591,6 +2591,7 @@ static int fib_route_seq_show(struct seq
23371
23372 seq_setwidth(seq, 127);
23373
23374+ /* FIXME: check for network context? */
23375 if (fi)
23376 seq_printf(seq,
23377 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
f19bd705
AM
23378diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_connection_sock.c linux-4.4.111-vs2.3.9.1/net/ipv4/inet_connection_sock.c
23379--- linux-4.4.111/net/ipv4/inet_connection_sock.c 2018-01-11 07:57:54.000000000 +0000
23380+++ linux-4.4.111-vs2.3.9.1/net/ipv4/inet_connection_sock.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23381@@ -43,6 +43,37 @@ void inet_get_local_port_range(struct ne
4bf69007
AM
23382 }
23383 EXPORT_SYMBOL(inet_get_local_port_range);
23384
23385+int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23386+{
c2e5f7c8
JR
23387+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr,
23388+ sk2_rcv_saddr = sk2->sk_rcv_saddr;
2ba6f0dd 23389+
4bf69007
AM
23390+ if (inet_v6_ipv6only(sk2))
23391+ return 0;
2ba6f0dd 23392+
4bf69007
AM
23393+ if (sk1_rcv_saddr &&
23394+ sk2_rcv_saddr &&
23395+ sk1_rcv_saddr == sk2_rcv_saddr)
23396+ return 1;
2ba6f0dd 23397+
4bf69007
AM
23398+ if (sk1_rcv_saddr &&
23399+ !sk2_rcv_saddr &&
23400+ v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND))
23401+ return 1;
2ba6f0dd 23402+
4bf69007
AM
23403+ if (sk2_rcv_saddr &&
23404+ !sk1_rcv_saddr &&
23405+ v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND))
23406+ return 1;
2ba6f0dd 23407+
4bf69007
AM
23408+ if (!sk1_rcv_saddr &&
23409+ !sk2_rcv_saddr &&
23410+ nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info))
23411+ return 1;
2ba6f0dd 23412+
4bf69007
AM
23413+ return 0;
23414+}
2ba6f0dd 23415+
4bf69007
AM
23416 int inet_csk_bind_conflict(const struct sock *sk,
23417 const struct inet_bind_bucket *tb, bool relax)
23418 {
927ca606 23419@@ -70,15 +101,13 @@ int inet_csk_bind_conflict(const struct
b00e13aa
AM
23420 (sk2->sk_state != TCP_TIME_WAIT &&
23421 !uid_eq(uid, sock_i_uid(sk2))))) {
c2e5f7c8
JR
23422
23423- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23424- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
4bf69007
AM
23425+ if (ipv4_rcv_saddr_equal(sk, sk2))
23426 break;
23427 }
23428 if (!relax && reuse && sk2->sk_reuse &&
b00e13aa 23429 sk2->sk_state != TCP_LISTEN) {
c2e5f7c8
JR
23430
23431- if (!sk2->sk_rcv_saddr || !sk->sk_rcv_saddr ||
23432- sk2->sk_rcv_saddr == sk->sk_rcv_saddr)
b00e13aa
AM
23433+ if (ipv4_rcv_saddr_equal(sk, sk2))
23434 break;
23435 }
23436 }
f19bd705
AM
23437diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_diag.c linux-4.4.111-vs2.3.9.1/net/ipv4/inet_diag.c
23438--- linux-4.4.111/net/ipv4/inet_diag.c 2016-07-05 04:15:14.000000000 +0000
23439+++ linux-4.4.111-vs2.3.9.1/net/ipv4/inet_diag.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
23440@@ -31,6 +31,8 @@
23441
23442 #include <linux/inet.h>
23443 #include <linux/stddef.h>
23444+#include <linux/vs_network.h>
23445+#include <linux/vs_inet.h>
23446
23447 #include <linux/inet_diag.h>
23448 #include <linux/sock_diag.h>
927ca606 23449@@ -761,6 +763,8 @@ void inet_diag_dump_icsk(struct inet_has
4bf69007
AM
23450 if (!net_eq(sock_net(sk), net))
23451 continue;
23452
23453+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23454+ continue;
23455 if (num < s_num) {
23456 num++;
23457 continue;
927ca606 23458@@ -822,6 +826,8 @@ skip_listen_ht:
4bf69007
AM
23459
23460 if (!net_eq(sock_net(sk), net))
23461 continue;
23462+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23463+ continue;
23464 if (num < s_num)
23465 goto next_normal;
c2e5f7c8 23466 state = (sk->sk_state == TCP_TIME_WAIT) ?
f19bd705
AM
23467diff -NurpP --minimal linux-4.4.111/net/ipv4/inet_hashtables.c linux-4.4.111-vs2.3.9.1/net/ipv4/inet_hashtables.c
23468--- linux-4.4.111/net/ipv4/inet_hashtables.c 2016-07-05 04:15:14.000000000 +0000
23469+++ linux-4.4.111-vs2.3.9.1/net/ipv4/inet_hashtables.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23470@@ -23,6 +23,7 @@
4bf69007
AM
23471 #include <net/inet_connection_sock.h>
23472 #include <net/inet_hashtables.h>
23473 #include <net/secure_seq.h>
23474+#include <net/route.h>
23475 #include <net/ip.h>
23476
927ca606
AM
23477 static u32 inet_ehashfn(const struct net *net, const __be32 laddr,
23478@@ -183,6 +184,11 @@ static inline int compute_score(struct s
4bf69007
AM
23479 if (rcv_saddr != daddr)
23480 return -1;
b00e13aa 23481 score += 4;
4bf69007
AM
23482+ } else {
23483+ /* block non nx_info ips */
23484+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23485+ daddr, NXA_MASK_BIND))
23486+ return -1;
23487 }
23488 if (sk->sk_bound_dev_if) {
23489 if (sk->sk_bound_dev_if != dif)
927ca606 23490@@ -202,7 +208,6 @@ static inline int compute_score(struct s
4bf69007
AM
23491 * wildcarded during the search since they can never be otherwise.
23492 */
23493
23494-
23495 struct sock *__inet_lookup_listener(struct net *net,
23496 struct inet_hashinfo *hashinfo,
b00e13aa 23497 const __be32 saddr, __be16 sport,
927ca606 23498@@ -238,6 +243,7 @@ begin:
b00e13aa 23499 phash = next_pseudo_random32(phash);
4bf69007
AM
23500 }
23501 }
2ba6f0dd 23502+
4bf69007
AM
23503 /*
23504 * if the nulls value we got at the end of this lookup is
23505 * not the expected one, we must restart lookup.
f19bd705
AM
23506diff -NurpP --minimal linux-4.4.111/net/ipv4/netfilter.c linux-4.4.111-vs2.3.9.1/net/ipv4/netfilter.c
23507--- linux-4.4.111/net/ipv4/netfilter.c 2016-07-05 04:15:14.000000000 +0000
23508+++ linux-4.4.111-vs2.3.9.1/net/ipv4/netfilter.c 2018-01-09 16:36:34.000000000 +0000
09be7631 23509@@ -11,7 +11,7 @@
4bf69007
AM
23510 #include <linux/skbuff.h>
23511 #include <linux/gfp.h>
23512 #include <linux/export.h>
23513-#include <net/route.h>
23514+// #include <net/route.h>
23515 #include <net/xfrm.h>
23516 #include <net/ip.h>
23517 #include <net/netfilter/nf_queue.h>
f19bd705
AM
23518diff -NurpP --minimal linux-4.4.111/net/ipv4/raw.c linux-4.4.111-vs2.3.9.1/net/ipv4/raw.c
23519--- linux-4.4.111/net/ipv4/raw.c 2018-01-11 07:57:55.000000000 +0000
23520+++ linux-4.4.111-vs2.3.9.1/net/ipv4/raw.c 2018-01-09 17:06:10.000000000 +0000
927ca606 23521@@ -126,7 +126,7 @@ static struct sock *__raw_v4_lookup(stru
4bf69007
AM
23522
23523 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
23524 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
23525- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
23526+ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) &&
23527 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23528 goto found; /* gotcha */
23529 }
927ca606
AM
23530@@ -416,6 +416,12 @@ static int raw_send_hdrinc(struct sock *
23531 skb_transport_header(skb))->type);
23532 }
4bf69007
AM
23533
23534+ err = -EPERM;
23535+ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) &&
23536+ sk->sk_nx_info &&
23537+ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND))
23538+ goto error_free;
2ba6f0dd 23539+
927ca606
AM
23540 err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
23541 net, sk, skb, NULL, rt->dst.dev,
23542 dst_output);
23543@@ -626,6 +632,16 @@ static int raw_sendmsg(struct sock *sk,
4bf69007
AM
23544 goto done;
23545 }
23546
23547+ if (sk->sk_nx_info) {
23548+ rt = ip_v4_find_src(sock_net(sk), sk->sk_nx_info, &fl4);
23549+ if (IS_ERR(rt)) {
23550+ err = PTR_ERR(rt);
23551+ rt = NULL;
23552+ goto done;
23553+ }
23554+ ip_rt_put(rt);
23555+ }
2ba6f0dd 23556+
4bf69007 23557 security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
927ca606 23558 rt = ip_route_output_flow(net, &fl4, sk);
4bf69007 23559 if (IS_ERR(rt)) {
927ca606 23560@@ -704,17 +720,19 @@ static int raw_bind(struct sock *sk, str
4bf69007
AM
23561 {
23562 struct inet_sock *inet = inet_sk(sk);
23563 struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
23564+ struct nx_v4_sock_addr nsa = { 0 };
23565 int ret = -EINVAL;
23566 int chk_addr_ret;
23567
23568 if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
23569 goto out;
23570- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr);
23571+ v4_map_sock_addr(inet, addr, &nsa);
23572+ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr);
23573 ret = -EADDRNOTAVAIL;
23574- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
23575+ if (nsa.saddr && chk_addr_ret != RTN_LOCAL &&
23576 chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
23577 goto out;
23578- inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
23579+ v4_set_sock_addr(inet, &nsa);
23580 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
23581 inet->inet_saddr = 0; /* Use device */
23582 sk_dst_reset(sk);
927ca606 23583@@ -763,7 +781,8 @@ static int raw_recvmsg(struct sock *sk,
4bf69007
AM
23584 /* Copy the address. */
23585 if (sin) {
23586 sin->sin_family = AF_INET;
23587- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23588+ sin->sin_addr.s_addr =
23589+ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr);
23590 sin->sin_port = 0;
23591 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23592 *addr_len = sizeof(*sin);
927ca606 23593@@ -959,7 +978,8 @@ static struct sock *raw_get_first(struct
b00e13aa
AM
23594 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
23595 ++state->bucket) {
23596 sk_for_each(sk, &state->h->ht[state->bucket])
4bf69007
AM
23597- if (sock_net(sk) == seq_file_net(seq))
23598+ if ((sock_net(sk) == seq_file_net(seq)) &&
b00e13aa 23599+ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
4bf69007
AM
23600 goto found;
23601 }
23602 sk = NULL;
927ca606 23603@@ -975,7 +995,8 @@ static struct sock *raw_get_next(struct
4bf69007
AM
23604 sk = sk_next(sk);
23605 try_again:
23606 ;
23607- } while (sk && sock_net(sk) != seq_file_net(seq));
23608+ } while (sk && ((sock_net(sk) != seq_file_net(seq)) ||
23609+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23610
23611 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
23612 sk = sk_head(&state->h->ht[state->bucket]);
f19bd705
AM
23613diff -NurpP --minimal linux-4.4.111/net/ipv4/route.c linux-4.4.111-vs2.3.9.1/net/ipv4/route.c
23614--- linux-4.4.111/net/ipv4/route.c 2018-01-11 07:57:55.000000000 +0000
23615+++ linux-4.4.111-vs2.3.9.1/net/ipv4/route.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23616@@ -2226,7 +2226,7 @@ struct rtable *__ip_route_output_key_has
4bf69007
AM
23617
23618
23619 if (fl4->flowi4_oif) {
23620- dev_out = dev_get_by_index_rcu(net, fl4->flowi4_oif);
23621+ dev_out = dev_get_by_index_real_rcu(net, fl4->flowi4_oif);
23622 rth = ERR_PTR(-ENODEV);
927ca606 23623 if (!dev_out)
4bf69007 23624 goto out;
f19bd705
AM
23625diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp.c linux-4.4.111-vs2.3.9.1/net/ipv4/tcp.c
23626--- linux-4.4.111/net/ipv4/tcp.c 2018-01-11 07:57:55.000000000 +0000
23627+++ linux-4.4.111-vs2.3.9.1/net/ipv4/tcp.c 2018-01-09 16:36:34.000000000 +0000
927ca606 23628@@ -269,6 +269,7 @@
4bf69007
AM
23629 #include <linux/crypto.h>
23630 #include <linux/time.h>
23631 #include <linux/slab.h>
23632+#include <linux/in.h>
23633
23634 #include <net/icmp.h>
23635 #include <net/inet_common.h>
f19bd705
AM
23636diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp_ipv4.c linux-4.4.111-vs2.3.9.1/net/ipv4/tcp_ipv4.c
23637--- linux-4.4.111/net/ipv4/tcp_ipv4.c 2018-01-11 07:57:55.000000000 +0000
23638+++ linux-4.4.111-vs2.3.9.1/net/ipv4/tcp_ipv4.c 2018-01-09 17:13:45.000000000 +0000
927ca606
AM
23639@@ -1885,6 +1885,10 @@ static void *listening_get_next(struct s
23640 sk = sk_nulls_next(sk);
4bf69007
AM
23641 get_sk:
23642 sk_nulls_for_each_from(sk, node) {
23643+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
23644+ sk, sk->sk_nid, nx_current_nid());
23645+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23646+ continue;
23647 if (!net_eq(sock_net(sk), net))
23648 continue;
23649 if (sk->sk_family == st->family) {
927ca606 23650@@ -1949,6 +1953,11 @@ static void *established_get_first(struc
4bf69007
AM
23651
23652 spin_lock_bh(lock);
23653 sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
23654+ vxdprintk(VXD_CBIT(net, 6),
23655+ "sk,egf: %p [#%d] (from %d)",
23656+ sk, sk->sk_nid, nx_current_nid());
23657+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23658+ continue;
23659 if (sk->sk_family != st->family ||
23660 !net_eq(sock_net(sk), net)) {
23661 continue;
927ca606 23662@@ -1975,6 +1984,11 @@ static void *established_get_next(struct
c2e5f7c8 23663 sk = sk_nulls_next(sk);
4bf69007
AM
23664
23665 sk_nulls_for_each_from(sk, node) {
23666+ vxdprintk(VXD_CBIT(net, 6),
23667+ "sk,egn: %p [#%d] (from %d)",
23668+ sk, sk->sk_nid, nx_current_nid());
23669+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23670+ continue;
23671 if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
c2e5f7c8 23672 return sk;
4bf69007 23673 }
927ca606 23674@@ -2166,9 +2180,9 @@ static void get_openreq4(const struct re
4bf69007 23675 seq_printf(f, "%4d: %08X:%04X %08X:%04X"
c2e5f7c8 23676 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
4bf69007 23677 i,
c2e5f7c8
JR
23678- ireq->ir_loc_addr,
23679+ nx_map_sock_lback(current_nx_info(), ireq->ir_loc_addr),
927ca606 23680 ireq->ir_num,
c2e5f7c8
JR
23681- ireq->ir_rmt_addr,
23682+ nx_map_sock_lback(current_nx_info(), ireq->ir_rmt_addr),
23683 ntohs(ireq->ir_rmt_port),
4bf69007
AM
23684 TCP_SYN_RECV,
23685 0, 0, /* could print option size, but that is af dependent. */
927ca606 23686@@ -2191,8 +2205,8 @@ static void get_tcp4_sock(struct sock *s
4bf69007
AM
23687 const struct inet_connection_sock *icsk = inet_csk(sk);
23688 const struct inet_sock *inet = inet_sk(sk);
927ca606 23689 const struct fastopen_queue *fastopenq = &icsk->icsk_accept_queue.fastopenq;
4bf69007
AM
23690- __be32 dest = inet->inet_daddr;
23691- __be32 src = inet->inet_rcv_saddr;
23692+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23693+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23694 __u16 destp = ntohs(inet->inet_dport);
23695 __u16 srcp = ntohs(inet->inet_sport);
23696 int rx_queue;
927ca606
AM
23697@@ -2251,8 +2265,8 @@ static void get_timewait4_sock(const str
23698 __be32 dest, src;
4bf69007 23699 __u16 destp, srcp;
4bf69007
AM
23700
23701- dest = tw->tw_daddr;
23702- src = tw->tw_rcv_saddr;
23703+ dest = nx_map_sock_lback(current_nx_info(), tw->tw_daddr);
23704+ src = nx_map_sock_lback(current_nx_info(), tw->tw_rcv_saddr);
23705 destp = ntohs(tw->tw_dport);
23706 srcp = ntohs(tw->tw_sport);
23707
f19bd705
AM
23708diff -NurpP --minimal linux-4.4.111/net/ipv4/tcp_minisocks.c linux-4.4.111-vs2.3.9.1/net/ipv4/tcp_minisocks.c
23709--- linux-4.4.111/net/ipv4/tcp_minisocks.c 2018-01-11 07:57:55.000000000 +0000
23710+++ linux-4.4.111-vs2.3.9.1/net/ipv4/tcp_minisocks.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
23711@@ -23,6 +23,9 @@
23712 #include <linux/slab.h>
23713 #include <linux/sysctl.h>
23714 #include <linux/workqueue.h>
23715+#include <linux/vs_limit.h>
23716+#include <linux/vs_socket.h>
23717+#include <linux/vs_context.h>
23718 #include <net/tcp.h>
23719 #include <net/inet_common.h>
23720 #include <net/xfrm.h>
927ca606 23721@@ -291,6 +294,11 @@ void tcp_time_wait(struct sock *sk, int
b00e13aa 23722 tcptw->tw_ts_offset = tp->tsoffset;
927ca606 23723 tcptw->tw_last_oow_ack_time = 0;
4bf69007
AM
23724
23725+ tw->tw_xid = sk->sk_xid;
23726+ tw->tw_vx_info = NULL;
23727+ tw->tw_nid = sk->sk_nid;
23728+ tw->tw_nx_info = NULL;
2ba6f0dd 23729+
4bf69007
AM
23730 #if IS_ENABLED(CONFIG_IPV6)
23731 if (tw->tw_family == PF_INET6) {
23732 struct ipv6_pinfo *np = inet6_sk(sk);
f19bd705
AM
23733diff -NurpP --minimal linux-4.4.111/net/ipv4/udp.c linux-4.4.111-vs2.3.9.1/net/ipv4/udp.c
23734--- linux-4.4.111/net/ipv4/udp.c 2018-01-11 07:57:55.000000000 +0000
23735+++ linux-4.4.111-vs2.3.9.1/net/ipv4/udp.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 23736@@ -309,14 +309,7 @@ fail:
4bf69007
AM
23737 }
23738 EXPORT_SYMBOL(udp_lib_get_port);
23739
23740-static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
23741-{
23742- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
23743-
23744- return (!ipv6_only_sock(sk2) &&
23745- (!inet1->inet_rcv_saddr || !inet2->inet_rcv_saddr ||
23746- inet1->inet_rcv_saddr == inet2->inet_rcv_saddr));
23747-}
23748+extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
23749
927ca606
AM
23750 static u32 udp4_portaddr_hash(const struct net *net, __be32 saddr,
23751 unsigned int port)
23752@@ -355,6 +348,11 @@ static inline int compute_score(struct s
23753 if (inet->inet_rcv_saddr != daddr)
23754 return -1;
23755 score += 4;
4bf69007
AM
23756+ } else {
23757+ /* block non nx_info ips */
23758+ if (!v4_addr_in_nx_info(sk->sk_nx_info,
23759+ daddr, NXA_MASK_BIND))
23760+ return -1;
927ca606
AM
23761 }
23762
23763 if (inet->inet_daddr) {
23764@@ -489,6 +487,7 @@ begin:
4bf69007
AM
23765 return result;
23766 }
23767
2ba6f0dd 23768+
4bf69007
AM
23769 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
23770 * harder than this. -DaveM
23771 */
927ca606 23772@@ -535,6 +534,11 @@ begin:
4bf69007
AM
23773 sk_nulls_for_each_rcu(sk, node, &hslot->head) {
23774 score = compute_score(sk, net, saddr, hnum, sport,
23775 daddr, dport, dif);
23776+ /* FIXME: disabled?
23777+ if (score == 9) {
23778+ result = sk;
23779+ break;
23780+ } else */
23781 if (score > badness) {
23782 result = sk;
23783 badness = score;
927ca606 23784@@ -559,6 +563,7 @@ begin:
4bf69007
AM
23785 if (get_nulls_value(node) != slot)
23786 goto begin;
23787
2ba6f0dd 23788+
4bf69007
AM
23789 if (result) {
23790 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
23791 result = NULL;
927ca606 23792@@ -568,6 +573,7 @@ begin:
4bf69007
AM
23793 goto begin;
23794 }
23795 }
2ba6f0dd 23796+
4bf69007
AM
23797 rcu_read_unlock();
23798 return result;
23799 }
927ca606 23800@@ -602,7 +608,7 @@ static inline bool __udp_is_mcast_sock(s
c2e5f7c8
JR
23801 udp_sk(sk)->udp_port_hash != hnum ||
23802 (inet->inet_daddr && inet->inet_daddr != rmt_addr) ||
23803 (inet->inet_dport != rmt_port && inet->inet_dport) ||
23804- (inet->inet_rcv_saddr && inet->inet_rcv_saddr != loc_addr) ||
23805+ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) ||
23806 ipv6_only_sock(sk) ||
23807 (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
23808 return false;
927ca606
AM
23809@@ -1033,6 +1039,16 @@ int udp_sendmsg(struct sock *sk, struct
23810 goto out;
23811 }
4bf69007
AM
23812
23813+ if (sk->sk_nx_info) {
23814+ rt = ip_v4_find_src(net, sk->sk_nx_info, fl4);
23815+ if (IS_ERR(rt)) {
23816+ err = PTR_ERR(rt);
23817+ rt = NULL;
23818+ goto out;
23819+ }
23820+ ip_rt_put(rt);
23821+ }
2ba6f0dd 23822+
4bf69007
AM
23823 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
23824 rt = ip_route_output_flow(net, fl4, sk);
23825 if (IS_ERR(rt)) {
927ca606 23826@@ -1337,7 +1353,8 @@ try_again:
4bf69007
AM
23827 if (sin) {
23828 sin->sin_family = AF_INET;
23829 sin->sin_port = udp_hdr(skb)->source;
23830- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
23831+ sin->sin_addr.s_addr = nx_map_sock_lback(
23832+ skb->sk->sk_nx_info, ip_hdr(skb)->saddr);
23833 memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
c2e5f7c8 23834 *addr_len = sizeof(*sin);
4bf69007 23835 }
927ca606 23836@@ -2319,6 +2336,8 @@ static struct sock *udp_get_first(struct
4bf69007
AM
23837 sk_nulls_for_each(sk, node, &hslot->head) {
23838 if (!net_eq(sock_net(sk), net))
23839 continue;
23840+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
23841+ continue;
23842 if (sk->sk_family == state->family)
23843 goto found;
23844 }
927ca606 23845@@ -2336,7 +2355,9 @@ static struct sock *udp_get_next(struct
4bf69007
AM
23846
23847 do {
23848 sk = sk_nulls_next(sk);
23849- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
23850+ } while (sk && (!net_eq(sock_net(sk), net) ||
23851+ sk->sk_family != state->family ||
23852+ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)));
23853
23854 if (!sk) {
23855 if (state->bucket <= state->udp_table->mask)
927ca606 23856@@ -2432,8 +2453,8 @@ static void udp4_format_sock(struct sock
c2e5f7c8 23857 int bucket)
4bf69007
AM
23858 {
23859 struct inet_sock *inet = inet_sk(sp);
23860- __be32 dest = inet->inet_daddr;
23861- __be32 src = inet->inet_rcv_saddr;
23862+ __be32 dest = nx_map_sock_lback(current_nx_info(), inet->inet_daddr);
23863+ __be32 src = nx_map_sock_lback(current_nx_info(), inet->inet_rcv_saddr);
23864 __u16 destp = ntohs(inet->inet_dport);
23865 __u16 srcp = ntohs(inet->inet_sport);
23866
f19bd705
AM
23867diff -NurpP --minimal linux-4.4.111/net/ipv6/addrconf.c linux-4.4.111-vs2.3.9.1/net/ipv6/addrconf.c
23868--- linux-4.4.111/net/ipv6/addrconf.c 2018-01-11 07:57:55.000000000 +0000
23869+++ linux-4.4.111-vs2.3.9.1/net/ipv6/addrconf.c 2018-01-09 23:41:55.000000000 +0000
927ca606 23870@@ -92,6 +92,8 @@
4bf69007
AM
23871 #include <linux/proc_fs.h>
23872 #include <linux/seq_file.h>
23873 #include <linux/export.h>
23874+#include <linux/vs_network.h>
23875+#include <linux/vs_inet6.h>
23876
23877 /* Set to 3 to get tracing... */
23878 #define ACONF_DEBUG 2
927ca606
AM
23879@@ -1442,7 +1444,8 @@ static int __ipv6_dev_get_saddr(struct n
23880 struct ipv6_saddr_dst *dst,
23881 struct inet6_dev *idev,
23882 struct ipv6_saddr_score *scores,
23883- int hiscore_idx)
23884+ int hiscore_idx,
23885+ struct nx_info *nxi)
23886 {
23887 struct ipv6_saddr_score *score = &scores[1 - hiscore_idx], *hiscore = &scores[hiscore_idx];
23888
23889@@ -1472,6 +1475,8 @@ static int __ipv6_dev_get_saddr(struct n
23890 idev->dev->name);
23891 continue;
23892 }
23893+ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1))
23894+ continue;
23895
23896 score->rule = -1;
23897 bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX);
23898@@ -1519,7 +1524,7 @@ out:
4bf69007
AM
23899
23900 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
23901 const struct in6_addr *daddr, unsigned int prefs,
23902- struct in6_addr *saddr)
23903+ struct in6_addr *saddr, struct nx_info *nxi)
23904 {
927ca606
AM
23905 struct ipv6_saddr_score scores[2], *hiscore;
23906 struct ipv6_saddr_dst dst;
23907@@ -1568,13 +1573,15 @@ int ipv6_dev_get_saddr(struct net *net,
23908
23909 if (use_oif_addr) {
23910 if (idev)
23911- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
23912+ hiscore_idx = __ipv6_dev_get_saddr(net, &dst,
23913+ idev, scores, hiscore_idx, nxi);
23914 } else {
23915 for_each_netdev_rcu(net, dev) {
23916 idev = __in6_dev_get(dev);
23917 if (!idev)
4bf69007 23918 continue;
927ca606
AM
23919- hiscore_idx = __ipv6_dev_get_saddr(net, &dst, idev, scores, hiscore_idx);
23920+ hiscore_idx = __ipv6_dev_get_saddr(net, &dst,
23921+ idev, scores, hiscore_idx, nxi);
23922 }
23923 }
23924 rcu_read_unlock();
23925@@ -3846,7 +3853,10 @@ static void if6_seq_stop(struct seq_file
4bf69007
AM
23926 static int if6_seq_show(struct seq_file *seq, void *v)
23927 {
23928 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
23929- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
2ba6f0dd 23930+
4bf69007
AM
23931+ if (nx_check(0, VS_ADMIN|VS_WATCH) ||
23932+ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1))
23933+ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
23934 &ifp->addr,
23935 ifp->idev->dev->ifindex,
23936 ifp->prefix_len,
927ca606 23937@@ -4430,6 +4440,11 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23938 struct ifacaddr6 *ifaca;
23939 int err = 1;
23940 int ip_idx = *p_ip_idx;
23941+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
2ba6f0dd 23942+
4bf69007
AM
23943+ /* disable ipv6 on non v6 guests */
23944+ if (nxi && !nx_info_has_v6(nxi))
23945+ return skb->len;
23946
23947 read_lock_bh(&idev->lock);
23948 switch (type) {
927ca606 23949@@ -4440,6 +4455,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23950 list_for_each_entry(ifa, &idev->addr_list, if_list) {
23951 if (++ip_idx < s_ip_idx)
23952 continue;
927ca606
AM
23953+ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1))
23954+ continue;
4bf69007
AM
23955 err = inet6_fill_ifaddr(skb, ifa,
23956 NETLINK_CB(cb->skb).portid,
23957 cb->nlh->nlmsg_seq,
927ca606 23958@@ -4457,6 +4474,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23959 ifmca = ifmca->next, ip_idx++) {
23960 if (ip_idx < s_ip_idx)
23961 continue;
927ca606
AM
23962+ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1))
23963+ continue;
4bf69007
AM
23964 err = inet6_fill_ifmcaddr(skb, ifmca,
23965 NETLINK_CB(cb->skb).portid,
23966 cb->nlh->nlmsg_seq,
927ca606 23967@@ -4472,6 +4491,8 @@ static int in6_dump_addrs(struct inet6_d
4bf69007
AM
23968 ifaca = ifaca->aca_next, ip_idx++) {
23969 if (ip_idx < s_ip_idx)
23970 continue;
927ca606
AM
23971+ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1))
23972+ continue;
4bf69007
AM
23973 err = inet6_fill_ifacaddr(skb, ifaca,
23974 NETLINK_CB(cb->skb).portid,
23975 cb->nlh->nlmsg_seq,
927ca606 23976@@ -4500,6 +4521,10 @@ static int inet6_dump_addr(struct sk_buf
4bf69007
AM
23977 struct inet6_dev *idev;
23978 struct hlist_head *head;
b00e13aa 23979
4bf69007
AM
23980+ /* FIXME: maybe disable ipv6 on non v6 guests?
23981+ if (skb->sk && skb->sk->sk_vx_info)
23982+ return skb->len; */
b00e13aa
AM
23983+
23984 s_h = cb->args[0];
23985 s_idx = idx = cb->args[1];
23986 s_ip_idx = ip_idx = cb->args[2];
927ca606 23987@@ -5008,6 +5033,7 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa
AM
23988 struct net_device *dev;
23989 struct inet6_dev *idev;
23990 struct hlist_head *head;
23991+ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL;
4bf69007
AM
23992
23993 s_h = cb->args[0];
23994 s_idx = cb->args[1];
927ca606 23995@@ -5019,6 +5045,8 @@ static int inet6_dump_ifinfo(struct sk_b
b00e13aa 23996 hlist_for_each_entry_rcu(dev, head, index_hlist) {
4bf69007
AM
23997 if (idx < s_idx)
23998 goto cont;
23999+ if (!v6_dev_in_nx_info(dev, nxi))
24000+ goto cont;
24001 idev = __in6_dev_get(dev);
24002 if (!idev)
24003 goto cont;
f19bd705
AM
24004diff -NurpP --minimal linux-4.4.111/net/ipv6/af_inet6.c linux-4.4.111-vs2.3.9.1/net/ipv6/af_inet6.c
24005--- linux-4.4.111/net/ipv6/af_inet6.c 2018-01-11 07:57:55.000000000 +0000
24006+++ linux-4.4.111-vs2.3.9.1/net/ipv6/af_inet6.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24007@@ -43,6 +43,8 @@
24008 #include <linux/netdevice.h>
24009 #include <linux/icmpv6.h>
24010 #include <linux/netfilter_ipv6.h>
24011+#include <linux/vs_inet.h>
24012+#include <linux/vs_inet6.h>
24013
24014 #include <net/ip.h>
24015 #include <net/ipv6.h>
927ca606 24016@@ -158,10 +160,13 @@ lookup_protocol:
4bf69007
AM
24017 }
24018
24019 err = -EPERM;
24020+ if ((protocol == IPPROTO_ICMPV6) &&
24021+ nx_capable(CAP_NET_RAW, NXC_RAW_ICMP))
24022+ goto override;
b00e13aa
AM
24023 if (sock->type == SOCK_RAW && !kern &&
24024 !ns_capable(net->user_ns, CAP_NET_RAW))
4bf69007
AM
24025 goto out_rcu_unlock;
24026-
24027+override:
24028 sock->ops = answer->ops;
24029 answer_prot = answer->prot;
bb20add7 24030 answer_flags = answer->flags;
927ca606 24031@@ -259,6 +264,7 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24032 struct inet_sock *inet = inet_sk(sk);
24033 struct ipv6_pinfo *np = inet6_sk(sk);
24034 struct net *net = sock_net(sk);
24035+ struct nx_v6_sock_addr nsa;
24036 __be32 v4addr = 0;
24037 unsigned short snum;
24038 int addr_type = 0;
927ca606 24039@@ -274,6 +280,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24040 if (addr->sin6_family != AF_INET6)
24041 return -EAFNOSUPPORT;
24042
24043+ err = v6_map_sock_addr(inet, addr, &nsa);
24044+ if (err)
24045+ return err;
2ba6f0dd 24046+
4bf69007
AM
24047 addr_type = ipv6_addr_type(&addr->sin6_addr);
24048 if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
24049 return -EINVAL;
927ca606 24050@@ -314,6 +324,10 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24051 err = -EADDRNOTAVAIL;
24052 goto out;
24053 }
24054+ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) {
24055+ err = -EADDRNOTAVAIL;
24056+ goto out;
24057+ }
24058 } else {
24059 if (addr_type != IPV6_ADDR_ANY) {
24060 struct net_device *dev = NULL;
927ca606 24061@@ -340,6 +354,11 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24062 }
24063 }
24064
24065+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24066+ err = -EADDRNOTAVAIL;
24067+ goto out_unlock;
24068+ }
2ba6f0dd 24069+
4bf69007
AM
24070 /* ipv4 addr of the socket is invalid. Only the
24071 * unspecified and mapped address have a v4 equivalent.
24072 */
927ca606 24073@@ -357,6 +376,9 @@ int inet6_bind(struct socket *sock, stru
4bf69007
AM
24074 }
24075 }
24076
24077+ /* what's that for? */
24078+ v6_set_sock_addr(inet, &nsa);
2ba6f0dd 24079+
4bf69007
AM
24080 inet->inet_rcv_saddr = v4addr;
24081 inet->inet_saddr = v4addr;
24082
927ca606 24083@@ -461,9 +483,11 @@ int inet6_getname(struct socket *sock, s
4bf69007
AM
24084 return -ENOTCONN;
24085 sin->sin6_port = inet->inet_dport;
c2e5f7c8 24086 sin->sin6_addr = sk->sk_v6_daddr;
4bf69007
AM
24087+ /* FIXME: remap lback? */
24088 if (np->sndflow)
24089 sin->sin6_flowinfo = np->flow_label;
24090 } else {
24091+ /* FIXME: remap lback? */
c2e5f7c8 24092 if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
4bf69007
AM
24093 sin->sin6_addr = np->saddr;
24094 else
f19bd705
AM
24095diff -NurpP --minimal linux-4.4.111/net/ipv6/datagram.c linux-4.4.111-vs2.3.9.1/net/ipv6/datagram.c
24096--- linux-4.4.111/net/ipv6/datagram.c 2018-01-11 07:57:55.000000000 +0000
24097+++ linux-4.4.111-vs2.3.9.1/net/ipv6/datagram.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24098@@ -733,7 +733,7 @@ int ip6_datagram_send_ctl(struct net *ne
4bf69007
AM
24099
24100 rcu_read_lock();
24101 if (fl6->flowi6_oif) {
24102- dev = dev_get_by_index_rcu(net, fl6->flowi6_oif);
24103+ dev = dev_get_by_index_real_rcu(net, fl6->flowi6_oif);
24104 if (!dev) {
24105 rcu_read_unlock();
24106 return -ENODEV;
f19bd705
AM
24107diff -NurpP --minimal linux-4.4.111/net/ipv6/fib6_rules.c linux-4.4.111-vs2.3.9.1/net/ipv6/fib6_rules.c
24108--- linux-4.4.111/net/ipv6/fib6_rules.c 2018-01-11 07:57:55.000000000 +0000
24109+++ linux-4.4.111-vs2.3.9.1/net/ipv6/fib6_rules.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 24110@@ -97,7 +97,7 @@ static int fib6_rule_action(struct fib_r
4bf69007
AM
24111 ip6_dst_idev(&rt->dst)->dev,
24112 &flp6->daddr,
24113 rt6_flags2srcprefs(flags),
24114- &saddr))
24115+ &saddr, NULL))
24116 goto again;
24117 if (!ipv6_prefix_equal(&saddr, &r->src.addr,
24118 r->src.plen))
f19bd705
AM
24119diff -NurpP --minimal linux-4.4.111/net/ipv6/inet6_hashtables.c linux-4.4.111-vs2.3.9.1/net/ipv6/inet6_hashtables.c
24120--- linux-4.4.111/net/ipv6/inet6_hashtables.c 2016-07-05 04:15:14.000000000 +0000
24121+++ linux-4.4.111-vs2.3.9.1/net/ipv6/inet6_hashtables.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24122@@ -16,6 +16,7 @@
24123
24124 #include <linux/module.h>
24125 #include <linux/random.h>
24126+#include <linux/vs_inet6.h>
24127
24128 #include <net/inet_connection_sock.h>
24129 #include <net/inet_hashtables.h>
927ca606 24130@@ -66,7 +67,6 @@ struct sock *__inet6_lookup_established(
4bf69007
AM
24131 unsigned int slot = hash & hashinfo->ehash_mask;
24132 struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
24133
24134-
24135 rcu_read_lock();
24136 begin:
24137 sk_nulls_for_each_rcu(sk, node, &head->chain) {
927ca606 24138@@ -108,6 +108,9 @@ static inline int compute_score(struct s
c2e5f7c8 24139 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
4bf69007
AM
24140 return -1;
24141 score++;
24142+ } else {
24143+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24144+ return -1;
24145 }
24146 if (sk->sk_bound_dev_if) {
24147 if (sk->sk_bound_dev_if != dif)
f19bd705
AM
24148diff -NurpP --minimal linux-4.4.111/net/ipv6/ip6_fib.c linux-4.4.111-vs2.3.9.1/net/ipv6/ip6_fib.c
24149--- linux-4.4.111/net/ipv6/ip6_fib.c 2018-01-11 07:57:55.000000000 +0000
24150+++ linux-4.4.111-vs2.3.9.1/net/ipv6/ip6_fib.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24151@@ -1968,6 +1968,7 @@ static int ipv6_route_seq_show(struct se
c2e5f7c8
JR
24152 struct rt6_info *rt = v;
24153 struct ipv6_route_iter *iter = seq->private;
24154
24155+ /* FIXME: check for network context? */
24156 seq_printf(seq, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
24157
24158 #ifdef CONFIG_IPV6_SUBTREES
f19bd705
AM
24159diff -NurpP --minimal linux-4.4.111/net/ipv6/ip6_output.c linux-4.4.111-vs2.3.9.1/net/ipv6/ip6_output.c
24160--- linux-4.4.111/net/ipv6/ip6_output.c 2018-01-11 07:57:55.000000000 +0000
24161+++ linux-4.4.111-vs2.3.9.1/net/ipv6/ip6_output.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
24162@@ -941,7 +941,8 @@ static int ip6_dst_lookup_tail(struct ne
24163 rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
4bf69007
AM
24164 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
24165 sk ? inet6_sk(sk)->srcprefs : 0,
24166- &fl6->saddr);
24167+ &fl6->saddr,
24168+ sk ? sk->sk_nx_info : NULL);
24169 if (err)
24170 goto out_err_release;
927ca606 24171
f19bd705
AM
24172diff -NurpP --minimal linux-4.4.111/net/ipv6/ndisc.c linux-4.4.111-vs2.3.9.1/net/ipv6/ndisc.c
24173--- linux-4.4.111/net/ipv6/ndisc.c 2016-07-05 04:15:14.000000000 +0000
24174+++ linux-4.4.111-vs2.3.9.1/net/ipv6/ndisc.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24175@@ -501,7 +501,7 @@ void ndisc_send_na(struct net_device *de
4bf69007
AM
24176 } else {
24177 if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
24178 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
24179- &tmpaddr))
24180+ &tmpaddr, NULL))
24181 return;
24182 src_addr = &tmpaddr;
24183 }
f19bd705
AM
24184diff -NurpP --minimal linux-4.4.111/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c linux-4.4.111-vs2.3.9.1/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
24185--- linux-4.4.111/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2016-07-05 04:15:14.000000000 +0000
24186+++ linux-4.4.111-vs2.3.9.1/net/ipv6/netfilter/nf_nat_masquerade_ipv6.c 2018-01-09 17:04:44.000000000 +0000
bb20add7 24187@@ -35,7 +35,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *s
4bf69007
AM
24188 ctinfo == IP_CT_RELATED_REPLY));
24189
927ca606 24190 if (ipv6_dev_get_saddr(nf_ct_net(ct), out,
4bf69007
AM
24191- &ipv6_hdr(skb)->daddr, 0, &src) < 0)
24192+ &ipv6_hdr(skb)->daddr, 0, &src, NULL) < 0)
24193 return NF_DROP;
24194
bb20add7 24195 nfct_nat(ct)->masq_index = out->ifindex;
f19bd705
AM
24196diff -NurpP --minimal linux-4.4.111/net/ipv6/raw.c linux-4.4.111-vs2.3.9.1/net/ipv6/raw.c
24197--- linux-4.4.111/net/ipv6/raw.c 2018-01-11 07:57:55.000000000 +0000
24198+++ linux-4.4.111-vs2.3.9.1/net/ipv6/raw.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24199@@ -30,6 +30,7 @@
24200 #include <linux/icmpv6.h>
24201 #include <linux/netfilter.h>
24202 #include <linux/netfilter_ipv6.h>
24203+#include <linux/vs_inet6.h>
24204 #include <linux/skbuff.h>
24205 #include <linux/compat.h>
927ca606 24206 #include <linux/uaccess.h>
bb20add7 24207@@ -291,6 +292,13 @@ static int rawv6_bind(struct sock *sk, s
4bf69007
AM
24208 goto out_unlock;
24209 }
24210
24211+ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) {
24212+ err = -EADDRNOTAVAIL;
24213+ if (dev)
24214+ dev_put(dev);
24215+ goto out;
24216+ }
2ba6f0dd 24217+
4bf69007
AM
24218 /* ipv4 addr of the socket is invalid. Only the
24219 * unspecified and mapped address have a v4 equivalent.
24220 */
f19bd705
AM
24221diff -NurpP --minimal linux-4.4.111/net/ipv6/route.c linux-4.4.111-vs2.3.9.1/net/ipv6/route.c
24222--- linux-4.4.111/net/ipv6/route.c 2018-01-11 07:57:55.000000000 +0000
24223+++ linux-4.4.111-vs2.3.9.1/net/ipv6/route.c 2018-01-09 17:03:24.000000000 +0000
927ca606
AM
24224@@ -62,6 +62,7 @@
24225 #include <net/lwtunnel.h>
24226 #include <net/ip_tunnels.h>
24227 #include <net/l3mdev.h>
4bf69007
AM
24228+#include <linux/vs_inet6.h>
24229
24230 #include <asm/uaccess.h>
24231
927ca606 24232@@ -2545,16 +2546,18 @@ int ip6_route_get_saddr(struct net *net,
4bf69007
AM
24233 struct rt6_info *rt,
24234 const struct in6_addr *daddr,
24235 unsigned int prefs,
24236- struct in6_addr *saddr)
24237+ struct in6_addr *saddr,
24238+ struct nx_info *nxi)
24239 {
927ca606
AM
24240 struct inet6_dev *idev =
24241 rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
4bf69007 24242 int err = 0;
927ca606
AM
24243- if (rt && rt->rt6i_prefsrc.plen)
24244+ if (rt && rt->rt6i_prefsrc.plen && (!nxi ||
4bf69007
AM
24245+ v6_addr_in_nx_info(nxi, &rt->rt6i_prefsrc.addr, NXA_TYPE_ADDR)))
24246 *saddr = rt->rt6i_prefsrc.addr;
24247 else
24248 err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
24249- daddr, prefs, saddr);
24250+ daddr, prefs, saddr, nxi);
24251 return err;
24252 }
24253
927ca606 24254@@ -3168,7 +3171,8 @@ static int rt6_fill_node(struct net *net
4bf69007
AM
24255 goto nla_put_failure;
24256 } else if (dst) {
24257 struct in6_addr saddr_buf;
24258- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
24259+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf,
24260+ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0 &&
927ca606 24261 nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf))
4bf69007
AM
24262 goto nla_put_failure;
24263 }
f19bd705
AM
24264diff -NurpP --minimal linux-4.4.111/net/ipv6/tcp_ipv6.c linux-4.4.111-vs2.3.9.1/net/ipv6/tcp_ipv6.c
24265--- linux-4.4.111/net/ipv6/tcp_ipv6.c 2018-01-11 07:57:55.000000000 +0000
24266+++ linux-4.4.111-vs2.3.9.1/net/ipv6/tcp_ipv6.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 24267@@ -69,6 +69,7 @@
4bf69007
AM
24268
24269 #include <linux/crypto.h>
24270 #include <linux/scatterlist.h>
24271+#include <linux/vs_inet6.h>
24272
927ca606
AM
24273 static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb);
24274 static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
24275@@ -150,11 +151,18 @@ static int tcp_v6_connect(struct sock *s
4bf69007
AM
24276 */
24277
927ca606
AM
24278 if (ipv6_addr_any(&usin->sin6_addr)) {
24279- if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24280- ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24281- &usin->sin6_addr);
24282- else
24283- usin->sin6_addr = in6addr_loopback;
4bf69007 24284+ struct nx_info *nxi = sk->sk_nx_info;
2ba6f0dd 24285+
4bf69007
AM
24286+ if (nxi && nx_info_has_v6(nxi))
24287+ /* FIXME: remap lback? */
24288+ usin->sin6_addr = nxi->v6.ip;
927ca606
AM
24289+ else {
24290+ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
24291+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
24292+ &usin->sin6_addr);
24293+ else
24294+ usin->sin6_addr = in6addr_loopback;
24295+ }
24296 }
4bf69007
AM
24297
24298 addr_type = ipv6_addr_type(&usin->sin6_addr);
f19bd705
AM
24299diff -NurpP --minimal linux-4.4.111/net/ipv6/udp.c linux-4.4.111-vs2.3.9.1/net/ipv6/udp.c
24300--- linux-4.4.111/net/ipv6/udp.c 2018-01-11 07:57:55.000000000 +0000
24301+++ linux-4.4.111-vs2.3.9.1/net/ipv6/udp.c 2018-01-09 16:36:34.000000000 +0000
c2e5f7c8 24302@@ -47,6 +47,7 @@
4bf69007 24303 #include <net/xfrm.h>
b00e13aa 24304 #include <net/inet6_hashtables.h>
c2e5f7c8 24305 #include <net/busy_poll.h>
4bf69007
AM
24306+#include <linux/vs_inet6.h>
24307
24308 #include <linux/proc_fs.h>
24309 #include <linux/seq_file.h>
927ca606
AM
24310@@ -76,32 +77,60 @@ static u32 udp6_ehashfn(const struct net
24311 udp_ipv6_hash_secret + net_hash_mix(net));
24312 }
24313
24314-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
24315+int ipv6_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
24316 {
24317+ const struct in6_addr *sk1_rcv_saddr6 = inet6_rcv_saddr(sk1);
24318 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
24319+ __be32 sk1_rcv_saddr = sk1->sk_rcv_saddr;
24320+ __be32 sk2_rcv_saddr = sk2->sk_rcv_saddr;
24321 int sk2_ipv6only = inet_v6_ipv6only(sk2);
24322- int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
24323+ int addr_type1 = ipv6_addr_type(sk1_rcv_saddr6);
24324 int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
24325
24326 /* if both are mapped, treat as IPv4 */
24327- if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
24328- return (!sk2_ipv6only &&
24329- (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24330- sk->sk_rcv_saddr == sk2->sk_rcv_saddr));
24331+ if (addr_type1 == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {
24332+ if (!sk2_ipv6only &&
24333+ (!sk1->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
24334+ sk1->sk_rcv_saddr == sk2->sk_rcv_saddr))
24335+ goto vs_v4;
24336+ else
24337+ return 0;
24338+ }
24339
24340 if (addr_type2 == IPV6_ADDR_ANY &&
24341- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
24342- return 1;
24343+ !(sk2_ipv6only && addr_type1 == IPV6_ADDR_MAPPED))
24344+ goto vs;
24345
24346- if (addr_type == IPV6_ADDR_ANY &&
24347- !(ipv6_only_sock(sk) && addr_type2 == IPV6_ADDR_MAPPED))
24348- return 1;
24349+ if (addr_type1 == IPV6_ADDR_ANY &&
24350+ !(ipv6_only_sock(sk1) && addr_type2 == IPV6_ADDR_MAPPED))
24351+ goto vs;
24352
24353 if (sk2_rcv_saddr6 &&
24354- ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24355- return 1;
24356+ ipv6_addr_equal(&sk1->sk_v6_rcv_saddr, sk2_rcv_saddr6))
24357+ goto vs;
24358
24359 return 0;
24360+
24361+vs_v4:
24362+ if (!sk1_rcv_saddr && !sk2_rcv_saddr)
24363+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24364+ if (!sk2_rcv_saddr)
24365+ return v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, -1);
24366+ if (!sk1_rcv_saddr)
24367+ return v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, -1);
24368+ return 1;
24369+vs:
24370+ if (addr_type2 == IPV6_ADDR_ANY && addr_type1 == IPV6_ADDR_ANY)
24371+ return nx_v6_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24372+ else if (addr_type2 == IPV6_ADDR_ANY)
24373+ return v6_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr6, -1);
24374+ else if (addr_type1 == IPV6_ADDR_ANY) {
24375+ if (addr_type2 == IPV6_ADDR_MAPPED)
24376+ return nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info);
24377+ else
24378+ return v6_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr6, -1);
24379+ }
24380+ return 1;
24381 }
24382
24383 static u32 udp6_portaddr_hash(const struct net *net,
24384@@ -162,6 +191,10 @@ static inline int compute_score(struct s
24385 if (inet->inet_dport != sport)
24386 return -1;
24387 score++;
4bf69007
AM
24388+ } else {
24389+ /* block non nx_info ips */
24390+ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1))
24391+ return -1;
927ca606
AM
24392 }
24393
24394 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
f19bd705
AM
24395diff -NurpP --minimal linux-4.4.111/net/ipv6/xfrm6_policy.c linux-4.4.111-vs2.3.9.1/net/ipv6/xfrm6_policy.c
24396--- linux-4.4.111/net/ipv6/xfrm6_policy.c 2016-07-05 04:15:14.000000000 +0000
24397+++ linux-4.4.111-vs2.3.9.1/net/ipv6/xfrm6_policy.c 2018-01-09 16:36:34.000000000 +0000
927ca606
AM
24398@@ -64,7 +64,8 @@ static int xfrm6_get_saddr(struct net *n
24399 return -EHOSTUNREACH;
24400
4bf69007 24401 dev = ip6_dst_idev(dst)->dev;
927ca606
AM
24402- ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6);
24403+ ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6,
24404+ 0, &saddr->in6, NULL);
4bf69007
AM
24405 dst_release(dst);
24406 return 0;
24407 }
f19bd705
AM
24408diff -NurpP --minimal linux-4.4.111/net/netfilter/ipvs/ip_vs_xmit.c linux-4.4.111-vs2.3.9.1/net/netfilter/ipvs/ip_vs_xmit.c
24409--- linux-4.4.111/net/netfilter/ipvs/ip_vs_xmit.c 2016-07-05 04:15:15.000000000 +0000
24410+++ linux-4.4.111-vs2.3.9.1/net/netfilter/ipvs/ip_vs_xmit.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24411@@ -381,7 +381,7 @@ __ip_vs_route_output_v6(struct net *net,
4bf69007
AM
24412 return dst;
24413 if (ipv6_addr_any(&fl6.saddr) &&
24414 ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
24415- &fl6.daddr, 0, &fl6.saddr) < 0)
24416+ &fl6.daddr, 0, &fl6.saddr, NULL) < 0)
24417 goto out_err;
24418 if (do_xfrm) {
24419 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
f19bd705
AM
24420diff -NurpP --minimal linux-4.4.111/net/netlink/af_netlink.c linux-4.4.111-vs2.3.9.1/net/netlink/af_netlink.c
24421--- linux-4.4.111/net/netlink/af_netlink.c 2018-01-11 07:57:56.000000000 +0000
24422+++ linux-4.4.111-vs2.3.9.1/net/netlink/af_netlink.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24423@@ -62,6 +62,8 @@
bb20add7
AM
24424 #include <asm/cacheflush.h>
24425 #include <linux/hash.h>
927ca606 24426 #include <linux/genetlink.h>
4bf69007
AM
24427+#include <linux/vs_context.h>
24428+#include <linux/vs_network.h>
4bf69007
AM
24429
24430 #include <net/net_namespace.h>
bb20add7 24431 #include <net/sock.h>
927ca606
AM
24432@@ -2460,7 +2462,8 @@ static void *__netlink_seq_next(struct s
24433 if (err)
24434 return ERR_PTR(err);
24435 }
24436- } while (sock_net(&nlk->sk) != seq_file_net(seq));
24437+ } while ((sock_net(&nlk->sk) != seq_file_net(seq)) ||
24438+ !nx_check(nlk->sk.sk_nid, VS_WATCH_P | VS_IDENT));
bb20add7 24439
927ca606
AM
24440 return nlk;
24441 }
f19bd705
AM
24442diff -NurpP --minimal linux-4.4.111/net/socket.c linux-4.4.111-vs2.3.9.1/net/socket.c
24443--- linux-4.4.111/net/socket.c 2018-01-11 07:57:56.000000000 +0000
24444+++ linux-4.4.111-vs2.3.9.1/net/socket.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24445@@ -99,10 +99,12 @@
4bf69007
AM
24446
24447 #include <net/sock.h>
24448 #include <linux/netfilter.h>
4bf69007
AM
24449+#include <linux/vs_socket.h>
24450+#include <linux/vs_inet.h>
24451+#include <linux/vs_inet6.h>
24452
24453 #include <linux/if_tun.h>
24454 #include <linux/ipv6_route.h>
927ca606
AM
24455-#include <linux/route.h>
24456 #include <linux/sockios.h>
24457 #include <linux/atalk.h>
24458 #include <net/busy_poll.h>
24459@@ -608,8 +610,24 @@ EXPORT_SYMBOL(__sock_tx_timestamp);
4bf69007 24460
927ca606
AM
24461 static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
24462 {
24463- int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
24464- BUG_ON(ret == -EIOCBQUEUED);
24465+ size_t size = msg_data_left(msg);
24466+ int ret = sock->ops->sendmsg(sock, msg, size);
24467+#if 0
4bf69007 24468+ if (sock->sk) {
927ca606 24469+ if (!ret)
4bf69007 24470+ vx_sock_fail(sock->sk, size);
927ca606
AM
24471+ else
24472+ vx_sock_send(sock->sk, size);
4bf69007 24473+ }
927ca606 24474+#endif
4bf69007 24475+ vxdprintk(VXD_CBIT(net, 7),
927ca606 24476+ "sock_sendmsg_nosec: %p[%p,%p,%p;%d/%d]:%zu/%zu",
4bf69007
AM
24477+ sock, sock->sk,
24478+ (sock->sk)?sock->sk->sk_nx_info:0,
24479+ (sock->sk)?sock->sk->sk_vx_info:0,
24480+ (sock->sk)?sock->sk->sk_xid:0,
24481+ (sock->sk)?sock->sk->sk_nid:0,
927ca606
AM
24482+ size, msg_data_left(msg));
24483 return ret;
4bf69007
AM
24484 }
24485
927ca606 24486@@ -1100,6 +1118,13 @@ int __sock_create(struct net *net, int f
4bf69007
AM
24487 if (type < 0 || type >= SOCK_MAX)
24488 return -EINVAL;
24489
24490+ if (!nx_check(0, VS_ADMIN)) {
24491+ if (family == PF_INET && !current_nx_info_has_v4())
24492+ return -EAFNOSUPPORT;
24493+ if (family == PF_INET6 && !current_nx_info_has_v6())
24494+ return -EAFNOSUPPORT;
24495+ }
2ba6f0dd 24496+
4bf69007
AM
24497 /* Compatibility.
24498
24499 This uglymoron is moved from INET layer to here to avoid
927ca606 24500@@ -1234,6 +1259,7 @@ SYSCALL_DEFINE3(socket, int, family, int
4bf69007
AM
24501 if (retval < 0)
24502 goto out;
24503
24504+ set_bit(SOCK_USER_SOCKET, &sock->flags);
24505 retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
24506 if (retval < 0)
24507 goto out_release;
927ca606 24508@@ -1275,10 +1301,12 @@ SYSCALL_DEFINE4(socketpair, int, family,
4bf69007
AM
24509 err = sock_create(family, type, protocol, &sock1);
24510 if (err < 0)
24511 goto out;
24512+ set_bit(SOCK_USER_SOCKET, &sock1->flags);
24513
24514 err = sock_create(family, type, protocol, &sock2);
24515 if (err < 0)
24516 goto out_release_1;
24517+ set_bit(SOCK_USER_SOCKET, &sock2->flags);
24518
24519 err = sock1->ops->socketpair(sock1, sock2);
24520 if (err < 0)
f19bd705
AM
24521diff -NurpP --minimal linux-4.4.111/net/sunrpc/auth.c linux-4.4.111-vs2.3.9.1/net/sunrpc/auth.c
24522--- linux-4.4.111/net/sunrpc/auth.c 2015-10-29 09:21:46.000000000 +0000
24523+++ linux-4.4.111-vs2.3.9.1/net/sunrpc/auth.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24524@@ -15,6 +15,7 @@
24525 #include <linux/sunrpc/clnt.h>
24526 #include <linux/sunrpc/gss_api.h>
24527 #include <linux/spinlock.h>
24528+#include <linux/vs_tag.h>
24529
927ca606 24530 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
4bf69007 24531 # define RPCDBG_FACILITY RPCDBG_AUTH
bb20add7 24532@@ -630,6 +631,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
4bf69007
AM
24533 memset(&acred, 0, sizeof(acred));
24534 acred.uid = cred->fsuid;
24535 acred.gid = cred->fsgid;
a4a22af8 24536+ acred.tag = make_ktag(&init_user_ns, dx_current_tag());
bb20add7 24537 acred.group_info = cred->group_info;
4bf69007 24538 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
bb20add7
AM
24539 return ret;
24540@@ -669,6 +671,7 @@ rpcauth_bind_root_cred(struct rpc_task *
4bf69007 24541 struct auth_cred acred = {
b00e13aa
AM
24542 .uid = GLOBAL_ROOT_UID,
24543 .gid = GLOBAL_ROOT_GID,
a4a22af8 24544+ .tag = KTAGT_INIT(dx_current_tag()),
4bf69007
AM
24545 };
24546
24547 dprintk("RPC: %5u looking up %s cred\n",
f19bd705
AM
24548diff -NurpP --minimal linux-4.4.111/net/sunrpc/auth_unix.c linux-4.4.111-vs2.3.9.1/net/sunrpc/auth_unix.c
24549--- linux-4.4.111/net/sunrpc/auth_unix.c 2016-07-05 04:12:45.000000000 +0000
24550+++ linux-4.4.111-vs2.3.9.1/net/sunrpc/auth_unix.c 2018-01-09 16:36:34.000000000 +0000
4bf69007
AM
24551@@ -13,11 +13,13 @@
24552 #include <linux/sunrpc/clnt.h>
24553 #include <linux/sunrpc/auth.h>
24554 #include <linux/user_namespace.h>
24555+#include <linux/vs_tag.h>
24556
24557 #define NFS_NGROUPS 16
24558
24559 struct unx_cred {
24560 struct rpc_cred uc_base;
b00e13aa
AM
24561+ ktag_t uc_tag;
24562 kgid_t uc_gid;
24563 kgid_t uc_gids[NFS_NGROUPS];
4bf69007 24564 };
b00e13aa 24565@@ -80,6 +82,7 @@ unx_create_cred(struct rpc_auth *auth, s
4bf69007
AM
24566 groups = NFS_NGROUPS;
24567
24568 cred->uc_gid = acred->gid;
24569+ cred->uc_tag = acred->tag;
b00e13aa
AM
24570 for (i = 0; i < groups; i++)
24571 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
24572 if (i < NFS_NGROUPS)
24573@@ -121,7 +124,9 @@ unx_match(struct auth_cred *acred, struc
4bf69007
AM
24574 unsigned int i;
24575
24576
b00e13aa
AM
24577- if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
24578+ if (!uid_eq(cred->uc_uid, acred->uid) ||
24579+ !gid_eq(cred->uc_gid, acred->gid) ||
24580+ !tag_eq(cred->uc_tag, acred->tag))
4bf69007
AM
24581 return 0;
24582
24583 if (acred->group_info != NULL)
b00e13aa 24584@@ -146,7 +151,7 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24585 struct rpc_clnt *clnt = task->tk_client;
24586 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
24587 __be32 *base, *hold;
24588- int i;
24589+ int i, tag;
24590
24591 *p++ = htonl(RPC_AUTH_UNIX);
24592 base = p++;
a4a22af8 24593@@ -157,8 +162,11 @@ unx_marshal(struct rpc_task *task, __be3
4bf69007
AM
24594 */
24595 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
4bf69007 24596
b00e13aa
AM
24597- *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
24598- *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
24599+ tag = task->tk_client->cl_tag;
a4a22af8
AM
24600+ *p++ = htonl((u32) from_kuid(&init_user_ns,
24601+ TAGINO_KUID(tag, cred->uc_uid, cred->uc_tag)));
24602+ *p++ = htonl((u32) from_kgid(&init_user_ns,
24603+ TAGINO_KGID(tag, cred->uc_gid, cred->uc_tag)));
4bf69007 24604 hold = p++;
b00e13aa
AM
24605 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
24606 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
f19bd705
AM
24607diff -NurpP --minimal linux-4.4.111/net/sunrpc/clnt.c linux-4.4.111-vs2.3.9.1/net/sunrpc/clnt.c
24608--- linux-4.4.111/net/sunrpc/clnt.c 2018-01-11 07:57:57.000000000 +0000
24609+++ linux-4.4.111-vs2.3.9.1/net/sunrpc/clnt.c 2018-01-09 16:36:34.000000000 +0000
4bf69007 24610@@ -31,6 +31,7 @@
c2e5f7c8 24611 #include <linux/in.h>
4bf69007
AM
24612 #include <linux/in6.h>
24613 #include <linux/un.h>
4bf69007
AM
24614+#include <linux/vs_cvirt.h>
24615
24616 #include <linux/sunrpc/clnt.h>
b00e13aa 24617 #include <linux/sunrpc/addr.h>
927ca606 24618@@ -477,6 +478,9 @@ static struct rpc_clnt *rpc_create_xprt(
4bf69007
AM
24619 if (!(args->flags & RPC_CLNT_CREATE_QUIET))
24620 clnt->cl_chatty = 1;
24621
24622+ /* TODO: handle RPC_CLNT_CREATE_TAGGED
24623+ if (args->flags & RPC_CLNT_CREATE_TAGGED)
24624+ clnt->cl_tag = 1; */
24625 return clnt;
24626 }
927ca606 24627
f19bd705
AM
24628diff -NurpP --minimal linux-4.4.111/net/unix/af_unix.c linux-4.4.111-vs2.3.9.1/net/unix/af_unix.c
24629--- linux-4.4.111/net/unix/af_unix.c 2018-01-11 07:57:57.000000000 +0000
24630+++ linux-4.4.111-vs2.3.9.1/net/unix/af_unix.c 2018-01-09 16:36:34.000000000 +0000
bb20add7 24631@@ -117,6 +117,8 @@
4bf69007
AM
24632 #include <net/checksum.h>
24633 #include <linux/security.h>
c2e5f7c8 24634 #include <linux/freezer.h>
4bf69007
AM
24635+#include <linux/vs_context.h>
24636+#include <linux/vs_limit.h>
24637
24638 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
24639 EXPORT_SYMBOL_GPL(unix_socket_table);
927ca606 24640@@ -282,6 +284,8 @@ static struct sock *__unix_find_socket_b
4bf69007
AM
24641 if (!net_eq(sock_net(s), net))
24642 continue;
24643
24644+ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))
24645+ continue;
24646 if (u->addr->len == len &&
24647 !memcmp(u->addr->name, sunname, len))
24648 goto found;
927ca606 24649@@ -2741,6 +2745,8 @@ static struct sock *unix_from_bucket(str
4bf69007
AM
24650 for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
24651 if (sock_net(sk) != seq_file_net(seq))
24652 continue;
24653+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24654+ continue;
24655 if (++count == offset)
24656 break;
24657 }
927ca606 24658@@ -2758,6 +2764,8 @@ static struct sock *unix_next_socket(str
4bf69007
AM
24659 sk = sk_next(sk);
24660 if (!sk)
24661 goto next_bucket;
24662+ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))
24663+ continue;
24664 if (sock_net(sk) == seq_file_net(seq))
24665 return sk;
24666 }
f19bd705
AM
24667diff -NurpP --minimal linux-4.4.111/scripts/checksyscalls.sh linux-4.4.111-vs2.3.9.1/scripts/checksyscalls.sh
24668--- linux-4.4.111/scripts/checksyscalls.sh 2015-10-29 09:21:46.000000000 +0000
24669+++ linux-4.4.111-vs2.3.9.1/scripts/checksyscalls.sh 2018-01-09 16:36:34.000000000 +0000
bb20add7 24670@@ -196,7 +196,6 @@ cat << EOF
4bf69007
AM
24671 #define __IGNORE_afs_syscall
24672 #define __IGNORE_getpmsg
24673 #define __IGNORE_putpmsg
24674-#define __IGNORE_vserver
24675 EOF
24676 }
24677
f19bd705
AM
24678diff -NurpP --minimal linux-4.4.111/security/commoncap.c linux-4.4.111-vs2.3.9.1/security/commoncap.c
24679--- linux-4.4.111/security/commoncap.c 2018-01-11 07:57:57.000000000 +0000
24680+++ linux-4.4.111-vs2.3.9.1/security/commoncap.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24681@@ -71,6 +71,7 @@ static void warn_setuid_and_fcaps_mixed(
4bf69007
AM
24682 int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
24683 int cap, int audit)
24684 {
24685+ struct vx_info *vxi = current_vx_info(); /* FIXME: get vxi from cred? */
b00e13aa 24686 struct user_namespace *ns = targ_ns;
4bf69007 24687
b00e13aa 24688 /* See if cred has the capability in the target user namespace
927ca606 24689@@ -79,8 +80,12 @@ int cap_capable(const struct cred *cred,
b00e13aa
AM
24690 */
24691 for (;;) {
4bf69007 24692 /* Do we have the necessary capabilities? */
b00e13aa 24693- if (ns == cred->user_ns)
4bf69007 24694- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
b00e13aa 24695+ if (ns == cred->user_ns) {
4bf69007
AM
24696+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) &&
24697+ cap_raised(cred->cap_effective, cap))
24698+ return 0;
24699+ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM;
24700+ }
24701
24702 /* Have we tried all of the parent namespaces? */
b00e13aa 24703 if (ns == &init_user_ns)
927ca606 24704@@ -664,7 +669,7 @@ int cap_inode_setxattr(struct dentry *de
4bf69007
AM
24705
24706 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24707 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24708- !capable(CAP_SYS_ADMIN))
24709+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24710 return -EPERM;
24711 return 0;
24712 }
927ca606 24713@@ -690,7 +695,7 @@ int cap_inode_removexattr(struct dentry
4bf69007
AM
24714
24715 if (!strncmp(name, XATTR_SECURITY_PREFIX,
24716 sizeof(XATTR_SECURITY_PREFIX) - 1) &&
24717- !capable(CAP_SYS_ADMIN))
24718+ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY))
24719 return -EPERM;
24720 return 0;
24721 }
f19bd705
AM
24722diff -NurpP --minimal linux-4.4.111/security/selinux/hooks.c linux-4.4.111-vs2.3.9.1/security/selinux/hooks.c
24723--- linux-4.4.111/security/selinux/hooks.c 2018-01-11 07:57:57.000000000 +0000
24724+++ linux-4.4.111-vs2.3.9.1/security/selinux/hooks.c 2018-01-09 16:36:34.000000000 +0000
927ca606 24725@@ -67,7 +67,6 @@
4bf69007
AM
24726 #include <linux/dccp.h>
24727 #include <linux/quota.h>
24728 #include <linux/un.h> /* for Unix socket types */
24729-#include <net/af_unix.h> /* for Unix socket types */
24730 #include <linux/parser.h>
24731 #include <linux/nfs_mount.h>
24732 #include <net/ipv6.h>
This page took 5.144298 seconds and 4 git commands to generate.